KT-27705: Use proper types for captured outer class instance
Call typeMapper only if we have an inline class.
This commit is contained in:
@@ -86,7 +86,7 @@ public class ConstructorCodegen {
|
|||||||
ClassConstructorDescriptor constructorDescriptor = descriptor.getUnsubstitutedPrimaryConstructor();
|
ClassConstructorDescriptor constructorDescriptor = descriptor.getUnsubstitutedPrimaryConstructor();
|
||||||
if (constructorDescriptor == null) return;
|
if (constructorDescriptor == null) return;
|
||||||
|
|
||||||
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
|
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
|
||||||
|
|
||||||
KtPrimaryConstructor primaryConstructor = myClass.getPrimaryConstructor();
|
KtPrimaryConstructor primaryConstructor = myClass.getPrimaryConstructor();
|
||||||
JvmDeclarationOrigin origin = JvmDeclarationOriginKt
|
JvmDeclarationOrigin origin = JvmDeclarationOriginKt
|
||||||
@@ -127,7 +127,7 @@ public class ConstructorCodegen {
|
|||||||
) {
|
) {
|
||||||
if (!canHaveDeclaredConstructors(descriptor)) return;
|
if (!canHaveDeclaredConstructors(descriptor)) return;
|
||||||
|
|
||||||
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
|
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
|
||||||
|
|
||||||
KtSecondaryConstructor constructor = (KtSecondaryConstructor) descriptorToDeclaration(constructorDescriptor);
|
KtSecondaryConstructor constructor = (KtSecondaryConstructor) descriptorToDeclaration(constructorDescriptor);
|
||||||
|
|
||||||
|
|||||||
@@ -309,8 +309,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ConstructorContext intoConstructor(@NotNull ConstructorDescriptor descriptor) {
|
public ConstructorContext intoConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull KotlinTypeMapper typeMapper) {
|
||||||
return new ConstructorContext(descriptor, getContextKind(), this, closure);
|
return new ConstructorContext(descriptor, getContextKind(), this, closure, typeMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -21,26 +21,45 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.codegen.OwnerKind;
|
import org.jetbrains.kotlin.codegen.OwnerKind;
|
||||||
import org.jetbrains.kotlin.codegen.StackValue;
|
import org.jetbrains.kotlin.codegen.StackValue;
|
||||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||||
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor;
|
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
import org.jetbrains.kotlin.types.SimpleType;
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
public class ConstructorContext extends MethodContext {
|
public class ConstructorContext extends MethodContext {
|
||||||
private static final StackValue LOCAL_1 = StackValue.local(1, OBJECT_TYPE);
|
|
||||||
private boolean thisInitialized = false;
|
private boolean thisInitialized = false;
|
||||||
|
private final KotlinTypeMapper kotlinTypeMapper;
|
||||||
|
|
||||||
public ConstructorContext(
|
public ConstructorContext(
|
||||||
@NotNull ConstructorDescriptor contextDescriptor,
|
@NotNull ConstructorDescriptor contextDescriptor,
|
||||||
@NotNull OwnerKind kind,
|
@NotNull OwnerKind kind,
|
||||||
@NotNull CodegenContext parent,
|
@NotNull CodegenContext parent,
|
||||||
@Nullable MutableClosure closure
|
@Nullable MutableClosure closure,
|
||||||
|
@NotNull KotlinTypeMapper kotlinTypeMapper
|
||||||
) {
|
) {
|
||||||
super(contextDescriptor, kind, parent, closure, false);
|
super(contextDescriptor, kind, parent, closure, false);
|
||||||
|
this.kotlinTypeMapper = kotlinTypeMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StackValue getOuterExpression(StackValue prefix, boolean ignoreNoOuter) {
|
public StackValue getOuterExpression(StackValue prefix, boolean ignoreNoOuter) {
|
||||||
StackValue stackValue = closure != null && closure.getCapturedOuterClassDescriptor() != null ? LOCAL_1 : null;
|
ClassDescriptor capturedOuterClassDescriptor = closure != null ? closure.getCapturedOuterClassDescriptor() : null;
|
||||||
|
StackValue stackValue;
|
||||||
|
if (capturedOuterClassDescriptor != null) {
|
||||||
|
if (capturedOuterClassDescriptor.isInline()) {
|
||||||
|
SimpleType outerClassKotlinType = capturedOuterClassDescriptor.getDefaultType();
|
||||||
|
Type outerClassType = kotlinTypeMapper.mapType(capturedOuterClassDescriptor);
|
||||||
|
stackValue = StackValue.local(1, outerClassType, outerClassKotlinType);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stackValue = StackValue.local(1, AsmTypes.OBJECT_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stackValue = null;
|
||||||
|
}
|
||||||
if (!ignoreNoOuter && stackValue == null) {
|
if (!ignoreNoOuter && stackValue == null) {
|
||||||
throw new UnsupportedOperationException("Don't know how to generate outer expression for " + getContextDescriptor());
|
throw new UnsupportedOperationException("Don't know how to generate outer expression for " + getContextDescriptor());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// !LANGUAGE: +InlineClasses
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
|
||||||
|
inline class Z(val x: Int) {
|
||||||
|
inner class Inner(val y: Int) {
|
||||||
|
val xx = x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val zi = Z(42).Inner(100)
|
||||||
|
if (zi.xx != 42) throw AssertionError()
|
||||||
|
if (zi.y != 100) throw AssertionError()
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+5
@@ -12055,6 +12055,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt27705.kt")
|
||||||
|
public void testKt27705() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/kt27705.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||||
|
|||||||
+5
@@ -12055,6 +12055,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt27705.kt")
|
||||||
|
public void testKt27705() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/kt27705.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||||
|
|||||||
+5
@@ -12060,6 +12060,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt27705.kt")
|
||||||
|
public void testKt27705() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/kt27705.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||||
|
|||||||
+5
@@ -10455,6 +10455,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt27705.kt")
|
||||||
|
public void testKt27705() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/kt27705.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||||
|
|||||||
+5
@@ -11500,6 +11500,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/kt27140.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt27705.kt")
|
||||||
|
public void testKt27705() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/kt27705.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
|
||||||
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user