Skip to content

Commit 948fdab

Browse files
cypressiousSpace Team
authored andcommitted
[FE] Refactor FlatSignature comparison
1 parent a615c4d commit 948fdab

File tree

1 file changed

+65
-45
lines changed
  • compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/results

1 file changed

+65
-45
lines changed

compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,49 @@ interface SimpleConstraintSystem {
6666
val constraintSystemMarker: ConstraintSystemMarker
6767
}
6868

69-
private fun <T> SimpleConstraintSystem.isValueParameterTypeEquallyOrMoreSpecific(
69+
class FlatSignatureComparisonState(
70+
private val cs: SimpleConstraintSystem,
71+
private val typeParameters: Collection<TypeParameterMarker>,
72+
private val typeSubstitutor: TypeSubstitutorMarker,
73+
private val callbacks: SpecificityComparisonCallbacks,
74+
private val specificityComparator: TypeSpecificityComparator,
75+
) {
76+
fun isLessSpecific(specificType: KotlinTypeMarker, generalType: KotlinTypeMarker): Boolean {
77+
if (specificityComparator.isDefinitelyLessSpecific(specificType, generalType)) {
78+
return true
79+
} else if (typeParameters.isEmpty() || !generalType.dependsOnTypeParameters(cs.context, typeParameters)) {
80+
if (!AbstractTypeChecker.isSubtypeOf(cs.context, specificType, generalType)) {
81+
if (!callbacks.isNonSubtypeEquallyOrMoreSpecific(specificType, generalType)) {
82+
return true
83+
}
84+
}
85+
} else {
86+
val substitutedGeneralType = typeSubstitutor.safeSubstitute(cs.context, generalType)
87+
88+
/**
89+
* Example:
90+
* fun <X> Array<out X>.sort(): Unit {}
91+
* fun <Y: Comparable<Y>> Array<out Y>.sort(): Unit {}
92+
* Here, when we try solve this CS(Y is variables) then Array<out X> <: Array<out Y> and this system impossible to solve,
93+
* so we capture types from receiver and value parameters.
94+
*/
95+
val specificCapturedType = AbstractTypeChecker.prepareType(cs.context, specificType)
96+
.let { if (cs.captureFromArgument) cs.context.captureFromExpression(it) ?: it else it }
97+
cs.addSubtypeConstraint(specificCapturedType, substitutedGeneralType)
98+
if (cs.hasContradiction()) {
99+
return true
100+
}
101+
}
102+
103+
return false
104+
}
105+
}
106+
107+
private fun <T> FlatSignatureComparisonState.isValueParameterTypeEquallyOrMoreSpecific(
70108
specific: FlatSignature<T>,
71109
general: FlatSignature<T>,
72-
callbacks: SpecificityComparisonCallbacks,
73-
specificityComparator: TypeSpecificityComparator,
74-
typeKindSelector: (TypeWithConversion?) -> KotlinTypeMarker?
110+
typeKindSelector: (TypeWithConversion?) -> KotlinTypeMarker?,
75111
): Boolean {
76-
val typeParameters = general.typeParameters
77-
val typeSubstitutor = registerTypeVariables(typeParameters)
78-
79112
val specificContextReceiverCount = specific.contextReceiverCount
80113
val generalContextReceiverCount = general.contextReceiverCount
81114

@@ -91,57 +124,44 @@ private fun <T> SimpleConstraintSystem.isValueParameterTypeEquallyOrMoreSpecific
91124
val specificType = typeKindSelector(specificValueParameterTypes[index]) ?: continue
92125
val generalType = typeKindSelector(generalValueParameterTypes[index]) ?: continue
93126

94-
if (specificityComparator.isDefinitelyLessSpecific(specificType, generalType)) {
95-
return false
96-
}
97-
98-
if (typeParameters.isEmpty() || !generalType.dependsOnTypeParameters(context, typeParameters)) {
99-
if (!AbstractTypeChecker.isSubtypeOf(context, specificType, generalType)) {
100-
if (!callbacks.isNonSubtypeEquallyOrMoreSpecific(specificType, generalType)) {
101-
return false
102-
}
103-
}
104-
} else {
105-
val substitutedGeneralType = typeSubstitutor.safeSubstitute(context, generalType)
106-
107-
/**
108-
* Example:
109-
* fun <X> Array<out X>.sort(): Unit {}
110-
* fun <Y: Comparable<Y>> Array<out Y>.sort(): Unit {}
111-
* Here, when we try solve this CS(Y is variables) then Array<out X> <: Array<out Y> and this system impossible to solve,
112-
* so we capture types from receiver and value parameters.
113-
*/
114-
val specificCapturedType = AbstractTypeChecker.prepareType(context, specificType)
115-
.let { if (captureFromArgument) context.captureFromExpression(it) ?: it else it }
116-
addSubtypeConstraint(specificCapturedType, substitutedGeneralType)
117-
}
127+
if (isLessSpecific(specificType, generalType)) return false
118128
}
119129

120130
return true
121131
}
122132

