typealias expansion fixes
- Exception on dynamic type in typealias argument expansion #KT-18858 Fixed Target versions 1.1.5 - Wrong report location for repeated annotations in typealias arguments #KT-18940 Fixed Target versions 1.1.5 - Don't drop type annotations for dynamic type #KT-18944 Fixed Target versions 1.1.5
This commit is contained in:
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.resolve
|
||||
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.composeAnnotations
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.containsTypeAliasParameters
|
||||
@@ -53,6 +53,7 @@ class TypeAliasExpander(
|
||||
"Type alias expansion: result for ${typeAliasExpansion.descriptor} is ${expandedProjection.projectionKind}, should be invariant"
|
||||
}
|
||||
|
||||
checkRepeatedAnnotations(expandedType.annotations, annotations)
|
||||
val expandedTypeWithExtraAnnotations = expandedType.combineAnnotations(annotations).let { TypeUtils.makeNullableIfNeeded(it, isNullable) }
|
||||
|
||||
return if (withAbbreviatedType)
|
||||
@@ -82,59 +83,72 @@ class TypeAliasExpander(
|
||||
if (underlyingProjection.isStarProjection) return TypeUtils.makeStarProjection(typeParameterDescriptor!!)
|
||||
|
||||
val underlyingType = underlyingProjection.type
|
||||
val argument = typeAliasExpansion.getReplacement(underlyingType.constructor)
|
||||
|
||||
if (argument == null) {
|
||||
return expandNonArgumentTypeProjection(underlyingProjection, typeAliasExpansion, recursionDepth)
|
||||
}
|
||||
val argument = typeAliasExpansion.getReplacement(underlyingType.constructor) ?:
|
||||
return expandNonArgumentTypeProjection(underlyingProjection, typeAliasExpansion, recursionDepth)
|
||||
|
||||
if (argument.isStarProjection) return TypeUtils.makeStarProjection(typeParameterDescriptor!!)
|
||||
|
||||
val argumentVariance = argument.projectionKind
|
||||
val underlyingVariance = underlyingProjection.projectionKind
|
||||
val argumentType = argument.type.unwrap()
|
||||
|
||||
val argumentType = argument.type.unwrap().asSimpleType()
|
||||
val resultingVariance = run {
|
||||
val argumentVariance = argument.projectionKind
|
||||
val underlyingVariance = underlyingProjection.projectionKind
|
||||
|
||||
val substitutionVariance =
|
||||
when {
|
||||
underlyingVariance == argumentVariance -> argumentVariance
|
||||
underlyingVariance == Variance.INVARIANT -> argumentVariance
|
||||
argumentVariance == Variance.INVARIANT -> underlyingVariance
|
||||
else -> {
|
||||
reportStrategy.conflictingProjection(typeAliasExpansion.descriptor, typeParameterDescriptor, argumentType)
|
||||
argumentVariance
|
||||
val substitutionVariance =
|
||||
when {
|
||||
underlyingVariance == argumentVariance -> argumentVariance
|
||||
underlyingVariance == Variance.INVARIANT -> argumentVariance
|
||||
argumentVariance == Variance.INVARIANT -> underlyingVariance
|
||||
else -> {
|
||||
reportStrategy.conflictingProjection(typeAliasExpansion.descriptor, typeParameterDescriptor, argumentType)
|
||||
argumentVariance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val parameterVariance = typeParameterDescriptor?.variance ?: Variance.INVARIANT
|
||||
val resultingVariance =
|
||||
when {
|
||||
parameterVariance == substitutionVariance -> substitutionVariance
|
||||
parameterVariance == Variance.INVARIANT -> substitutionVariance
|
||||
substitutionVariance == Variance.INVARIANT -> Variance.INVARIANT
|
||||
else -> {
|
||||
reportStrategy.conflictingProjection(typeAliasExpansion.descriptor, typeParameterDescriptor, argumentType)
|
||||
substitutionVariance
|
||||
}
|
||||
}
|
||||
val parameterVariance = typeParameterDescriptor?.variance ?: Variance.INVARIANT
|
||||
|
||||
val substitutedType = argumentType.combineNullabilityAndAnnotations(underlyingType)
|
||||
when {
|
||||
parameterVariance == substitutionVariance -> substitutionVariance
|
||||
parameterVariance == Variance.INVARIANT -> substitutionVariance
|
||||
substitutionVariance == Variance.INVARIANT -> Variance.INVARIANT
|
||||
else -> {
|
||||
reportStrategy.conflictingProjection(typeAliasExpansion.descriptor, typeParameterDescriptor, argumentType)
|
||||
substitutionVariance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkRepeatedAnnotations(underlyingType.annotations, argumentType.annotations)
|
||||
|
||||
val substitutedType =
|
||||
if (argumentType is DynamicType)
|
||||
argumentType.combineAnnotations(underlyingType.annotations)
|
||||
else
|
||||
argumentType.asSimpleType().combineNullabilityAndAnnotations(underlyingType)
|
||||
|
||||
return TypeProjectionImpl(resultingVariance, substitutedType)
|
||||
}
|
||||
|
||||
private fun SimpleType.combineAnnotations(annotations: Annotations): SimpleType {
|
||||
if (isError) return this
|
||||
private fun DynamicType.combineAnnotations(newAnnotations: Annotations): DynamicType =
|
||||
replaceAnnotations(createCombinedAnnotations(newAnnotations))
|
||||
|
||||
val existingAnnotationTypes = this.annotations.getAllAnnotations().mapTo(hashSetOf<KotlinType>()) { it.annotation.type }
|
||||
private fun SimpleType.combineAnnotations(newAnnotations: Annotations): SimpleType =
|
||||
if (isError) this else replace(newAnnotations = createCombinedAnnotations(newAnnotations))
|
||||
|
||||
for (annotation in annotations) {
|
||||
private fun KotlinType.createCombinedAnnotations(newAnnotations: Annotations): Annotations {
|
||||
if (isError) return annotations
|
||||
|
||||
return composeAnnotations(newAnnotations, annotations)
|
||||
}
|
||||
|
||||
private fun checkRepeatedAnnotations(existingAnnotations: Annotations, newAnnotations: Annotations) {
|
||||
val existingAnnotationTypes = existingAnnotations.mapTo(hashSetOf()) { it.type }
|
||||
|
||||
for (annotation in newAnnotations) {
|
||||
if (annotation.type in existingAnnotationTypes) {
|
||||
reportStrategy.repeatedAnnotation(annotation)
|
||||
}
|
||||
}
|
||||
|
||||
return replace(newAnnotations = CompositeAnnotations(listOf(annotations, this.annotations)))
|
||||
}
|
||||
|
||||
private fun SimpleType.combineNullability(fromType: KotlinType) =
|
||||
@@ -148,7 +162,11 @@ class TypeAliasExpander(
|
||||
typeAliasExpansion: TypeAliasExpansion,
|
||||
recursionDepth: Int
|
||||
): TypeProjection {
|
||||
val type = originalProjection.type.asSimpleType()
|
||||
val originalType = originalProjection.type.unwrap()
|
||||
|
||||
if (originalType.isDynamic()) return originalProjection
|
||||
|
||||
val type = originalType.asSimpleType()
|
||||
|
||||
if (type.isError || !type.requiresTypeAliasExpansion()) {
|
||||
return originalProjection
|
||||
|
||||
@@ -301,7 +301,7 @@ class TypeResolver(
|
||||
}
|
||||
|
||||
override fun visitDynamicType(type: KtDynamicType) {
|
||||
result = type(dynamicCallableDescriptors.dynamicType)
|
||||
result = type(dynamicCallableDescriptors.dynamicType.replaceAnnotations(annotations))
|
||||
if (!dynamicTypesSettings.dynamicTypesAllowed) {
|
||||
c.trace.report(UNSUPPORTED.on(type, "Dynamic types are not supported in this context"))
|
||||
}
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
@Target(AnnotationTarget.TYPE)
|
||||
annotation class A
|
||||
|
||||
typealias Gen<T> = List<@A T>
|
||||
|
||||
typealias Test1 = Gen<<!REPEATED_ANNOTATION!>@A<!> Int>
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) public final annotation class A : kotlin.Annotation {
|
||||
public constructor A()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
public typealias Gen</*0*/ T> = kotlin.collections.List<@A T>
|
||||
public typealias Test1 = Gen<@A kotlin.Int>
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
@Target(AnnotationTarget.TYPE)
|
||||
annotation class Ann1
|
||||
|
||||
@Target(AnnotationTarget.TYPE)
|
||||
annotation class Ann2
|
||||
|
||||
typealias AnnGenList<T> = List<@Ann1 T>
|
||||
typealias TestAnnGen1 = AnnGenList<dynamic>
|
||||
typealias TestAnnGen2 = AnnGenList<@Ann2 dynamic>
|
||||
typealias TestAnnGen3 = AnnGenList<<!REPEATED_ANNOTATION!>@Ann1<!> dynamic>
|
||||
|
||||
fun useAnnGen1(x: TestAnnGen1) = x
|
||||
fun useAnnGen2(x: TestAnnGen2) = x
|
||||
|
||||
fun testUseAnnGen1(x: List<dynamic>) = useAnnGen1(x)
|
||||
fun testUseAnnGen2(x: List<dynamic>) = useAnnGen2(x)
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
package
|
||||
|
||||
public fun testUseAnnGen1(/*0*/ x: kotlin.collections.List<dynamic>): TestAnnGen1 /* = kotlin.collections.List<dynamic> */
|
||||
public fun testUseAnnGen2(/*0*/ x: kotlin.collections.List<dynamic>): TestAnnGen2 /* = kotlin.collections.List<dynamic> */
|
||||
public fun useAnnGen1(/*0*/ x: TestAnnGen1 /* = kotlin.collections.List<dynamic> */): TestAnnGen1 /* = kotlin.collections.List<dynamic> */
|
||||
public fun useAnnGen2(/*0*/ x: TestAnnGen2 /* = kotlin.collections.List<dynamic> */): TestAnnGen2 /* = kotlin.collections.List<dynamic> */
|
||||
|
||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) public final annotation class Ann1 : kotlin.Annotation {
|
||||
public constructor Ann1()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) public final annotation class Ann2 : kotlin.Annotation {
|
||||
public constructor Ann2()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
public typealias AnnGenList</*0*/ T> = kotlin.collections.List<@Ann1 T>
|
||||
public typealias TestAnnGen1 = AnnGenList<dynamic>
|
||||
public typealias TestAnnGen2 = AnnGenList<dynamic>
|
||||
public typealias TestAnnGen3 = AnnGenList<dynamic>
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
typealias Test1 = List<dynamic>
|
||||
|
||||
typealias Test2 = (dynamic) -> dynamic
|
||||
|
||||
typealias GenList<T> = List<T>
|
||||
typealias TestGen1 = GenList<dynamic>
|
||||
typealias TestGen2 = GenList<GenList<dynamic>>
|
||||
|
||||
fun useGen1(x: TestGen1) = x
|
||||
fun useGen2(x: TestGen2) = x
|
||||
|
||||
fun testUseGen1(x: List<dynamic>) = useGen1(x)
|
||||
fun testUseGen2(x: List<List<dynamic>>) = useGen2(x)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
public fun testUseGen1(/*0*/ x: kotlin.collections.List<dynamic>): TestGen1 /* = kotlin.collections.List<dynamic> */
|
||||
public fun testUseGen2(/*0*/ x: kotlin.collections.List<kotlin.collections.List<dynamic>>): TestGen2 /* = kotlin.collections.List<kotlin.collections.List<dynamic>> */
|
||||
public fun useGen1(/*0*/ x: TestGen1 /* = kotlin.collections.List<dynamic> */): TestGen1 /* = kotlin.collections.List<dynamic> */
|
||||
public fun useGen2(/*0*/ x: TestGen2 /* = kotlin.collections.List<kotlin.collections.List<dynamic>> */): TestGen2 /* = kotlin.collections.List<kotlin.collections.List<dynamic>> */
|
||||
public typealias GenList</*0*/ T> = kotlin.collections.List<T>
|
||||
public typealias Test1 = kotlin.collections.List<dynamic>
|
||||
public typealias Test2 = (dynamic) -> dynamic
|
||||
public typealias TestGen1 = GenList<dynamic>
|
||||
public typealias TestGen2 = GenList<GenList<dynamic>>
|
||||
@@ -23014,6 +23014,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typealiasRhsRepeatedAnnotationInArguments.kt")
|
||||
public void testTypealiasRhsRepeatedAnnotationInArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotationInArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typealiasRhsRepeatedAnnotations.kt")
|
||||
public void testTypealiasRhsRepeatedAnnotations() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotations.kt");
|
||||
|
||||
+12
@@ -314,6 +314,18 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typealiasWithAnnotatedDynamic.kt")
|
||||
public void testTypealiasWithAnnotatedDynamic() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/typealiasWithAnnotatedDynamic.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("typealiasWithDynamic.kt")
|
||||
public void testTypealiasWithDynamic() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/typealiasWithDynamic.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("varargs.kt")
|
||||
public void testVarargs() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/varargs.kt");
|
||||
|
||||
@@ -44,7 +44,7 @@ class DynamicType(builtIns: KotlinBuiltIns, override val annotations: Annotation
|
||||
|
||||
override val isMarkedNullable: Boolean get() = false
|
||||
|
||||
override fun replaceAnnotations(newAnnotations: Annotations): DynamicType = DynamicType(delegate.builtIns, annotations)
|
||||
override fun replaceAnnotations(newAnnotations: Annotations): DynamicType = DynamicType(delegate.builtIns, newAnnotations)
|
||||
|
||||
override fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String = "dynamic"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user