[NI] Use approximator as a component, don't recreate it during resolve

This commit is contained in:
Mikhail Zarechenskiy
2019-08-06 09:39:07 +03:00
parent cddabf140b
commit 5f76918c90
9 changed files with 40 additions and 21 deletions
@@ -68,13 +68,16 @@ fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDesc
return substitute(TypeSubstitutor.create(wrappedSubstitution))
}
fun CallableDescriptor.substituteAndApproximateCapturedTypes(substitutor: NewTypeSubstitutor): CallableDescriptor {
fun CallableDescriptor.substituteAndApproximateCapturedTypes(
substitutor: NewTypeSubstitutor,
typeApproximator: TypeApproximator
): CallableDescriptor {
val wrappedSubstitution = object : TypeSubstitution() {
override fun get(key: KotlinType): TypeProjection? = null
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
TypeApproximator(builtIns).approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation)
typeApproximator.approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation)
?: substitutedType
}
}
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
import org.jetbrains.kotlin.resolve.scopes.*
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeApproximator
interface ImplicitScopeTower {
val lexicalScope: LexicalScope
@@ -42,6 +43,8 @@ interface ImplicitScopeTower {
val isDebuggerContext: Boolean
val isNewInferenceEnabled: Boolean
val typeApproximator: TypeApproximator
}
interface ScopeTowerLevel {
@@ -83,6 +83,7 @@ internal class MemberScopeTowerLevel(
private val syntheticScopes = scopeTower.syntheticScopes
private val isNewInferenceEnabled = scopeTower.isNewInferenceEnabled
private val typeApproximator = scopeTower.typeApproximator
private fun collectMembers(
getMembers: ResolutionScope.(KotlinType?) -> Collection<CallableDescriptor>
@@ -108,9 +109,11 @@ internal class MemberScopeTowerLevel(
if (dispatchReceiver.possibleTypes.isNotEmpty()) {
if (unstableCandidates == null) {
result.retainAll(result.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes() })
result.retainAll(result.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes(typeApproximator) })
} else {
result.addAll(unstableCandidates.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes() })
result.addAll(
unstableCandidates.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes(typeApproximator) }
)
}
}
@@ -129,10 +132,9 @@ internal class MemberScopeTowerLevel(
* So method get has signature get(Int): Capture(*). If we also have smartcast to MutableList<String>, then there is also method get(Int): String.
* And we should chose get(Int): String.
*/
private fun CallableDescriptor.approximateCapturedTypes(): CallableDescriptor {
private fun CallableDescriptor.approximateCapturedTypes(approximator: TypeApproximator): CallableDescriptor {
if (!isNewInferenceEnabled) return this
val approximator = TypeApproximator(builtIns)
val wrappedSubstitution = object : TypeSubstitution() {
override fun get(key: KotlinType): TypeProjection? = null
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = when (position) {