From 932c1444a238599b8097750777d7753dbec2ef12 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 26 Mar 2013 14:30:32 +0400 Subject: [PATCH] Fix for local closures --- .../jet/codegen/ImplementationBodyCodegen.java | 11 +++++++++++ .../jet/codegen/context/ConstructorContext.java | 11 ++++++++++- .../jetbrains/jet/codegen/state/JetTypeMapper.java | 10 ++++++++++ .../box/closures/localFunctionInFunction.kt | 14 ++++++++++++++ .../box/closures/localFunctionInInitializer.kt | 12 ++++++++++++ .../generated/BlackBoxCodegenTestGenerated.java | 10 ++++++++++ 6 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/closures/localFunctionInFunction.kt create mode 100644 compiler/testData/codegen/box/closures/localFunctionInInitializer.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 8a829b98d59..0915a7ad618 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -40,6 +40,7 @@ import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.codegen.state.JetTypeMapperMode; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; @@ -1232,6 +1233,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } constructorContext.lookupInContext(descriptor, null, state, true); + } else if (descriptor instanceof CallableMemberDescriptor) { + MutableClassDescriptor classDescriptor = + (MutableClassDescriptor) constructorContext.getParentContext().getContextDescriptor(); + + for (CallableMemberDescriptor memberDescriptor : classDescriptor.getAllCallableMembers()) { + if (descriptor.equals(memberDescriptor)) { + return; + } + } + constructorContext.lookupInContext(descriptor, null, state, true); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/ConstructorContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/ConstructorContext.java index bb8f0d27fa4..449931cd78d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/ConstructorContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/ConstructorContext.java @@ -16,6 +16,8 @@ package org.jetbrains.jet.codegen.context; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.OwnerKind; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; @@ -29,7 +31,7 @@ public class ConstructorContext extends MethodContext { public ConstructorContext( ConstructorDescriptor contextDescriptor, OwnerKind kind, - CodegenContext parent + @NotNull CodegenContext parent ) { super(contextDescriptor, kind, parent); @@ -46,4 +48,11 @@ public class ConstructorContext extends MethodContext { public String toString() { return "Constructor: " + getContextDescriptor().getName(); } + + @NotNull + @Override + public CodegenContext getParentContext() { + //noinspection ConstantConditions + return super.getParentContext(); + } } 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 da442ec18ed..fee60e620a7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -816,6 +816,16 @@ public class JetTypeMapper extends BindingTraceAware { signatureWriter.writeAsmType(sharedVarType, false); signatureWriter.writeParameterTypeEnd(); } + else if (isLocalNamedFun(bindingContext, variableDescriptor)) { + Type type = classNameForAnonymousClass( + bindingContext, + (JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, variableDescriptor) + ).getAsmType(); + + signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); + signatureWriter.writeAsmType(type, false); + signatureWriter.writeParameterTypeEnd(); + } } JetDelegatorToSuperCall superCall = closure.getSuperCall(); diff --git a/compiler/testData/codegen/box/closures/localFunctionInFunction.kt b/compiler/testData/codegen/box/closures/localFunctionInFunction.kt new file mode 100644 index 00000000000..4639ab437dd --- /dev/null +++ b/compiler/testData/codegen/box/closures/localFunctionInFunction.kt @@ -0,0 +1,14 @@ +fun box(): String { + + fun local():Int { + return 10; + } + + class A { + fun test(): Int { + return local() + } + } + + return if (A().test() == 10) "OK" else "fail" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/closures/localFunctionInInitializer.kt b/compiler/testData/codegen/box/closures/localFunctionInInitializer.kt new file mode 100644 index 00000000000..6035aac60ad --- /dev/null +++ b/compiler/testData/codegen/box/closures/localFunctionInInitializer.kt @@ -0,0 +1,12 @@ +fun box(): String { + + fun local():Int { + return 10; + } + + class A { + val test = local() + } + + return if (A().test == 10) "OK" else "fail" +} \ 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 4a8b08c8787..cf55cdcf6af 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -951,6 +951,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/closures/kt2151.kt"); } + @TestMetadata("localFunctionInFunction.kt") + public void testLocalFunctionInFunction() throws Exception { + doTest("compiler/testData/codegen/box/closures/localFunctionInFunction.kt"); + } + + @TestMetadata("localFunctionInInitializer.kt") + public void testLocalFunctionInInitializer() throws Exception { + doTest("compiler/testData/codegen/box/closures/localFunctionInInitializer.kt"); + } + @TestMetadata("recursiveClosure.kt") public void testRecursiveClosure() throws Exception { doTest("compiler/testData/codegen/box/closures/recursiveClosure.kt");