FIR: Optimize Java types mapping

- Avoid duplicated computations for arguments
- Do not recreate types if they weren't enhanced
This commit is contained in:
Denis Zharkov
2020-02-19 11:13:06 +03:00
parent c8269baa92
commit 6793b27330
3 changed files with 31 additions and 14 deletions
@@ -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