diff --git a/idea/src/org/jetbrains/jet/codegen/ClassContext.java b/idea/src/org/jetbrains/jet/codegen/ClassContext.java new file mode 100644 index 00000000000..66321d31122 --- /dev/null +++ b/idea/src/org/jetbrains/jet/codegen/ClassContext.java @@ -0,0 +1,31 @@ +/* + * @author max + */ +package org.jetbrains.jet.codegen; + +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; + +public class ClassContext { + public static final ClassContext STATIC = new ClassContext(null, OwnerKind.NAMESPACE, null); + private final DeclarationDescriptor contextType; + private final OwnerKind contextKind; + private final StackValue thisExpression; + + public ClassContext(DeclarationDescriptor contextType, OwnerKind contextKind, StackValue thisExpression) { + this.contextType = contextType; + this.contextKind = contextKind; + this.thisExpression = thisExpression; + } + + public DeclarationDescriptor getContextType() { + return contextType; + } + + public OwnerKind getContextKind() { + return contextKind; + } + + public StackValue getThisExpression() { + return thisExpression; + } +} diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index fd04f0f85e8..72a99ac834a 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -78,29 +78,23 @@ public class ExpressionCodegen extends JetVisitor { private final JetTypeMapper typeMapper; private final GenerationState state; private final Type returnType; - private final DeclarationDescriptor contextType; - private final OwnerKind contextKind; private final BindingContext bindingContext; - private final StackValue thisExpression; private final Map outerThisExpressions = new HashMap(); private final Map typeParameterExpressions = new HashMap(); + private final ClassContext context; public ExpressionCodegen(MethodVisitor v, FrameMap myMap, Type returnType, - DeclarationDescriptor contextType, - OwnerKind contextKind, - @Nullable StackValue thisExpression, + ClassContext context, GenerationState state) { this.myMap = myMap; this.typeMapper = state.getTypeMapper(); this.returnType = returnType; - this.contextType = contextType; - this.contextKind = contextKind; this.state = state; this.v = new InstructionAdapter(v); this.bindingContext = state.getBindingContext(); - this.thisExpression = thisExpression; + this.context = context; } public void addOuterThis(ClassDescriptor outer, StackValue expression) { @@ -320,6 +314,18 @@ public class ExpressionCodegen extends JetVisitor { myContinueTargets.pop(); } + private DeclarationDescriptor contextType() { + return context.getContextType(); + } + + private OwnerKind contextKind() { + return context.getContextKind(); + } + + private StackValue thisExpression() { + return context.getThisExpression(); + } + private abstract class ForLoopGenerator { protected JetForExpression expression; protected Type loopRangeType; @@ -682,7 +688,7 @@ public class ExpressionCodegen extends JetVisitor { boolean isStatic = containingDeclaration instanceof NamespaceDescriptorImpl; propertyDescriptor = propertyDescriptor.getOriginal(); final JetType outType = propertyDescriptor.getOutType(); - boolean isInsideClass = !forceInterface && containingDeclaration == contextType; + boolean isInsideClass = !forceInterface && containingDeclaration == contextType(); Method getter; Method setter; if (forceField) { @@ -697,7 +703,7 @@ public class ExpressionCodegen extends JetVisitor { String owner; boolean isInterface; if (isInsideClass || isStatic) { - owner = typeMapper.getOwner(propertyDescriptor, contextKind); + owner = typeMapper.getOwner(propertyDescriptor, contextKind()); isInterface = false; } else { @@ -891,17 +897,17 @@ public class ExpressionCodegen extends JetVisitor { } else { // TODO hope it works; really need more checks here :) - if (calleeContainingClass != null && contextType instanceof ClassDescriptor && - calleeContainingClass == contextType.getContainingDeclaration()) { + if (calleeContainingClass != null && contextType() instanceof ClassDescriptor && + calleeContainingClass == contextType().getContainingDeclaration()) { v.load(0, JetTypeMapper.TYPE_OBJECT); return StackValue.field(typeMapper.jvmType(calleeContainingClass, OwnerKind.IMPLEMENTATION), - typeMapper.jvmName((ClassDescriptor) contextType, OwnerKind.IMPLEMENTATION), + typeMapper.jvmName((ClassDescriptor) contextType(), OwnerKind.IMPLEMENTATION), "this$0", false); // TODO handle more levels of class nestng } else { - return thisExpression != null ? thisExpression : StackValue.local(0, JetTypeMapper.TYPE_OBJECT); + return thisExpression() != null ? thisExpression() : StackValue.local(0, JetTypeMapper.TYPE_OBJECT); } } } @@ -1499,18 +1505,18 @@ public class ExpressionCodegen extends JetVisitor { } private void generateThis() { - if (thisExpression != null) { - myStack.push(thisExpression); + if (thisExpression() != null) { + myStack.push(thisExpression()); return; } - if (contextKind != OwnerKind.NAMESPACE) { - ClassDescriptor contextClass = (ClassDescriptor) contextType; - final Type thisType = typeMapper.jvmType(contextClass, contextKind); - if (contextKind == OwnerKind.IMPLEMENTATION) { + if (contextKind() != OwnerKind.NAMESPACE) { + ClassDescriptor contextClass = (ClassDescriptor) contextType(); + final Type thisType = typeMapper.jvmType(contextClass, contextKind()); + if (contextKind() == OwnerKind.IMPLEMENTATION) { myStack.push(StackValue.local(0, thisType)); return; } - else if (contextKind == OwnerKind.DELEGATING_IMPLEMENTATION) { + else if (contextKind() == OwnerKind.DELEGATING_IMPLEMENTATION) { v.load(0, thisType); myStack.push(StackValue.field(JetTypeMapper.jetInterfaceType(contextClass), thisType.getInternalName(), @@ -1701,8 +1707,8 @@ public class ExpressionCodegen extends JetVisitor { return; } DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration(); - if (containingDeclaration == contextType && contextType instanceof ClassDescriptor) { - loadTypeInfo(typeMapper, (ClassDescriptor) contextType, v); + if (containingDeclaration == contextType() && contextType() instanceof ClassDescriptor) { + loadTypeInfo(typeMapper, (ClassDescriptor) contextType(), v); v.iconst(typeParameterDescriptor.getIndex()); v.invokevirtual("jet/typeinfo/TypeInfo", "getTypeParameter", "(I)Ljet/typeinfo/TypeInfo;"); return; diff --git a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java index c8a73d0d719..835065387a7 100644 --- a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -92,7 +92,8 @@ public class FunctionCodegen { } StackValue thisExpression = receiverType == null ? null : StackValue.local(thisIdx, state.getTypeMapper().mapType(receiverType)); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), contextDesc, kind, thisExpression, state); + ClassContext context = new ClassContext(contextDesc, kind, thisExpression); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), context, state); int firstArg = thisIdx+1; Type[] argTypes = jvmSignature.getArgumentTypes(); diff --git a/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 974bf4cd7ab..a31a7418e62 100644 --- a/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -112,8 +112,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor, kind); final InstructionAdapter iv = new InstructionAdapter(mv); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, - descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)), state); + ClassContext context = new ClassContext(descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind))); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state); String classname = state.getTypeMapper().jvmName(descriptor, kind); final Type classType = Type.getType("L" + classname + ";"); @@ -291,8 +291,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ConstructorFrameMap frameMap = new ConstructorFrameMap(method, constructorDescriptor, kind); final InstructionAdapter iv = new InstructionAdapter(mv); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, - descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)), state); + ClassContext context = new ClassContext(descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind))); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state); for (JetDelegationSpecifier initializer : constructor.getInitializers()) { if (initializer instanceof JetDelegatorToThisCall) { diff --git a/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 752f83159bb..4f802805dc3 100644 --- a/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -70,7 +70,7 @@ public class NamespaceCodegen { mv.visitCode(); FrameMap frameMap = new FrameMap(); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, null, OwnerKind.NAMESPACE, null, state); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, ClassContext.STATIC, state); for (JetDeclaration declaration : namespace.getDeclarations()) { if (declaration instanceof JetProperty) {