diff --git a/idea/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/idea/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index 94a34fb77e5..a9b64bd2306 100644 --- a/idea/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -3,8 +3,6 @@ package org.jetbrains.jet.codegen; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Opcodes; @@ -16,21 +14,16 @@ import java.util.List; * @author yole */ public abstract class ClassBodyCodegen { - protected final BindingContext bindingContext; - protected final JetStandardLibrary stdlib; - protected final JetTypeMapper typeMapper; - protected final Codegens factory; + protected final GenerationState state; + protected final JetClassOrObject myClass; protected final OwnerKind kind; protected final ClassDescriptor descriptor; protected final ClassVisitor v; - public ClassBodyCodegen(BindingContext bindingContext, JetStandardLibrary stdlib, JetClassOrObject aClass, OwnerKind kind, ClassVisitor v, Codegens factory) { - this.bindingContext = bindingContext; - this.stdlib = stdlib; - this.factory = factory; - this.typeMapper = new JetTypeMapper(stdlib, bindingContext); - descriptor = bindingContext.getClassDescriptor(aClass); + public ClassBodyCodegen(JetClassOrObject aClass, OwnerKind kind, ClassVisitor v, GenerationState state) { + this.state = state; + descriptor = state.getBindingContext().getClassDescriptor(aClass); myClass = aClass; this.kind = kind; this.v = v; @@ -52,8 +45,8 @@ public abstract class ClassBodyCodegen { } private void generateClassBody() { - final FunctionCodegen functionCodegen = new FunctionCodegen((JetDeclaration) myClass, v, stdlib, bindingContext, factory); - final PropertyCodegen propertyCodegen = new PropertyCodegen(v, stdlib, bindingContext, functionCodegen); + final FunctionCodegen functionCodegen = new FunctionCodegen((JetDeclaration) myClass, v, state); + final PropertyCodegen propertyCodegen = new PropertyCodegen(v, functionCodegen, state); for (JetDeclaration declaration : myClass.getDeclarations()) { generateDeclaration(propertyCodegen, declaration, functionCodegen); @@ -78,15 +71,15 @@ public abstract class ClassBodyCodegen { private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen) { for (JetParameter p : getPrimaryConstructorParameters()) { if (p.getValOrVarNode() != null) { - PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor(p); + PropertyDescriptor propertyDescriptor = state.getBindingContext().getPropertyDescriptor(p); if (propertyDescriptor != null) { propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind); if (propertyDescriptor.isVar()) { propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind); } - if (!(kind instanceof OwnerKind.DelegateKind) && kind != OwnerKind.INTERFACE && bindingContext.hasBackingField(propertyDescriptor)) { - v.visitField(Opcodes.ACC_PRIVATE, p.getName(), typeMapper.mapType(propertyDescriptor.getOutType()).getDescriptor(), null, null); + if (!(kind instanceof OwnerKind.DelegateKind) && kind != OwnerKind.INTERFACE && state.getBindingContext().hasBackingField(propertyDescriptor)) { + v.visitField(Opcodes.ACC_PRIVATE, p.getName(), state.getTypeMapper().mapType(propertyDescriptor.getOutType()).getDescriptor(), null, null); } } } @@ -99,5 +92,4 @@ public abstract class ClassBodyCodegen { } return Collections.emptyList(); } - } diff --git a/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java b/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java index 2c85846dd89..09d36e40bec 100644 --- a/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java @@ -1,13 +1,10 @@ package org.jetbrains.jet.codegen; -import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetObjectDeclaration; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; @@ -16,14 +13,10 @@ import org.objectweb.asm.commons.InstructionAdapter; * @author max */ public class ClassCodegen { - private final Project project; - private final BindingContext bindingContext; - private final Codegens factory; + private final GenerationState state; - public ClassCodegen(Project project, Codegens factory, BindingContext bindingContext) { - this.project = project; - this.factory = factory; - this.bindingContext = bindingContext; + public ClassCodegen(GenerationState state) { + this.state = state; } public void generate(JetClassOrObject aClass) { @@ -44,16 +37,16 @@ public class ClassCodegen { } private void generateInterface(JetClassOrObject aClass) { - final ClassVisitor visitor = factory.forClassInterface(bindingContext.getClassDescriptor(aClass)); - new InterfaceBodyCodegen(bindingContext, JetStandardLibrary.getJetStandardLibrary(project), aClass, visitor, factory).generate(); + final ClassVisitor visitor = state.forClassInterface(state.getBindingContext().getClassDescriptor(aClass)); + new InterfaceBodyCodegen(aClass, visitor, state).generate(); } private void generateImplementation(JetClassOrObject aClass, OwnerKind kind) { - ClassDescriptor descriptor = bindingContext.getClassDescriptor(aClass); + ClassDescriptor descriptor = state.getBindingContext().getClassDescriptor(aClass); ClassVisitor v = kind == OwnerKind.IMPLEMENTATION - ? factory.forClassImplementation(descriptor) - : factory.forClassDelegatingImplementation(descriptor); - new ImplementationBodyCodegen(bindingContext, JetStandardLibrary.getJetStandardLibrary(project), aClass, kind, v, factory).generate(); + ? state.forClassImplementation(descriptor) + : state.forClassDelegatingImplementation(descriptor); + new ImplementationBodyCodegen(aClass, kind, v, state).generate(); } diff --git a/idea/src/org/jetbrains/jet/codegen/Codegens.java b/idea/src/org/jetbrains/jet/codegen/ClassFileFactory.java similarity index 65% rename from idea/src/org/jetbrains/jet/codegen/Codegens.java rename to idea/src/org/jetbrains/jet/codegen/ClassFileFactory.java index b92392cd0c8..ab2a9753e33 100644 --- a/idea/src/org/jetbrains/jet/codegen/Codegens.java +++ b/idea/src/org/jetbrains/jet/codegen/ClassFileFactory.java @@ -2,9 +2,7 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.psi.JetNamespace; -import org.jetbrains.jet.lang.resolve.BindingContext; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.util.TraceClassVisitor; @@ -16,20 +14,22 @@ import java.util.*; /** * @author max */ -public class Codegens { +public class ClassFileFactory { private final Project project; private final boolean isText; private final Map ns2codegen = new HashMap(); private final Map generators = new LinkedHashMap(); private final Map closuresCount = new HashMap(); private boolean isDone = false; + public final GenerationState state; - public Codegens(Project project, boolean text) { + public ClassFileFactory(Project project, boolean text, GenerationState state) { this.project = project; isText = text; + this.state = state; } - public ClassVisitor newVisitor(String filePath) { + ClassVisitor newVisitor(String filePath) { ClassVisitor visitor; if (isText) { visitor = new TraceClassVisitor(new PrintWriter(new StringWriter())); @@ -42,31 +42,7 @@ public class Codegens { return visitor; } - public ClassVisitor forClassInterface(ClassDescriptor aClass) { - return newVisitor(JetTypeMapper.jvmNameForInterface(aClass) + ".class"); - } - - public ClassCodegen forClass(BindingContext bindingContext) { - return new ClassCodegen(project, this, bindingContext); - } - - public ClassVisitor forClassImplementation(ClassDescriptor aClass) { - return newVisitor(JetTypeMapper.jvmNameForImplementation(aClass) + ".class"); - } - - public ClassVisitor forClassDelegatingImplementation(ClassDescriptor aClass) { - return newVisitor(JetTypeMapper.jvmNameForDelegatingImplementation(aClass) + ".class"); - } - - public Pair forClosureIn(ClassDescriptor aClass) { - return forClosureIn(JetTypeMapper.jvmNameForInterface(aClass)); - } - - public Pair forClosureIn(JetNamespace namespace) { - return forClosureIn(NamespaceCodegen.getJVMClassName(namespace.getFQName())); - } - - private Pair forClosureIn(String baseName) { + Pair forClosureIn(String baseName) { Integer count = closuresCount.get(baseName); if (count == null) count = 0; @@ -76,12 +52,12 @@ public class Codegens { return new Pair(className, newVisitor(className + ".class")); } - public NamespaceCodegen forNamespace(JetNamespace namespace) { + NamespaceCodegen forNamespace(JetNamespace namespace) { assert !isDone : "Already done!"; String fqName = namespace.getFQName(); NamespaceCodegen codegen = ns2codegen.get(fqName); if (codegen == null) { - codegen = new NamespaceCodegen(project, newVisitor(NamespaceCodegen.getJVMClassName(fqName) + ".class"), fqName, this); + codegen = new NamespaceCodegen(project, newVisitor(NamespaceCodegen.getJVMClassName(fqName) + ".class"), fqName, state); ns2codegen.put(fqName, codegen); } diff --git a/idea/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/idea/src/org/jetbrains/jet/codegen/ClosureCodegen.java index e6f5936fa01..e304a74b519 100644 --- a/idea/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -9,8 +9,6 @@ import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.jetbrains.jet.lang.types.JetType; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; @@ -24,14 +22,10 @@ import java.util.Arrays; import java.util.List; public class ClosureCodegen { - private final BindingContext bindingContext; - private final JetTypeMapper typeMapper; - private final Codegens factory; + private final GenerationState state; - public ClosureCodegen(BindingContext bindingContext, JetTypeMapper typeMapper, Codegens factory) { - this.bindingContext = bindingContext; - this.typeMapper = typeMapper; - this.factory = factory; + public ClosureCodegen(GenerationState state) { + this.state = state; } public static Method erasedInvokeSignature(FunctionDescriptor fd) { @@ -47,7 +41,7 @@ public class ClosureCodegen { } public Method invokeSignature(FunctionDescriptor fd) { - return typeMapper.mapSignature("invoke", fd); + return state.getTypeMapper().mapSignature("invoke", fd); } public GeneratedClosureDescriptor gen(JetFunctionLiteralExpression fun) { @@ -55,14 +49,14 @@ public class ClosureCodegen { final Pair nameAndVisitor; if (container instanceof JetNamespace) { - nameAndVisitor = factory.forClosureIn((JetNamespace) container); + nameAndVisitor = state.forClosureIn((JetNamespace) container); } else { - nameAndVisitor = factory.forClosureIn(bindingContext.getClassDescriptor((JetClassOrObject) container)); + nameAndVisitor = state.forClosureIn(state.getBindingContext().getClassDescriptor((JetClassOrObject) container)); } - final FunctionDescriptor funDescriptor = (FunctionDescriptor) bindingContext.getDeclarationDescriptor(fun); + final FunctionDescriptor funDescriptor = (FunctionDescriptor) state.getBindingContext().getDeclarationDescriptor(fun); final ClassVisitor cv = nameAndVisitor.getSecond(); final String name = nameAndVisitor.getFirst(); @@ -98,7 +92,7 @@ public class ClosureCodegen { } private void generateBody(String className, FunctionDescriptor funDescriptor, ClassVisitor cv, Project project, List body) { - FunctionCodegen fc = new FunctionCodegen(null, cv, JetStandardLibrary.getJetStandardLibrary(project), bindingContext, factory); + FunctionCodegen fc = new FunctionCodegen(null, cv, state); fc.generatedMethod(body, OwnerKind.IMPLEMENTATION, invokeSignature(funDescriptor), null, funDescriptor.getUnsubstitutedValueParameters(), null); } @@ -106,7 +100,7 @@ public class ClosureCodegen { final Method bridge = erasedInvokeSignature(funDescriptor); final Method delegate = invokeSignature(funDescriptor); - final MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "invoke", bridge.getDescriptor(), typeMapper.genericSignature(funDescriptor), new String[0]); + final MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "invoke", bridge.getDescriptor(), state.getTypeMapper().genericSignature(funDescriptor), new String[0]); mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); @@ -117,7 +111,7 @@ public class ClosureCodegen { int count = 1; for (ValueParameterDescriptor param : params) { StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); - StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(typeMapper.mapType(param.getOutType()), iv); + StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getTypeMapper().mapType(param.getOutType()), iv); count++; } @@ -160,6 +154,7 @@ public class ClosureCodegen { private void appendType(SignatureWriter signatureWriter, JetType type, char variance) { signatureWriter.visitTypeArgument(variance); + final JetTypeMapper typeMapper = state.getTypeMapper(); final Type rawRetType = typeMapper.boxType(typeMapper.mapType(type)); signatureWriter.visitClassType(rawRetType.getInternalName()); signatureWriter.visitEnd(); diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index d744a98fdeb..30c0dd42b60 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -12,7 +12,10 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.*; +import org.jetbrains.jet.lang.types.JetStandardClasses; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.resolve.DescriptorRenderer; import org.objectweb.asm.Label; @@ -61,7 +64,7 @@ public class ExpressionCodegen extends JetVisitor { private final InstructionAdapter v; private final FrameMap myMap; private final JetTypeMapper typeMapper; - private final Codegens factory; + private final GenerationState state; private final Type returnType; private final DeclarationDescriptor contextType; private final OwnerKind contextKind; @@ -70,22 +73,20 @@ public class ExpressionCodegen extends JetVisitor { private final Map outerThisExpressions = new HashMap(); public ExpressionCodegen(MethodVisitor v, - BindingContext bindingContext, FrameMap myMap, - JetTypeMapper typeMapper, Type returnType, DeclarationDescriptor contextType, OwnerKind contextKind, @Nullable StackValue thisExpression, - Codegens factory) { + GenerationState state) { this.myMap = myMap; - this.typeMapper = typeMapper; + this.typeMapper = state.getTypeMapper(); this.returnType = returnType; this.contextType = contextType; this.contextKind = contextKind; - this.factory = factory; + this.state = state; this.v = new InstructionAdapter(v); - this.bindingContext = bindingContext; + this.bindingContext = state.getBindingContext(); this.thisExpression = thisExpression; } @@ -481,7 +482,7 @@ public class ExpressionCodegen extends JetVisitor { generateBlock(expression.getFunctionLiteral().getBodyExpression().getStatements()); } else { - final GeneratedClosureDescriptor closure = new ClosureCodegen(bindingContext, typeMapper, factory).gen(expression); + final GeneratedClosureDescriptor closure = new ClosureCodegen(state).gen(expression); v.anew(Type.getObjectType(closure.getClassname())); v.dup(); v.invokespecial(closure.getClassname(), "", closure.getConstructor().getDescriptor()); diff --git a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java index ee2c0c57dae..45a66dafeea 100644 --- a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -4,8 +4,6 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.jetbrains.jet.lang.types.JetType; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; @@ -23,23 +21,19 @@ import java.util.List; public class FunctionCodegen { private final JetDeclaration owner; private final ClassVisitor v; - private final BindingContext bindingContext; - private final JetTypeMapper typeMapper; - private final Codegens factory; + private final GenerationState state; - public FunctionCodegen(JetDeclaration owner, ClassVisitor v, JetStandardLibrary standardLibrary, BindingContext bindingContext, Codegens factory) { + public FunctionCodegen(JetDeclaration owner, ClassVisitor v, GenerationState state) { this.owner = owner; this.v = v; - this.bindingContext = bindingContext; - this.factory = factory; - typeMapper = new JetTypeMapper(standardLibrary, bindingContext); + this.state = state; } public void gen(JetNamedFunction f, OwnerKind kind) { final JetTypeReference receiverTypeRef = f.getReceiverTypeRef(); - final JetType receiverType = receiverTypeRef == null ? null : bindingContext.resolveTypeReference(receiverTypeRef); - Method method = typeMapper.mapSignature(f); - List paramDescrs = bindingContext.getFunctionDescriptor(f).getUnsubstitutedValueParameters(); + final JetType receiverType = receiverTypeRef == null ? null : state.getBindingContext().resolveTypeReference(receiverTypeRef); + Method method = state.getTypeMapper().mapSignature(f); + List paramDescrs = state.getBindingContext().getFunctionDescriptor(f).getUnsubstitutedValueParameters(); generateMethod(f, kind, method, receiverType, paramDescrs); } @@ -49,8 +43,8 @@ public class FunctionCodegen { @Nullable JetType receiverType, List paramDescrs) { final DeclarationDescriptor contextDesc = owner instanceof JetClassOrObject - ? bindingContext.getClassDescriptor((JetClassOrObject) owner) - : bindingContext.getNamespaceDescriptor((JetNamespace) owner); + ? state.getBindingContext().getClassDescriptor((JetClassOrObject) owner) + : state.getBindingContext().getNamespaceDescriptor((JetNamespace) owner); final JetExpression bodyExpression = f.getBodyExpression(); final List bodyExpressions = bodyExpression != null ? Collections.singletonList(bodyExpression) : null; generatedMethod(bodyExpressions, kind, jvmSignature, receiverType, paramDescrs, contextDesc); @@ -90,9 +84,8 @@ public class FunctionCodegen { frameMap.enter(parameter, argTypes[i].getSize()); } - StackValue thisExpression = receiverType == null ? null : StackValue.local(0, typeMapper.mapType(receiverType)); - ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, - jvmSignature.getReturnType(), contextDesc, kind, thisExpression, factory); + StackValue thisExpression = receiverType == null ? null : StackValue.local(0, state.getTypeMapper().mapType(receiverType)); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), contextDesc, kind, thisExpression, state); if (kind instanceof OwnerKind.DelegateKind) { OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind; InstructionAdapter iv = new InstructionAdapter(mv); diff --git a/idea/src/org/jetbrains/jet/codegen/GenerationState.java b/idea/src/org/jetbrains/jet/codegen/GenerationState.java new file mode 100644 index 00000000000..a668d2c6473 --- /dev/null +++ b/idea/src/org/jetbrains/jet/codegen/GenerationState.java @@ -0,0 +1,97 @@ +/* + * @author max + */ +package org.jetbrains.jet.codegen; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.util.containers.Stack; +import org.jetbrains.jet.lang.ErrorHandler; +import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.lang.resolve.AnalyzingUtils; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.types.JetStandardLibrary; +import org.objectweb.asm.ClassVisitor; + +public class GenerationState { + private final ClassFileFactory factory; + private final Project project; + + private JetTypeMapper typeMapper; + private final Stack bindingContexts; + private final JetStandardLibrary standardLibrary; + + public GenerationState(Project project, boolean text) { + this.project = project; + this.bindingContexts = new Stack(); + this.standardLibrary = JetStandardLibrary.getJetStandardLibrary(project); + this.factory = new ClassFileFactory(project, text, this); + } + + public ClassFileFactory getFactory() { + return factory; + } + + public Project getProject() { + return project; + } + + public JetTypeMapper getTypeMapper() { + return typeMapper; + } + + public BindingContext getBindingContext() { + return bindingContexts.peek(); + } + + public JetStandardLibrary getStandardLibrary() { + return standardLibrary; + } + + public ClassVisitor forClassInterface(ClassDescriptor aClass) { + return factory.newVisitor(JetTypeMapper.jvmNameForInterface(aClass) + ".class"); + } + + public ClassCodegen forClass() { + return new ClassCodegen(this); + } + + public ClassVisitor forClassImplementation(ClassDescriptor aClass) { + return factory.newVisitor(JetTypeMapper.jvmNameForImplementation(aClass) + ".class"); + } + + public ClassVisitor forClassDelegatingImplementation(ClassDescriptor aClass) { + return factory.newVisitor(JetTypeMapper.jvmNameForDelegatingImplementation(aClass) + ".class"); + } + + public Pair forClosureIn(ClassDescriptor aClass) { + return factory.forClosureIn(JetTypeMapper.jvmNameForInterface(aClass)); + } + + public Pair forClosureIn(JetNamespace namespace) { + return factory.forClosureIn(NamespaceCodegen.getJVMClassName(namespace.getFQName())); + } + + public NamespaceCodegen forNamespace(JetNamespace namespace) { + return factory.forNamespace(namespace); + } + + public void compile(JetFile psiFile) { + final JetNamespace namespace = ((JetFile) psiFile).getRootNamespace(); + NamespaceCodegen codegen = forNamespace(namespace); + final BindingContext bindingContext = AnalyzingUtils.analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY); + bindingContexts.push(bindingContext); + typeMapper = new JetTypeMapper(standardLibrary, bindingContext); + try { + AnalyzingUtils.applyHandler(ErrorHandler.THROW_EXCEPTION, bindingContext); + codegen.generate(namespace); + } + finally { + bindingContexts.pop(); + typeMapper = null; + } + } +} diff --git a/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 11d881819ca..6b02264f326 100644 --- a/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -4,8 +4,6 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.jetbrains.jet.lang.types.JetType; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; @@ -21,9 +19,8 @@ import java.util.*; * @author yole */ public class ImplementationBodyCodegen extends ClassBodyCodegen { - public ImplementationBodyCodegen(BindingContext bindingContext, JetStandardLibrary stdlib, JetClassOrObject aClass, - OwnerKind kind, ClassVisitor v, Codegens factory) { - super(bindingContext, stdlib, aClass, kind, v, factory); + public ImplementationBodyCodegen(JetClassOrObject aClass, OwnerKind kind, ClassVisitor v, GenerationState state) { + super(aClass, kind, v, state); } @Override @@ -55,9 +52,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetDelegationSpecifier first = delegationSpecifiers.get(0); if (first instanceof JetDelegatorToSuperClass || first instanceof JetDelegatorToSuperCall) { - JetType superType = bindingContext.resolveTypeReference(first.getTypeReference()); + JetType superType = state.getBindingContext().resolveTypeReference(first.getTypeReference()); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); - return typeMapper.jvmName(superClassDescriptor, kind); + return state.getTypeMapper().jvmName(superClassDescriptor, kind); } return "java/lang/Object"; @@ -86,7 +83,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } protected void generatePrimaryConstructor() { - ConstructorDescriptor constructorDescriptor = bindingContext.getConstructorDescriptor((JetElement) myClass); + ConstructorDescriptor constructorDescriptor = state.getBindingContext().getConstructorDescriptor((JetElement) myClass); if (constructorDescriptor == null && !(myClass instanceof JetObjectDeclaration)) return; Method method; @@ -94,7 +91,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { method = new Method("", Type.VOID_TYPE, new Type[0]); } else { - method = typeMapper.mapConstructorSignature(constructorDescriptor, kind); + method = state.getTypeMapper().mapConstructorSignature(constructorDescriptor, kind); } int flags = Opcodes.ACC_PUBLIC; // TODO final MethodVisitor mv = v.visitMethod(flags, "", method.getDescriptor(), null, null); @@ -105,13 +102,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ? constructorDescriptor.getUnsubstitutedValueParameters() : Collections.emptyList(); - ConstructorFrameMap frameMap = new ConstructorFrameMap(typeMapper, constructorDescriptor, kind); + ConstructorFrameMap frameMap = new ConstructorFrameMap(state.getTypeMapper(), constructorDescriptor, kind); final InstructionAdapter iv = new InstructionAdapter(mv); - ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, Type.VOID_TYPE, - descriptor, kind, StackValue.local(0, typeMapper.jvmType(descriptor, kind)), factory); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, + descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)), state); - String classname = typeMapper.jvmName(descriptor, kind); + String classname = state.getTypeMapper().jvmName(descriptor, kind); final Type classType = Type.getType("L" + classname + ";"); List specifiers = myClass.getDelegationSpecifiers(); @@ -120,7 +117,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { // TODO correct calculation of super class String superClass = "java/lang/Object"; if (!specifiers.isEmpty()) { - final JetType superType = bindingContext.resolveTypeReference(specifiers.get(0).getTypeReference()); + final JetType superType = state.getBindingContext().resolveTypeReference(specifiers.get(0).getTypeReference()); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); if (superClassDescriptor.hasConstructors()) { superClass = getSuperClass(); @@ -153,8 +150,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { HashSet overridden = new HashSet(); for (JetDeclaration declaration : myClass.getDeclarations()) { - if (declaration instanceof JetNamedFunction) { - overridden.addAll(bindingContext.getFunctionDescriptor((JetNamedFunction) declaration).getOverriddenFunctions()); + if (declaration instanceof JetFunction) { + overridden.addAll(state.getBindingContext().getFunctionDescriptor((JetFunction) declaration).getOverriddenFunctions()); } } @@ -168,7 +165,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } if (specifier instanceof JetDelegatorToSuperCall) { - ConstructorDescriptor constructorDescriptor1 = bindingContext.resolveSuperConstructor((JetDelegatorToSuperCall) specifier); + ConstructorDescriptor constructorDescriptor1 = state.getBindingContext().resolveSuperConstructor((JetDelegatorToSuperCall) specifier); generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) specifier, constructorDescriptor1, n == 0, frameMap); } else if (specifier instanceof JetDelegatorByExpressionSpecifier) { @@ -176,7 +173,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } if (delegateOnStack) { - JetType superType = bindingContext.resolveTypeReference(specifier.getTypeReference()); + JetType superType = state.getBindingContext().resolveTypeReference(specifier.getTypeReference()); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); String delegateField = "$delegate_" + n; Type fieldType = JetTypeMapper.jetInterfaceType(superClassDescriptor); @@ -184,7 +181,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { v.visitField(Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null); iv.putfield(classname, delegateField, fieldDesc); - JetClass superClass = (JetClass) bindingContext.getDeclarationPsiElement(superClassDescriptor); + JetClass superClass = (JetClass) state.getBindingContext().getDeclarationPsiElement(superClassDescriptor); generateDelegates(myClass, superClass, new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false), JetTypeMapper.jvmNameForInterface(superClassDescriptor)), overridden); @@ -204,7 +201,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { for (JetParameter parameter : constructorParameters) { if (parameter.getValOrVarNode() != null) { VariableDescriptor descriptor = paramDescrs.get(curParam); - Type type = typeMapper.mapType(descriptor.getOutType()); + Type type = state.getTypeMapper().mapType(descriptor.getOutType()); iv.load(0, classType); iv.load(frameMap.getIndex(descriptor), type); iv.putfield(classname, descriptor.getName(), type.getDescriptor()); @@ -222,7 +219,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ConstructorFrameMap frameMap) { ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration(); boolean isDelegating = kind == OwnerKind.DELEGATING_IMPLEMENTATION; - PsiElement declaration = bindingContext.getDeclarationPsiElement(classDecl); + PsiElement declaration = state.getBindingContext().getDeclarationPsiElement(classDecl); Type type; if (declaration instanceof PsiClass) { type = JetTypeMapper.psiClassType((PsiClass) declaration); @@ -248,18 +245,18 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } if (kind == OwnerKind.DELEGATING_IMPLEMENTATION) { - iv.load(frameMap.getDelegateThisIndex(), typeMapper.jvmType(classDecl, OwnerKind.INTERFACE)); + iv.load(frameMap.getDelegateThisIndex(), state.getTypeMapper().jvmType(classDecl, OwnerKind.INTERFACE)); } if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) { - iv.load(frameMap.getOuterThisIndex(), typeMapper.jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION)); + iv.load(frameMap.getOuterThisIndex(), state.getTypeMapper().jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION)); } - Method method = typeMapper.mapConstructorSignature(constructorDescriptor, kind); + Method method = state.getTypeMapper().mapConstructorSignature(constructorDescriptor, kind); List valueParameters = constructorDescriptor.getUnsubstitutedValueParameters(); List args = constructorCall.getValueArguments(); for (int i = 0, argsSize = args.size(); i < argsSize; i++) { JetArgument arg = args.get(i); - codegen.gen(arg.getArgumentExpression(), typeMapper.mapType(valueParameters.get(i).getOutType())); + codegen.gen(arg.getArgumentExpression(), state.getTypeMapper().mapType(valueParameters.get(i).getOutType())); } iv.invokespecial(type.getInternalName(), "", method.getDescriptor()); @@ -276,25 +273,25 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void generateSecondaryConstructor(JetConstructor constructor) { - ConstructorDescriptor constructorDescriptor = bindingContext.getConstructorDescriptor(constructor); + ConstructorDescriptor constructorDescriptor = state.getBindingContext().getConstructorDescriptor(constructor); if (constructorDescriptor == null) { throw new UnsupportedOperationException("failed to get descriptor for secondary constructor"); } - Method method = typeMapper.mapConstructorSignature(constructorDescriptor, kind); + Method method = state.getTypeMapper().mapConstructorSignature(constructorDescriptor, kind); int flags = Opcodes.ACC_PUBLIC; // TODO final MethodVisitor mv = v.visitMethod(flags, "", method.getDescriptor(), null, null); mv.visitCode(); - ConstructorFrameMap frameMap = new ConstructorFrameMap(typeMapper, constructorDescriptor, kind); + ConstructorFrameMap frameMap = new ConstructorFrameMap(state.getTypeMapper(), constructorDescriptor, kind); final InstructionAdapter iv = new InstructionAdapter(mv); - ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, Type.VOID_TYPE, - descriptor, kind, StackValue.local(0, typeMapper.jvmType(descriptor, kind)), factory); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, + descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)), state); for (JetDelegationSpecifier initializer : constructor.getInitializers()) { if (initializer instanceof JetDelegatorToThisCall) { JetDelegatorToThisCall thisCall = (JetDelegatorToThisCall) initializer; - DeclarationDescriptor thisDescriptor = bindingContext.resolveReferenceExpression(thisCall.getThisReference()); + DeclarationDescriptor thisDescriptor = state.getBindingContext().resolveReferenceExpression(thisCall.getThisReference()); if (!(thisDescriptor instanceof ConstructorDescriptor)) { throw new UnsupportedOperationException("expected 'this' delegator to resolve to constructor"); } @@ -320,7 +317,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.anew(JetTypeMapper.TYPE_TYPEINFO); iv.dup(); - iv.aconst(typeMapper.jvmType(descriptor, OwnerKind.INTERFACE)); + iv.aconst(state.getTypeMapper().jvmType(descriptor, OwnerKind.INTERFACE)); iv.iconst(typeParamCount); iv.newarray(JetTypeMapper.TYPE_TYPEINFO); @@ -331,14 +328,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.astore(JetTypeMapper.TYPE_OBJECT); } iv.invokespecial("jet/typeinfo/TypeInfo", "", "(Ljava/lang/Class;[Ljet/typeinfo/TypeInfo;)V"); - iv.putfield(typeMapper.jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$typeInfo", "Ljet/typeinfo/TypeInfo;"); + iv.putfield(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$typeInfo", "Ljet/typeinfo/TypeInfo;"); } protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) { for (JetDeclaration declaration : myClass.getDeclarations()) { if (declaration instanceof JetProperty) { - final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.getVariableDescriptor((JetProperty) declaration); - if (bindingContext.hasBackingField(propertyDescriptor)) { + final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().getVariableDescriptor((JetProperty) declaration); + if (state.getBindingContext().hasBackingField(propertyDescriptor)) { final JetExpression initializer = ((JetProperty) declaration).getInitializer(); if (initializer != null) { iv.load(0, JetTypeMapper.TYPE_OBJECT); @@ -355,23 +352,23 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } protected void generateDelegates(JetClassOrObject inClass, JetClass toClass, OwnerKind kind, Set overriden) { - final FunctionCodegen functionCodegen = new FunctionCodegen(toClass, v, stdlib, bindingContext, factory); - final PropertyCodegen propertyCodegen = new PropertyCodegen(v, stdlib, bindingContext, functionCodegen); + final FunctionCodegen functionCodegen = new FunctionCodegen(toClass, v, state); + final PropertyCodegen propertyCodegen = new PropertyCodegen(v, functionCodegen, state); for (JetDeclaration declaration : toClass.getDeclarations()) { if (declaration instanceof JetProperty) { propertyCodegen.gen((JetProperty) declaration, kind); } - else if (declaration instanceof JetNamedFunction) { - if (!overriden.contains(bindingContext.getFunctionDescriptor((JetNamedFunction) declaration))) { - functionCodegen.gen((JetNamedFunction) declaration, kind); + else if (declaration instanceof JetFunction) { + if (!overriden.contains(state.getBindingContext().getFunctionDescriptor((JetFunction) declaration))) { + functionCodegen.gen((JetFunction) declaration, kind); } } } for (JetParameter p : toClass.getPrimaryConstructorParameters()) { if (p.getValOrVarNode() != null) { - PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor(p); + PropertyDescriptor propertyDescriptor = state.getBindingContext().getPropertyDescriptor(p); if (propertyDescriptor != null) { propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind); if (propertyDescriptor.isVar()) { @@ -396,7 +393,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { InstructionAdapter v = new InstructionAdapter(mv); if (needTypeInfo) { - ClassCodegen.newTypeInfo(v, typeMapper.jvmType(descriptor, OwnerKind.INTERFACE)); + ClassCodegen.newTypeInfo(v, state.getTypeMapper().jvmType(descriptor, OwnerKind.INTERFACE)); v.putstatic(JetTypeMapper.jvmNameForImplementation(descriptor), "$typeInfo", "Ljet/typeinfo/TypeInfo;"); } if (needInstance) { diff --git a/idea/src/org/jetbrains/jet/codegen/InterfaceBodyCodegen.java b/idea/src/org/jetbrains/jet/codegen/InterfaceBodyCodegen.java index c54071af164..3cecc1df70c 100644 --- a/idea/src/org/jetbrains/jet/codegen/InterfaceBodyCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/InterfaceBodyCodegen.java @@ -5,8 +5,6 @@ import com.intellij.psi.PsiElement; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetDelegationSpecifier; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.jetbrains.jet.lang.types.JetType; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Opcodes; @@ -19,8 +17,8 @@ import java.util.Set; * @author yole */ public class InterfaceBodyCodegen extends ClassBodyCodegen { - public InterfaceBodyCodegen(BindingContext bindingContext, JetStandardLibrary stdlib, JetClassOrObject aClass, ClassVisitor v, Codegens factory) { - super(bindingContext, stdlib, aClass, OwnerKind.INTERFACE, v, factory); + public InterfaceBodyCodegen(JetClassOrObject aClass, ClassVisitor v, GenerationState state) { + super(aClass, OwnerKind.INTERFACE, v, state); } protected void generateDeclaration() { @@ -41,9 +39,9 @@ public class InterfaceBodyCodegen extends ClassBodyCodegen { String superClassName = null; Set superInterfaces = new LinkedHashSet(); for (JetDelegationSpecifier specifier : delegationSpecifiers) { - JetType superType = bindingContext.resolveTypeReference(specifier.getTypeReference()); + JetType superType = state.getBindingContext().resolveTypeReference(specifier.getTypeReference()); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); - PsiElement superPsi = bindingContext.getDeclarationPsiElement(superClassDescriptor); + PsiElement superPsi = state.getBindingContext().getDeclarationPsiElement(superClassDescriptor); if (superPsi instanceof PsiClass) { PsiClass psiClass = (PsiClass) superPsi; diff --git a/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index f8ab79b7467..99ae887905f 100644 --- a/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -1,12 +1,8 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.project.Project; -import org.jetbrains.jet.lang.ErrorHandler; -import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.AnalyzingUtils; -import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; @@ -20,12 +16,12 @@ import org.objectweb.asm.commons.InstructionAdapter; public class NamespaceCodegen { private final Project project; private final ClassVisitor v; - private final Codegens codegens; + private final GenerationState state; - public NamespaceCodegen(Project project, ClassVisitor v, String fqName, Codegens codegens) { + public NamespaceCodegen(Project project, ClassVisitor v, String fqName, GenerationState state) { this.project = project; this.v = v; - this.codegens = codegens; + this.state = state; v.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, @@ -34,23 +30,17 @@ public class NamespaceCodegen { //"jet/lang/Namespace", "java/lang/Object", new String[0] - ); + ); } public void generate(JetNamespace namespace) { - generate(namespace, AnalyzingUtils.analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY)); - } - - public void generate(JetNamespace namespace, BindingContext bindingContext) { - AnalyzingUtils.applyHandler(ErrorHandler.THROW_EXCEPTION, bindingContext); - final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project); - final FunctionCodegen functionCodegen = new FunctionCodegen(namespace, v, standardLibrary, bindingContext, codegens); - final PropertyCodegen propertyCodegen = new PropertyCodegen(v, standardLibrary, bindingContext, functionCodegen); - final ClassCodegen classCodegen = codegens.forClass(bindingContext); + final FunctionCodegen functionCodegen = new FunctionCodegen(namespace, v, state); + final PropertyCodegen propertyCodegen = new PropertyCodegen(v, functionCodegen, state); + final ClassCodegen classCodegen = state.forClass(); if (hasNonConstantPropertyInitializers(namespace)) { - generateStaticInitializers(namespace, bindingContext); + generateStaticInitializers(namespace); } for (JetDeclaration declaration : namespace.getDeclarations()) { @@ -69,25 +59,24 @@ public class NamespaceCodegen { } else if (declaration instanceof JetNamespace) { JetNamespace childNamespace = (JetNamespace) declaration; - codegens.forNamespace(childNamespace).generate(childNamespace, bindingContext); + state.forNamespace(childNamespace).generate(childNamespace); } } } - private void generateStaticInitializers(JetNamespace namespace, BindingContext bindingContext) { + private void generateStaticInitializers(JetNamespace namespace) { MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "", "()V", null, null); mv.visitCode(); FrameMap frameMap = new FrameMap(); - JetTypeMapper typeMapper = new JetTypeMapper(JetStandardLibrary.getJetStandardLibrary(namespace.getProject()), bindingContext); - ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, Type.VOID_TYPE, null, OwnerKind.NAMESPACE, null, codegens); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, null, OwnerKind.NAMESPACE, null, state); for (JetDeclaration declaration : namespace.getDeclarations()) { if (declaration instanceof JetProperty) { final JetExpression initializer = ((JetProperty) declaration).getInitializer(); if (initializer != null && !(initializer instanceof JetConstantExpression)) { - final PropertyDescriptor descriptor = (PropertyDescriptor) bindingContext.getVariableDescriptor((JetProperty) declaration); + final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().getVariableDescriptor((JetProperty) declaration); codegen.genToJVMStack(initializer); codegen.intermediateValueForProperty(descriptor, false, false).store(new InstructionAdapter(mv)); } diff --git a/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 545b113470a..0d224317dc9 100644 --- a/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -7,7 +7,6 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lexer.JetTokens; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; @@ -21,16 +20,18 @@ import java.util.Collections; * @author max */ public class PropertyCodegen { + private final GenerationState state; private final BindingContext context; private final FunctionCodegen functionCodegen; private final ClassVisitor v; private final JetTypeMapper mapper; - public PropertyCodegen(ClassVisitor v, JetStandardLibrary standardLibrary, BindingContext context, FunctionCodegen functionCodegen) { + public PropertyCodegen(ClassVisitor v, FunctionCodegen functionCodegen, GenerationState state) { this.v = v; - this.context = context; this.functionCodegen = functionCodegen; - this.mapper = new JetTypeMapper(standardLibrary, context); + this.state = state; + mapper = state.getTypeMapper(); + context = state.getBindingContext(); } public void gen(JetProperty p, OwnerKind kind) { diff --git a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java index 0fe9f5b3c27..df5e4d7f02f 100644 --- a/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java +++ b/idea/src/org/jetbrains/jet/plugin/compiler/JetCompiler.java @@ -12,11 +12,10 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.util.Chunk; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.codegen.Codegens; -import org.jetbrains.jet.codegen.NamespaceCodegen; -import org.jetbrains.jet.plugin.JetFileType; +import org.jetbrains.jet.codegen.ClassFileFactory; +import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.psi.JetNamespace; +import org.jetbrains.jet.plugin.JetFileType; import java.io.File; import java.io.IOException; @@ -65,7 +64,7 @@ public class JetCompiler implements TranslatingCompiler { } private static class ModuleCompileState { - private final Codegens codegens; + private final GenerationState state; private final CompileContext compileContext; private final Module module; private final OutputSink outputSink; @@ -74,7 +73,7 @@ public class JetCompiler implements TranslatingCompiler { this.compileContext = compileContext; this.module = module; this.outputSink = outputSink; - codegens = new Codegens(compileContext.getProject(), false); + state = new GenerationState(compileContext.getProject(), false); } public void compile(final VirtualFile virtualFile) { @@ -83,9 +82,7 @@ public class JetCompiler implements TranslatingCompiler { public void run() { PsiFile psiFile = PsiManager.getInstance(module.getProject()).findFile(virtualFile); if (psiFile instanceof JetFile) { - final JetNamespace namespace = ((JetFile) psiFile).getRootNamespace(); - NamespaceCodegen codegen = codegens.forNamespace(namespace); - codegen.generate(namespace); + state.compile((JetFile) psiFile); } } }); @@ -93,11 +90,12 @@ public class JetCompiler implements TranslatingCompiler { public void done() { VirtualFile outputDir = compileContext.getModuleOutputDirectory(module); - List files = codegens.files(); + final ClassFileFactory factory = state.getFactory(); + List files = factory.files(); for (String file : files) { File target = new File(outputDir.getPath(), file); try { - FileUtil.writeToFile(target, codegens.asBytes(file)); + FileUtil.writeToFile(target, factory.asBytes(file)); } catch (IOException e) { compileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, 0, 0); } diff --git a/idea/testData/codegen/classes/enclosingLocalVariable.jet b/idea/testData/codegen/classes/enclosingLocalVariable.jet new file mode 100644 index 00000000000..57ce1d33833 --- /dev/null +++ b/idea/testData/codegen/classes/enclosingLocalVariable.jet @@ -0,0 +1,8 @@ +fun box() : String { + val cl = 39 + return if (sum(200, { cl }) == 2) "OK" else "FAIL" +} + +fun sum(arg:Int, f : {() : Int}) : Int { + return arg + f() +} diff --git a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java index 4a21d7faa56..7c8560bb6fa 100644 --- a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -72,7 +72,7 @@ public class ClassGenTest extends CodegenTestCase { public void testAbstractMethod() throws Exception { loadText("class Foo { abstract fun x(): String; fun y(): Int = 0 }"); - final Codegens codegens = generateClassesInFile(); + final ClassFileFactory codegens = generateClassesInFile(); final Class aClass = loadClass("Foo", codegens); assertNotNull(aClass.getMethod("x")); final Class implClass = loadClass("Foo$$Impl", codegens); diff --git a/idea/tests/org/jetbrains/jet/codegen/ClosuresGenTest.java b/idea/tests/org/jetbrains/jet/codegen/ClosuresGenTest.java index 6be33e761e0..02031d3d0af 100644 --- a/idea/tests/org/jetbrains/jet/codegen/ClosuresGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/ClosuresGenTest.java @@ -23,4 +23,8 @@ public class ClosuresGenTest extends CodegenTestCase { public void testExtensionClosure() throws Exception { blackBoxFile("classes/extensionClosure.jet"); } + + public void testEnclosingLocalVariable() throws Exception { + blackBoxFile("classes/enclosingLocalVariable.jet"); + } } diff --git a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index f38ffc9800c..bb8aed70251 100644 --- a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -6,11 +6,11 @@ import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetLightProjectDescriptor; -import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamespace; import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.parsing.JetParsingTest; +import org.jetbrains.jet.plugin.JetFileType; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -79,7 +79,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { } protected String blackBox() throws Exception { - Codegens codegens = generateClassesInFile(); + ClassFileFactory codegens = generateClassesInFile(); CodegensClassLoader loader = new CodegensClassLoader(codegens); JetFile jetFile = (JetFile) myFixture.getFile(); @@ -91,30 +91,29 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { } protected String generateToText() { - Codegens state = new Codegens(getProject(), true); + GenerationState state = new GenerationState(getProject(), true); JetFile jetFile = (JetFile) myFixture.getFile(); AnalyzingUtils.checkForSyntacticErrors(jetFile); - JetNamespace namespace = jetFile.getRootNamespace(); - NamespaceCodegen codegen = state.forNamespace(namespace); - codegen.generate(namespace); + state.compile(jetFile); StringBuilder answer = new StringBuilder(); - List files = state.files(); + final ClassFileFactory factory = state.getFactory(); + List files = factory.files(); for (String file : files) { answer.append("@").append(file).append('\n'); - answer.append(state.asText(file)); + answer.append(factory.asText(file)); } return answer.toString(); } protected Class generateNamespaceClass() { - Codegens state = generateClassesInFile(); + ClassFileFactory state = generateClassesInFile(); return loadRootNamespaceClass(state); } - protected Class loadRootNamespaceClass(Codegens state) { + protected Class loadRootNamespaceClass(ClassFileFactory state) { JetFile jetFile = (JetFile) myFixture.getFile(); final JetNamespace namespace = jetFile.getRootNamespace(); String fqName = NamespaceCodegen.getJVMClassName(namespace.getFQName()).replace("/", "."); @@ -122,7 +121,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { return classMap.get(fqName); } - protected Class loadClass(String fqName, Codegens state) { + protected Class loadClass(String fqName, ClassFileFactory state) { List files = state.files(); for (String file : files) { if (file.equals(fqName.replace('.', '/') + ".class")) { @@ -135,7 +134,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { return null; } - protected Map loadAllClasses(Codegens state) { + protected Map loadAllClasses(ClassFileFactory state) { Map result = new HashMap(); for (String fileName : state.files()) { String className = StringUtil.trimEnd(fileName, ".class").replace('/', '.'); @@ -146,16 +145,14 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { return result; } - protected Codegens generateClassesInFile() { + protected ClassFileFactory generateClassesInFile() { try { - Codegens state = new Codegens(getProject(), false); + GenerationState state = new GenerationState(getProject(), false); JetFile jetFile = (JetFile) myFixture.getFile(); AnalyzingUtils.checkForSyntacticErrors(jetFile); - final JetNamespace namespace = jetFile.getRootNamespace(); + state.compile(jetFile); - NamespaceCodegen codegen = state.forNamespace(namespace); - codegen.generate(namespace); - return state; + return state.getFactory(); } catch (RuntimeException e) { System.out.println(generateToText()); throw e; @@ -196,7 +193,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { assertTrue(Math.abs(returnValue - currentTime) <= 1L); } - protected Class loadImplementationClass(Codegens codegens, final String name) { + protected Class loadImplementationClass(ClassFileFactory codegens, final String name) { loadClass(name, codegens); return loadClass(name + "$$Impl", codegens); } @@ -217,9 +214,9 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { } private static class CodegensClassLoader extends ClassLoader { - private final Codegens state; + private final ClassFileFactory state; - public CodegensClassLoader(Codegens state) { + public CodegensClassLoader(ClassFileFactory state) { super(CodegenTestCase.class.getClassLoader()); this.state = state; } diff --git a/idea/tests/org/jetbrains/jet/codegen/PropertyGenTest.java b/idea/tests/org/jetbrains/jet/codegen/PropertyGenTest.java index 130af2d598a..e62bf750316 100644 --- a/idea/tests/org/jetbrains/jet/codegen/PropertyGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/PropertyGenTest.java @@ -123,7 +123,7 @@ public class PropertyGenTest extends CodegenTestCase { public void testAbstractVal() throws Exception { loadText("class Foo { public abstract val x: String }"); - final Codegens codegens = generateClassesInFile(); + final ClassFileFactory codegens = generateClassesInFile(); final Class aClass = loadClass("Foo", codegens); assertNotNull(aClass.getMethod("getX")); }