From a8a9f774d0b4a1cee6332fc033ff9ec42b8508ca Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Fri, 9 Feb 2018 08:26:25 +0300 Subject: [PATCH] Map inline classes in generic argument position to theirs wrap classes --- .../inlineClassAsGenericArgument.kt | 18 ++++++++++++++ .../inlineClassBasedOnOtherInlineClass.kt | 17 +++++++++++++ .../inlineClassWithComplexSubstitutedType.kt | 24 +++++++++++++++++++ .../compiler/WriteSignatureTestGenerated.java | 18 ++++++++++++++ .../kotlin/load/kotlin/TypeMappingMode.kt | 15 +++++++++--- .../load/kotlin/typeSignatureMapping.kt | 4 +++- 6 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/writeSignature/inlineClasses/inlineClassAsGenericArgument.kt create mode 100644 compiler/testData/writeSignature/inlineClasses/inlineClassBasedOnOtherInlineClass.kt create mode 100644 compiler/testData/writeSignature/inlineClasses/inlineClassWithComplexSubstitutedType.kt diff --git a/compiler/testData/writeSignature/inlineClasses/inlineClassAsGenericArgument.kt b/compiler/testData/writeSignature/inlineClasses/inlineClassAsGenericArgument.kt new file mode 100644 index 00000000000..2a0d9cdb539 --- /dev/null +++ b/compiler/testData/writeSignature/inlineClasses/inlineClassAsGenericArgument.kt @@ -0,0 +1,18 @@ +// !LANGUAGE: +InlineClasses + +class Inv + +inline class UInt(val value: Int) + +object Test { + fun asNotNullTypeArgument(i: Inv) {} + fun asInnerTypeArgument(i: Inv>) {} +} + +// method: Test::asNotNullTypeArgument +// jvm signature: (LInv;)V +// generic signature: (LInv;)V + +// method: Test::asInnerTypeArgument +// jvm signature: (LInv;)V +// generic signature: (LInv;>;)V \ No newline at end of file diff --git a/compiler/testData/writeSignature/inlineClasses/inlineClassBasedOnOtherInlineClass.kt b/compiler/testData/writeSignature/inlineClasses/inlineClassBasedOnOtherInlineClass.kt new file mode 100644 index 00000000000..61fb7048772 --- /dev/null +++ b/compiler/testData/writeSignature/inlineClasses/inlineClassBasedOnOtherInlineClass.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: +InlineClasses + +inline class Foo(val b: Bar) +inline class Bar(val i: Int) + +object Test { + fun simple(f: Foo) {} + fun listOfFoo(f: List) {} +} + +// method: Test::simple +// jvm signature: (I)V +// generic signature: null + +// method: Test::listOfFoo +// jvm signature: (Ljava/util/List;)V +// generic signature: (Ljava/util/List;)V diff --git a/compiler/testData/writeSignature/inlineClasses/inlineClassWithComplexSubstitutedType.kt b/compiler/testData/writeSignature/inlineClasses/inlineClassWithComplexSubstitutedType.kt new file mode 100644 index 00000000000..a3cdcdeb0e6 --- /dev/null +++ b/compiler/testData/writeSignature/inlineClasses/inlineClassWithComplexSubstitutedType.kt @@ -0,0 +1,24 @@ +// !LANGUAGE: +InlineClasses + +class Inv + +inline class AsList(val list: List) +inline class UInt(val value: Int) + +object Test { + fun withInlineClassArgument(a: AsList) {} + fun withListOfInlineClassArgument(a: AsList>) {} + fun withInnerGenericInlineClass(a: AsList>>) {} +} + +// method: Test::withInlineClassArgument +// jvm signature: (Ljava/util/List;)V +// generic signature: (Ljava/util/List;)V + +// method: Test::withListOfInlineClassArgument +// jvm signature: (Ljava/util/List;)V +// generic signature: (Ljava/util/List<+Ljava/util/List;>;)V + +// method: Test::withInnerGenericInlineClass +// jvm signature: (Ljava/util/List;)V +// generic signature: (Ljava/util/List;>;>;)V diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java index 31df9867097..6736e1a4823 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/WriteSignatureTestGenerated.java @@ -582,6 +582,24 @@ public class WriteSignatureTestGenerated extends AbstractWriteSignatureTest { doTest(fileName); } + @TestMetadata("inlineClassAsGenericArgument.kt") + public void testInlineClassAsGenericArgument() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/inlineClasses/inlineClassAsGenericArgument.kt"); + doTest(fileName); + } + + @TestMetadata("inlineClassBasedOnOtherInlineClass.kt") + public void testInlineClassBasedOnOtherInlineClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/inlineClasses/inlineClassBasedOnOtherInlineClass.kt"); + doTest(fileName); + } + + @TestMetadata("inlineClassWithComplexSubstitutedType.kt") + public void testInlineClassWithComplexSubstitutedType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/inlineClasses/inlineClassWithComplexSubstitutedType.kt"); + doTest(fileName); + } + @TestMetadata("nullableInlineClassType.kt") public void testNullableInlineClassType() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/inlineClasses/nullableInlineClassType.kt"); diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/TypeMappingMode.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/TypeMappingMode.kt index e229d42cdb5..71389f5b00d 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/TypeMappingMode.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/TypeMappingMode.kt @@ -5,12 +5,13 @@ package org.jetbrains.kotlin.load.kotlin +import org.jetbrains.kotlin.resolve.isInlineClassType import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.Variance class TypeMappingMode private constructor( val needPrimitiveBoxing: Boolean = true, - val needInlineClassWrapping: Boolean = false, + val needInlineClassWrapping: Boolean = true, val isForAnnotationParameter: Boolean = false, // Here DeclarationSiteWildcards means wildcard generated because of declaration-site variance val skipDeclarationSiteWildcards: Boolean = false, @@ -38,7 +39,7 @@ class TypeMappingMode private constructor( * kotlin.Int is mapped to I */ @JvmField - val DEFAULT = TypeMappingMode(genericArgumentMode = GENERIC_ARGUMENT, needPrimitiveBoxing = false) + val DEFAULT = TypeMappingMode(genericArgumentMode = GENERIC_ARGUMENT, needPrimitiveBoxing = false, needInlineClassWrapping = false) /** * kotlin.Int is mapped to I @@ -120,7 +121,9 @@ class TypeMappingMode private constructor( skipDeclarationSiteWildcards = !canBeUsedInSupertypePosition, skipDeclarationSiteWildcardsIfPossible = true, genericContravariantArgumentMode = contravariantArgumentMode, - genericInvariantArgumentMode = invariantArgumentMode) + genericInvariantArgumentMode = invariantArgumentMode, + needInlineClassWrapping = !type.isInlineClassType() + ) } @JvmStatic @@ -140,4 +143,10 @@ class TypeMappingMode private constructor( Variance.INVARIANT -> genericInvariantArgumentMode ?: this else -> genericArgumentMode ?: this } + + fun wrapInlineClassesMode(): TypeMappingMode = + TypeMappingMode( + needPrimitiveBoxing, true, isForAnnotationParameter, skipDeclarationSiteWildcards, skipDeclarationSiteWildcardsIfPossible, + genericArgumentMode, kotlinCollectionsToJavaCollections, genericContravariantArgumentMode, genericInvariantArgumentMode + ) } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt index 17d6bccb74e..45c14019360 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/typeSignatureMapping.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe +import org.jetbrains.kotlin.resolve.isInlineClassType import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType import org.jetbrains.kotlin.resolve.substitutedUnderlyingType @@ -133,7 +134,8 @@ fun mapType( if (descriptor.isInline && !mode.needInlineClassWrapping) { val typeForMapping = computeUnderlyingType(kotlinType) if (typeForMapping != null) { - return mapType(typeForMapping, factory, mode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType) + val newMode = if (typeForMapping.isInlineClassType()) mode else mode.wrapInlineClassesMode() + return mapType(typeForMapping, factory, newMode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType) } }