KT-27705: Use proper types for captured outer class instance

Call typeMapper only if we have an inline class.
This commit is contained in:
Dmitry Petrov
2018-10-19 16:48:18 +03:00
parent 60986293bf
commit ea4afdaebe
9 changed files with 70 additions and 9 deletions
@@ -86,7 +86,7 @@ public class ConstructorCodegen {
ClassConstructorDescriptor constructorDescriptor = descriptor.getUnsubstitutedPrimaryConstructor();
if (constructorDescriptor == null) return;
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
KtPrimaryConstructor primaryConstructor = myClass.getPrimaryConstructor();
JvmDeclarationOrigin origin = JvmDeclarationOriginKt
@@ -127,7 +127,7 @@ public class ConstructorCodegen {
) {
if (!canHaveDeclaredConstructors(descriptor)) return;
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
KtSecondaryConstructor constructor = (KtSecondaryConstructor) descriptorToDeclaration(constructorDescriptor);
@@ -309,8 +309,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
@NotNull
public ConstructorContext intoConstructor(@NotNull ConstructorDescriptor descriptor) {
return new ConstructorContext(descriptor, getContextKind(), this, closure);
public ConstructorContext intoConstructor(@NotNull ConstructorDescriptor descriptor, @NotNull KotlinTypeMapper typeMapper) {
return new ConstructorContext(descriptor, getContextKind(), this, closure, typeMapper);
}
@NotNull
@@ -21,26 +21,45 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.OwnerKind;
import org.jetbrains.kotlin.codegen.StackValue;
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 static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.types.SimpleType;
import org.jetbrains.org.objectweb.asm.Type;
public class ConstructorContext extends MethodContext {
private static final StackValue LOCAL_1 = StackValue.local(1, OBJECT_TYPE);
private boolean thisInitialized = false;
private final KotlinTypeMapper kotlinTypeMapper;
public ConstructorContext(
@NotNull ConstructorDescriptor contextDescriptor,
@NotNull OwnerKind kind,
@NotNull CodegenContext parent,
@Nullable MutableClosure closure
@Nullable MutableClosure closure,
@NotNull KotlinTypeMapper kotlinTypeMapper
) {
super(contextDescriptor, kind, parent, closure, false);
this.kotlinTypeMapper = kotlinTypeMapper;
}
@Override
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) {
throw new UnsupportedOperationException("Don't know how to generate outer expression for " + getContextDescriptor());
}
+17
View File
@@ -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"
}
@@ -12055,6 +12055,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
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")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -12055,6 +12055,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
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")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -12060,6 +12060,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
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")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -10455,6 +10455,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
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")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -11500,6 +11500,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
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")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");