Call factory method for primary constructors of inner classes
We might want to add 'init' blocks later, so now, for the sake of binary compatibility with 1.3-RC binaries, we have to generate these 'constructor' calls. Note that in some tests inline class boxing is no longer redundant, because resulting value is passed to 'constructor' as an argument.
This commit is contained in:
@@ -2180,11 +2180,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
FunctionDescriptor descriptor = accessibleFunctionDescriptor(resolvedCall);
|
||||
|
||||
if (descriptor instanceof ConstructorDescriptor) {
|
||||
if (InlineClassesUtilsKt.isInlineClass(descriptor.getContainingDeclaration()) && ((ConstructorDescriptor) descriptor).isPrimary()) {
|
||||
// we do not call static function `constructor`, because it's empty
|
||||
return generateInlineClassConstructorCall(expression);
|
||||
}
|
||||
|
||||
return generateNewCall(expression, resolvedCall);
|
||||
}
|
||||
|
||||
@@ -2197,24 +2192,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
return invokeFunction(resolvedCall, receiver);
|
||||
}
|
||||
|
||||
private StackValue generateInlineClassConstructorCall(@NotNull KtCallExpression expression) {
|
||||
KtValueArgument valueArgument = CollectionsKt.singleOrNull(expression.getValueArguments());
|
||||
assert valueArgument != null : "Inline class constructor call should have single argument";
|
||||
|
||||
KotlinType inlineClassType = kotlinType(expression);
|
||||
assert inlineClassType != null && InlineClassesUtilsKt.isInlineClassType(inlineClassType) :
|
||||
"Constructor call expression of inline class should have inline class type, but have: " + inlineClassType;
|
||||
|
||||
Type underlyingType = typeMapper.mapType(inlineClassType);
|
||||
KotlinType underlyingKotlinType = InlineClassesUtilsKt.unsubstitutedUnderlyingType(inlineClassType);
|
||||
|
||||
StackValue argumentValue = gen(valueArgument.getArgumentExpression());
|
||||
|
||||
return StackValue.coercionValueForArgumentOfInlineClassConstructor(
|
||||
argumentValue, underlyingType, inlineClassType, underlyingKotlinType
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitCollectionLiteralExpression(
|
||||
@NotNull KtCollectionLiteralExpression expression, StackValue data
|
||||
@@ -4215,8 +4192,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
private StackValue generateNewCall(@NotNull KtCallExpression expression, @NotNull ResolvedCall<?> resolvedCall) {
|
||||
Type type = expressionType(expression);
|
||||
if (type.getSort() == Type.ARRAY) {
|
||||
//noinspection ConstantConditions
|
||||
return generateNewArray(expression, bindingContext.getType(expression), resolvedCall);
|
||||
KotlinType kotlinType = kotlinType(expression);
|
||||
assert kotlinType != null : "No kotlinType for expression of type " + type + ": " + expression.getText();
|
||||
if (KotlinBuiltIns.isArrayOrPrimitiveArray(kotlinType)) {
|
||||
//noinspection ConstantConditions
|
||||
return generateNewArray(expression, bindingContext.getType(expression), resolvedCall);
|
||||
}
|
||||
}
|
||||
|
||||
return generateConstructorCall(resolvedCall, type);
|
||||
@@ -4250,7 +4231,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@NotNull
|
||||
public StackValue generateConstructorCall(@NotNull ResolvedCall<?> resolvedCall, @NotNull Type objectType) {
|
||||
return StackValue.functionCall(objectType, null, v -> {
|
||||
return StackValue.functionCall(objectType, resolvedCall.getResultingDescriptor().getReturnType(), v -> {
|
||||
ClassConstructorDescriptor constructor = getConstructorDescriptor(resolvedCall);
|
||||
ReceiverParameterDescriptor dispatchReceiver = constructor.getDispatchReceiverParameter();
|
||||
ClassDescriptor containingDeclaration = constructor.getContainingDeclaration();
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
inline class Result<T>(val a: Any?)
|
||||
|
||||
fun box(): String {
|
||||
val a = Result<Int>(1) // valueOf
|
||||
val b = Result<String>("sample")
|
||||
val c = Result<Result<Int>>(a)
|
||||
val d = Result<Result<Int>>(Result<Int>(1)) // valueOf
|
||||
|
||||
if (a.a !is Int) throw AssertionError()
|
||||
|
||||
if (b.a !is String) throw AssertionError()
|
||||
|
||||
if (c.a !is Result<*>) throw AssertionError()
|
||||
val ca = c.a as Result<*>
|
||||
if (ca.a !is Int) throw AssertionError()
|
||||
|
||||
if (d.a !is Result<*>) throw AssertionError()
|
||||
val da = d.a as Result<*>
|
||||
if (da.a !is Int) throw AssertionError()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// WITH_RUNTIME
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
inline class Z(val x: Int) {
|
||||
constructor(vararg ys: Long) : this(ys.size)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val z1 = Z(111)
|
||||
if (z1.x != 111) throw AssertionError()
|
||||
|
||||
val z2 = Z()
|
||||
if (z2.x != 0) throw AssertionError()
|
||||
|
||||
val z3 = Z(2222L)
|
||||
if (z3.x != 1) throw AssertionError()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+1
@@ -12,6 +12,7 @@ fun f() {
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 INVOKESTATIC UInt\$Erased.box
|
||||
// 0 INVOKESTATIC UInt\.box
|
||||
// 0 INVOKEVIRTUAL UInt.unbox
|
||||
// 0 valueOf
|
||||
// 0 intValue
|
||||
Vendored
+1
@@ -16,6 +16,7 @@ fun test() {
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 INVOKESTATIC Result\$Erased.box
|
||||
// 2 INVOKESTATIC Result\.box
|
||||
// 0 INVOKEVIRTUAL Result.unbox
|
||||
|
||||
// 2 valueOf
|
||||
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
|
||||
// FILE: Z.kt
|
||||
inline class Z(val x: Int)
|
||||
|
||||
// FILE: test.kt
|
||||
fun testZ() = Z(42)
|
||||
|
||||
// @TestKt.class:
|
||||
// 1 INVOKESTATIC Z\.constructor \(I\)I
|
||||
Vendored
+1
@@ -27,6 +27,7 @@ fun test(asInt: Result<Int>, asString: Result<String>, asResult: Result<Result<I
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 INVOKESTATIC Result\$Erased.box
|
||||
// 0 INVOKESTATIC Result\.box
|
||||
// 3 INVOKEVIRTUAL Result.unbox
|
||||
|
||||
// 0 valueOf
|
||||
|
||||
+10
@@ -11471,6 +11471,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxResultInlineClassOfConstructorCall.kt")
|
||||
public void testBoxResultInlineClassOfConstructorCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxUnboxInlineClassesWithOperatorsGetSet.kt")
|
||||
public void testBoxUnboxInlineClassesWithOperatorsGetSet() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxUnboxInlineClassesWithOperatorsGetSet.kt");
|
||||
@@ -11761,6 +11766,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorsInsideInlineClass.kt")
|
||||
public void testSecondaryConstructorsInsideInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorsInsideInlineClass.kt");
|
||||
|
||||
@@ -2158,6 +2158,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/propertySetterWithInlineClassTypeArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("primaryConstructorCalledByInlineClass.kt")
|
||||
public void testPrimaryConstructorCalledByInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/primaryConstructorCalledByInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("skipCallToUnderlyingValueOfInlineClass.kt")
|
||||
public void testSkipCallToUnderlyingValueOfInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/inlineClasses/skipCallToUnderlyingValueOfInlineClass.kt");
|
||||
|
||||
+10
@@ -11471,6 +11471,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxResultInlineClassOfConstructorCall.kt")
|
||||
public void testBoxResultInlineClassOfConstructorCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxUnboxInlineClassesWithOperatorsGetSet.kt")
|
||||
public void testBoxUnboxInlineClassesWithOperatorsGetSet() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxUnboxInlineClassesWithOperatorsGetSet.kt");
|
||||
@@ -11761,6 +11766,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorsInsideInlineClass.kt")
|
||||
public void testSecondaryConstructorsInsideInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorsInsideInlineClass.kt");
|
||||
|
||||
+10
@@ -11471,6 +11471,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxResultInlineClassOfConstructorCall.kt")
|
||||
public void testBoxResultInlineClassOfConstructorCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxUnboxInlineClassesWithOperatorsGetSet.kt")
|
||||
public void testBoxUnboxInlineClassesWithOperatorsGetSet() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxUnboxInlineClassesWithOperatorsGetSet.kt");
|
||||
@@ -11761,6 +11766,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorsInsideInlineClass.kt")
|
||||
public void testSecondaryConstructorsInsideInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorsInsideInlineClass.kt");
|
||||
|
||||
+10
@@ -10016,6 +10016,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxResultInlineClassOfConstructorCall.kt")
|
||||
public void testBoxResultInlineClassOfConstructorCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxUnboxInlineClassesWithOperatorsGetSet.kt")
|
||||
public void testBoxUnboxInlineClassesWithOperatorsGetSet() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxUnboxInlineClassesWithOperatorsGetSet.kt");
|
||||
@@ -10296,6 +10301,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorsInsideInlineClass.kt")
|
||||
public void testSecondaryConstructorsInsideInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorsInsideInlineClass.kt");
|
||||
|
||||
+10
@@ -11081,6 +11081,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxNullableValueOfInlineClassWithPrimitiveUnderlyingType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxResultInlineClassOfConstructorCall.kt")
|
||||
public void testBoxResultInlineClassOfConstructorCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("boxUnboxInlineClassesWithOperatorsGetSet.kt")
|
||||
public void testBoxUnboxInlineClassesWithOperatorsGetSet() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxUnboxInlineClassesWithOperatorsGetSet.kt");
|
||||
@@ -11361,6 +11366,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/referToUnderlyingPropertyOfInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithVararg.kt")
|
||||
public void testSecondaryConstructorWithVararg() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorsInsideInlineClass.kt")
|
||||
public void testSecondaryConstructorsInsideInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorsInsideInlineClass.kt");
|
||||
|
||||
Reference in New Issue
Block a user