From 22b9c25dd019eea32a42cb7c6c0eaea6ea3dbf9a Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Thu, 8 Feb 2018 14:18:17 +0300 Subject: [PATCH] Add `KotlinType` info about `this` inside inline class --- .../kotlin/codegen/ExpressionCodegen.java | 4 ++-- .../jetbrains/kotlin/codegen/StackValue.java | 8 +++++++ .../inlineClasses/useThisInsideInlineClass.kt | 21 +++++++++++++++++++ .../inlineClasses/boxThisOfInlineClass.kt | 20 ++++++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 6 ++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++++ .../codegen/BytecodeTextTestGenerated.java | 6 ++++++ .../LightAnalysisModeTestGenerated.java | 6 ++++++ .../semantics/JsCodegenBoxTestGenerated.java | 6 ++++++ 9 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/box/inlineClasses/useThisInsideInlineClass.kt create mode 100644 compiler/testData/codegen/bytecodeText/inlineClasses/boxThisOfInlineClass.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index cf76d29a371..8055b799b85 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2678,8 +2678,8 @@ public class ExpressionCodegen extends KtVisitor impleme private StackValue generateThisOrOuterFromContext(@NotNull ClassDescriptor thisOrOuterClass, boolean isSuper, boolean forceOuter) { CodegenContext cur = context; - Type type = asmType(thisOrOuterClass.getDefaultType()); - StackValue result = StackValue.local(0, type); + SimpleType thisType = thisOrOuterClass.getDefaultType(); + StackValue result = StackValue.local(0, asmType(thisType), thisType); boolean inStartConstructorContext = cur instanceof ConstructorContext; while (cur != null) { ClassDescriptor thisDescriptor = cur.getThisDescriptor(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index 71e932ac3f4..70dcf8fbc64 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -151,6 +151,10 @@ public abstract class StackValue { return new Local(index, type); } + public static Local local(int index, @NotNull Type type, @Nullable KotlinType kotlinType) { + return new Local(index, type, kotlinType); + } + @NotNull public static Local local(int index, @NotNull Type type, @NotNull VariableDescriptor descriptor) { return new Local(index, type, descriptor.getType(), descriptor.isLateInit(), descriptor.getName()); @@ -802,6 +806,10 @@ public abstract class StackValue { this(index, type, null, false, null); } + private Local(int index, Type type, KotlinType kotlinType) { + this(index, type, kotlinType, false, null); + } + @Override public void putSelector(@NotNull Type type, @Nullable KotlinType kotlinType, @NotNull InstructionAdapter v) { v.load(index, this.type); diff --git a/compiler/testData/codegen/box/inlineClasses/useThisInsideInlineClass.kt b/compiler/testData/codegen/box/inlineClasses/useThisInsideInlineClass.kt new file mode 100644 index 00000000000..e6f3992e850 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/useThisInsideInlineClass.kt @@ -0,0 +1,21 @@ +// !LANGUAGE: +InlineClasses + +inline class UInt(val a: Int) { + fun test() { + takeNullable(this) + takeAnyInside(this) + + takeAnyInside(this.a) + } + + fun takeAnyInside(a: Any) {} +} + +fun takeNullable(a: UInt?) {} + +fun box(): String { + val a = UInt(0) + a.test() + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/boxThisOfInlineClass.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/boxThisOfInlineClass.kt new file mode 100644 index 00000000000..56c788386b1 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/boxThisOfInlineClass.kt @@ -0,0 +1,20 @@ +// !LANGUAGE: +InlineClasses + +inline class UInt(val a: Int) { + fun test() { + takeNullable(this) // box + takeAnyInside(this) // box + + takeAnyInside(this.a) // box int + } + + fun takeAnyInside(a: Any) {} +} + +fun takeNullable(a: UInt?) {} + +// 2 INVOKESTATIC UInt\$Erased.box +// 0 INVOKEVIRTUAL Foo.unbox + +// 1 valueOf +// 0 intValue \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 2f958987049..f81892adb73 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -10496,6 +10496,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineFunctionInsideInlineClass.kt"); doTest(fileName); } + + @TestMetadata("useThisInsideInlineClass.kt") + public void testUseThisInsideInlineClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useThisInsideInlineClass.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/innerNested") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 69b97efbb53..a099dbbb794 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -10496,6 +10496,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineFunctionInsideInlineClass.kt"); doTest(fileName); } + + @TestMetadata("useThisInsideInlineClass.kt") + public void testUseThisInsideInlineClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useThisInsideInlineClass.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/innerNested") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 341ccf2007a..105ad81c93c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1920,6 +1920,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("boxThisOfInlineClass.kt") + public void testBoxThisOfInlineClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxThisOfInlineClass.kt"); + doTest(fileName); + } + @TestMetadata("boxUnboxInlineClassFromMethodReturnType.kt") public void testBoxUnboxInlineClassFromMethodReturnType() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/boxUnboxInlineClassFromMethodReturnType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index f4fe76e117a..009e7afef9f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -10496,6 +10496,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineFunctionInsideInlineClass.kt"); doTest(fileName); } + + @TestMetadata("useThisInsideInlineClass.kt") + public void testUseThisInsideInlineClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useThisInsideInlineClass.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/innerNested") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 869846d7dd1..0efeb1a81f8 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -11480,6 +11480,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineFunctionInsideInlineClass.kt"); doTest(fileName); } + + @TestMetadata("useThisInsideInlineClass.kt") + public void testUseThisInsideInlineClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useThisInsideInlineClass.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/innerNested")