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.TypeAliasDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
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.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.containsTypeAliasParameters
|
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"
|
"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) }
|
val expandedTypeWithExtraAnnotations = expandedType.combineAnnotations(annotations).let { TypeUtils.makeNullableIfNeeded(it, isNullable) }
|
||||||
|
|
||||||
return if (withAbbreviatedType)
|
return if (withAbbreviatedType)
|
||||||
@@ -82,59 +83,72 @@ class TypeAliasExpander(
|
|||||||
if (underlyingProjection.isStarProjection) return TypeUtils.makeStarProjection(typeParameterDescriptor!!)
|
if (underlyingProjection.isStarProjection) return TypeUtils.makeStarProjection(typeParameterDescriptor!!)
|
||||||
|
|
||||||
val underlyingType = underlyingProjection.type
|
val underlyingType = underlyingProjection.type
|
||||||
val argument = typeAliasExpansion.getReplacement(underlyingType.constructor)
|
val argument = typeAliasExpansion.getReplacement(underlyingType.constructor) ?:
|
||||||
|
return expandNonArgumentTypeProjection(underlyingProjection, typeAliasExpansion, recursionDepth)
|
||||||
if (argument == null) {
|
|
||||||
return expandNonArgumentTypeProjection(underlyingProjection, typeAliasExpansion, recursionDepth)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argument.isStarProjection) return TypeUtils.makeStarProjection(typeParameterDescriptor!!)
|
if (argument.isStarProjection) return TypeUtils.makeStarProjection(typeParameterDescriptor!!)
|
||||||
|
|
||||||
val argumentVariance = argument.projectionKind
|
val argumentType = argument.type.unwrap()
|
||||||
val underlyingVariance = underlyingProjection.projectionKind
|
|
||||||
|
|
||||||
val argumentType = argument.type.unwrap().asSimpleType()
|
val resultingVariance = run {
|
||||||
|
val argumentVariance = argument.projectionKind
|
||||||
|
val underlyingVariance = underlyingProjection.projectionKind
|
||||||
|
|
||||||
val substitutionVariance =
|
val substitutionVariance =
|
||||||
when {
|
when {
|
||||||
underlyingVariance == argumentVariance -> argumentVariance
|
underlyingVariance == argumentVariance -> argumentVariance
|
||||||
underlyingVariance == Variance.INVARIANT -> argumentVariance
|
underlyingVariance == Variance.INVARIANT -> argumentVariance
|
||||||
argumentVariance == Variance.INVARIANT -> underlyingVariance
|
argumentVariance == Variance.INVARIANT -> underlyingVariance
|
||||||
else -> {
|
else -> {
|
||||||
reportStrategy.conflictingProjection(typeAliasExpansion.descriptor, typeParameterDescriptor, argumentType)
|
reportStrategy.conflictingProjection(typeAliasExpansion.descriptor, typeParameterDescriptor, argumentType)
|
||||||
argumentVariance
|
argumentVariance
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val parameterVariance = typeParameterDescriptor?.variance ?: Variance.INVARIANT
|
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 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)
|
return TypeProjectionImpl(resultingVariance, substitutedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SimpleType.combineAnnotations(annotations: Annotations): SimpleType {
|
private fun DynamicType.combineAnnotations(newAnnotations: Annotations): DynamicType =
|
||||||
if (isError) return this
|
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) {
|
if (annotation.type in existingAnnotationTypes) {
|
||||||
reportStrategy.repeatedAnnotation(annotation)
|
reportStrategy.repeatedAnnotation(annotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return replace(newAnnotations = CompositeAnnotations(listOf(annotations, this.annotations)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SimpleType.combineNullability(fromType: KotlinType) =
|
private fun SimpleType.combineNullability(fromType: KotlinType) =
|
||||||
@@ -148,7 +162,11 @@ class TypeAliasExpander(
|
|||||||
typeAliasExpansion: TypeAliasExpansion,
|
typeAliasExpansion: TypeAliasExpansion,
|
||||||
recursionDepth: Int
|
recursionDepth: Int
|
||||||
): TypeProjection {
|
): 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()) {
|
if (type.isError || !type.requiresTypeAliasExpansion()) {
|
||||||
return originalProjection
|
return originalProjection
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ class TypeResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDynamicType(type: KtDynamicType) {
|
override fun visitDynamicType(type: KtDynamicType) {
|
||||||
result = type(dynamicCallableDescriptors.dynamicType)
|
result = type(dynamicCallableDescriptors.dynamicType.replaceAnnotations(annotations))
|
||||||
if (!dynamicTypesSettings.dynamicTypesAllowed) {
|
if (!dynamicTypesSettings.dynamicTypesAllowed) {
|
||||||
c.trace.report(UNSUPPORTED.on(type, "Dynamic types are not supported in this context"))
|
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);
|
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")
|
@TestMetadata("typealiasRhsRepeatedAnnotations.kt")
|
||||||
public void testTypealiasRhsRepeatedAnnotations() throws Exception {
|
public void testTypealiasRhsRepeatedAnnotations() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotations.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/typealiasRhsRepeatedAnnotations.kt");
|
||||||
|
|||||||
+12
@@ -314,6 +314,18 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("varargs.kt")
|
||||||
public void testVarargs() throws Exception {
|
public void testVarargs() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/dynamicTypes/varargs.kt");
|
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 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"
|
override fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String = "dynamic"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user