From 69ef648005f1f7a1557000f499fd3ad046b094bf Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 26 May 2014 13:05:36 +0400 Subject: [PATCH] Write outer class info for closures --- .../org/jetbrains/jet/codegen/AsmUtil.java | 43 +++++++ .../jetbrains/jet/codegen/ClosureCodegen.java | 1 + .../codegen/ImplementationBodyCodegen.java | 25 +---- .../jet/codegen/binding/CodegenBinding.java | 9 +- .../reflection/insideLambda/classInLambda.kt | 19 ++++ .../reflection/insideLambda/objectInLambda.kt | 18 +++ .../reflection/lambda/lambdaInConstructor.kt | 17 +++ .../reflection/lambda/lambdaInFunction.kt | 15 +++ .../reflection/lambda/lambdaInLambda.kt | 17 +++ .../reflection/lambda/lambdaInLocalClass.kt | 19 ++++ .../lambda/lambdaInLocalFunction.kt | 17 +++ .../lambda/lambdaInMemberFunction.kt | 20 ++++ .../lambdaInMemberFunctionInLocalClass.kt | 19 ++++ .../lambdaInMemberFunctionInNestedClass.kt | 21 ++++ .../lambda/lambdaInObjectExpression.kt | 18 +++ .../reflection/lambda/lambdaInPackage.kt | 17 +++ .../lambda/lambdaInPropertyGetter.kt | 16 +++ .../lambda/lambdaInPropertySetter.kt | 23 ++++ .../innerClassInfo/anonymousObjectInline.kt | 2 +- ...lackBoxWithStdlibCodegenTestGenerated.java | 105 +++++++++++++++++- 20 files changed, 413 insertions(+), 28 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/classInLambda.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/objectInLambda.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInConstructor.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInFunction.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLambda.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalClass.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalFunction.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunction.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInLocalClass.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInNestedClass.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInObjectExpression.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPackage.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertyGetter.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertySetter.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index 0a855871113..60aa5cc8554 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -23,9 +23,12 @@ import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.binding.CalculatedClosure; +import org.jetbrains.jet.codegen.binding.CodegenBinding; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.java.*; @@ -39,6 +42,7 @@ import org.jetbrains.org.objectweb.asm.Label; import org.jetbrains.org.objectweb.asm.MethodVisitor; import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; +import org.jetbrains.org.objectweb.asm.commons.Method; import java.util.ArrayList; import java.util.List; @@ -707,4 +711,43 @@ public class AsmUtil { public static Type asmTypeByFqNameWithoutInnerClasses(@NotNull FqName fqName) { return Type.getObjectType(JvmClassName.byFqNameWithoutInnerClasses(fqName).getInternalName()); } + + public static void writeOuterClassAndEnclosingMethod( + @NotNull ClassDescriptor descriptor, + @NotNull DeclarationDescriptor originalDescriptor, + @NotNull JetTypeMapper typeMapper, + @NotNull ClassBuilder v + ) { + String outerClassName = getOuterClassName(descriptor, originalDescriptor, typeMapper); + FunctionDescriptor function = DescriptorUtils.getParentOfType(descriptor, FunctionDescriptor.class); + + if (function != null) { + Method method = typeMapper.mapSignature(function).getAsmMethod(); + v.visitOuterClass(outerClassName, method.getName(), method.getDescriptor()); + } + else { + v.visitOuterClass(outerClassName, null, null); + } + } + + @NotNull + private static String getOuterClassName(@NotNull ClassDescriptor classDescriptor, @NotNull DeclarationDescriptor originalDescriptor, @NotNull JetTypeMapper typeMapper) { + DeclarationDescriptor container = classDescriptor.getContainingDeclaration(); + while (container != null) { + if (container instanceof ClassDescriptor) { + return typeMapper.mapClass((ClassDescriptor)container).getInternalName(); + } else if (CodegenBinding.isLocalFunOrLambda(container)) { + ClassDescriptor descriptor = + CodegenBinding.anonymousClassForFunction(typeMapper.getBindingContext(), (FunctionDescriptor) container); + return typeMapper.mapClass(descriptor).getInternalName(); + } + + container = container.getContainingDeclaration(); + } + + JetFile containingFile = BindingContextUtils.getContainingFile(typeMapper.getBindingContext(), originalDescriptor); + assert containingFile != null : "Containing file should be present for " + classDescriptor; + return PackageCodegen.getPackagePartInternalName(containingFile); + } + } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index 8bddaf97f01..721151c4a55 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -179,6 +179,7 @@ public class ClosureCodegen extends ParentCodegenAwareImpl { null); + AsmUtil.writeOuterClassAndEnclosingMethod(anonymousClassForFunction(bindingContext, funDescriptor), funDescriptor, typeMapper, cv); cv.done(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 2e5cb0b7043..ee8ffe78cae 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -251,33 +251,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { !(parentDescriptor instanceof PackageFragmentDescriptor || parentDescriptor instanceof ClassDescriptor); // Do not emit enclosing method in "light-classes mode" since currently we generate local light classes as if they're top level if (isLocalOrAnonymousClass && state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES) { - String outerClassName = getOuterClassName(descriptor, typeMapper); - FunctionDescriptor function = AsmUtil.isDeclarationInsideInlineFunction(descriptor) - ? null - : DescriptorUtils.getParentOfType(descriptor, FunctionDescriptor.class); - - if (function != null) { - Method method = typeMapper.mapSignature(function).getAsmMethod(); - v.visitOuterClass(outerClassName, method.getName(), method.getDescriptor()); - } - else { - v.visitOuterClass(outerClassName, null, null); - } + writeOuterClassAndEnclosingMethod(descriptor, descriptor, typeMapper, v); } } - @NotNull - private static String getOuterClassName(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeMapper typeMapper) { - ClassDescriptor container = DescriptorUtils.getParentOfType(classDescriptor, ClassDescriptor.class); - if (container != null) { - return typeMapper.mapClass(container).getInternalName(); - } - - JetFile containingFile = BindingContextUtils.getContainingFile(typeMapper.getBindingContext(), classDescriptor); - assert containingFile != null : "Containing file should be present for " + classDescriptor; - return PackageCodegen.getPackagePartInternalName(containingFile); - } - private void writeInnerClasses() { Collection result = bindingContext.get(INNER_CLASSES, descriptor); if (result != null) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java index 8024ef79831..8355585d29f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java @@ -267,10 +267,15 @@ public class CodegenBinding { return sortedAnswer; } - public static boolean isLocalNamedFun(DeclarationDescriptor fd) { + public static boolean isLocalNamedFun(@Nullable DeclarationDescriptor fd) { + return isLocalFunOrLambda(fd) && !fd.getName().isSpecial(); + } + + /*named or not*/ + public static boolean isLocalFunOrLambda(@Nullable DeclarationDescriptor fd) { if (fd instanceof FunctionDescriptor) { FunctionDescriptor descriptor = (FunctionDescriptor) fd; - return descriptor.getVisibility() == Visibilities.LOCAL && !descriptor.getName().isSpecial(); + return descriptor.getVisibility() == Visibilities.LOCAL; } return false; } diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/classInLambda.kt b/compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/classInLambda.kt new file mode 100644 index 00000000000..3caa9125007 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/classInLambda.kt @@ -0,0 +1,19 @@ +fun box(): String { + + val classInLambda = { + class Z {} + Z() + }() + + val enclosingMethod = classInLambda.javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod" + + val enclosingClass = classInLambda.javaClass.getEnclosingClass() + if (enclosingClass?.getName() != "_DefaultPackage\$box\$classInLambda\$1") return "enclosing class: $enclosingClass" + + //KT-5092 + //val declaringClass = classInLambda.javaClass.getDeclaringClass() + //if (declaringClass == null) return "class hasn't a declaring class" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/objectInLambda.kt b/compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/objectInLambda.kt new file mode 100644 index 00000000000..a32ce78a8a2 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/objectInLambda.kt @@ -0,0 +1,18 @@ +fun box(): String { + + val objectInLambda = { + object : Any () {} + }() + + val enclosingMethod = objectInLambda.javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod" + + val enclosingClass = objectInLambda.javaClass.getEnclosingClass() + if (enclosingClass?.getName() != "_DefaultPackage\$box\$objectInLambda\$1") return "enclosing class: $enclosingClass" + + //KT-5092 + //val declaringClass = objectInLambda.javaClass.getDeclaringClass() + //if (declaringClass == null) return "anonymous object hasn't a declaring class" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInConstructor.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInConstructor.kt new file mode 100644 index 00000000000..85bc0d54920 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInConstructor.kt @@ -0,0 +1,17 @@ +class C { + val l: Any = {} +} + +fun box(): String { + val javaClass = C().l.javaClass + val enclosingConstructor = javaClass.getEnclosingConstructor() + if (enclosingConstructor?.getDeclaringClass()?.getName() != "C") return "ctor: $enclosingConstructor" + + val enclosingClass = javaClass.getEnclosingClass() + if (enclosingClass?.getName() != "C") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInFunction.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInFunction.kt new file mode 100644 index 00000000000..2cfe91a8ce5 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInFunction.kt @@ -0,0 +1,15 @@ +fun box(): String { + val l: Any = {} + + val javaClass = l.javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "box") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass() + if (!enclosingClass!!.getName().startsWith("_DefaultPackage-lambdaInFunction-")) return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLambda.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLambda.kt new file mode 100644 index 00000000000..f4e998e1e60 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLambda.kt @@ -0,0 +1,17 @@ +fun box(): String { + val l = { + {} + } + + val javaClass = l().javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass() + if (enclosingClass!!.getName() != "_DefaultPackage\$box\$l$1") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalClass.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalClass.kt new file mode 100644 index 00000000000..d9e58d20842 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalClass.kt @@ -0,0 +1,19 @@ +open class C(val a: Any) + +fun box(): String { + class L : C({}) { + } + val l = L() + + val javaClass = l.a.javaClass + val enclosingMethod = javaClass.getEnclosingConstructor() + if (enclosingMethod?.getName() != "_DefaultPackage\$box\$L") return "ctor: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass() + if (!enclosingClass!!.getName().startsWith("_DefaultPackage\$box\$L")) return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalFunction.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalFunction.kt new file mode 100644 index 00000000000..0234248c39e --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalFunction.kt @@ -0,0 +1,17 @@ +fun box(): String { + fun foo(): Any { + return {} + } + + val javaClass = foo().javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass() + if (enclosingClass!!.getName() != "_DefaultPackage\$box$1") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunction.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunction.kt new file mode 100644 index 00000000000..25bf499b73c --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunction.kt @@ -0,0 +1,20 @@ +class C { + fun foo(): Any { + return {} + } +} + + +fun box(): String { + val javaClass = C().foo().javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "foo") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass() + if (enclosingClass?.getName() != "C") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInLocalClass.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInLocalClass.kt new file mode 100644 index 00000000000..5d3604317ac --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInLocalClass.kt @@ -0,0 +1,19 @@ +fun box(): String { + class C { + fun foo(): Any { + return {} + } + } + + val javaClass = C().foo().javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "foo") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass() + if (enclosingClass?.getName() != "_DefaultPackage\$box\$C") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInNestedClass.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInNestedClass.kt new file mode 100644 index 00000000000..4be5c4543b1 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInNestedClass.kt @@ -0,0 +1,21 @@ +class C { + class D { + fun foo(): Any { + return {} + } + } +} + +fun box(): String { + val javaClass = C.D().foo().javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "foo") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass() + if (enclosingClass?.getSimpleName() != "D") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInObjectExpression.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInObjectExpression.kt new file mode 100644 index 00000000000..d99af95b209 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInObjectExpression.kt @@ -0,0 +1,18 @@ +open class C(val a: Any) + +fun box(): String { + val l = object : C({}) { + } + + val javaClass = l.a.javaClass + val enclosingMethod = javaClass.getEnclosingConstructor() + if (enclosingMethod?.getName() != "_DefaultPackage\$box\$l\$1") return "ctor: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass() + if (!enclosingClass!!.getName().startsWith("_DefaultPackage\$box\$l\$1")) return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPackage.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPackage.kt new file mode 100644 index 00000000000..fe94a8e5e02 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPackage.kt @@ -0,0 +1,17 @@ +val l: Any = {} + +fun box(): String { + val enclosingClass = l.javaClass.getEnclosingClass() + if (!enclosingClass!!.getName().startsWith("_DefaultPackage-lambdaInPackage-")) return "enclosing class: $enclosingClass" + + val enclosingConstructor = l.javaClass.getEnclosingConstructor() + if (enclosingConstructor != null) return "enclosing constructor found: $enclosingConstructor" + + val enclosingMethod = l.javaClass.getEnclosingMethod() + if (enclosingMethod != null) return "enclosing method found: $enclosingMethod" + + val declaringClass = l.javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertyGetter.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertyGetter.kt new file mode 100644 index 00000000000..14c4f735d0d --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertyGetter.kt @@ -0,0 +1,16 @@ +val l: Any + get() = {} + +fun box(): String { + + val enclosingMethod = l.javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "getL") return "method: $enclosingMethod" + + val enclosingClass = l.javaClass.getEnclosingClass() + if (!enclosingClass!!.getName().startsWith("_DefaultPackage-lambdaInPropertyGetter-")) return "enclosing class: $enclosingClass" + + val declaringClass = l.javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertySetter.kt b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertySetter.kt new file mode 100644 index 00000000000..f92401b0678 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertySetter.kt @@ -0,0 +1,23 @@ + +var _l: Any = "" + +var l: Any + get() = _l + set(v) { + _l = {} + } + +fun box(): String { + l = "" // to invoke the setter + + val enclosingMethod = l.javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "setL") return "method: $enclosingMethod" + + val enclosingClass = l.javaClass.getEnclosingClass() + if (!enclosingClass!!.getName().startsWith("_DefaultPackage-lambdaInPropertySetter-")) return "enclosing class: $enclosingClass" + + val declaringClass = l.javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/innerClassInfo/anonymousObjectInline.kt b/compiler/testData/codegen/innerClassInfo/anonymousObjectInline.kt index dd370f45ade..d7b37705a20 100644 --- a/compiler/testData/codegen/innerClassInfo/anonymousObjectInline.kt +++ b/compiler/testData/codegen/innerClassInfo/anonymousObjectInline.kt @@ -1,4 +1,4 @@ -class A { +dclass A { fun foo() { inlineFun { "test" } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 2129bcc83e6..65df1b36754 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("compiler/testData/codegen/boxWithStdlib") -@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class}) +@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class}) public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBoxWithStdlib() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib"), Pattern.compile("^(.+)\\.kt$"), true); @@ -1215,6 +1215,108 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode } } + @TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection") + @InnerTestClasses({Reflection.InsideLambda.class, Reflection.Lambda.class}) + public static class Reflection extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInReflection() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/insideLambda") + public static class InsideLambda extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInInsideLambda() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection/insideLambda"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("classInLambda.kt") + public void testClassInLambda() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/classInLambda.kt"); + } + + @TestMetadata("objectInLambda.kt") + public void testObjectInLambda() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/insideLambda/objectInLambda.kt"); + } + + } + + @TestMetadata("compiler/testData/codegen/boxWithStdlib/reflection/lambda") + public static class Lambda extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInLambda() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/reflection/lambda"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("lambdaInConstructor.kt") + public void testLambdaInConstructor() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInConstructor.kt"); + } + + @TestMetadata("lambdaInFunction.kt") + public void testLambdaInFunction() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInFunction.kt"); + } + + @TestMetadata("lambdaInLambda.kt") + public void testLambdaInLambda() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLambda.kt"); + } + + @TestMetadata("lambdaInLocalClass.kt") + public void testLambdaInLocalClass() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalClass.kt"); + } + + @TestMetadata("lambdaInLocalFunction.kt") + public void testLambdaInLocalFunction() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInLocalFunction.kt"); + } + + @TestMetadata("lambdaInMemberFunction.kt") + public void testLambdaInMemberFunction() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunction.kt"); + } + + @TestMetadata("lambdaInMemberFunctionInLocalClass.kt") + public void testLambdaInMemberFunctionInLocalClass() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInLocalClass.kt"); + } + + @TestMetadata("lambdaInMemberFunctionInNestedClass.kt") + public void testLambdaInMemberFunctionInNestedClass() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInMemberFunctionInNestedClass.kt"); + } + + @TestMetadata("lambdaInObjectExpression.kt") + public void testLambdaInObjectExpression() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInObjectExpression.kt"); + } + + @TestMetadata("lambdaInPackage.kt") + public void testLambdaInPackage() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPackage.kt"); + } + + @TestMetadata("lambdaInPropertyGetter.kt") + public void testLambdaInPropertyGetter() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertyGetter.kt"); + } + + @TestMetadata("lambdaInPropertySetter.kt") + public void testLambdaInPropertySetter() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/reflection/lambda/lambdaInPropertySetter.kt"); + } + + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("Reflection"); + suite.addTestSuite(Reflection.class); + suite.addTestSuite(InsideLambda.class); + suite.addTestSuite(Lambda.class); + return suite; + } + } + @TestMetadata("compiler/testData/codegen/boxWithStdlib/regressions") public static class Regressions extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInRegressions() throws Exception { @@ -1472,6 +1574,7 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode suite.addTestSuite(FullJdk.class); suite.addTestSuite(JdkAnnotations.class); suite.addTest(Ranges.innerSuite()); + suite.addTest(Reflection.innerSuite()); suite.addTestSuite(Regressions.class); suite.addTestSuite(Strings.class); suite.addTestSuite(ToArray.class);