From fb5bf2f8c602e241b71f3274dbd1e1038e2b781f Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 22 Aug 2012 18:40:37 +0300 Subject: [PATCH] local classes without closures --- .../jet/codegen/ClosureAnnotator.java | 80 ++++++++++------ .../jetbrains/jet/codegen/ClosureCodegen.java | 27 +++--- .../jet/codegen/ExpressionCodegen.java | 89 +++++++++++++---- .../jet/codegen/GenerationState.java | 21 ++-- .../jetbrains/jet/codegen/JetTypeMapper.java | 18 ++-- .../jet/codegen/LocalClassClosureCodegen.java | 35 +++++++ .../descriptors/LocalVariableDescriptor.java | 6 +- .../jet/lang/resolve/BindingContext.java | 95 +++++++++++++------ .../jet/lang/resolve/DescriptorResolver.java | 1 + .../jet/lang/resolve/name/FqName.java | 2 +- compiler/testData/codegen/localcls/enum.kt | 8 ++ .../testData/codegen/localcls/noclosure.kt | 11 +++ compiler/testData/codegen/localcls/object.kt | 7 ++ .../testData/codegen/localcls/withclosure.kt | 8 ++ .../jetbrains/jet/codegen/ClassGenTest.java | 54 +++++------ .../jet/codegen/LocalClassGenTest.java | 46 +++++++++ 16 files changed, 365 insertions(+), 143 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/LocalClassClosureCodegen.java create mode 100644 compiler/testData/codegen/localcls/enum.kt create mode 100644 compiler/testData/codegen/localcls/noclosure.kt create mode 100644 compiler/testData/codegen/localcls/object.kt create mode 100644 compiler/testData/codegen/localcls/withclosure.kt create mode 100644 compiler/tests/org/jetbrains/jet/codegen/LocalClassGenTest.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java index 14a7e835b6c..756cd2c1436 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java @@ -37,10 +37,11 @@ import java.util.*; * @author alex.tkachman */ public class ClosureAnnotator { - private final Map classNamesForAnonymousClasses = new HashMap(); private final Map classNamesForClassDescriptor = new HashMap(); private final Map anonymousSubclassesCount = new HashMap(); private final Map classNameForScript = new HashMap(); + private final Map localClassCodegenForClass = + new HashMap(); private final Set scriptClassNames = new HashSet(); private final Map classesForFunctions = new HashMap(); @@ -69,7 +70,8 @@ public class ClosureAnnotator { } - public ClassDescriptor classDescriptorForFunctionDescriptor(FunctionDescriptor funDescriptor, JvmClassName name) { + @NotNull + public ClassDescriptor classDescriptorForFunctionDescriptor(FunctionDescriptor funDescriptor) { ClassDescriptorImpl classDescriptor = classesForFunctions.get(funDescriptor); if (classDescriptor == null) { int arity = funDescriptor.getValueParameters().size(); @@ -79,7 +81,6 @@ public class ClosureAnnotator { Collections.emptyList(), Modality.FINAL, Name.special("")); - recordName(classDescriptor, name); classDescriptor.initialize( false, Collections.emptyList(), @@ -204,14 +205,13 @@ public class ClosureAnnotator { expression = jetObjectLiteralExpression.getObjectDeclaration(); } - if (expression instanceof JetFunctionLiteralExpression) { - JetFunctionLiteralExpression jetFunctionLiteralExpression = (JetFunctionLiteralExpression) expression; - expression = jetFunctionLiteralExpression.getFunctionLiteral(); + ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, expression); + if (descriptor == null) { + SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, expression); + assert functionDescriptor != null; + descriptor = classDescriptorForFunctionDescriptor(functionDescriptor); } - - JvmClassName name = classNamesForAnonymousClasses.get(expression); - assert name != null; - return name; + return classNameForClassDescriptor(descriptor); } public ClassDescriptor getEclosingClassDescriptor(ClassDescriptor descriptor) { @@ -240,6 +240,11 @@ public class ClosureAnnotator { return aBoolean != null && aBoolean; } + public void recordLocalClass(ClassDescriptor descriptor, LocalClassClosureCodegen codegen) { + LocalClassClosureCodegen put = localClassCodegenForClass.put(descriptor, codegen); + assert put == null; + } + private class MyJetVisitorVoid extends JetVisitorVoid { private final LinkedList classStack = new LinkedList(); private final LinkedList nameStack = new LinkedList(); @@ -252,28 +257,41 @@ public class ClosureAnnotator { } private JvmClassName recordAnonymousClass(JetElement declaration) { - JvmClassName name = classNamesForAnonymousClasses.get(declaration); - assert name == null; - String top = nameStack.peek(); Integer cnt = anonymousSubclassesCount.get(top); if (cnt == null) { cnt = 0; } - name = JvmClassName.byInternalName(top + "$" + (cnt + 1)); - classNamesForAnonymousClasses.put(declaration, name); + JvmClassName name = JvmClassName.byInternalName(top + "$" + (cnt + 1)); + ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, declaration); + if (descriptor == null) { + if (declaration instanceof JetFunctionLiteralExpression || declaration instanceof JetNamedFunction) { + DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration); + assert declarationDescriptor instanceof FunctionDescriptor; + descriptor = classDescriptorForFunctionDescriptor((FunctionDescriptor) declarationDescriptor); + } + else if (declaration instanceof JetObjectLiteralExpression) { + descriptor = + bindingContext.get(BindingContext.CLASS, ((JetObjectLiteralExpression) declaration).getObjectDeclaration()); + assert descriptor != null; + } + else { + throw new IllegalStateException( + "Class-less declaration which is not JetFunctionLiteralExpression|JetNamedFunction|JetObjectLiteralExpression : " + + declaration.getClass().getName()); + } + } + recordName(descriptor, name); anonymousSubclassesCount.put(top, cnt + 1); return name; } private JvmClassName recordClassObject(JetClassObject declaration) { - JvmClassName name = classNamesForAnonymousClasses.get(declaration.getObjectDeclaration()); - assert name == null; - - name = JvmClassName.byInternalName(nameStack.peek() + JvmAbi.CLASS_OBJECT_SUFFIX); - classNamesForAnonymousClasses.put(declaration.getObjectDeclaration(), name); - + JvmClassName name = JvmClassName.byInternalName(nameStack.peek() + JvmAbi.CLASS_OBJECT_SUFFIX); + ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, declaration.getObjectDeclaration()); + assert classDescriptor != null; + recordName(classDescriptor, name); return name; } @@ -309,7 +327,6 @@ public class ClosureAnnotator { ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); assert classDescriptor != null; recordEnclosing(classDescriptor); - recordName(classDescriptor, name); classStack.push(classDescriptor); nameStack.push(name.getInternalName()); super.visitClassObject(classObject); @@ -335,6 +352,7 @@ public class ClosureAnnotator { else { nameStack.push(base + '$' + classDescriptor.getName()); } + recordName(classDescriptor, JvmClassName.byInternalName(nameStack.peek())); super.visitObjectDeclaration(declaration); nameStack.pop(); classStack.pop(); @@ -355,6 +373,7 @@ public class ClosureAnnotator { else { nameStack.push(base + '$' + classDescriptor.getName()); } + recordName(classDescriptor, JvmClassName.byInternalName(nameStack.peek())); super.visitClass(klass); nameStack.pop(); classStack.pop(); @@ -362,13 +381,13 @@ public class ClosureAnnotator { @Override public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) { - JvmClassName name = recordAnonymousClass(expression.getObjectDeclaration()); ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, expression.getObjectDeclaration()); if (classDescriptor == null) { + // working around a problem with shallow analysis super.visitObjectLiteralExpression(expression); return; } - recordName(classDescriptor, name); + recordAnonymousClass(expression.getObjectDeclaration()); recordEnclosing(classDescriptor); classStack.push(classDescriptor); nameStack.push(classNameForClassDescriptor(classDescriptor).getInternalName()); @@ -379,15 +398,15 @@ public class ClosureAnnotator { @Override public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) { - JvmClassName name = recordAnonymousClass(expression.getFunctionLiteral()); - FunctionDescriptor declarationDescriptor = + FunctionDescriptor functionDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression); // working around a problem with shallow analysis - if (declarationDescriptor == null) return; - ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(declarationDescriptor, name); + if (functionDescriptor == null) return; + JvmClassName name = recordAnonymousClass(expression); + ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(functionDescriptor); recordEnclosing(classDescriptor); classStack.push(classDescriptor); - nameStack.push(classNameForClassDescriptor(classDescriptor).getInternalName()); + nameStack.push(name.getInternalName()); super.visitFunctionLiteralExpression(expression); nameStack.pop(); classStack.pop(); @@ -426,7 +445,7 @@ public class ClosureAnnotator { } else { JvmClassName name = recordAnonymousClass(function); - ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(functionDescriptor, name); + ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(functionDescriptor); recordEnclosing(classDescriptor); classStack.push(classDescriptor); nameStack.push(name.getInternalName()); @@ -444,7 +463,6 @@ public class ClosureAnnotator { } } - @NotNull public JvmClassName classNameForClassDescriptor(@NotNull ClassDescriptor classDescriptor) { return classNamesForClassDescriptor.get(classDescriptor); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index ae1008d0445..b959752ac0d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -51,10 +51,14 @@ import static org.jetbrains.asm4.Opcodes.*; public class ClosureCodegen extends ObjectOrClosureCodegen { private final BindingContext bindingContext; + private final ClosureAnnotator closureAnnotator; + private final JetTypeMapper typeMapper; public ClosureCodegen(GenerationState state, ExpressionCodegen exprContext, CodegenContext context) { super(exprContext, context, state); bindingContext = state.getBindingContext(); + typeMapper = this.state.getInjector().getJetTypeMapper(); + closureAnnotator = typeMapper.getClosureAnnotator(); } public static JvmMethodSignature erasedInvokeSignature(FunctionDescriptor fd) { @@ -103,13 +107,13 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { } public JvmMethodSignature invokeSignature(FunctionDescriptor fd) { - return state.getInjector().getJetTypeMapper().mapSignature(Name.identifier("invoke"), fd); + return typeMapper.mapSignature(Name.identifier("invoke"), fd); } public GeneratedAnonymousClassDescriptor gen(JetExpression fun) { final Pair nameAndVisitor = state.forAnonymousSubclass(fun); - final FunctionDescriptor funDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, fun); + final FunctionDescriptor funDescriptor = bindingContext.get(BindingContext.FUNCTION, fun); cv = nameAndVisitor.getSecond(); name = nameAndVisitor.getFirst(); @@ -143,7 +147,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { ClassDescriptor thisDescriptor = context.getThisDescriptor(); final Type enclosingType = thisDescriptor == null ? null - : state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE); + : typeMapper.mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE); if (enclosingType == null) { captureThis = null; } @@ -205,10 +209,10 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { private Type generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) { ClassDescriptor function = - state.getInjector().getJetTypeMapper().getClosureAnnotator().classDescriptorForFunctionDescriptor(funDescriptor, name); + closureAnnotator.classDescriptorForFunctionDescriptor(funDescriptor); final CodegenContexts.ClosureContext closureContext = context.intoClosure( - funDescriptor, function, name, this, state.getInjector().getJetTypeMapper()); + funDescriptor, function, name, this, typeMapper); FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state); JvmMethodSignature jvmMethodSignature = invokeSignature(funDescriptor); fc.generateMethod(body, jvmMethodSignature, false, null, funDescriptor); @@ -241,7 +245,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { if (receiver.exists()) { StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); StackValue.onStack(JetTypeMapper.TYPE_OBJECT) - .upcast(state.getInjector().getJetTypeMapper().mapType(receiver.getType(), MapTypeMode.VALUE), iv); + .upcast(typeMapper.mapType(receiver.getType(), MapTypeMode.VALUE), iv); count++; } @@ -249,7 +253,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { for (ValueParameterDescriptor param : params) { StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); StackValue.onStack(JetTypeMapper.TYPE_OBJECT) - .upcast(state.getInjector().getJetTypeMapper().mapType(param.getType(), MapTypeMode.VALUE), iv); + .upcast(typeMapper.mapType(param.getType(), MapTypeMode.VALUE), iv); count++; } @@ -290,7 +294,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { int i = 0; if (captureThis != null) { - argTypes[i++] = state.getInjector().getJetTypeMapper().mapType(context.getThisDescriptor().getDefaultType(), MapTypeMode.VALUE); + argTypes[i++] = typeMapper.mapType(context.getThisDescriptor().getDefaultType(), MapTypeMode.VALUE); } if (captureReceiver != null) { @@ -305,19 +309,19 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { continue; } if (descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) { - final Type sharedVarType = state.getInjector().getJetTypeMapper().getSharedVarType(descriptor); + final Type sharedVarType = typeMapper.getSharedVarType(descriptor); final Type type; if (sharedVarType != null) { type = sharedVarType; } else { - type = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE); + type = typeMapper.mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE); } argTypes[i++] = type; } else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { - final Type type = state.getInjector().getJetTypeMapper().getClosureAnnotator() + final Type type = closureAnnotator .classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor)) .getAsmType(); argTypes[i++] = type; @@ -387,7 +391,6 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { private void appendType(SignatureWriter signatureWriter, JetType type, char variance) { signatureWriter.visitTypeArgument(variance); - final JetTypeMapper typeMapper = state.getInjector().getJetTypeMapper(); final Type rawRetType = typeMapper.mapType(type, MapTypeMode.TYPE_PARAMETER); signatureWriter.visitClassType(rawRetType.getInternalName()); signatureWriter.visitEnd(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 6ea60be8c53..38bc89d306d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.codegen; import com.google.common.collect.Lists; import com.intellij.openapi.editor.Document; import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.tree.IElementType; @@ -194,6 +195,38 @@ public class ExpressionCodegen extends JetVisitor { gen(expr, expressionType(expr)); } + @Override + public StackValue visitClass(JetClass klass, StackValue data) { + ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, klass); + ObjectOrClosureCodegen closure = new LocalClassClosureCodegen(this, context, state, descriptor); + Pair nameAndVisitor = state.forAnonymousSubclass(klass); + + closure.cv = nameAndVisitor.getSecond(); + closure.name = nameAndVisitor.getFirst(); + final CodegenContext objectContext = closure.context.intoAnonymousClass( + closure, descriptor, OwnerKind.IMPLEMENTATION, + typeMapper); + + new ImplementationBodyCodegen(klass, objectContext, nameAndVisitor.getSecond(), state).generate(); + return StackValue.none(); + } + + @Override + public StackValue visitObjectDeclaration(JetObjectDeclaration declaration, StackValue data) { + ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, declaration); + ObjectOrClosureCodegen closure = new LocalClassClosureCodegen(this, context, state, descriptor); + Pair nameAndVisitor = state.forAnonymousSubclass(declaration); + + closure.cv = nameAndVisitor.getSecond(); + closure.name = nameAndVisitor.getFirst(); + final CodegenContext objectContext = closure.context.intoAnonymousClass( + closure, descriptor, OwnerKind.IMPLEMENTATION, + typeMapper); + + new ImplementationBodyCodegen(declaration, objectContext, nameAndVisitor.getSecond(), state).generate(); + return StackValue.none(); + } + @Override public StackValue visitExpression(JetExpression expression, StackValue receiver) { throw new UnsupportedOperationException("Codegen for " + expression + " is not yet implemented"); @@ -931,7 +964,6 @@ public class ExpressionCodegen extends JetVisitor { else { gen(statement, Type.VOID_TYPE); } - } v.mark(blockEnd); @@ -943,7 +975,11 @@ public class ExpressionCodegen extends JetVisitor { return answer; } - private void generateLocalVariableDeclaration(@NotNull JetVariableDeclaration variableDeclaration, final @NotNull Label blockEnd, @NotNull List> leaveTasks) { + private void generateLocalVariableDeclaration( + @NotNull JetVariableDeclaration variableDeclaration, + final @NotNull Label blockEnd, + @NotNull List> leaveTasks + ) { final VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, variableDeclaration); assert variableDescriptor != null; @@ -982,7 +1018,10 @@ public class ExpressionCodegen extends JetVisitor { }); } - private void generateLocalFunctionDeclaration(@NotNull JetNamedFunction namedFunction, @NotNull List> leaveTasks) { + private void generateLocalFunctionDeclaration( + @NotNull JetNamedFunction namedFunction, + @NotNull List> leaveTasks + ) { final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, namedFunction); myFrameMap.enter(descriptor, TYPE_OBJECT); @@ -1099,6 +1138,14 @@ public class ExpressionCodegen extends JetVisitor { assert descriptor != null; final DeclarationDescriptor container = descriptor.getContainingDeclaration(); + if (descriptor instanceof VariableDescriptor) { + VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor; + ClassDescriptor objectClassDescriptor = getBindingContext().get(BindingContext.OBJECT_DECLARATION_CLASS, variableDescriptor); + if (objectClassDescriptor != null) { + return genObjectClassInstance(variableDescriptor, objectClassDescriptor); + } + } + int index = lookupLocal(descriptor); if (index >= 0) { return stackValueForLocal(descriptor, index); @@ -1107,22 +1154,6 @@ public class ExpressionCodegen extends JetVisitor { if (descriptor instanceof PropertyDescriptor) { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; - ClassDescriptor objectClassDescriptor = getBindingContext().get(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor); - if (objectClassDescriptor != null) { - boolean isEnumEntry = DescriptorUtils.isEnumClassObject(propertyDescriptor.getContainingDeclaration()); - if (isEnumEntry) { - ClassDescriptor containing = (ClassDescriptor) propertyDescriptor.getContainingDeclaration().getContainingDeclaration(); - assert containing != null; - Type type = typeMapper.mapType(containing.getDefaultType(), MapTypeMode.VALUE); - StackValue.field(type, JvmClassName.byType(type), propertyDescriptor.getName().getName(), true).put(type, v); - return StackValue.onStack(type); - } - else { - Type type = typeMapper.mapType(objectClassDescriptor.getDefaultType(), MapTypeMode.VALUE); - return StackValue.field(type, JvmClassName.byType(type), "$instance", true); - } - } - boolean isStatic = container instanceof NamespaceDescriptor; final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL; @@ -1228,6 +1259,21 @@ public class ExpressionCodegen extends JetVisitor { throw new UnsupportedOperationException("don't know how to generate reference " + descriptor); } + private StackValue genObjectClassInstance(VariableDescriptor variableDescriptor, ClassDescriptor objectClassDescriptor) { + boolean isEnumEntry = DescriptorUtils.isEnumClassObject(variableDescriptor.getContainingDeclaration()); + if (isEnumEntry) { + ClassDescriptor containing = (ClassDescriptor) variableDescriptor.getContainingDeclaration().getContainingDeclaration(); + assert containing != null; + Type type = typeMapper.mapType(containing.getDefaultType(), MapTypeMode.VALUE); + StackValue.field(type, JvmClassName.byType(type), variableDescriptor.getName().getName(), true).put(type, v); + return StackValue.onStack(type); + } + else { + Type type = typeMapper.mapType(objectClassDescriptor.getDefaultType(), MapTypeMode.VALUE); + return StackValue.field(type, JvmClassName.byType(type), "$instance", true); + } + } + private StackValue stackValueForLocal(DeclarationDescriptor descriptor, int index) { if (descriptor instanceof VariableDescriptor) { Type sharedVarType = typeMapper.getSharedVarType(descriptor); @@ -1588,6 +1634,8 @@ public class ExpressionCodegen extends JetVisitor { Call call = bindingContext.get(CALL, calleeExpression); ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, calleeExpression); + assert resolvedCall != null; + assert call != null; invokeMethodWithArguments(callableMethod, resolvedCall, call, receiver); } @@ -2624,7 +2672,8 @@ public class ExpressionCodegen extends JetVisitor { initializeLocalVariable(variableDeclaration, new Function() { @Override public Void fun(VariableDescriptor descriptor) { - ResolvedCall resolvedCall = bindingContext.get(BindingContext.COMPONENT_RESOLVED_CALL, variableDeclaration); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.COMPONENT_RESOLVED_CALL, variableDeclaration); assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText(); Call call = CallMaker.makeCall(initializerAsReceiver, (JetExpression) null); invokeFunction(call, StackValue.none(), resolvedCall); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java index cb6465292c9..2aa3879243b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java @@ -43,8 +43,6 @@ import java.util.Map; public class GenerationState { private final Progress progress; @NotNull - private final AnalyzeExhaust analyzeExhaust; - @NotNull private final List files; @NotNull private final InjectorForJvmCodegen injector; @@ -56,6 +54,8 @@ public class GenerationState { // out parameter private Method scriptConstructorMethod; + private final BindingContext bindingContext; + private final JetTypeMapper typeMapper; public GenerationState(ClassBuilderFactory builderFactory, AnalyzeExhaust analyzeExhaust, List files) { @@ -67,12 +67,13 @@ public class GenerationState { @NotNull AnalyzeExhaust exhaust, @NotNull List files, @NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping ) { this.progress = progress; - this.analyzeExhaust = exhaust; this.files = files; this.classBuilderMode = builderFactory.getClassBuilderMode(); + bindingContext = exhaust.getBindingContext(); this.injector = new InjectorForJvmCodegen( - analyzeExhaust.getBindingContext(), + bindingContext, this.files, builtinToJavaTypesMapping, builderFactory.getClassBuilderMode(), this, builderFactory); + typeMapper = injector.getJetTypeMapper(); } private void markUsed() { @@ -98,7 +99,7 @@ public class GenerationState { } public BindingContext getBindingContext() { - return analyzeExhaust.getBindingContext(); + return bindingContext; } @NotNull @@ -199,16 +200,16 @@ public class GenerationState { closure.cv = nameAndVisitor.getSecond(); closure.name = nameAndVisitor.getFirst(); final CodegenContext objectContext = closure.context.intoAnonymousClass( - closure, analyzeExhaust.getBindingContext().get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION, - injector.getJetTypeMapper()); + closure, bindingContext.get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION, + typeMapper); new ImplementationBodyCodegen(objectDeclaration, objectContext, nameAndVisitor.getSecond(), this).generate(); - ConstructorDescriptor constructorDescriptor = analyzeExhaust.getBindingContext().get(BindingContext.CONSTRUCTOR, objectDeclaration); + ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, objectDeclaration); assert constructorDescriptor != null; - CallableMethod callableMethod = injector.getJetTypeMapper().mapToCallableMethod( + CallableMethod callableMethod = typeMapper.mapToCallableMethod( constructorDescriptor, OwnerKind.IMPLEMENTATION, - injector.getJetTypeMapper().hasThis0(constructorDescriptor.getContainingDeclaration())); + typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); return new GeneratedAnonymousClassDescriptor(nameAndVisitor.first, callableMethod.getSignature().getAsmMethod(), objectContext.outerWasUsed, null); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 7c231353bfa..fb1ab4def96 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -28,7 +28,6 @@ import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetClassObject; -import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetObjectDeclaration; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -392,6 +391,11 @@ public class JetTypeMapper { return getJvmInternalFQName(klass.getContainingDeclaration()); } } + + JvmClassName name = closureAnnotator.classNameForClassDescriptor((ClassDescriptor) descriptor); + if (name != null) { + return name.getInternalName(); + } } DeclarationDescriptor container = descriptor.getContainingDeclaration(); @@ -402,12 +406,6 @@ public class JetTypeMapper { Name name = descriptor.getName(); - if (descriptor instanceof ClassDescriptor && name.isSpecial()) { - ClassDescriptor clazz = (ClassDescriptor) descriptor; - JvmClassName className = closureAnnotator.classNameForClassDescriptor(clazz); - return className.getInternalName(); - } - String baseName = getJvmInternalFQName(container); if (!baseName.isEmpty()) { return baseName + (container instanceof NamespaceDescriptor ? "/" : "$") + name.getIdentifier(); @@ -511,8 +509,6 @@ public class JetTypeMapper { } if (descriptor instanceof ClassDescriptor) { - - JvmClassName name = getJvmClassName((ClassDescriptor) descriptor); Type asmType = Type.getObjectType(name.getInternalName() + (kind == MapTypeMode.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : "")); boolean forceReal = isForceReal(name); @@ -1113,7 +1109,7 @@ public class JetTypeMapper { public boolean isVarCapturedInClosure(DeclarationDescriptor descriptor) { if (!(descriptor instanceof VariableDescriptor) || descriptor instanceof PropertyDescriptor) return false; VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor; - Boolean aBoolean = bindingContext.get(BindingContext.CAPTURED_IN_CLOSURE, variableDescriptor); - return aBoolean != null && aBoolean && variableDescriptor.isVar(); + return Boolean.TRUE.equals(bindingContext.get(BindingContext.CAPTURED_IN_CLOSURE, variableDescriptor)) && + variableDescriptor.isVar(); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/LocalClassClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/LocalClassClosureCodegen.java new file mode 100644 index 00000000000..7714898ac70 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/LocalClassClosureCodegen.java @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.codegen; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; + +/** + * @author alex.tkachman + */ +public class LocalClassClosureCodegen extends ObjectOrClosureCodegen { + public LocalClassClosureCodegen( + ExpressionCodegen exprContext, + CodegenContext context, + @NotNull GenerationState state, + ClassDescriptor descriptor + ) { + super(exprContext, context, state); + state.getInjector().getClosureAnnotator().recordLocalClass(descriptor, this); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LocalVariableDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LocalVariableDescriptor.java index 2d43e6cf51d..9cb692ec6f2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LocalVariableDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/LocalVariableDescriptor.java @@ -29,13 +29,15 @@ import java.util.List; * @author abreslav */ public class LocalVariableDescriptor extends VariableDescriptorImpl { - private boolean isVar; + private final boolean isVar; + public LocalVariableDescriptor( @NotNull DeclarationDescriptor containingDeclaration, @NotNull List annotations, @NotNull Name name, @Nullable JetType type, - boolean mutable) { + boolean mutable + ) { super(containingDeclaration, annotations, name, type); isVar = mutable; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index 4f73dd1752b..ca430378f6f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -68,11 +68,14 @@ public interface BindingContext { WritableSlice EXPRESSION_TYPE = new BasicWritableSlice(DO_NOTHING); WritableSlice EXPRESSION_DATA_FLOW_INFO = new BasicWritableSlice(DO_NOTHING); - WritableSlice REFERENCE_TARGET = new BasicWritableSlice(DO_NOTHING); - WritableSlice> RESOLVED_CALL = new BasicWritableSlice>(DO_NOTHING); + WritableSlice REFERENCE_TARGET = + new BasicWritableSlice(DO_NOTHING); + WritableSlice> RESOLVED_CALL = + new BasicWritableSlice>(DO_NOTHING); WritableSlice CALL = new BasicWritableSlice(DO_NOTHING); - WritableSlice> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice>(DO_NOTHING); + WritableSlice> AMBIGUOUS_REFERENCE_TARGET = + new BasicWritableSlice>(DO_NOTHING); WritableSlice> RESOLUTION_RESULTS_FOR_FUNCTION = Slices.createSimpleSlice(); WritableSlice> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice(); @@ -89,35 +92,46 @@ public interface BindingContext { WritableSlice AUTOCAST = Slices.createSimpleSlice(); - /** A scope where type of expression has been resolved */ + /** + * A scope where type of expression has been resolved + */ WritableSlice TYPE_RESOLUTION_SCOPE = Slices.createSimpleSlice(); WritableSlice RESOLUTION_SCOPE = Slices.createSimpleSlice(); WritableSlice SCRIPT_SCOPE = Slices.createSimpleSlice(); - /** Collected during analyze, used in IDE in auto-cast completion */ + /** + * Collected during analyze, used in IDE in auto-cast completion + */ WritableSlice NON_DEFAULT_EXPRESSION_DATA_FLOW = Slices.createSimpleSlice(); WritableSlice VARIABLE_REASSIGNMENT = Slices.createSimpleSetSlice(); WritableSlice AUTO_CREATED_IT = Slices.createSimpleSetSlice(); WritableSlice VARIABLE_ASSIGNMENT = Slices.createSimpleSlice(); - /** Has type of current expression has been already resolved */ + /** + * Has type of current expression has been already resolved + */ WritableSlice PROCESSED = Slices.createSimpleSetSlice(); WritableSlice STATEMENT = Slices.createRemovableSetSlice(); WritableSlice CAPTURED_IN_CLOSURE = Slices.createSimpleSetSlice(); - -// enum DeferredTypeKey {DEFERRED_TYPE_KEY} -// WritableSlice> DEFERRED_TYPES = Slices.createSimpleSlice(); + + // enum DeferredTypeKey {DEFERRED_TYPE_KEY} + // WritableSlice> DEFERRED_TYPES = Slices.createSimpleSlice(); WritableSlice, Boolean> DEFERRED_TYPE = Slices.createCollectiveSetSlice(); - WritableSlice OBJECT_DECLARATION_CLASS = Slices.createSimpleSlice(); + WritableSlice OBJECT_DECLARATION_CLASS = Slices.createSimpleSlice(); WritableSlice BACKING_FIELD_REQUIRED = new Slices.SetSlice(DO_NOTHING) { @Override - public Boolean computeValue(SlicedMap map, PropertyDescriptor propertyDescriptor, Boolean backingFieldRequired, boolean valueNotFound) { + public Boolean computeValue( + SlicedMap map, + PropertyDescriptor propertyDescriptor, + Boolean backingFieldRequired, + boolean valueNotFound + ) { if (propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.DECLARATION) { return false; } @@ -159,33 +173,56 @@ public interface BindingContext { } }; - WritableSlice NAMESPACE = Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); - WritableSlice CLASS = Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); - WritableSlice SCRIPT = Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); - WritableSlice TYPE_PARAMETER = Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); - /** @see BindingContextUtils#recordFunctionDeclarationToDescriptor(BindingTrace, PsiElement, SimpleFunctionDescriptor)} */ - WritableSlice FUNCTION = Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); - WritableSlice CONSTRUCTOR = Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); - WritableSlice VARIABLE = Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); - WritableSlice VALUE_PARAMETER = Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); - WritableSlice PROPERTY_ACCESSOR = Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); + WritableSlice NAMESPACE = Slices.sliceBuilder() + .setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); + WritableSlice CLASS = + Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION) + .build(); + WritableSlice SCRIPT = + Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION) + .build(); + WritableSlice TYPE_PARAMETER = + Slices.sliceBuilder() + .setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); + /** + * @see BindingContextUtils#recordFunctionDeclarationToDescriptor(BindingTrace, PsiElement, SimpleFunctionDescriptor)} + */ + WritableSlice FUNCTION = Slices.sliceBuilder() + .setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); + WritableSlice CONSTRUCTOR = Slices.sliceBuilder() + .setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); + WritableSlice VARIABLE = + Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION) + .build(); + WritableSlice VALUE_PARAMETER = Slices.sliceBuilder() + .setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); + WritableSlice PROPERTY_ACCESSOR = + Slices.sliceBuilder() + .setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); // normalize value to getOriginal(value) - WritableSlice PRIMARY_CONSTRUCTOR_PARAMETER = Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); - WritableSlice OBJECT_DECLARATION = Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); + WritableSlice PRIMARY_CONSTRUCTOR_PARAMETER = + Slices.sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION) + .build(); + WritableSlice OBJECT_DECLARATION = + Slices.sliceBuilder() + .setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build(); WritableSlice[] DECLARATIONS_TO_DESCRIPTORS = new WritableSlice[] { - NAMESPACE, CLASS, TYPE_PARAMETER, FUNCTION, CONSTRUCTOR, VARIABLE, VALUE_PARAMETER, PROPERTY_ACCESSOR, PRIMARY_CONSTRUCTOR_PARAMETER, OBJECT_DECLARATION + NAMESPACE, CLASS, TYPE_PARAMETER, FUNCTION, CONSTRUCTOR, VARIABLE, VALUE_PARAMETER, PROPERTY_ACCESSOR, + PRIMARY_CONSTRUCTOR_PARAMETER, OBJECT_DECLARATION }; ReadOnlySlice DECLARATION_TO_DESCRIPTOR = Slices.sliceBuilder() .setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS).build(); WritableSlice LABEL_TARGET = Slices.sliceBuilder().build(); - WritableSlice VALUE_PARAMETER_AS_PROPERTY = Slices.sliceBuilder().build(); + WritableSlice VALUE_PARAMETER_AS_PROPERTY = + Slices.sliceBuilder().build(); WritableSlice FQNAME_TO_CLASS_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING, true); - WritableSlice FQNAME_TO_NAMESPACE_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING); + WritableSlice FQNAME_TO_NAMESPACE_DESCRIPTOR = + new BasicWritableSlice(DO_NOTHING); WritableSlice FILE_TO_NAMESPACE = Slices.createSimpleSlice(); WritableSlice> NAMESPACE_TO_FILES = Slices.createSimpleSlice(); @@ -193,13 +230,13 @@ public interface BindingContext { * Each namespace found in src must be registered here. */ WritableSlice NAMESPACE_IS_SRC = Slices.createSimpleSlice(); - + WritableSlice INCOMPLETE_HIERARCHY = Slices.createCollectiveSetSlice(); @SuppressWarnings("UnusedDeclaration") @Deprecated // This field is needed only for the side effects of its initializer - Void _static_initializer = BasicWritableSlice.initSliceDebugNames(BindingContext.class); - + Void _static_initializer = BasicWritableSlice.initSliceDebugNames(BindingContext.class); + Collection getDiagnostics(); @Nullable diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index f65f9292514..762f262c882 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -703,6 +703,7 @@ public class DescriptorResolver { JetPsiUtil.safeName(objectDeclaration.getName()), classDescriptor.getDefaultType(), /*isVar =*/ false); + trace.record(BindingContext.OBJECT_DECLARATION_CLASS, variableDescriptor, classDescriptor); JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration(); if (nameAsDeclaration != null) { trace.record(BindingContext.VARIABLE, nameAsDeclaration, variableDescriptor); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/FqName.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/FqName.java index 71a4282691f..09125825bb8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/FqName.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/name/FqName.java @@ -73,6 +73,7 @@ public class FqName extends FqNameBase { isValidAfterUnsafeCheck(qualifiedName); } + @Override @NotNull public String getFqName() { return fqName.getFqName(); @@ -145,7 +146,6 @@ public class FqName extends FqNameBase { } - @NotNull public static FqName topLevel(@NotNull Name shortName) { return new FqName(FqNameUnsafe.topLevel(shortName)); diff --git a/compiler/testData/codegen/localcls/enum.kt b/compiler/testData/codegen/localcls/enum.kt new file mode 100644 index 00000000000..4608636d65e --- /dev/null +++ b/compiler/testData/codegen/localcls/enum.kt @@ -0,0 +1,8 @@ +fun box(): String { + enum class K { + O + K + } + + return K.O.toString() + K.K.toString() +} diff --git a/compiler/testData/codegen/localcls/noclosure.kt b/compiler/testData/codegen/localcls/noclosure.kt new file mode 100644 index 00000000000..8f9417505e7 --- /dev/null +++ b/compiler/testData/codegen/localcls/noclosure.kt @@ -0,0 +1,11 @@ +fun box(): String { + open class K { + val o = "O" + } + + class Bar : K() { + val k = "K" + } + + return K().o + Bar().k +} diff --git a/compiler/testData/codegen/localcls/object.kt b/compiler/testData/codegen/localcls/object.kt new file mode 100644 index 00000000000..baa86d5a9f5 --- /dev/null +++ b/compiler/testData/codegen/localcls/object.kt @@ -0,0 +1,7 @@ +fun box(): String { + object K { + val ok = "OK" + } + + return K.ok +} diff --git a/compiler/testData/codegen/localcls/withclosure.kt b/compiler/testData/codegen/localcls/withclosure.kt new file mode 100644 index 00000000000..b9dc2f5bee3 --- /dev/null +++ b/compiler/testData/codegen/localcls/withclosure.kt @@ -0,0 +1,8 @@ +fun box(): String { + val x = "OK" + class Aaa { + val y = x + } + + return Aaa().y +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java index e7418971036..bde0cace45d 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -48,7 +48,7 @@ public class ClassGenTest extends CodegenTestCase { public void testArrayListInheritance() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); loadFile("classes/inheritingFromArrayList.jet"); -// System.out.println(generateToText()); + // System.out.println(generateToText()); final Class aClass = loadClass("Foo", generateClassesInFile()); assertInstanceOf(aClass.newInstance(), List.class); } @@ -86,7 +86,7 @@ public class ClassGenTest extends CodegenTestCase { public void testNewInstanceExplicitConstructor() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); loadFile("classes/newInstanceDefaultConstructor.jet"); -// System.out.println(generateToText()); + // System.out.println(generateToText()); final Method method = generateFunction("test"); final Integer returnValue = (Integer) method.invoke(null); assertEquals(610, returnValue.intValue()); @@ -163,7 +163,7 @@ public class ClassGenTest extends CodegenTestCase { public void testClassObjectMethod() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); // todo to be implemented after removal of type info -// blackBoxFile("classes/classObjectMethod.jet"); + // blackBoxFile("classes/classObjectMethod.jet"); } public void testClassObjectInterface() throws Exception { @@ -203,7 +203,7 @@ public class ClassGenTest extends CodegenTestCase { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); loadText("enum class Direction { NORTH; SOUTH; EAST; WEST }"); final Class direction = createClassLoader(generateClassesInFile()).loadClass("Direction"); -// System.out.println(generateToText()); + // System.out.println(generateToText()); final Field north = direction.getField("NORTH"); assertEquals(direction, north.getType()); assertInstanceOf(north.get(null), direction); @@ -241,94 +241,94 @@ public class ClassGenTest extends CodegenTestCase { blackBoxFile("regressions/kt249.jet"); } - public void testKt48 () throws Exception { + public void testKt48() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxFile("regressions/kt48.jet"); -// System.out.println(generateToText()); + // System.out.println(generateToText()); } - public void testKt309 () throws Exception { + public void testKt309() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); loadText("fun box() = null"); final Method method = generateFunction("box"); assertEquals(method.getReturnType().getName(), "java.lang.Object"); -// System.out.println(generateToText()); + // System.out.println(generateToText()); } - public void testKt343 () throws Exception { + public void testKt343() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxFile("regressions/kt343.jet"); -// System.out.println(generateToText()); + // System.out.println(generateToText()); } - public void testKt508 () throws Exception { + public void testKt508() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); loadFile("regressions/kt508.jet"); -// System.out.println(generateToText()); + // System.out.println(generateToText()); blackBox(); } - public void testKt504 () throws Exception { + public void testKt504() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); loadFile("regressions/kt504.jet"); -// System.out.println(generateToText()); + // System.out.println(generateToText()); blackBox(); } - public void testKt501 () throws Exception { + public void testKt501() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxFile("regressions/kt501.jet"); } - public void testKt496 () throws Exception { + public void testKt496() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxFile("regressions/kt496.jet"); -// System.out.println(generateToText()); + // System.out.println(generateToText()); } - public void testKt500 () throws Exception { + public void testKt500() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxFile("regressions/kt500.jet"); } - public void testKt694 () throws Exception { + public void testKt694() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); // blackBoxFile("regressions/kt694.jet"); } - public void testKt285 () throws Exception { + public void testKt285() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); // blackBoxFile("regressions/kt285.jet"); } - public void testKt707 () throws Exception { + public void testKt707() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxFile("regressions/kt707.jet"); } - public void testKt857 () throws Exception { + public void testKt857() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); // blackBoxFile("regressions/kt857.jet"); } - public void testKt903 () throws Exception { + public void testKt903() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxFile("regressions/kt903.jet"); } - public void testKt940 () throws Exception { + public void testKt940() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxFile("regressions/kt940.kt"); } - public void testKt1018 () throws Exception { + public void testKt1018() throws Exception { createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); blackBoxFile("regressions/kt1018.kt"); } - public void testKt1120 () throws Exception { + public void testKt1120() throws Exception { //createEnvironmentWithFullJdk(); -// blackBoxFile("regressions/kt1120.kt"); + // blackBoxFile("regressions/kt1120.kt"); } public void testSelfCreate() throws Exception { diff --git a/compiler/tests/org/jetbrains/jet/codegen/LocalClassGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/LocalClassGenTest.java new file mode 100644 index 00000000000..3d56d679165 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/LocalClassGenTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.codegen; + +import org.jetbrains.jet.ConfigurationKind; + +/** + * @author alex.tkachman + */ +public class LocalClassGenTest extends CodegenTestCase { + @Override + public void setUp() throws Exception { + super.setUp(); + createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); + } + + public void testNoClosure() { + blackBoxFile("localcls/noclosure.kt"); + } + + public void testWithClosure() { + //blackBoxFile("localcls/withclosure.kt"); + } + + public void testEnum() { + //blackBoxFile("localcls/enum.kt"); + } + + public void testObject() { + blackBoxFile("localcls/object.kt"); + } +}