Support unboxing of inline classes in elvis

This commit is contained in:
Mikhail Zarechenskiy
2018-02-07 06:11:15 +03:00
parent fefcddc803
commit 396cc7d02b
8 changed files with 74 additions and 3 deletions
@@ -342,7 +342,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
value.put(type, null, v);
KotlinType ktType = null;
if (expr instanceof KtExpression) {
ktType = kotlinType((KtExpression) expr);
}
value.put(type, ktType, v);
}
@NotNull
@@ -3358,7 +3363,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
KtExpression left = expression.getLeft();
Type exprType = expressionType(expression);
KotlinType exprKotlinType = kotlinType(expression);
Type leftType = expressionType(left);
KotlinType leftKotlinType = kotlinType(left);
Label ifNull = new Label();
@@ -3369,12 +3377,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return value;
}
return StackValue.operation(exprType, v -> {
return StackValue.operation(exprType, exprKotlinType, v -> {
value.put(value.type, value.kotlinType, v);
v.dup();
v.ifnull(ifNull);
StackValue.onStack(leftType).put(exprType, null, v);
StackValue.onStack(leftType, leftKotlinType).put(exprType, exprKotlinType, v);
Label end = new Label();
v.goTo(end);
@@ -0,0 +1,19 @@
// !LANGUAGE: +InlineClasses
inline class UInt(private val u: Int) {
fun asResult() = u
}
fun test(x1: UInt?, x2: UInt?, y: UInt, z: UInt?): Int {
val a = x1 ?: y
val b = x1 ?: z!!
val c = x1 ?: x2 ?: y
return a.asResult() + b.asResult() + c.asResult()
}
fun box(): String {
val u1 = UInt(10)
val u2 = UInt(20)
val r = test(null, null, u1, u2)
return if (r != 40) "fail: $r" else "OK"
}
@@ -0,0 +1,14 @@
// !LANGUAGE: +InlineClasses
inline class UInt(private val u: Int)
fun test(x: UInt?, y: UInt) {
val a = x ?: y // unbox
val b = x ?: x!! // unbox unbox
}
// 0 INVOKESTATIC UInt\$Erased.box
// 3 INVOKEVIRTUAL UInt.unbox
// 0 valueOf
// 0 intValue
@@ -10359,6 +10359,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTest(fileName);
}
@TestMetadata("useInlineClassesInsideElvisOperator.kt")
public void testUseInlineClassesInsideElvisOperator() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt");
doTest(fileName);
}
@TestMetadata("useInlineFunctionInsideInlineClass.kt")
public void testUseInlineFunctionInsideInlineClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineFunctionInsideInlineClass.kt");
@@ -10359,6 +10359,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("useInlineClassesInsideElvisOperator.kt")
public void testUseInlineClassesInsideElvisOperator() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt");
doTest(fileName);
}
@TestMetadata("useInlineFunctionInsideInlineClass.kt")
public void testUseInlineFunctionInsideInlineClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineFunctionInsideInlineClass.kt");
@@ -1962,6 +1962,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
doTest(fileName);
}
@TestMetadata("unboxInlineClassAfterElvis.kt")
public void testUnboxInlineClassAfterElvis() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/unboxInlineClassAfterElvis.kt");
doTest(fileName);
}
@TestMetadata("unboxInlineClassAfterSafeCall.kt")
public void testUnboxInlineClassAfterSafeCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/unboxInlineClassAfterSafeCall.kt");
@@ -10359,6 +10359,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
doTest(fileName);
}
@TestMetadata("useInlineClassesInsideElvisOperator.kt")
public void testUseInlineClassesInsideElvisOperator() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt");
doTest(fileName);
}
@TestMetadata("useInlineFunctionInsideInlineClass.kt")
public void testUseInlineFunctionInsideInlineClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineFunctionInsideInlineClass.kt");
@@ -11319,6 +11319,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
doTest(fileName);
}
@TestMetadata("useInlineClassesInsideElvisOperator.kt")
public void testUseInlineClassesInsideElvisOperator() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt");
doTest(fileName);
}
@TestMetadata("useInlineFunctionInsideInlineClass.kt")
public void testUseInlineFunctionInsideInlineClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineFunctionInsideInlineClass.kt");