diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index c9fc22aa137..d91af314b59 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -25,6 +25,7 @@ import com.intellij.util.containers.ContainerUtil; import kotlin.Function1; 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.bridges.Bridge; import org.jetbrains.jet.codegen.bridges.BridgesPackage; @@ -36,6 +37,7 @@ 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.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; @@ -514,9 +516,10 @@ public class FunctionCodegen extends ParentCodegenAware { @NotNull GenerationState state, @NotNull CallableMethod method, @NotNull ConstructorDescriptor constructorDescriptor, - @NotNull ClassBuilder classBuilder + @NotNull ClassBuilder classBuilder, + @NotNull JetClassOrObject classOrObject ) { - if (!isDefaultConstructorNeeded(state.getBindingContext(), constructorDescriptor)) { + if (!isEmptyConstructorNeeded(state.getBindingContext(), constructorDescriptor, classOrObject)) { return; } int flags = getVisibilityAccessFlag(constructorDescriptor); @@ -550,7 +553,7 @@ public class FunctionCodegen extends ParentCodegenAware { String desc = JetTypeMapper.getDefaultDescriptor(method.getAsmMethod(), false); v.invokespecial(methodOwner.getInternalName(), "", desc, false); v.areturn(Type.VOID_TYPE); - endVisit(mv, "default constructor for " + methodOwner.getInternalName(), null); + endVisit(mv, "default constructor for " + methodOwner.getInternalName(), classOrObject); } void generateDefaultIfNeeded( @@ -739,9 +742,15 @@ public class FunctionCodegen extends ParentCodegenAware { return needed; } - private static boolean isDefaultConstructorNeeded(@NotNull BindingContext context, @NotNull ConstructorDescriptor constructorDescriptor) { + private static boolean isEmptyConstructorNeeded( + @NotNull BindingContext context, + @NotNull ConstructorDescriptor constructorDescriptor, + @NotNull JetClassOrObject classOrObject + ) { ClassDescriptor classDescriptor = constructorDescriptor.getContainingDeclaration(); + if (classOrObject.isLocal()) return false; + if (CodegenBinding.canHaveOuter(context, classDescriptor)) return false; if (classDescriptor.getVisibility() == Visibilities.PRIVATE || diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index ed6f66f56ea..df21937bbdf 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -1151,7 +1151,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { DefaultParameterValueLoader.DEFAULT, null); CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor); - FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v); + FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v, myClass); if (isClassObject(descriptor)) { context.recordSyntheticAccessorIfNeeded(constructorDescriptor, bindingContext); diff --git a/compiler/testData/codegen/box/localClasses/kt3584.kt b/compiler/testData/codegen/box/localClasses/kt3584.kt new file mode 100644 index 00000000000..06dd0e8e2cb --- /dev/null +++ b/compiler/testData/codegen/box/localClasses/kt3584.kt @@ -0,0 +1,13 @@ +fun box(): String { + val s = "captured"; + + class A(val param: String = "OK") { + val s2 = s + param + } + + if (A().s2 != "capturedOK") return "fail 1: ${A().s2}" + + if (A("Test").s2 != "capturedTest") return "fail 1: ${A("Test").s2}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 9daa9b6e477..33ed7968b1c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -4151,6 +4151,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt3584.kt") + public void testKt3584() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/localClasses/kt3584.kt"); + doTest(fileName); + } + @TestMetadata("localClass.kt") public void testLocalClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/localClasses/localClass.kt");