From 0d239a3e0e047efff470235ddf5cd28f0024a39f Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 31 Mar 2014 15:53:00 +0400 Subject: [PATCH] Moving local fun callee generation to CallReceiver --- .../jet/codegen/ExpressionCodegen.java | 9 -------- .../org/jetbrains/jet/codegen/StackValue.java | 19 +++++++++++++++-- .../box/functions/localFunctions/kt4514.kt | 9 ++++++++ .../box/functions/localFunctions/kt4784.kt | 20 ++++++++++++++++++ .../localExtensionOnNullableParameter.kt | 21 +++++++++++++++++++ .../BlackBoxCodegenTestGenerated.java | 15 +++++++++++++ 6 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 compiler/testData/codegen/box/functions/localFunctions/kt4514.kt create mode 100644 compiler/testData/codegen/box/functions/localFunctions/kt4784.kt create mode 100644 compiler/testData/codegen/box/functions/localFunctions/localExtensionOnNullableParameter.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 6b982a090eb..824473e7e9f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2277,15 +2277,6 @@ public class ExpressionCodegen extends JetVisitor implem ) { CallableDescriptor descriptor = resolvedCall.getResultingDescriptor(); - //generate callee for local function - Type calleeType = callableMethod.getGenerateCalleeType(); - if (calleeType != null) { - StackValue value = findLocalOrCapturedValue(descriptor.getOriginal()); - assert value != null : "Local fun should be found in locals or in captured params: " + resolvedCall; - value.put(calleeType, v); - } - - //generate this (absent for local fun) and receiver if (!(descriptor instanceof ConstructorDescriptor)) { // otherwise already receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod); receiver.put(receiver.type, v); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 5b40e9823aa..baf7a826eb9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -330,12 +330,16 @@ public abstract class StackValue { ExpressionCodegen codegen, @Nullable CallableMethod callableMethod ) { - if (resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists()) { + if (resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists() || isLocalFunCall(callableMethod)) { return new CallReceiver(resolvedCall, receiver, codegen, callableMethod, true); } return receiver; } + private static boolean isLocalFunCall(@Nullable CallableMethod callableMethod) { + return callableMethod != null && callableMethod.getGenerateCalleeType() != null; + } + public static StackValue receiverWithoutReceiverArgument(StackValue receiverWithParameter) { if (receiverWithParameter instanceof CallReceiver) { CallReceiver callReceiver = (CallReceiver) receiverWithParameter; @@ -1139,7 +1143,11 @@ public abstract class StackValue { else { return codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType()); } - } else { + } + else if (isLocalFunCall(callableMethod)) { + return callableMethod.getGenerateCalleeType(); + } + else { return Type.VOID_TYPE; } } @@ -1162,6 +1170,13 @@ public abstract class StackValue { genReceiver(v, thisObject, type, null, 0); } + depth = 1; + } else if (isLocalFunCall(callableMethod)) { + assert receiver == none() || receiverArgument.exists(): "Receiver should be present only for local extension function: " + callableMethod; + StackValue value = codegen.findLocalOrCapturedValue(descriptor.getOriginal()); + assert value != null : "Local fun should be found in locals or in captured params: " + resolvedCall; + value.put(callableMethod.getGenerateCalleeType(), v); + depth = 1; } else { diff --git a/compiler/testData/codegen/box/functions/localFunctions/kt4514.kt b/compiler/testData/codegen/box/functions/localFunctions/kt4514.kt new file mode 100644 index 00000000000..c767d3f0352 --- /dev/null +++ b/compiler/testData/codegen/box/functions/localFunctions/kt4514.kt @@ -0,0 +1,9 @@ +fun box(): String { + fun String.f() = this + val vf: String.() -> String = { this } + + val localExt = "O".f() + "K"?.f() + if (localExt != "OK") return "localExt $localExt" + + return "O".vf() + "K"?.vf() +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/functions/localFunctions/kt4784.kt b/compiler/testData/codegen/box/functions/localFunctions/kt4784.kt new file mode 100644 index 00000000000..7e1b45ef5ff --- /dev/null +++ b/compiler/testData/codegen/box/functions/localFunctions/kt4784.kt @@ -0,0 +1,20 @@ +open class T(var value: Int) {} + +fun plusAssign(): T { + + fun T.plusAssign(s: Int) { + value += s + } + + var t = T(1) + t += 1 + + return t +} + +fun box(): String { + val result = plusAssign().value + if (result != 2) return "fail 1: $result" + + return "OK" +} diff --git a/compiler/testData/codegen/box/functions/localFunctions/localExtensionOnNullableParameter.kt b/compiler/testData/codegen/box/functions/localFunctions/localExtensionOnNullableParameter.kt new file mode 100644 index 00000000000..709b1c9ac1e --- /dev/null +++ b/compiler/testData/codegen/box/functions/localFunctions/localExtensionOnNullableParameter.kt @@ -0,0 +1,21 @@ +open class T(var value: Int) {} + +fun localExtensionOnNullableParameter(): T { + + fun T.local(s: Int) { + value += s + } + + var t: T? = T(1) + t?.local(2) + + return t!! +} + + +fun box(): String { + val result = localExtensionOnNullableParameter().value + if (result != 3) return "fail 2: $result" + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index beff96793f6..f702d7fc68a 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -2961,6 +2961,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/functions/localFunctions/kt4119_2.kt"); } + @TestMetadata("kt4514.kt") + public void testKt4514() throws Exception { + doTest("compiler/testData/codegen/box/functions/localFunctions/kt4514.kt"); + } + @TestMetadata("kt4777.kt") public void testKt4777() throws Exception { doTest("compiler/testData/codegen/box/functions/localFunctions/kt4777.kt"); @@ -2971,6 +2976,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/functions/localFunctions/kt4783.kt"); } + @TestMetadata("kt4784.kt") + public void testKt4784() throws Exception { + doTest("compiler/testData/codegen/box/functions/localFunctions/kt4784.kt"); + } + + @TestMetadata("localExtensionOnNullableParameter.kt") + public void testLocalExtensionOnNullableParameter() throws Exception { + doTest("compiler/testData/codegen/box/functions/localFunctions/localExtensionOnNullableParameter.kt"); + } + @TestMetadata("localFunctionInConstructor.kt") public void testLocalFunctionInConstructor() throws Exception { doTest("compiler/testData/codegen/box/functions/localFunctions/localFunctionInConstructor.kt");