Do not build enhanced descriptors if they are unchanged
This commit is contained in:
+16
-7
@@ -33,19 +33,24 @@ private fun <D : CallableMemberDescriptor> D.enhanceSignature(): D {
|
||||
|
||||
if (this !is JavaCallableMemberDescriptor) return this
|
||||
|
||||
val enhancedReceiverType =
|
||||
val receiverTypeEnhancement =
|
||||
if (extensionReceiverParameter != null)
|
||||
parts(isCovariant = false) { it.extensionReceiverParameter!!.type }.enhance()
|
||||
else null
|
||||
|
||||
val enhancedValueParametersTypes = valueParameters.map {
|
||||
val valueParameterEnhancements = valueParameters.map {
|
||||
p -> parts(isCovariant = false) { it.valueParameters[p.index].type }.enhance()
|
||||
}
|
||||
|
||||
val enhancedReturnType = parts(isCovariant = true) { it.returnType!! }.enhance()
|
||||
val returnTypeEnhancement = parts(isCovariant = true) { it.returnType!! }.enhance()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return this.enhance(enhancedReceiverType, enhancedValueParametersTypes, enhancedReturnType) as D
|
||||
if ((receiverTypeEnhancement?.wereChanges ?: false)
|
||||
|| returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges }) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return this.enhance(receiverTypeEnhancement?.type, valueParameterEnhancements.map { it.type }, returnTypeEnhancement.type) as D
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
private class SignatureParts(
|
||||
@@ -53,12 +58,16 @@ private class SignatureParts(
|
||||
val fromOverridden: Collection<KotlinType>,
|
||||
val isCovariant: Boolean
|
||||
) {
|
||||
fun enhance(): KotlinType {
|
||||
fun enhance(): PartEnhancementResult {
|
||||
val qualifiers = fromOverride.computeIndexedQualifiersForOverride(this.fromOverridden, isCovariant)
|
||||
return fromOverride.enhance(qualifiers)
|
||||
return fromOverride.enhance(qualifiers)?.let {
|
||||
enhanced -> PartEnhancementResult(enhanced, wereChanges = true)
|
||||
} ?: PartEnhancementResult(fromOverride, wereChanges = false)
|
||||
}
|
||||
}
|
||||
|
||||
private data class PartEnhancementResult(val type: KotlinType, val wereChanges: Boolean)
|
||||
|
||||
private fun <D : CallableMemberDescriptor> D.parts(isCovariant: Boolean, collector: (D) -> KotlinType): SignatureParts {
|
||||
return SignatureParts(
|
||||
collector(this),
|
||||
|
||||
+26
-9
@@ -33,13 +33,14 @@ import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.createProjection
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
import org.jetbrains.kotlin.utils.toReadOnlyList
|
||||
|
||||
// The index in the lambda is the position of the type component:
|
||||
// Example: for `A<B, C<D, E>>`, indices go as follows: `0 - A<...>, 1 - B, 2 - C<D, E>, 3 - D, 4 - E`,
|
||||
// which corresponds to the left-to-right breadth-first walk of the tree representation of the type.
|
||||
// For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`.
|
||||
fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = this.enhancePossiblyFlexible(qualifiers, 0).type
|
||||
fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = this.enhancePossiblyFlexible(qualifiers, 0).typeIfChanged
|
||||
|
||||
|
||||
private enum class TypeComponentPosition {
|
||||
@@ -48,10 +49,12 @@ private enum class TypeComponentPosition {
|
||||
INFLEXIBLE
|
||||
}
|
||||
|
||||
private data class Result(val type: KotlinType, val subtreeSize: Int)
|
||||
private data class Result(val type: KotlinType, val subtreeSize: Int, val wereChanges: Boolean) {
|
||||
val typeIfChanged: KotlinType? get() = type.check { wereChanges }
|
||||
}
|
||||
|
||||
private fun KotlinType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int): Result {
|
||||
if (this.isError()) return Result(this, 1)
|
||||
if (this.isError) return Result(this, 1, false)
|
||||
return if (this.isFlexible()) {
|
||||
with(this.flexibility()) {
|
||||
val lowerResult = lowerBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_LOWER)
|
||||
@@ -61,8 +64,15 @@ private fun KotlinType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQual
|
||||
"lower = ($lowerBound, ${lowerResult.subtreeSize}), " +
|
||||
"upper = ($upperBound, ${upperResult.subtreeSize})"
|
||||
}
|
||||
|
||||
val wereChanges = lowerResult.wereChanges || upperResult.wereChanges
|
||||
Result(
|
||||
DelegatingFlexibleType.create(lowerResult.type, upperResult.type, extraCapabilities), lowerResult.subtreeSize
|
||||
if (wereChanges)
|
||||
DelegatingFlexibleType.create(lowerResult.type, upperResult.type, extraCapabilities)
|
||||
else
|
||||
this@enhancePossiblyFlexible,
|
||||
lowerResult.subtreeSize,
|
||||
wereChanges
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -71,10 +81,10 @@ private fun KotlinType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQual
|
||||
|
||||
private fun KotlinType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int, position: TypeComponentPosition): Result {
|
||||
val shouldEnhance = position.shouldEnhance()
|
||||
if (!shouldEnhance && getArguments().isEmpty()) return Result(this, 1)
|
||||
if (!shouldEnhance && arguments.isEmpty()) return Result(this, 1, false)
|
||||
|
||||
val originalClass = getConstructor().declarationDescriptor
|
||||
?: return Result(this, 1)
|
||||
val originalClass = constructor.declarationDescriptor
|
||||
?: return Result(this, 1, false)
|
||||
|
||||
val effectiveQualifiers = qualifiers(index)
|
||||
val (enhancedClassifier, enhancedMutabilityAnnotations) = originalClass.enhanceMutability(effectiveQualifiers, position)
|
||||
@@ -82,6 +92,7 @@ private fun KotlinType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers
|
||||
val typeConstructor = enhancedClassifier.typeConstructor
|
||||
|
||||
var globalArgIndex = index + 1
|
||||
var wereChanges = enhancedMutabilityAnnotations != null
|
||||
val enhancedArguments = getArguments().mapIndexed {
|
||||
localArgIndex, arg ->
|
||||
if (arg.isStarProjection) {
|
||||
@@ -89,13 +100,19 @@ private fun KotlinType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers
|
||||
TypeUtils.makeStarProjection(enhancedClassifier.typeConstructor.parameters[localArgIndex])
|
||||
}
|
||||
else {
|
||||
val (enhancedType, subtreeSize) = arg.type.enhancePossiblyFlexible(qualifiers, globalArgIndex)
|
||||
val (enhancedType, subtreeSize, wasChangeInArgument) = arg.type.enhancePossiblyFlexible(qualifiers, globalArgIndex)
|
||||
wereChanges = wereChanges || wasChangeInArgument
|
||||
globalArgIndex += subtreeSize
|
||||
createProjection(enhancedType, arg.projectionKind, typeParameterDescriptor = typeConstructor.parameters[localArgIndex])
|
||||
}
|
||||
}
|
||||
|
||||
val (enhancedNullability, enhancedNullabilityAnnotations) = this.getEnhancedNullability(effectiveQualifiers, position)
|
||||
wereChanges = wereChanges || enhancedNullabilityAnnotations != null
|
||||
|
||||
val subtreeSize = globalArgIndex - index
|
||||
if (!wereChanges) return Result(this, subtreeSize, wereChanges = false)
|
||||
|
||||
val newAnnotations = listOf(
|
||||
getAnnotations(),
|
||||
enhancedMutabilityAnnotations,
|
||||
@@ -123,7 +140,7 @@ private fun KotlinType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers
|
||||
else enhancedClassifier.getDefaultType().getMemberScope(),
|
||||
newCapabilities
|
||||
)
|
||||
return Result(enhancedType, globalArgIndex - index)
|
||||
return Result(enhancedType, subtreeSize, wereChanges = true)
|
||||
}
|
||||
|
||||
private fun List<Annotations>.compositeAnnotationsOrSingle() = when (size) {
|
||||
|
||||
Reference in New Issue
Block a user