Do not add container annotaions to type artificially
It was only used for type-related nullability/mutability annotations and it was necessary to remove them in the descriptor renderer (duplicating their fqnames there). At the same time they're only needed for types enhancement where they can be simply restored from type owners' descriptors The testData changes are more or less correct: this kind of annotations is bound both to types themselves and their use because of their targets
This commit is contained in:
-13
@@ -18,10 +18,7 @@ package org.jetbrains.kotlin.load.java
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.resolveClassByFqName
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
@@ -52,16 +49,6 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager) {
|
||||
|
||||
return resolveTypeQualifierNickname(annotationClass)
|
||||
}
|
||||
|
||||
fun isTypeQualifier(moduleDescriptor: ModuleDescriptor, classFqName: FqName): Boolean {
|
||||
val classDescriptor = moduleDescriptor.resolveClassByFqName(
|
||||
classFqName, NoLookupLocation.FROM_JAVA_LOADER
|
||||
) ?: return false
|
||||
|
||||
if (classDescriptor.isTypeQualifierAnnotation) return true
|
||||
|
||||
return resolveTypeQualifierNickname(classDescriptor) != null
|
||||
}
|
||||
}
|
||||
|
||||
private val ClassDescriptor.isAnnotatedWithTypeQualifier: Boolean
|
||||
|
||||
@@ -52,10 +52,3 @@ val READ_ONLY_ANNOTATIONS = listOf(
|
||||
val MUTABLE_ANNOTATIONS = listOf(
|
||||
JvmAnnotationNames.JETBRAINS_MUTABLE_ANNOTATION
|
||||
)
|
||||
|
||||
// When these annotations appear on a declaration, they are copied to the _type_ of the declaration, becoming type annotations
|
||||
// See also DescriptorRendererOptions#excludedTypeAnnotationClasses
|
||||
val ANNOTATIONS_COPIED_TO_TYPES: Set<FqName> = listOf(
|
||||
NULLABLE_ANNOTATIONS, NOT_NULL_ANNOTATIONS, READ_ONLY_ANNOTATIONS, MUTABLE_ANNOTATIONS,
|
||||
listOf(JAVAX_NONNULL_ANNOTATION)
|
||||
).flatMap { it }.toSet()
|
||||
|
||||
+4
-10
@@ -145,10 +145,8 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
|
||||
protected fun computeMethodReturnType(method: JavaMethod, annotations: Annotations, c: LazyJavaResolverContext): KotlinType {
|
||||
val annotationMethod = method.containingClass.isAnnotationType
|
||||
val returnTypeAttrs = LazyJavaTypeAttributes(
|
||||
TypeUsage.COMMON, annotations,
|
||||
isForAnnotationParameter = annotationMethod,
|
||||
moduleDescriptor = c.module,
|
||||
annotationTypeQualifierResolver = c.components.annotationTypeQualifierResolver
|
||||
TypeUsage.COMMON,
|
||||
isForAnnotationParameter = annotationMethod
|
||||
)
|
||||
return c.typeResolver.transformJavaType(method.returnType, returnTypeAttrs)
|
||||
}
|
||||
@@ -167,9 +165,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
|
||||
val annotations = c.resolveAnnotations(javaParameter)
|
||||
val typeUsage =
|
||||
LazyJavaTypeAttributes(
|
||||
TypeUsage.COMMON, annotations,
|
||||
annotationTypeQualifierResolver = c.components.annotationTypeQualifierResolver,
|
||||
moduleDescriptor = c.module
|
||||
TypeUsage.COMMON
|
||||
)
|
||||
val (outType, varargElementType) =
|
||||
if (javaParameter.isVararg) {
|
||||
@@ -289,9 +285,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
|
||||
val propertyType = c.typeResolver.transformJavaType(
|
||||
field.type,
|
||||
LazyJavaTypeAttributes(
|
||||
TypeUsage.COMMON, annotations,
|
||||
annotationTypeQualifierResolver = c.components.annotationTypeQualifierResolver,
|
||||
moduleDescriptor = c.module
|
||||
TypeUsage.COMMON
|
||||
)
|
||||
)
|
||||
if (!isNotNullable) {
|
||||
|
||||
+21
-39
@@ -17,13 +17,7 @@
|
||||
package org.jetbrains.kotlin.load.java.lazy.types
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
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.FilteredAnnotations
|
||||
import org.jetbrains.kotlin.load.java.ANNOTATIONS_COPIED_TO_TYPES
|
||||
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver
|
||||
import org.jetbrains.kotlin.load.java.components.TypeUsage
|
||||
import org.jetbrains.kotlin.load.java.components.TypeUsage.COMMON
|
||||
import org.jetbrains.kotlin.load.java.components.TypeUsage.SUPERTYPE
|
||||
@@ -64,29 +58,27 @@ class JavaTypeResolver(
|
||||
}
|
||||
|
||||
fun transformArrayType(arrayType: JavaArrayType, attr: JavaTypeAttributes, isVararg: Boolean = false): KotlinType {
|
||||
return run {
|
||||
val javaComponentType = arrayType.componentType
|
||||
val primitiveType = (javaComponentType as? JavaPrimitiveType)?.type
|
||||
if (primitiveType != null) {
|
||||
val jetType = c.module.builtIns.getPrimitiveArrayKotlinType(primitiveType)
|
||||
return@run if (attr.isForAnnotationParameter)
|
||||
jetType
|
||||
else KotlinTypeFactory.flexibleType(jetType, jetType.makeNullableAsSpecified(true))
|
||||
}
|
||||
val javaComponentType = arrayType.componentType
|
||||
val primitiveType = (javaComponentType as? JavaPrimitiveType)?.type
|
||||
if (primitiveType != null) {
|
||||
val jetType = c.module.builtIns.getPrimitiveArrayKotlinType(primitiveType)
|
||||
return if (attr.isForAnnotationParameter)
|
||||
jetType
|
||||
else KotlinTypeFactory.flexibleType(jetType, jetType.makeNullableAsSpecified(true))
|
||||
}
|
||||
|
||||
val componentType = transformJavaType(javaComponentType,
|
||||
COMMON.toAttributes(attr.isForAnnotationParameter))
|
||||
val componentType = transformJavaType(javaComponentType,
|
||||
COMMON.toAttributes(attr.isForAnnotationParameter))
|
||||
|
||||
if (attr.isForAnnotationParameter) {
|
||||
val projectionKind = if (isVararg) OUT_VARIANCE else INVARIANT
|
||||
return@run c.module.builtIns.getArrayType(projectionKind, componentType)
|
||||
}
|
||||
if (attr.isForAnnotationParameter) {
|
||||
val projectionKind = if (isVararg) OUT_VARIANCE else INVARIANT
|
||||
return c.module.builtIns.getArrayType(projectionKind, componentType)
|
||||
}
|
||||
|
||||
KotlinTypeFactory.flexibleType(
|
||||
c.module.builtIns.getArrayType(INVARIANT, componentType),
|
||||
c.module.builtIns.getArrayType(OUT_VARIANCE, componentType).makeNullableAsSpecified(true)
|
||||
)
|
||||
}.replaceAnnotations(attr.typeAnnotations)
|
||||
return KotlinTypeFactory.flexibleType(
|
||||
c.module.builtIns.getArrayType(INVARIANT, componentType),
|
||||
c.module.builtIns.getArrayType(OUT_VARIANCE, componentType).makeNullableAsSpecified(true)
|
||||
)
|
||||
}
|
||||
|
||||
private fun transformJavaClassifierType(javaType: JavaClassifierType, attr: JavaTypeAttributes): KotlinType {
|
||||
@@ -113,7 +105,7 @@ class JavaTypeResolver(
|
||||
}
|
||||
|
||||
private fun computeSimpleJavaClassifierType(javaType: JavaClassifierType, attr: JavaTypeAttributes): SimpleType? {
|
||||
val annotations = CompositeAnnotations(listOf(LazyJavaAnnotations(c, javaType), attr.typeAnnotations))
|
||||
val annotations = LazyJavaAnnotations(c, javaType)
|
||||
val constructor = computeTypeConstructor(javaType, attr) ?: return null
|
||||
val arguments = computeArguments(javaType, attr, constructor)
|
||||
val isNullable = attr.isNullable()
|
||||
@@ -294,7 +286,6 @@ interface JavaTypeAttributes {
|
||||
val howThisTypeIsUsed: TypeUsage
|
||||
val flexibility: JavaTypeFlexibility
|
||||
get() = INFLEXIBLE
|
||||
val typeAnnotations: Annotations
|
||||
val isForAnnotationParameter: Boolean
|
||||
get() = false
|
||||
// Current type is upper bound of this type parameter
|
||||
@@ -310,15 +301,8 @@ enum class JavaTypeFlexibility {
|
||||
|
||||
class LazyJavaTypeAttributes(
|
||||
override val howThisTypeIsUsed: TypeUsage,
|
||||
annotations: Annotations,
|
||||
override val isForAnnotationParameter: Boolean = false,
|
||||
private val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver,
|
||||
private val moduleDescriptor: ModuleDescriptor
|
||||
): JavaTypeAttributes {
|
||||
override val typeAnnotations = FilteredAnnotations(annotations) {
|
||||
it in ANNOTATIONS_COPIED_TO_TYPES || annotationTypeQualifierResolver.isTypeQualifier(moduleDescriptor, it)
|
||||
}
|
||||
}
|
||||
override val isForAnnotationParameter: Boolean = false
|
||||
): JavaTypeAttributes
|
||||
|
||||
fun TypeUsage.toAttributes(
|
||||
isForAnnotationParameter: Boolean = false,
|
||||
@@ -326,8 +310,6 @@ fun TypeUsage.toAttributes(
|
||||
) = object : JavaTypeAttributes {
|
||||
override val howThisTypeIsUsed: TypeUsage = this@toAttributes
|
||||
|
||||
override val typeAnnotations: Annotations = Annotations.EMPTY
|
||||
|
||||
override val isForAnnotationParameter: Boolean = isForAnnotationParameter
|
||||
override val upperBoundOfTypeParameter: TypeParameterDescriptor? = upperBoundForTypeParameter
|
||||
}
|
||||
|
||||
+29
-10
@@ -18,7 +18,9 @@ package org.jetbrains.kotlin.load.java.typeEnhancement
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.composeAnnotations
|
||||
import org.jetbrains.kotlin.load.java.*
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||
@@ -54,7 +56,7 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
||||
|
||||
val receiverTypeEnhancement =
|
||||
if (extensionReceiverParameter != null)
|
||||
parts(isCovariant = false) { it.extensionReceiverParameter!!.type }.enhance()
|
||||
parts(typeContainer = null, isCovariant = false) { it.extensionReceiverParameter!!.type }.enhance()
|
||||
else null
|
||||
|
||||
|
||||
@@ -72,11 +74,12 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
||||
|
||||
val valueParameterEnhancements = valueParameters.map {
|
||||
p ->
|
||||
parts(isCovariant = false) { it.valueParameters[p.index].type }
|
||||
parts(typeContainer = p, isCovariant = false) { it.valueParameters[p.index].type }
|
||||
.enhance(predefinedEnhancementInfo?.parametersInfo?.getOrNull(p.index))
|
||||
}
|
||||
|
||||
val returnTypeEnhancement = parts(isCovariant = true) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
|
||||
val returnTypeEnhancement =
|
||||
parts(typeContainer = this, isCovariant = true) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
|
||||
|
||||
if ((receiverTypeEnhancement?.wereChanges ?: false)
|
||||
|| returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges }) {
|
||||
@@ -88,6 +91,7 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
||||
}
|
||||
|
||||
private inner class SignatureParts(
|
||||
private val typeContainer: Annotated?,
|
||||
private val fromOverride: KotlinType,
|
||||
private val fromOverridden: Collection<KotlinType>,
|
||||
private val isCovariant: Boolean
|
||||
@@ -129,12 +133,19 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
||||
isNotNullTypeParameter = unwrap() is NotNullTypeParameter)
|
||||
}
|
||||
|
||||
private fun KotlinType.extractQualifiersFromAnnotations(): JavaTypeQualifiers {
|
||||
fun <T: Any> List<FqName>.ifPresent(qualifier: T) = if (any { annotations.findAnnotation(it) != null}) qualifier else null
|
||||
private fun KotlinType.extractQualifiersFromAnnotations(isHeadTypeConstructor: Boolean): JavaTypeQualifiers {
|
||||
val composedAnnotation =
|
||||
if (isHeadTypeConstructor && typeContainer != null)
|
||||
composeAnnotations(typeContainer.annotations, annotations)
|
||||
else
|
||||
annotations
|
||||
|
||||
fun <T: Any> List<FqName>.ifPresent(qualifier: T) =
|
||||
if (any { composedAnnotation.findAnnotation(it) != null }) qualifier else null
|
||||
|
||||
fun <T: Any> uniqueNotNull(x: T?, y: T?) = if (x == null || y == null || x == y) x ?: y else null
|
||||
|
||||
val nullability = annotations.extractNullability()
|
||||
val nullability = composedAnnotation.extractNullability()
|
||||
|
||||
return JavaTypeQualifiers(
|
||||
nullability,
|
||||
@@ -213,17 +224,20 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
||||
val verticalSlice = indexedFromSupertypes.mapNotNull { it.getOrNull(index) }
|
||||
|
||||
// Only the head type constructor is safely co-variant
|
||||
qualifiers.computeQualifiersForOverride(verticalSlice, isCovariant && isHeadTypeConstructor)
|
||||
qualifiers.computeQualifiersForOverride(verticalSlice, isCovariant && isHeadTypeConstructor, isHeadTypeConstructor)
|
||||
}
|
||||
|
||||
return { index -> computedResult.getOrElse(index) { JavaTypeQualifiers.NONE } }
|
||||
}
|
||||
|
||||
private fun KotlinType.computeQualifiersForOverride(fromSupertypes: Collection<KotlinType>, isCovariant: Boolean): JavaTypeQualifiers {
|
||||
private fun KotlinType.computeQualifiersForOverride(
|
||||
fromSupertypes: Collection<KotlinType>, isCovariant: Boolean,
|
||||
isHeadTypeConstructor: Boolean
|
||||
): JavaTypeQualifiers {
|
||||
val nullabilityFromSupertypes = fromSupertypes.mapNotNull { it.extractQualifiers().nullability }.toSet()
|
||||
val mutabilityFromSupertypes = fromSupertypes.mapNotNull { it.extractQualifiers().mutability }.toSet()
|
||||
|
||||
val own = extractQualifiersFromAnnotations()
|
||||
val own = extractQualifiersFromAnnotations(isHeadTypeConstructor)
|
||||
|
||||
val isAnyNonNullTypeParameter = own.isNotNullTypeParameter || fromSupertypes.any { it.extractQualifiers().isNotNullTypeParameter }
|
||||
|
||||
@@ -268,8 +282,13 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
|
||||
|
||||
private data class PartEnhancementResult(val type: KotlinType, val wereChanges: Boolean)
|
||||
|
||||
private fun <D : CallableMemberDescriptor> D.parts(isCovariant: Boolean, collector: (D) -> KotlinType): SignatureParts {
|
||||
private fun <D : CallableMemberDescriptor> D.parts(
|
||||
typeContainer: Annotated?,
|
||||
isCovariant: Boolean,
|
||||
collector: (D) -> KotlinType
|
||||
): SignatureParts {
|
||||
return SignatureParts(
|
||||
typeContainer,
|
||||
collector(this),
|
||||
this.overriddenDescriptors.map {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
||||
Reference in New Issue
Block a user