From 7600f89f0bdc8893be3e0540c787618d25d534f3 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 1 Feb 2017 12:27:42 +0300 Subject: [PATCH] KT-15574 Can't instantiate Array through Type Alias Array instatiation code should handle type alias constructors properly. So far, we don't have constructors with type parameters different from the type parameters of the resulting type, so we can safely take type arguments of the underlying type. --- .../kotlin/codegen/ExpressionCodegen.java | 32 ++++++++++++++++++- .../typealias/genericTypeAliasConstructor2.kt | 8 +++++ .../typealias/typeAliasConstructorForArray.kt | 16 ++++++++++ .../genericTypeAliasConstructor2.txt | 13 ++++++++ .../typeAliasConstructorForArray.txt | 4 +++ .../ir/IrBlackBoxCodegenTestGenerated.java | 12 +++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 +++++++ ...LightAnalysisModeCodegenTestGenerated.java | 12 +++++++ .../semantics/JsCodegenBoxTestGenerated.java | 12 +++++++ 9 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/typealias/genericTypeAliasConstructor2.kt create mode 100644 compiler/testData/codegen/box/typealias/typeAliasConstructorForArray.kt create mode 100644 compiler/testData/codegen/light-analysis/typealias/genericTypeAliasConstructor2.txt create mode 100644 compiler/testData/codegen/light-analysis/typealias/typeAliasConstructorForArray.txt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 9d1f194b782..c9b113c955a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2998,7 +2998,8 @@ public class ExpressionCodegen extends KtVisitor impleme @NotNull CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall resolvedCall, @NotNull CallableDescriptor descriptor) { - Map typeArguments = resolvedCall.getTypeArguments(); + Map typeArguments = getTypeArgumentsForResolvedCall(resolvedCall, descriptor); + TypeParameterMappings mappings = new TypeParameterMappings(); for (Map.Entry entry : typeArguments.entrySet()) { TypeParameterDescriptor key = entry.getKey(); @@ -3023,9 +3024,38 @@ public class ExpressionCodegen extends KtVisitor impleme ); } } + return getOrCreateCallGenerator(descriptor, resolvedCall.getCall().getCallElement(), mappings, false); } + @NotNull + private static Map getTypeArgumentsForResolvedCall( + @NotNull ResolvedCall resolvedCall, + @NotNull CallableDescriptor descriptor + ) { + if (!(descriptor instanceof TypeAliasConstructorDescriptor)) { + return resolvedCall.getTypeArguments(); + } + + TypeAliasConstructorDescriptor typeAliasConstructorDescriptor = (TypeAliasConstructorDescriptor) descriptor; + ClassConstructorDescriptor underlyingConstructorDescriptor = typeAliasConstructorDescriptor.getUnderlyingConstructorDescriptor(); + KotlinType resultingType = typeAliasConstructorDescriptor.getReturnType(); + List typeArgumentsForReturnType = resultingType.getArguments(); + List typeParameters = underlyingConstructorDescriptor.getTypeParameters(); + + assert typeParameters.size() == typeArgumentsForReturnType.size() : + "Type parameters of the underlying constructor " + underlyingConstructorDescriptor + + "should correspond to type arguments for the resulting type " + resultingType; + + Map typeArgumentsMap = Maps.newHashMapWithExpectedSize(typeParameters.size()); + for (TypeParameterDescriptor typeParameter: typeParameters) { + KotlinType typeArgument = typeArgumentsForReturnType.get(typeParameter.getIndex()).getType(); + typeArgumentsMap.put(typeParameter, typeArgument); + } + + return typeArgumentsMap; + } + @Nullable private static Pair extractReificationArgument(@NotNull KotlinType type) { diff --git a/compiler/testData/codegen/box/typealias/genericTypeAliasConstructor2.kt b/compiler/testData/codegen/box/typealias/genericTypeAliasConstructor2.kt new file mode 100644 index 00000000000..845d35b4aed --- /dev/null +++ b/compiler/testData/codegen/box/typealias/genericTypeAliasConstructor2.kt @@ -0,0 +1,8 @@ +class Pair(val x1: T1, val x2: T2) + +typealias ST = Pair + +fun box(): String { + val st = ST("O", "K") + return st.x1 + st.x2 +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/typealias/typeAliasConstructorForArray.kt b/compiler/testData/codegen/box/typealias/typeAliasConstructorForArray.kt new file mode 100644 index 00000000000..8be95d2e91d --- /dev/null +++ b/compiler/testData/codegen/box/typealias/typeAliasConstructorForArray.kt @@ -0,0 +1,16 @@ +typealias BoolArray = Array +typealias IArray = IntArray +typealias MyArray = Array + +fun box(): String { + val ba = BoolArray(1) { true } + if (!ba[0]) return "Fail #1" + + val ia = IArray(1) { 42 } + if (ia[0] != 42) return "Fail #2" + + val ma = MyArray(1) { 42 } + if (ma[0] != 42) return "Fail #2" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/light-analysis/typealias/genericTypeAliasConstructor2.txt b/compiler/testData/codegen/light-analysis/typealias/genericTypeAliasConstructor2.txt new file mode 100644 index 00000000000..715ac5f7f55 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/typealias/genericTypeAliasConstructor2.txt @@ -0,0 +1,13 @@ +@kotlin.Metadata +public final class GenericTypeAliasConstructor2Kt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} + +@kotlin.Metadata +public final class Pair { + private final field x1: java.lang.Object + private final field x2: java.lang.Object + public method (p0: java.lang.Object, p1: java.lang.Object): void + public final method getX1(): java.lang.Object + public final method getX2(): java.lang.Object +} diff --git a/compiler/testData/codegen/light-analysis/typealias/typeAliasConstructorForArray.txt b/compiler/testData/codegen/light-analysis/typealias/typeAliasConstructorForArray.txt new file mode 100644 index 00000000000..3348f12fbe2 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/typealias/typeAliasConstructorForArray.txt @@ -0,0 +1,4 @@ +@kotlin.Metadata +public final class TypeAliasConstructorForArrayKt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} 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 5e9a4d68ac0..1d2c04e1118 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 @@ -17303,6 +17303,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("genericTypeAliasConstructor2.kt") + public void testGenericTypeAliasConstructor2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor2.kt"); + doTest(fileName); + } + @TestMetadata("innerClassTypeAliasConstructor.kt") public void testInnerClassTypeAliasConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructor.kt"); @@ -17345,6 +17351,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("typeAliasConstructorForArray.kt") + public void testTypeAliasConstructorForArray() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasConstructorForArray.kt"); + doTest(fileName); + } + @TestMetadata("typeAliasConstructorInSuperCall.kt") public void testTypeAliasConstructorInSuperCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasConstructorInSuperCall.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 239e4cbfea6..8d530c9c01f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -17303,6 +17303,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("genericTypeAliasConstructor2.kt") + public void testGenericTypeAliasConstructor2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor2.kt"); + doTest(fileName); + } + @TestMetadata("innerClassTypeAliasConstructor.kt") public void testInnerClassTypeAliasConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructor.kt"); @@ -17345,6 +17351,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("typeAliasConstructorForArray.kt") + public void testTypeAliasConstructorForArray() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasConstructorForArray.kt"); + doTest(fileName); + } + @TestMetadata("typeAliasConstructorInSuperCall.kt") public void testTypeAliasConstructorInSuperCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasConstructorInSuperCall.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java index 46ca3060f41..bd134e52a9f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java @@ -17303,6 +17303,12 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis doTest(fileName); } + @TestMetadata("genericTypeAliasConstructor2.kt") + public void testGenericTypeAliasConstructor2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor2.kt"); + doTest(fileName); + } + @TestMetadata("innerClassTypeAliasConstructor.kt") public void testInnerClassTypeAliasConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructor.kt"); @@ -17345,6 +17351,12 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis doTest(fileName); } + @TestMetadata("typeAliasConstructorForArray.kt") + public void testTypeAliasConstructorForArray() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasConstructorForArray.kt"); + doTest(fileName); + } + @TestMetadata("typeAliasConstructorInSuperCall.kt") public void testTypeAliasConstructorInSuperCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasConstructorInSuperCall.kt"); 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 0aa6faf6ce0..075b4cccfef 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 @@ -21771,6 +21771,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("genericTypeAliasConstructor2.kt") + public void testGenericTypeAliasConstructor2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor2.kt"); + doTest(fileName); + } + @TestMetadata("innerClassTypeAliasConstructor.kt") public void testInnerClassTypeAliasConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/innerClassTypeAliasConstructor.kt"); @@ -21813,6 +21819,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("typeAliasConstructorForArray.kt") + public void testTypeAliasConstructorForArray() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasConstructorForArray.kt"); + doTest(fileName); + } + @TestMetadata("typeAliasConstructorInSuperCall.kt") public void testTypeAliasConstructorInSuperCall() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasConstructorInSuperCall.kt");