FIR: Do not re-initialize type parameter bounds for Java classes
This commit is contained in:
committed by
Space Team
parent
80d7404faf
commit
73cffa315d
@@ -175,19 +175,17 @@ abstract class FirJavaFacade(
|
|||||||
// TODO: some (all?) of those loops can be avoided, e.g. we don't actually need to resolve class arguments of annotations
|
// TODO: some (all?) of those loops can be avoided, e.g. we don't actually need to resolve class arguments of annotations
|
||||||
// to determine whether they set default nullability - but without laziness, breaking those loops is somewhat hard,
|
// to determine whether they set default nullability - but without laziness, breaking those loops is somewhat hard,
|
||||||
// as we have a nested ordering here.
|
// as we have a nested ordering here.
|
||||||
for (typeParameter in firJavaClass.typeParameters) {
|
|
||||||
if (typeParameter is FirTypeParameter) {
|
val enhancement = FirSignatureEnhancement(firJavaClass, session) { emptyList() }
|
||||||
typeParameter.replaceBounds(typeParameter.bounds.map {
|
enhancement.performFirstRoundOfBoundsResolution(firJavaClass.typeParameters)
|
||||||
it.resolveIfJavaType(session, javaTypeParameterStack, FirJavaTypeConversionMode.TYPE_PARAMETER_BOUND)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 1. Resolve annotations
|
// 1. Resolve annotations
|
||||||
// 2. Enhance type parameter bounds - may refer to each other, take default nullability from annotations
|
// 2. Enhance type parameter bounds - may refer to each other, take default nullability from annotations
|
||||||
// 3. Enhance super types - may refer to type parameter bounds, take default nullability from annotations
|
// 3. Enhance super types - may refer to type parameter bounds, take default nullability from annotations
|
||||||
firJavaClass.annotations.addFromJava(session, javaClass, javaTypeParameterStack)
|
firJavaClass.annotations.addFromJava(session, javaClass, javaTypeParameterStack)
|
||||||
val enhancement = FirSignatureEnhancement(firJavaClass, session) { emptyList() }
|
|
||||||
enhancement.enhanceTypeParameterBounds(firJavaClass.typeParameters)
|
enhancement.enhanceTypeParameterBoundsAfterFirstRound(firJavaClass.typeParameters)
|
||||||
|
|
||||||
val enhancedSuperTypes = buildList {
|
val enhancedSuperTypes = buildList {
|
||||||
val purelyImplementedSupertype = firJavaClass.getPurelyImplementedSupertype()
|
val purelyImplementedSupertype = firJavaClass.getPurelyImplementedSupertype()
|
||||||
val purelyImplementedSupertypeClassId = purelyImplementedSupertype?.classId
|
val purelyImplementedSupertypeClassId = purelyImplementedSupertype?.classId
|
||||||
|
|||||||
+22
-10
@@ -68,8 +68,11 @@ class FirSignatureEnhancement(
|
|||||||
|
|
||||||
private val typeQualifierResolver = session.javaAnnotationTypeQualifierResolver
|
private val typeQualifierResolver = session.javaAnnotationTypeQualifierResolver
|
||||||
|
|
||||||
private val contextQualifiers: JavaTypeQualifiersByElementType? =
|
// This property is assumed to be initialized only after annotations for the class are initialized
|
||||||
|
// While in one of the cases FirSignatureEnhancement is created just one step before annotations resolution
|
||||||
|
private val contextQualifiers: JavaTypeQualifiersByElementType? by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
typeQualifierResolver.extractDefaultQualifiers(owner)
|
typeQualifierResolver.extractDefaultQualifiers(owner)
|
||||||
|
}
|
||||||
|
|
||||||
private val enhancementsCache = session.enhancedSymbolStorage.cacheByOwner.getValue(owner.symbol, null)
|
private val enhancementsCache = session.enhancedSymbolStorage.cacheByOwner.getValue(owner.symbol, null)
|
||||||
|
|
||||||
@@ -187,7 +190,7 @@ class FirSignatureEnhancement(
|
|||||||
if (firMethod !is FirJavaMethod && firMethod !is FirJavaConstructor) {
|
if (firMethod !is FirJavaMethod && firMethod !is FirJavaConstructor) {
|
||||||
return original
|
return original
|
||||||
}
|
}
|
||||||
enhanceTypeParameterBounds(firMethod.typeParameters)
|
enhanceTypeParameterBoundsForMethod(firMethod)
|
||||||
return enhanceMethod(firMethod, original.callableId, name)
|
return enhanceMethod(firMethod, original.callableId, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,18 +330,22 @@ class FirSignatureEnhancement(
|
|||||||
return function.symbol
|
return function.symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enhanceTypeParameterBounds(typeParameters: List<FirTypeParameterRef>) {
|
// Perform first time initialization of bounds with FirResolvedTypeRef instances
|
||||||
|
fun performFirstRoundOfBoundsResolution(typeParameters: List<FirTypeParameterRef>) {
|
||||||
|
for (typeParameter in typeParameters) {
|
||||||
|
if (typeParameter is FirTypeParameter) {
|
||||||
|
typeParameter.replaceBounds(typeParameter.bounds.map {
|
||||||
|
it.resolveIfJavaType(session, javaTypeParameterStack, FirJavaTypeConversionMode.TYPE_PARAMETER_BOUND)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enhanceTypeParameterBoundsAfterFirstRound(typeParameters: List<FirTypeParameterRef>) {
|
||||||
// Type parameters can have interdependencies between them. Assuming that there are no top-level cycles
|
// Type parameters can have interdependencies between them. Assuming that there are no top-level cycles
|
||||||
// (`A : B, B : A` - invalid), the cycles can still appear when type parameters use each other in argument
|
// (`A : B, B : A` - invalid), the cycles can still appear when type parameters use each other in argument
|
||||||
// position (`A : C<B>, B : D<A>` - valid). In this case the precise enhancement of each bound depends on
|
// position (`A : C<B>, B : D<A>` - valid). In this case the precise enhancement of each bound depends on
|
||||||
// the others' nullability, for which we need to enhance at least its head type constructor.
|
// the others' nullability, for which we need to enhance at least its head type constructor.
|
||||||
typeParameters.replaceBounds { _, bound ->
|
|
||||||
// Resolve without enhancement so we don't crash the frontend if there is a restricted cycle (`A : B, B : A`)
|
|
||||||
// or if we visit type parameters in the wrong order (`A : B, B : C<A>` with `A` enhanced before `B`).
|
|
||||||
// TODO: the second case technically produces incorrect results - the loop below should visit type parameters
|
|
||||||
// in topological order, then a resolved-but-not-enhanced type will never be observable with valid code.
|
|
||||||
bound.resolveIfJavaType(session, javaTypeParameterStack, FirJavaTypeConversionMode.TYPE_PARAMETER_BOUND)
|
|
||||||
}
|
|
||||||
typeParameters.replaceBounds { typeParameter, bound ->
|
typeParameters.replaceBounds { typeParameter, bound ->
|
||||||
enhanceTypeParameterBound(typeParameter, bound, forceOnlyHeadTypeConstructor = true)
|
enhanceTypeParameterBound(typeParameter, bound, forceOnlyHeadTypeConstructor = true)
|
||||||
}
|
}
|
||||||
@@ -347,6 +354,11 @@ class FirSignatureEnhancement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun enhanceTypeParameterBoundsForMethod(firMethod: FirFunction) {
|
||||||
|
performFirstRoundOfBoundsResolution(firMethod.typeParameters)
|
||||||
|
enhanceTypeParameterBoundsAfterFirstRound(firMethod.typeParameters)
|
||||||
|
}
|
||||||
|
|
||||||
private inline fun List<FirTypeParameterRef>.replaceBounds(block: (FirTypeParameter, FirTypeRef) -> FirTypeRef) {
|
private inline fun List<FirTypeParameterRef>.replaceBounds(block: (FirTypeParameter, FirTypeRef) -> FirTypeRef) {
|
||||||
for (typeParameter in this) {
|
for (typeParameter in this) {
|
||||||
if (typeParameter is FirTypeParameter) {
|
if (typeParameter is FirTypeParameter) {
|
||||||
|
|||||||
Reference in New Issue
Block a user