From 2566a7a25ebf98252541f1e23eb41280d6bd6cf1 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Wed, 28 Dec 2016 14:21:00 +0100 Subject: [PATCH] Rename receiver$0 in CallableReference to receiver #KT-15449 Fixed --- .../org/jetbrains/kotlin/codegen/AsmUtil.java | 1 + .../kotlin/codegen/ExpressionCodegen.java | 3 +- .../FunctionReferenceGenerationStrategy.java | 7 +++- .../codegen/PropertyReferenceCodegen.kt | 9 +++-- .../kotlin/codegen/callableReferenceUtil.kt | 9 ++++- .../kotlin/codegen/inline/InlineCodegen.java | 6 +-- .../boxInline/callableReference/kt15449.kt | 40 +++++++++++++++++++ .../BlackBoxInlineCodegenTestGenerated.java | 6 +++ ...otlinAgainstInlineKotlinTestGenerated.java | 6 +++ .../jvm/internal/CallableReference.java | 8 ++-- .../internal/MutablePropertyReference.java | 4 +- .../internal/MutablePropertyReference0.java | 4 +- .../internal/MutablePropertyReference1.java | 4 +- .../jvm/internal/PropertyReference.java | 4 +- .../jvm/internal/PropertyReference0.java | 4 +- .../jvm/internal/PropertyReference1.java | 4 +- ...CallableReferenceInlineTestsGenerated.java | 6 +++ 17 files changed, 96 insertions(+), 29 deletions(-) create mode 100644 compiler/testData/codegen/boxInline/callableReference/kt15449.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index c704030b3dc..2fcf29825ff 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -95,6 +95,7 @@ public class AsmUtil { .put(JavaVisibilities.PACKAGE_VISIBILITY, NO_FLAG_PACKAGE_PRIVATE) .build(); + public static final String BOUND_REFERENCE_RECEIVER = "receiver"; public static final String RECEIVER_NAME = "$receiver"; public static final String CAPTURED_RECEIVER_FIELD = "receiver$0"; public static final String CAPTURED_THIS_FIELD = "this$0"; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index c2316305a18..b90afe33244 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -91,7 +91,6 @@ import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.TypeProjection; import org.jetbrains.kotlin.types.TypeUtils; -import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; import org.jetbrains.kotlin.types.expressions.DoubleColonLHS; import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt; import org.jetbrains.kotlin.util.OperatorNameConventions; @@ -3269,7 +3268,7 @@ public class ExpressionCodegen extends KtVisitor impleme FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression); if (functionDescriptor != null) { FunctionReferenceGenerationStrategy strategy = - new FunctionReferenceGenerationStrategy(state, functionDescriptor, resolvedCall, receiverAsmType, null); + new FunctionReferenceGenerationStrategy(state, functionDescriptor, resolvedCall, receiverAsmType, null, false); return genClosure( expression, functionDescriptor, strategy, null, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionReferenceGenerationStrategy.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionReferenceGenerationStrategy.java index ebfc1a38305..d9c907cc974 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionReferenceGenerationStrategy.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionReferenceGenerationStrategy.java @@ -42,13 +42,15 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat private final FunctionDescriptor functionDescriptor; private final Type receiverType; // non-null for bound references private final StackValue receiverValue; + private final boolean isInliningStrategy; public FunctionReferenceGenerationStrategy( @NotNull GenerationState state, @NotNull FunctionDescriptor functionDescriptor, @NotNull ResolvedCall resolvedCall, @Nullable Type receiverType, - @Nullable StackValue receiverValue + @Nullable StackValue receiverValue, + boolean isInliningStrategy ) { super(state); this.resolvedCall = resolvedCall; @@ -56,6 +58,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat this.functionDescriptor = functionDescriptor; this.receiverType = receiverType; this.receiverValue = receiverValue; + this.isInliningStrategy = isInliningStrategy; assert receiverType != null || receiverValue == null : "A receiver value is provided for unbound function reference. Either this is a bound reference and you forgot " + "to pass receiverType, or you accidentally passed some receiverValue for a reference without receiver"; @@ -187,7 +190,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat if (receiverType != null) { ClassDescriptor classDescriptor = (ClassDescriptor) codegen.getContext().getParentContext().getContextDescriptor(); Type asmType = codegen.getState().getTypeMapper().mapClass(classDescriptor); - return CallableReferenceUtilKt.capturedBoundReferenceReceiver(asmType, receiverType); + return CallableReferenceUtilKt.capturedBoundReferenceReceiver(asmType, receiverType, isInliningStrategy); } // 0 is this (the callable reference class), 1 is the invoke() method's first parameter diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt index 5a98f5ec66b..b2af0a0726b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt @@ -146,12 +146,12 @@ class PropertyReferenceCodegen( private fun generateAccessors() { val getFunction = findGetFunction(localVariableDescriptorForReference) val getImpl = createFakeOpenDescriptor(getFunction, classDescriptor) - functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, getImpl, PropertyReferenceGenerationStrategy(true, getFunction, target, asmType, receiverType, element, state)) + functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, getImpl, PropertyReferenceGenerationStrategy(true, getFunction, target, asmType, receiverType, element, state, false)) if (!ReflectionTypes.isNumberedKMutablePropertyType(localVariableDescriptorForReference.type)) return val setFunction = localVariableDescriptorForReference.type.memberScope.getContributedFunctions(OperatorNameConventions.SET, NoLookupLocation.FROM_BACKEND).single() val setImpl = createFakeOpenDescriptor(setFunction, classDescriptor) - functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, setImpl, PropertyReferenceGenerationStrategy(false, setFunction, target, asmType, receiverType, element, state)) + functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, setImpl, PropertyReferenceGenerationStrategy(false, setFunction, target, asmType, receiverType, element, state, false)) } @@ -243,7 +243,8 @@ class PropertyReferenceCodegen( val asmType: Type, val receiverType: Type?, val expression: KtElement, - state: GenerationState + state: GenerationState, + val isInliningStrategy: Boolean ) : FunctionGenerationStrategy.CodegenBased(state) { override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) { @@ -258,7 +259,7 @@ class PropertyReferenceCodegen( val expectedReceiver = target.dispatchReceiverParameter ?: target.extensionReceiverParameter ?: throw AssertionError("receiverType: $receiverType; no dispatch or extension receiver: $target") val expectedReceiverType = typeMapper.mapType(expectedReceiver.type) - capturedBoundReferenceReceiver(asmType, expectedReceiverType).put(expectedReceiverType, v) + capturedBoundReferenceReceiver(asmType, expectedReceiverType, isInliningStrategy).put(expectedReceiverType, v) } else { val receivers = originalFunctionDesc.valueParameters.dropLast(if (isGetter) 0 else 1) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/callableReferenceUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/callableReferenceUtil.kt index 338d18f4f16..c3d7c682464 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/callableReferenceUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/callableReferenceUtil.kt @@ -24,10 +24,15 @@ import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -fun capturedBoundReferenceReceiver(ownerType: Type, expectedReceiverType: Type): StackValue = +fun capturedBoundReferenceReceiver(ownerType: Type, expectedReceiverType: Type, isInliningStrategy: Boolean): StackValue = StackValue.operation(expectedReceiverType) { iv -> iv.load(0, ownerType) - iv.getfield(ownerType.internalName, AsmUtil.CAPTURED_RECEIVER_FIELD, AsmTypes.OBJECT_TYPE.descriptor) + iv.getfield( + ownerType.internalName, + //HACK for inliner - it should recognize field as captured receiver + if (isInliningStrategy) AsmUtil.CAPTURED_RECEIVER_FIELD else AsmUtil.BOUND_REFERENCE_RECEIVER, + AsmTypes.OBJECT_TYPE.descriptor + ) StackValue.coerce(AsmTypes.OBJECT_TYPE, expectedReceiverType, iv) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java index 6d0e1dc3be2..74a2434dd00 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java @@ -581,8 +581,7 @@ public class InlineCodegen extends CallGenerator { Type asmType = state.getTypeMapper().mapClass(lambdaInfo.getClassDescriptor()); PropertyReferenceInfo info = lambdaInfo.getPropertyReferenceInfo(); strategy = new PropertyReferenceCodegen.PropertyReferenceGenerationStrategy( - true, info.getGetFunction(), info.getTarget(), asmType, receiverType, lambdaInfo.expression, state - ); + true, info.getGetFunction(), info.getTarget(), asmType, receiverType, lambdaInfo.expression, state, true); } else { strategy = new FunctionReferenceGenerationStrategy( @@ -591,7 +590,8 @@ public class InlineCodegen extends CallGenerator { CallUtilKt .getResolvedCallWithAssert(callableReferenceExpression.getCallableReference(), codegen.getBindingContext()), receiverType, - null + null, + true ); } } diff --git a/compiler/testData/codegen/boxInline/callableReference/kt15449.kt b/compiler/testData/codegen/boxInline/callableReference/kt15449.kt new file mode 100644 index 00000000000..7d537bbffa9 --- /dev/null +++ b/compiler/testData/codegen/boxInline/callableReference/kt15449.kt @@ -0,0 +1,40 @@ +// FILE: 1.kt + +package test + +inline fun linearLayout2(init: X.() -> Unit) { + return X().init() +} + +var result = "fail" +class X { + fun calc() { + result = "OK" + } +} + +// FILE: 2.kt +//NO_CHECK_LAMBDA_INLINING +import test.* + +class A { + fun test() { + linearLayout2 { + { + apply2 { + this@linearLayout2::calc + }() + }() + } + } + + public fun T.apply2(block: T.() -> Z): Z { + return block() + } + +} + +fun box(): String { + A().test() + return result +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index 10203e7af3c..26cf6d44b7f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -584,6 +584,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo doTest(fileName); } + @TestMetadata("kt15449.kt") + public void testKt15449() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/kt15449.kt"); + doTest(fileName); + } + @TestMetadata("propertyIntrinsic.kt") public void testPropertyIntrinsic() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/propertyIntrinsic.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index 7f2b555c832..c14fd6d2ffe 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -584,6 +584,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi doTest(fileName); } + @TestMetadata("kt15449.kt") + public void testKt15449() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/kt15449.kt"); + doTest(fileName); + } + @TestMetadata("propertyIntrinsic.kt") public void testPropertyIntrinsic() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/propertyIntrinsic.kt"); diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/CallableReference.java b/core/runtime.jvm/src/kotlin/jvm/internal/CallableReference.java index 478501da093..24fba0ade7f 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/CallableReference.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/CallableReference.java @@ -39,21 +39,21 @@ public abstract class CallableReference implements KCallable { // objects are written to it. The latter is guaranteed because both KFunctionImpl and KPropertyImpl have at least one final field. private KCallable reflected; - protected final Object receiver$0; + protected final Object receiver; public static final Object NO_RECEIVER = new Object(); public CallableReference() { this(NO_RECEIVER); } - protected CallableReference(Object receiver$0) { - this.receiver$0 = receiver$0; + protected CallableReference(Object receiver) { + this.receiver = receiver; } protected abstract KCallable computeReflected(); public Object getBoundReceiver() { - return receiver$0; + return receiver; } public KCallable compute() { diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference.java b/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference.java index cc43d50dc9b..f27be57cc36 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference.java @@ -22,7 +22,7 @@ public abstract class MutablePropertyReference extends PropertyReference impleme public MutablePropertyReference() { } - public MutablePropertyReference(Object receiver$0) { - super(receiver$0); + public MutablePropertyReference(Object receiver) { + super(receiver); } } diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference0.java b/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference0.java index ca397d41f7a..00d09c2125c 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference0.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference0.java @@ -24,8 +24,8 @@ public abstract class MutablePropertyReference0 extends MutablePropertyReference public MutablePropertyReference0() { } - public MutablePropertyReference0(Object receiver$0) { - super(receiver$0); + public MutablePropertyReference0(Object receiver) { + super(receiver); } @Override diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference1.java b/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference1.java index d3c335d87b2..c9c9ba9dfc6 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference1.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/MutablePropertyReference1.java @@ -24,8 +24,8 @@ public abstract class MutablePropertyReference1 extends MutablePropertyReference public MutablePropertyReference1() { } - public MutablePropertyReference1(Object receiver$0) { - super(receiver$0); + public MutablePropertyReference1(Object receiver) { + super(receiver); } @Override diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference.java b/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference.java index 15f21c3c4db..266494189db 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference.java @@ -24,8 +24,8 @@ public abstract class PropertyReference extends CallableReference implements KPr super(); } - public PropertyReference(Object receiver$0) { - super(receiver$0); + public PropertyReference(Object receiver) { + super(receiver); } @Override diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference0.java b/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference0.java index b7dd0bfddf4..ed40c2d9a95 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference0.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference0.java @@ -24,8 +24,8 @@ public abstract class PropertyReference0 extends PropertyReference implements KP super(); } - public PropertyReference0(Object receiver$0) { - super(receiver$0); + public PropertyReference0(Object receiver) { + super(receiver); } @Override diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference1.java b/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference1.java index e113e94a11b..9846916c43b 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference1.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/PropertyReference1.java @@ -23,8 +23,8 @@ public abstract class PropertyReference1 extends PropertyReference implements KP public PropertyReference1() { } - public PropertyReference1(Object receiver$0) { - super(receiver$0); + public PropertyReference1(Object receiver) { + super(receiver); } @Override diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/CallableReferenceInlineTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/CallableReferenceInlineTestsGenerated.java index fc625687238..41f33794825 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/CallableReferenceInlineTestsGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/CallableReferenceInlineTestsGenerated.java @@ -78,6 +78,12 @@ public class CallableReferenceInlineTestsGenerated extends AbstractCallableRefer throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } + @TestMetadata("kt15449.kt") + public void testKt15449() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/kt15449.kt"); + doTest(fileName); + } + @TestMetadata("propertyIntrinsic.kt") public void testPropertyIntrinsic() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/callableReference/propertyIntrinsic.kt");