123-
fun <T> SimpleConstraintSystem.isSignatureEquallyOrMoreSpecific(
133+
fun <T> SimpleConstraintSystem.signatureComparisonStateIfEquallyOrMoreSpecific(
124134
specific: FlatSignature<T>,
125135
general: FlatSignature<T>,
126136
callbacks: SpecificityComparisonCallbacks,
127137
specificityComparator: TypeSpecificityComparator,
128-
useOriginalSamTypes: Boolean = false
129-
): Boolean {
130-
if (specific.hasExtensionReceiver != general.hasExtensionReceiver) return false
131-
if (specific.contextReceiverCount > general.contextReceiverCount) return false
138+
useOriginalSamTypes: Boolean = false,
139+
): FlatSignatureComparisonState? {
140+
if (specific.hasExtensionReceiver != general.hasExtensionReceiver) return null
141+
if (specific.contextReceiverCount > general.contextReceiverCount) return null
132142
if (specific.valueParameterTypes.size - specific.contextReceiverCount != general.valueParameterTypes.size - general.contextReceiverCount)
133-
return false
143+
return null
134144

135-
if (!isValueParameterTypeEquallyOrMoreSpecific(specific, general, callbacks, specificityComparator) { it?.resultType }) {
136-
return false
145+
val typeSubstitutor = registerTypeVariables(general.typeParameters)
146+
val state = FlatSignatureComparisonState(this, general.typeParameters, typeSubstitutor, callbacks, specificityComparator)
147+
148+
if (!state.isValueParameterTypeEquallyOrMoreSpecific(specific, general) { it?.resultType }) {
149+
return null
137150
}
138151

139-
if (useOriginalSamTypes && !isValueParameterTypeEquallyOrMoreSpecific(
140-
specific, general, callbacks, specificityComparator
141-
) { it?.originalTypeIfWasConverted }
142-
) {
143-
return false
152+
if (useOriginalSamTypes && !state.isValueParameterTypeEquallyOrMoreSpecific(specific, general) { it?.originalTypeIfWasConverted }) {
153+
return null
144154
}
145155

146-
return !hasContradiction()
156+
return state
157+
}
158+
159+
fun <T> SimpleConstraintSystem.isSignatureEquallyOrMoreSpecific(
160+
specific: FlatSignature<T>,
161+
general: FlatSignature<T>,
162+
callbacks: SpecificityComparisonCallbacks,
163+
specificityComparator: TypeSpecificityComparator,
164+
useOriginalSamTypes: Boolean = false
165+
): Boolean {
166+
return signatureComparisonStateIfEquallyOrMoreSpecific(specific, general, callbacks, specificityComparator, useOriginalSamTypes) != null
147167
}

0 commit comments

Comments
 (0)