diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 740e2574d9e..04f547a7cda 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -295,4 +295,21 @@ public class CodegenUtil { // If you try to remove it, run tests on Windows. return FileUtil.toSystemDependentName(file.getVirtualFile().getPath()).hashCode(); } + + @Nullable + public static ClassDescriptor getExpectedThisObjectForConstructorCall( + @NotNull ConstructorDescriptor descriptor, + @Nullable CalculatedClosure closure + ) { + //for compilation against sources + if (closure != null) { + return closure.getCaptureThis(); + } + + //for compilation against binaries + //TODO: It's best to use this code also for compilation against sources + // but sometimes structures that have expectedThisObject (bug?) mapped to static classes + ReceiverParameterDescriptor expectedThisObject = descriptor.getExpectedThisObject(); + return expectedThisObject != null ? (ClassDescriptor) expectedThisObject.getContainingDeclaration() : null; + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index f1b8ab91304..bbd707dacdf 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -3255,7 +3255,8 @@ public class ExpressionCodegen extends JetVisitor implem ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) resolvedCall.getResultingDescriptor(); MutableClosure closure = bindingContext.get(CLOSURE, constructorDescriptor.getContainingDeclaration()); - if (receiver.type.getSort() != Type.VOID && (closure == null || closure.getCaptureThis() == null)) { + ClassDescriptor descriptor = getExpectedThisObjectForConstructorCall(constructorDescriptor, closure); + if (receiver.type.getSort() != Type.VOID && descriptor == null) { v.pop(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java index cd7427c4c2b..66f4f2905c8 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -838,7 +838,7 @@ public class JetTypeMapper extends BindingTraceAware { signatureWriter.writeParametersStart(); ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration(); - ClassDescriptor captureThis = closure != null ? closure.getCaptureThis() : null; + ClassDescriptor captureThis = getExpectedThisObjectForConstructorCall(descriptor, closure); if (captureThis != null) { signatureWriter.writeParameterType(JvmMethodParameterKind.OUTER); mapType(captureThis.getDefaultType(), signatureWriter, JetTypeMapperMode.VALUE); diff --git a/compiler/testData/codegen/boxWithJava/innerClass/kt3532.java b/compiler/testData/codegen/boxWithJava/innerClass/kt3532.java new file mode 100644 index 00000000000..590f92dbf37 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/innerClass/kt3532.java @@ -0,0 +1,3 @@ +public class kt3532 { + public class Inner { } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/innerClass/kt3532.kt b/compiler/testData/codegen/boxWithJava/innerClass/kt3532.kt new file mode 100644 index 00000000000..c935a7b7e93 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/innerClass/kt3532.kt @@ -0,0 +1,4 @@ +fun box(): String { + kt3532().Inner() + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/compileKotlinAgainstKotlin/InnerClassConstructor.A.kt b/compiler/testData/compileKotlinAgainstKotlin/InnerClassConstructor.A.kt new file mode 100644 index 00000000000..0bebf5453cb --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/InnerClassConstructor.A.kt @@ -0,0 +1,6 @@ +//test for KT-3702 Inner class constructor cannot be invoked in override function with receiver +package second + +public class Outer() { + inner class Inner(test: String) +} \ No newline at end of file diff --git a/compiler/testData/compileKotlinAgainstKotlin/InnerClassConstructor.B.kt b/compiler/testData/compileKotlinAgainstKotlin/InnerClassConstructor.B.kt new file mode 100644 index 00000000000..35c6bd280f1 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/InnerClassConstructor.B.kt @@ -0,0 +1,10 @@ +//test for KT-3702 Inner class constructor cannot be invoked in override function with receiver +import second.Outer + +fun Outer.testExt() { + Inner("test") +} + +fun main(args: Array) { + Outer().testExt() +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index b85b9016bc3..46f3ab25fd2 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("compiler/testData/codegen/boxWithJava") -@InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.Annotations.class, BlackBoxWithJavaCodegenTestGenerated.CallableReference.class, BlackBoxWithJavaCodegenTestGenerated.Enum.class, BlackBoxWithJavaCodegenTestGenerated.Functions.class, BlackBoxWithJavaCodegenTestGenerated.Property.class, BlackBoxWithJavaCodegenTestGenerated.Sam.class, BlackBoxWithJavaCodegenTestGenerated.StaticFun.class, BlackBoxWithJavaCodegenTestGenerated.Visibility.class}) +@InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.Annotations.class, BlackBoxWithJavaCodegenTestGenerated.CallableReference.class, BlackBoxWithJavaCodegenTestGenerated.Enum.class, BlackBoxWithJavaCodegenTestGenerated.Functions.class, BlackBoxWithJavaCodegenTestGenerated.InnerClass.class, BlackBoxWithJavaCodegenTestGenerated.Property.class, BlackBoxWithJavaCodegenTestGenerated.Sam.class, BlackBoxWithJavaCodegenTestGenerated.StaticFun.class, BlackBoxWithJavaCodegenTestGenerated.Visibility.class}) public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBoxWithJava() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithJava"), Pattern.compile("^(.+)\\.kt$"), true); @@ -134,6 +134,19 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege } + @TestMetadata("compiler/testData/codegen/boxWithJava/innerClass") + public static class InnerClass extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInInnerClass() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithJava/innerClass"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("kt3532.kt") + public void testKt3532() throws Exception { + doTestWithJava("compiler/testData/codegen/boxWithJava/innerClass/kt3532.kt"); + } + + } + @TestMetadata("compiler/testData/codegen/boxWithJava/property") public static class Property extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInProperty() throws Exception { @@ -501,6 +514,7 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege suite.addTestSuite(CallableReference.class); suite.addTestSuite(Enum.class); suite.addTestSuite(Functions.class); + suite.addTestSuite(InnerClass.class); suite.addTestSuite(Property.class); suite.addTest(Sam.innerSuite()); suite.addTestSuite(StaticFun.class); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java index 4e750ab007f..701f5eb8753 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java @@ -61,6 +61,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl doTest("compiler/testData/compileKotlinAgainstKotlin/InnerClass.A.kt"); } + @TestMetadata("InnerClassConstructor.A.kt") + public void testInnerClassConstructor() throws Exception { + doTest("compiler/testData/compileKotlinAgainstKotlin/InnerClassConstructor.A.kt"); + } + @TestMetadata("InnerEnum.A.kt") public void testInnerEnum() throws Exception { doTest("compiler/testData/compileKotlinAgainstKotlin/InnerEnum.A.kt");