FIR: Optimize Java types mapping
- Avoid duplicated computations for arguments - Do not recreate types if they weren't enhanced
This commit is contained in:
@@ -96,12 +96,11 @@ internal fun JavaClassifierType.toFirResolvedTypeRef(
|
||||
forTypeParameterBounds: Boolean
|
||||
): FirResolvedTypeRef {
|
||||
val coneType =
|
||||
this.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, forTypeParameterBounds).run {
|
||||
if (isForSupertypes)
|
||||
this.lowerBoundIfFlexible()
|
||||
else
|
||||
this
|
||||
}
|
||||
if (isForSupertypes)
|
||||
toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, isLowerBound = true, forTypeParameterBounds)
|
||||
else
|
||||
toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, forTypeParameterBounds)
|
||||
|
||||
return buildResolvedTypeRef {
|
||||
type = coneType
|
||||
this@toFirResolvedTypeRef.annotations.mapTo(annotations) { it.toFirAnnotationCall(session, javaTypeParameterStack) }
|
||||
@@ -166,7 +165,10 @@ private fun JavaClassifierType.toConeKotlinTypeWithoutEnhancement(
|
||||
forTypeParameterBounds: Boolean = false
|
||||
): ConeKotlinType {
|
||||
val lowerBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, isLowerBound = true, forTypeParameterBounds)
|
||||
val upperBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, isLowerBound = false, forTypeParameterBounds)
|
||||
val upperBound =
|
||||
toConeKotlinTypeForFlexibleBound(
|
||||
session, javaTypeParameterStack, isLowerBound = false, forTypeParameterBounds, lowerBound
|
||||
)
|
||||
|
||||
return if (isRaw) ConeRawType(lowerBound, upperBound) else ConeFlexibleType(lowerBound, upperBound)
|
||||
}
|
||||
@@ -263,8 +265,9 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
||||
session: FirSession,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
isLowerBound: Boolean,
|
||||
forTypeParameterBounds: Boolean
|
||||
): ConeKotlinType {
|
||||
forTypeParameterBounds: Boolean,
|
||||
lowerBound: ConeLookupTagBasedType? = null
|
||||
): ConeLookupTagBasedType {
|
||||
return when (val classifier = classifier) {
|
||||
is JavaClass -> {
|
||||
//val classId = classifier.classId!!
|
||||
@@ -275,6 +278,11 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
||||
}
|
||||
|
||||
val lookupTag = ConeClassLikeLookupTagImpl(classId)
|
||||
if (!isLowerBound && !isRaw && lookupTag == lowerBound?.lookupTag) {
|
||||
return lookupTag.constructClassType(
|
||||
lowerBound.typeArguments, isNullable = true
|
||||
)
|
||||
}
|
||||
|
||||
val mappedTypeArguments = if (isRaw) {
|
||||
|
||||
@@ -306,7 +314,7 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
||||
val symbol = javaTypeParameterStack[classifier]
|
||||
ConeTypeParameterTypeImpl(symbol.toLookupTag(), isNullable = !isLowerBound)
|
||||
}
|
||||
else -> ConeClassErrorType(reason = "Unexpected classifier: $classifier")
|
||||
else -> ConeKotlinErrorType("Unexpected classifier: $classifier")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,8 +91,9 @@ private fun ConeKotlinType.enhanceConeKotlinType(
|
||||
session, TypeComponentPosition.FLEXIBLE_UPPER, qualifiers, index
|
||||
)
|
||||
|
||||
when (this) {
|
||||
is ConeRawType -> ConeRawType(lowerResult, upperResult)
|
||||
when {
|
||||
lowerResult === lowerBound && upperResult === upperBound -> this
|
||||
this is ConeRawType -> ConeRawType(lowerResult, upperResult)
|
||||
else -> coneFlexibleOrSimpleType(
|
||||
session, lowerResult, upperResult, isNotNullTypeParameter = qualifiers(index).isNotNullTypeParameter
|
||||
)
|
||||
@@ -165,6 +166,8 @@ private fun ConeKotlinType.enhanceInflexibleType(
|
||||
val effectiveQualifiers = qualifiers(index)
|
||||
val enhancedTag = originalTag.enhanceMutability(effectiveQualifiers, position)
|
||||
|
||||
var wereChangesInArgs = false
|
||||
|
||||
val enhancedArguments = if (this is RawType) {
|
||||
// TODO: Support enhancing for raw types
|
||||
typeArguments
|
||||
@@ -178,13 +181,19 @@ private fun ConeKotlinType.enhanceInflexibleType(
|
||||
require(arg is ConeKotlinType) { "Should be invariant type: $arg" }
|
||||
globalArgIndex += arg.subtreeSize()
|
||||
|
||||
arg.enhanceConeKotlinType(session, qualifiers, globalArgIndex)
|
||||
arg.enhanceConeKotlinType(session, qualifiers, globalArgIndex).also {
|
||||
if (it !== arg) {
|
||||
wereChangesInArgs = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}.toTypedArray()
|
||||
}
|
||||
|
||||
val enhancedNullability = getEnhancedNullability(effectiveQualifiers, position)
|
||||
|
||||
if (!wereChangesInArgs && originalTag == enhancedTag && enhancedNullability == isNullable) return this
|
||||
|
||||
val enhancedType = enhancedTag.constructType(enhancedArguments, enhancedNullability)
|
||||
|
||||
// TODO: why all of these is needed
|
||||
|
||||
Reference in New Issue
Block a user