Fix accessor generation for inline class members

TODO 'generateMethodCallTo' is a bloody mess that deserves rewriting.
This commit is contained in:
Dmitry Petrov
2018-09-24 14:20:19 +03:00
parent edc8cf3ed0
commit 850d72f13f
11 changed files with 163 additions and 18 deletions
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
@@ -868,11 +869,15 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
boolean isJvmStaticInObjectOrClass = CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(functionDescriptor);
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor) &&
!isNonDefaultInterfaceMember(functionDescriptor) &&
!isJvmStaticInObjectOrClass;
!isJvmStaticInObjectOrClass &&
!InlineClassesUtilsKt.isInlineClass(functionDescriptor.getContainingDeclaration());
boolean accessorIsConstructor = accessorDescriptor instanceof AccessorForConstructorDescriptor;
ReceiverParameterDescriptor dispatchReceiver = functionDescriptor.getDispatchReceiverParameter();
Type dispatchReceiverType = dispatchReceiver != null ? typeMapper.mapType(dispatchReceiver.getType()) : AsmTypes.OBJECT_TYPE;
int accessorParam = (hasDispatchReceiver && !accessorIsConstructor) ? 1 : 0;
int reg = hasDispatchReceiver ? 1 : 0;
int reg = hasDispatchReceiver ? dispatchReceiverType.getSize() : 0;
if (!accessorIsConstructor && functionDescriptor instanceof ConstructorDescriptor) {
iv.anew(callableMethod.getOwner());
iv.dup();
@@ -881,7 +886,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
}
else if (KotlinTypeMapper.isAccessor(accessorDescriptor) && (hasDispatchReceiver || accessorIsConstructor)) {
if (!isJvmStaticInObjectOrClass) {
iv.load(0, OBJECT_TYPE);
iv.load(0, dispatchReceiverType);
}
}
@@ -0,0 +1,10 @@
// !LANGUAGE: +InlineClasses
// IGNORE_BACKEND: JVM_IR
inline class R(private val r: Long) {
fun test() = run { ok() }
private fun ok() = "OK"
}
fun box() = R(0).test()
@@ -0,0 +1,10 @@
// !LANGUAGE: +InlineClasses
// IGNORE_BACKEND: JVM_IR
inline class R(private val r: Int) {
fun test() = { ok() }()
private fun ok() = "OK"
}
fun box() = R(0).test()
@@ -0,0 +1,10 @@
// !LANGUAGE: +InlineClasses
// IGNORE_BACKEND: JVM_IR
inline class R(private val r: Long) {
fun test() = { ok() }()
private fun ok() = "OK"
}
fun box() = R(0).test()
@@ -0,0 +1,10 @@
// !LANGUAGE: +InlineClasses
// IGNORE_BACKEND: JVM_IR
inline class R(private val r: Long) {
fun test() = { ok() }()
fun ok() = "OK"
}
fun box() = R(0).test()
@@ -11932,9 +11932,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambdaInInlineClass.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambdaInInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambdaInInlineClass.kt");
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambda.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambda() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambda.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambda2.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambda2.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromLambda.kt")
public void testAccessPrivateInlineClassMethodFromLambda() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromLambda.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromLambda2.kt")
public void testAccessPrivateInlineClassMethodFromLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromLambda2.kt");
}
public void testAllFilesPresentInContextsAndAccessors() throws Exception {
@@ -11946,6 +11961,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInLambda.kt");
}
@TestMetadata("captureInlineClassInstanceInLambda2.kt")
public void testCaptureInlineClassInstanceInLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInLambda2.kt");
}
@TestMetadata("captureInlineClassInstanceInObject.kt")
public void testCaptureInlineClassInstanceInObject() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInObject.kt");
@@ -11932,9 +11932,24 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambdaInInlineClass.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambdaInInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambdaInInlineClass.kt");
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambda.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambda() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambda.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambda2.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambda2.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromLambda.kt")
public void testAccessPrivateInlineClassMethodFromLambda() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromLambda.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromLambda2.kt")
public void testAccessPrivateInlineClassMethodFromLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromLambda2.kt");
}
public void testAllFilesPresentInContextsAndAccessors() throws Exception {
@@ -11946,6 +11961,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInLambda.kt");
}
@TestMetadata("captureInlineClassInstanceInLambda2.kt")
public void testCaptureInlineClassInstanceInLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInLambda2.kt");
}
@TestMetadata("captureInlineClassInstanceInObject.kt")
public void testCaptureInlineClassInstanceInObject() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInObject.kt");
@@ -11937,9 +11937,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
}
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambdaInInlineClass.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambdaInInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambdaInInlineClass.kt");
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambda.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambda() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambda.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambda2.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambda2.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromLambda.kt")
public void testAccessPrivateInlineClassMethodFromLambda() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromLambda.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromLambda2.kt")
public void testAccessPrivateInlineClassMethodFromLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromLambda2.kt");
}
public void testAllFilesPresentInContextsAndAccessors() throws Exception {
@@ -11951,6 +11966,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInLambda.kt");
}
@TestMetadata("captureInlineClassInstanceInLambda2.kt")
public void testCaptureInlineClassInstanceInLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInLambda2.kt");
}
@TestMetadata("captureInlineClassInstanceInObject.kt")
public void testCaptureInlineClassInstanceInObject() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInObject.kt");
@@ -10472,9 +10472,24 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
}
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambdaInInlineClass.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambdaInInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambdaInInlineClass.kt");
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambda.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambda() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambda.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambda2.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambda2.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromLambda.kt")
public void testAccessPrivateInlineClassMethodFromLambda() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromLambda.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromLambda2.kt")
public void testAccessPrivateInlineClassMethodFromLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromLambda2.kt");
}
public void testAllFilesPresentInContextsAndAccessors() throws Exception {
@@ -10486,6 +10501,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInLambda.kt");
}
@TestMetadata("captureInlineClassInstanceInLambda2.kt")
public void testCaptureInlineClassInstanceInLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInLambda2.kt");
}
@TestMetadata("captureInlineClassInstanceInObject.kt")
public void testCaptureInlineClassInstanceInObject() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInObject.kt");
@@ -11517,9 +11517,24 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
}
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambdaInInlineClass.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambdaInInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambdaInInlineClass.kt");
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambda.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambda() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambda.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromInlineLambda2.kt")
public void testAccessPrivateInlineClassMethodFromInlineLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromInlineLambda2.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromLambda.kt")
public void testAccessPrivateInlineClassMethodFromLambda() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromLambda.kt");
}
@TestMetadata("accessPrivateInlineClassMethodFromLambda2.kt")
public void testAccessPrivateInlineClassMethodFromLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/accessPrivateInlineClassMethodFromLambda2.kt");
}
public void testAllFilesPresentInContextsAndAccessors() throws Exception {
@@ -11531,6 +11546,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInLambda.kt");
}
@TestMetadata("captureInlineClassInstanceInLambda2.kt")
public void testCaptureInlineClassInstanceInLambda2() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInLambda2.kt");
}
@TestMetadata("captureInlineClassInstanceInObject.kt")
public void testCaptureInlineClassInstanceInObject() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/contextsAndAccessors/captureInlineClassInstanceInObject.kt");