提交 83ec8aa9 编写于 作者: D Dmitry Petrov

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
上级 a0f11f77
......@@ -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 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 argumentType = argument.type.unwrap().asSimpleType()
val parameterVariance = typeParameterDescriptor?.variance ?: Variance.INVARIANT
val substitutionVariance =
when {
underlyingVariance == argumentVariance -> argumentVariance
underlyingVariance == Variance.INVARIANT -> argumentVariance
argumentVariance == Variance.INVARIANT -> underlyingVariance
else -> {
reportStrategy.conflictingProjection(typeAliasExpansion.descriptor, typeParameterDescriptor, argumentType)
argumentVariance
}
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 resultingVariance =
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 = argumentType.combineNullabilityAndAnnotations(underlyingType)
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"))
}
......
@Target(AnnotationTarget.TYPE)
annotation class A
typealias Gen<T> = List<@A T>
typealias Test1 = Gen<<!REPEATED_ANNOTATION!>@A<!> Int>
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>
@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)
\ No newline at end of file
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>
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)
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");
......@@ -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"
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册