[UAST] Fix mapping types containing type aliases

#KT-27935 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2020-04-03 20:08:23 +03:00
parent 73e1ddc505
commit 86fd4da567
15 changed files with 106 additions and 13 deletions
@@ -200,7 +200,8 @@ class KotlinTypeMapper @JvmOverloads constructor(
return mapType(returnType, sw, TypeMappingMode.getModeForReturnTypeNoGeneric(isAnnotationMethod)) return mapType(returnType, sw, TypeMappingMode.getModeForReturnTypeNoGeneric(isAnnotationMethod))
} }
val typeMappingModeFromAnnotation = extractTypeMappingModeFromAnnotation(descriptor, returnType, isAnnotationMethod) val typeMappingModeFromAnnotation =
extractTypeMappingModeFromAnnotation(descriptor, returnType, isAnnotationMethod, mapTypeAliases = false)
if (typeMappingModeFromAnnotation != null) { if (typeMappingModeFromAnnotation != null) {
return mapType(returnType, sw, typeMappingModeFromAnnotation) return mapType(returnType, sw, typeMappingModeFromAnnotation)
} }
@@ -1020,7 +1021,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
} }
val typeMappingMode = val typeMappingMode =
extractTypeMappingModeFromAnnotation(callableDescriptor, type, isForAnnotationParameter = false) extractTypeMappingModeFromAnnotation(callableDescriptor, type, isForAnnotationParameter = false, mapTypeAliases = false)
?: if (callableDescriptor.isMethodWithDeclarationSiteWildcards && type.arguments.isNotEmpty()) { ?: if (callableDescriptor.isMethodWithDeclarationSiteWildcards && type.arguments.isNotEmpty()) {
TypeMappingMode.GENERIC_ARGUMENT // Render all wildcards TypeMappingMode.GENERIC_ARGUMENT // Render all wildcards
} else { } else {
@@ -93,7 +93,8 @@ fun TypeMappingMode.updateArgumentModeFromAnnotations(
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode( return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
skipDeclarationSiteWildcards = it, skipDeclarationSiteWildcards = it,
isForAnnotationParameter = isForAnnotationParameter, isForAnnotationParameter = isForAnnotationParameter,
needInlineClassWrapping = needInlineClassWrapping needInlineClassWrapping = needInlineClassWrapping,
mapTypeAliases = mapTypeAliases
) )
} }
@@ -102,7 +103,8 @@ fun TypeMappingMode.updateArgumentModeFromAnnotations(
skipDeclarationSiteWildcards = false, skipDeclarationSiteWildcards = false,
isForAnnotationParameter = isForAnnotationParameter, isForAnnotationParameter = isForAnnotationParameter,
fallbackMode = this, fallbackMode = this,
needInlineClassWrapping = needInlineClassWrapping needInlineClassWrapping = needInlineClassWrapping,
mapTypeAliases = mapTypeAliases
) )
} }
@@ -112,16 +114,18 @@ fun TypeMappingMode.updateArgumentModeFromAnnotations(
internal fun extractTypeMappingModeFromAnnotation( internal fun extractTypeMappingModeFromAnnotation(
callableDescriptor: CallableDescriptor?, callableDescriptor: CallableDescriptor?,
outerType: KotlinType, outerType: KotlinType,
isForAnnotationParameter: Boolean isForAnnotationParameter: Boolean,
mapTypeAliases: Boolean
): TypeMappingMode? = ): TypeMappingMode? =
SimpleClassicTypeSystemContext.extractTypeMappingModeFromAnnotation( SimpleClassicTypeSystemContext.extractTypeMappingModeFromAnnotation(
callableDescriptor?.suppressWildcardsMode(), outerType, isForAnnotationParameter callableDescriptor?.suppressWildcardsMode(), outerType, isForAnnotationParameter, mapTypeAliases
) )
fun TypeSystemCommonBackendContext.extractTypeMappingModeFromAnnotation( fun TypeSystemCommonBackendContext.extractTypeMappingModeFromAnnotation(
callableSuppressWildcardsMode: Boolean?, callableSuppressWildcardsMode: Boolean?,
outerType: KotlinTypeMarker, outerType: KotlinTypeMarker,
isForAnnotationParameter: Boolean isForAnnotationParameter: Boolean,
mapTypeAliases: Boolean
): TypeMappingMode? { ): TypeMappingMode? {
val suppressWildcards = val suppressWildcards =
outerType.suppressWildcardsMode(this) ?: callableSuppressWildcardsMode ?: return null outerType.suppressWildcardsMode(this) ?: callableSuppressWildcardsMode ?: return null
@@ -131,7 +135,8 @@ fun TypeSystemCommonBackendContext.extractTypeMappingModeFromAnnotation(
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode( return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
skipDeclarationSiteWildcards = suppressWildcards, skipDeclarationSiteWildcards = suppressWildcards,
isForAnnotationParameter = isForAnnotationParameter, isForAnnotationParameter = isForAnnotationParameter,
needInlineClassWrapping = !outerType.typeConstructor().isInlineClass() needInlineClassWrapping = !outerType.typeConstructor().isInlineClass(),
mapTypeAliases = mapTypeAliases
) )
} }
@@ -24028,6 +24028,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasInvisibleObject.kt"); runTest("compiler/testData/diagnostics/tests/typealias/typeAliasInvisibleObject.kt");
} }
@TestMetadata("typeAliasIsUsedAsATypeArgumentInOtherAlias.kt")
public void testTypeAliasIsUsedAsATypeArgumentInOtherAlias() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasIsUsedAsATypeArgumentInOtherAlias.kt");
}
@TestMetadata("typeAliasNotNull.kt") @TestMetadata("typeAliasNotNull.kt")
public void testTypeAliasNotNull() throws Exception { public void testTypeAliasNotNull() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasNotNull.kt"); runTest("compiler/testData/diagnostics/tests/typealias/typeAliasNotNull.kt");
@@ -159,7 +159,9 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
} }
val typeMappingModeFromAnnotation = val typeMappingModeFromAnnotation =
typeSystem.extractTypeMappingModeFromAnnotation(declaration.suppressWildcardsMode(), returnType, isAnnotationMethod) typeSystem.extractTypeMappingModeFromAnnotation(
declaration.suppressWildcardsMode(), returnType, isAnnotationMethod, mapTypeAliases = false
)
if (typeMappingModeFromAnnotation != null) { if (typeMappingModeFromAnnotation != null) {
return typeMapper.mapType(returnType, typeMappingModeFromAnnotation, sw) return typeMapper.mapType(returnType, typeMappingModeFromAnnotation, sw)
} }
@@ -259,7 +261,9 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
} }
val mode = with(typeSystem) { val mode = with(typeSystem) {
extractTypeMappingModeFromAnnotation(declaration.suppressWildcardsMode(), type, isForAnnotationParameter = false) extractTypeMappingModeFromAnnotation(
declaration.suppressWildcardsMode(), type, isForAnnotationParameter = false, mapTypeAliases = false
)
?: if (declaration.isMethodWithDeclarationSiteWildcards && type.argumentsCount() != 0) { ?: if (declaration.isMethodWithDeclarationSiteWildcards && type.argumentsCount() != 0) {
TypeMappingMode.GENERIC_ARGUMENT // Render all wildcards TypeMappingMode.GENERIC_ARGUMENT // Render all wildcards
} else { } else {
@@ -0,0 +1,4 @@
// FIR_IDENTICAL
typealias A = String
typealias My = (Map<A, Int>) -> Unit
@@ -0,0 +1,4 @@
package
public typealias A = kotlin.String
public typealias My = (kotlin.collections.Map<A, kotlin.Int>) -> kotlin.Unit
@@ -24110,6 +24110,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasInvisibleObject.kt"); runTest("compiler/testData/diagnostics/tests/typealias/typeAliasInvisibleObject.kt");
} }
@TestMetadata("typeAliasIsUsedAsATypeArgumentInOtherAlias.kt")
public void testTypeAliasIsUsedAsATypeArgumentInOtherAlias() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasIsUsedAsATypeArgumentInOtherAlias.kt");
}
@TestMetadata("typeAliasNotNull.kt") @TestMetadata("typeAliasNotNull.kt")
public void testTypeAliasNotNull() throws Exception { public void testTypeAliasNotNull() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasNotNull.kt"); runTest("compiler/testData/diagnostics/tests/typealias/typeAliasNotNull.kt");
@@ -24030,6 +24030,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasInvisibleObject.kt"); runTest("compiler/testData/diagnostics/tests/typealias/typeAliasInvisibleObject.kt");
} }
@TestMetadata("typeAliasIsUsedAsATypeArgumentInOtherAlias.kt")
public void testTypeAliasIsUsedAsATypeArgumentInOtherAlias() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasIsUsedAsATypeArgumentInOtherAlias.kt");
}
@TestMetadata("typeAliasNotNull.kt") @TestMetadata("typeAliasNotNull.kt")
public void testTypeAliasNotNull() throws Exception { public void testTypeAliasNotNull() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasNotNull.kt"); runTest("compiler/testData/diagnostics/tests/typealias/typeAliasNotNull.kt");
@@ -19,7 +19,8 @@ class TypeMappingMode private constructor(
private val genericArgumentMode: TypeMappingMode? = null, private val genericArgumentMode: TypeMappingMode? = null,
val kotlinCollectionsToJavaCollections: Boolean = true, val kotlinCollectionsToJavaCollections: Boolean = true,
private val genericContravariantArgumentMode: TypeMappingMode? = genericArgumentMode, private val genericContravariantArgumentMode: TypeMappingMode? = genericArgumentMode,
private val genericInvariantArgumentMode: TypeMappingMode? = genericArgumentMode private val genericInvariantArgumentMode: TypeMappingMode? = genericArgumentMode,
val mapTypeAliases: Boolean = false
) { ) {
companion object { companion object {
/** /**
@@ -28,6 +29,13 @@ class TypeMappingMode private constructor(
@JvmField @JvmField
val GENERIC_ARGUMENT = TypeMappingMode() val GENERIC_ARGUMENT = TypeMappingMode()
/**
* kotlin.Int is mapped to Ljava/lang/Integer;
* Type aliases are mapped to their expanded form
*/
@JvmField
val GENERIC_ARGUMENT_UAST = TypeMappingMode(mapTypeAliases = true)
/** /**
* see KotlinTypeMapper.forceBoxedReturnType() * see KotlinTypeMapper.forceBoxedReturnType()
* This configuration should be called only for method return type * This configuration should be called only for method return type
@@ -41,6 +49,18 @@ class TypeMappingMode private constructor(
@JvmField @JvmField
val DEFAULT = TypeMappingMode(genericArgumentMode = GENERIC_ARGUMENT, needPrimitiveBoxing = false, needInlineClassWrapping = false) val DEFAULT = TypeMappingMode(genericArgumentMode = GENERIC_ARGUMENT, needPrimitiveBoxing = false, needInlineClassWrapping = false)
/**
* kotlin.Int is mapped to I
* Type aliases are mapped to their expanded form
*/
@JvmField
val DEFAULT_UAST = TypeMappingMode(
genericArgumentMode = GENERIC_ARGUMENT_UAST,
needPrimitiveBoxing = false,
needInlineClassWrapping = false,
mapTypeAliases = true
)
/** /**
* kotlin.Int is mapped to I * kotlin.Int is mapped to I
* inline class Foo(val x: Int) is mapped to LFoo; * inline class Foo(val x: Int) is mapped to LFoo;
@@ -133,12 +153,14 @@ class TypeMappingMode private constructor(
skipDeclarationSiteWildcards: Boolean, skipDeclarationSiteWildcards: Boolean,
isForAnnotationParameter: Boolean, isForAnnotationParameter: Boolean,
needInlineClassWrapping: Boolean, needInlineClassWrapping: Boolean,
mapTypeAliases: Boolean,
fallbackMode: TypeMappingMode? = null fallbackMode: TypeMappingMode? = null
) = TypeMappingMode( ) = TypeMappingMode(
isForAnnotationParameter = isForAnnotationParameter, isForAnnotationParameter = isForAnnotationParameter,
skipDeclarationSiteWildcards = skipDeclarationSiteWildcards, skipDeclarationSiteWildcards = skipDeclarationSiteWildcards,
genericArgumentMode = fallbackMode, genericArgumentMode = fallbackMode,
needInlineClassWrapping = needInlineClassWrapping needInlineClassWrapping = needInlineClassWrapping,
mapTypeAliases = mapTypeAliases
) )
} }
@@ -173,6 +173,10 @@ fun <T : Any> mapType(
return type return type
} }
descriptor is TypeAliasDescriptor && mode.mapTypeAliases -> {
return mapType(descriptor.expandedType, factory, mode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType)
}
else -> throw UnsupportedOperationException("Unknown type $kotlinType") else -> throw UnsupportedOperationException("Unknown type $kotlinType")
} }
} }
@@ -285,7 +285,7 @@ internal fun KotlinType.toPsiType(lightDeclaration: PsiModifierListOwner?, conte
.getLanguageVersionSettings(context) .getLanguageVersionSettings(context)
val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.TYPE) val signatureWriter = BothSignatureWriter(BothSignatureWriter.Mode.TYPE)
val typeMappingMode = if (boxed) TypeMappingMode.GENERIC_ARGUMENT else TypeMappingMode.DEFAULT val typeMappingMode = if (boxed) TypeMappingMode.GENERIC_ARGUMENT_UAST else TypeMappingMode.DEFAULT_UAST
val approximatedType = TypeApproximator(this.builtIns).approximateDeclarationType(this, true, languageVersionSettings) val approximatedType = TypeApproximator(this.builtIns).approximateDeclarationType(this, true, languageVersionSettings)
typeMapper.mapType(approximatedType, signatureWriter, typeMappingMode) typeMapper.mapType(approximatedType, signatureWriter, typeMappingMode)
@@ -0,0 +1,5 @@
typealias A = String
typealias My = (Map<A, Int>) -> Unit
fun My.foo(x: My): My? = null
fun Map<A, Int>.bar(x: Map<A, Int>): Map<A, Int>? = null
@@ -0,0 +1,18 @@
UFile (package = )
UClass (name = TypeAliasExpansionWithOtherAliasInArgumentKt)
UMethod (name = foo)
UParameter (name = $this$foo)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UParameter (name = x)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UBlockExpression
UReturnExpression
ULiteralExpression (value = null)
UMethod (name = bar)
UParameter (name = $this$bar)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UParameter (name = x)
UAnnotation (fqName = org.jetbrains.annotations.NotNull)
UBlockExpression
UReturnExpression
ULiteralExpression (value = null)
@@ -0,0 +1,8 @@
public final class TypeAliasExpansionWithOtherAliasInArgumentKt {
public static final fun foo(@org.jetbrains.annotations.NotNull $this$foo: kotlin.jvm.functions.Function1<? super java.util.Map<java.lang.String,java.lang.Integer>,kotlin.Unit>, @org.jetbrains.annotations.NotNull x: kotlin.jvm.functions.Function1<? super java.util.Map<java.lang.String,java.lang.Integer>,kotlin.Unit>) : kotlin.jvm.functions.Function1<java.util.Map<java.lang.String,java.lang.Integer>,kotlin.Unit> {
return null
}
public static final fun bar(@org.jetbrains.annotations.NotNull $this$bar: java.util.Map<java.lang.String,java.lang.Integer>, @org.jetbrains.annotations.NotNull x: java.util.Map<java.lang.String,java.lang.Integer>) : java.util.Map<java.lang.String,java.lang.Integer> {
return null
}
}
@@ -150,6 +150,9 @@ class SimpleKotlinRenderLogTest : AbstractKotlinUastTest(), AbstractKotlinRender
@Test @Test
fun testNonTrivialIdentifiers() = doTest("NonTrivialIdentifiers") fun testNonTrivialIdentifiers() = doTest("NonTrivialIdentifiers")
@Test
fun testTypeAliasExpansionWithOtherAliasInArgument() = doTest("TypeAliasExpansionWithOtherAliasInArgument")
} }
fun withForceUInjectionHostValue(call: () -> Unit) { fun withForceUInjectionHostValue(call: () -> Unit) {