[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
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.*
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
import org.jetbrains.kotlin.types.StubType import org.jetbrains.kotlin.types.StubType
import org.jetbrains.kotlin.types.TypeApproximator
import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
@@ -47,7 +48,8 @@ class CoroutineInferenceSession(
private val argumentTypeResolver: ArgumentTypeResolver, private val argumentTypeResolver: ArgumentTypeResolver,
private val doubleColonExpressionResolver: DoubleColonExpressionResolver, private val doubleColonExpressionResolver: DoubleColonExpressionResolver,
private val deprecationResolver: DeprecationResolver, private val deprecationResolver: DeprecationResolver,
private val moduleDescriptor: ModuleDescriptor private val moduleDescriptor: ModuleDescriptor,
private val typeApproximator: TypeApproximator
) : ManyCandidatesResolver<CallableDescriptor>( ) : ManyCandidatesResolver<CallableDescriptor>(
psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns
) { ) {
@@ -220,7 +222,7 @@ class CoroutineInferenceSession(
return ResolvedAtomCompleter( return ResolvedAtomCompleter(
resultSubstitutor, context, kotlinToResolvedCallTransformer, resultSubstitutor, context, kotlinToResolvedCallTransformer,
expressionTypingServices, argumentTypeResolver, doubleColonExpressionResolver, builtIns, expressionTypingServices, argumentTypeResolver, doubleColonExpressionResolver, builtIns,
deprecationResolver, moduleDescriptor, context.dataFlowValueFactory deprecationResolver, moduleDescriptor, context.dataFlowValueFactory, typeApproximator
) )
} }
} }
@@ -161,7 +161,7 @@ class KotlinResolutionCallbacksImpl(
psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter,
callComponents, builtIns, topLevelCallContext, stubsForPostponedVariables, trace, callComponents, builtIns, topLevelCallContext, stubsForPostponedVariables, trace,
kotlinToResolvedCallTransformer, expressionTypingServices, argumentTypeResolver, kotlinToResolvedCallTransformer, expressionTypingServices, argumentTypeResolver,
doubleColonExpressionResolver, deprecationResolver, moduleDescriptor doubleColonExpressionResolver, deprecationResolver, moduleDescriptor, typeApproximator
) )
} else { } else {
null null
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
@@ -71,7 +70,8 @@ class KotlinToResolvedCallTransformer(
private val dataFlowValueFactory: DataFlowValueFactory, private val dataFlowValueFactory: DataFlowValueFactory,
private val builtIns: KotlinBuiltIns, private val builtIns: KotlinBuiltIns,
private val typeSystemContext: TypeSystemInferenceExtensionContextDelegate, private val typeSystemContext: TypeSystemInferenceExtensionContextDelegate,
private val smartCastManager: SmartCastManager private val smartCastManager: SmartCastManager,
private val typeApproximator: TypeApproximator
) { ) {
companion object { companion object {
private val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC private val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC
@@ -128,7 +128,8 @@ class KotlinToResolvedCallTransformer(
val ktPrimitiveCompleter = ResolvedAtomCompleter( val ktPrimitiveCompleter = ResolvedAtomCompleter(
resultSubstitutor, context, this, expressionTypingServices, argumentTypeResolver, resultSubstitutor, context, this, expressionTypingServices, argumentTypeResolver,
doubleColonExpressionResolver, builtIns, deprecationResolver, moduleDescriptor, dataFlowValueFactory doubleColonExpressionResolver, builtIns, deprecationResolver, moduleDescriptor, dataFlowValueFactory,
typeApproximator
) )
if (!ErrorUtils.isError(candidate.candidateDescriptor)) { if (!ErrorUtils.isError(candidate.candidateDescriptor)) {
@@ -209,7 +210,7 @@ class KotlinToResolvedCallTransformer(
return storedResolvedCall return storedResolvedCall
} }
} }
return NewResolvedCallImpl(completedSimpleAtom, resultSubstitutor, diagnostics) return NewResolvedCallImpl(completedSimpleAtom, resultSubstitutor, diagnostics, typeApproximator)
} }
fun runCallCheckers(resolvedCall: ResolvedCall<*>, callCheckerContext: CallCheckerContext) { fun runCallCheckers(resolvedCall: ResolvedCall<*>, callCheckerContext: CallCheckerContext) {
@@ -609,7 +610,8 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
class NewResolvedCallImpl<D : CallableDescriptor>( class NewResolvedCallImpl<D : CallableDescriptor>(
val resolvedCallAtom: ResolvedCallAtom, val resolvedCallAtom: ResolvedCallAtom,
substitutor: NewTypeSubstitutor?, substitutor: NewTypeSubstitutor?,
private var diagnostics: Collection<KotlinCallDiagnostic> private var diagnostics: Collection<KotlinCallDiagnostic>,
private val typeApproximator: TypeApproximator
) : NewAbstractResolvedCall<D>() { ) : NewAbstractResolvedCall<D>() {
var isCompleted = false var isCompleted = false
private set private set
@@ -702,7 +704,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
// this code is very suspicious. Now it is very useful for BE, because they cannot do nothing with captured types, // this code is very suspicious. Now it is very useful for BE, because they cannot do nothing with captured types,
// but it seems like temporary solution. // but it seems like temporary solution.
candidateDescriptor.substitute(resolvedCallAtom.substitutor).substituteAndApproximateCapturedTypes( candidateDescriptor.substitute(resolvedCallAtom.substitutor).substituteAndApproximateCapturedTypes(
substitutor ?: FreshVariableNewTypeSubstitutor.Empty substitutor ?: FreshVariableNewTypeSubstitutor.Empty, typeApproximator
) )
else -> else ->
candidateDescriptor candidateDescriptor
@@ -711,7 +713,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
typeArguments = resolvedCallAtom.substitutor.freshVariables.map { typeArguments = resolvedCallAtom.substitutor.freshVariables.map {
val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType) val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
TypeApproximator(substituted.constructor.builtIns) typeApproximator
.approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation) .approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation)
?: substituted ?: substituted
} }
@@ -57,6 +57,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.*
import org.jetbrains.kotlin.resolve.scopes.utils.canBeResolvedWithoutDeprecation import org.jetbrains.kotlin.resolve.scopes.utils.canBeResolvedWithoutDeprecation
import org.jetbrains.kotlin.types.DeferredType import org.jetbrains.kotlin.types.DeferredType
import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.TypeApproximator
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.types.isDynamic import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -72,7 +73,8 @@ class NewResolutionOldInference(
private val syntheticScopes: SyntheticScopes, private val syntheticScopes: SyntheticScopes,
private val languageVersionSettings: LanguageVersionSettings, private val languageVersionSettings: LanguageVersionSettings,
private val coroutineInferenceSupport: CoroutineInferenceSupport, private val coroutineInferenceSupport: CoroutineInferenceSupport,
private val deprecationResolver: DeprecationResolver private val deprecationResolver: DeprecationResolver,
private val typeApproximator: TypeApproximator
) { ) {
sealed class ResolutionKind { sealed class ResolutionKind {
abstract internal fun createTowerProcessor( abstract internal fun createTowerProcessor(
@@ -170,7 +172,9 @@ class NewResolutionOldInference(
} }
val dynamicScope = dynamicCallableDescriptors.createDynamicDescriptorScope(context.call, context.scope.ownerDescriptor) val dynamicScope = dynamicCallableDescriptors.createDynamicDescriptorScope(context.call, context.scope.ownerDescriptor)
val scopeTower = ImplicitScopeTowerImpl(context, dynamicScope, syntheticScopes, context.call.createLookupLocation()) val scopeTower = ImplicitScopeTowerImpl(
context, dynamicScope, syntheticScopes, context.call.createLookupLocation(), typeApproximator
)
val shouldUseOperatorRem = languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem) val shouldUseOperatorRem = languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem)
val isBinaryRemOperator = isBinaryRemOperator(context.call) val isBinaryRemOperator = isBinaryRemOperator(context.call)
@@ -353,7 +357,8 @@ class NewResolutionOldInference(
val resolutionContext: ResolutionContext<*>, val resolutionContext: ResolutionContext<*>,
override val dynamicScope: MemberScope, override val dynamicScope: MemberScope,
override val syntheticScopes: SyntheticScopes, override val syntheticScopes: SyntheticScopes,
override val location: LookupLocation override val location: LookupLocation,
override val typeApproximator: TypeApproximator
) : ImplicitScopeTower { ) : ImplicitScopeTower {
private val cache = HashMap<ReceiverValue, ReceiverValueWithSmartCastInfo>() private val cache = HashMap<ReceiverValue, ReceiverValueWithSmartCastInfo>()
@@ -375,6 +375,7 @@ class PSICallResolver(
override val isDebuggerContext: Boolean get() = context.isDebuggerContext override val isDebuggerContext: Boolean get() = context.isDebuggerContext
override val isNewInferenceEnabled: Boolean get() = context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference) override val isNewInferenceEnabled: Boolean get() = context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
override val lexicalScope: LexicalScope get() = context.scope override val lexicalScope: LexicalScope get() = context.scope
override val typeApproximator: TypeApproximator get() = this@PSICallResolver.typeApproximator
private val cache = HashMap<ReceiverParameterDescriptor, ReceiverValueWithSmartCastInfo>() private val cache = HashMap<ReceiverParameterDescriptor, ReceiverValueWithSmartCastInfo>()
override fun getImplicitReceiver(scope: LexicalScope): ReceiverValueWithSmartCastInfo? { override fun getImplicitReceiver(scope: LexicalScope): ReceiverValueWithSmartCastInfo? {
@@ -50,7 +50,8 @@ class ResolvedAtomCompleter(
private val builtIns: KotlinBuiltIns, private val builtIns: KotlinBuiltIns,
private val deprecationResolver: DeprecationResolver, private val deprecationResolver: DeprecationResolver,
private val moduleDescriptor: ModuleDescriptor, private val moduleDescriptor: ModuleDescriptor,
private val dataFlowValueFactory: DataFlowValueFactory private val dataFlowValueFactory: DataFlowValueFactory,
private val typeApproximator: TypeApproximator
) { ) {
private val topLevelCallCheckerContext = CallCheckerContext(topLevelCallContext, deprecationResolver, moduleDescriptor) private val topLevelCallCheckerContext = CallCheckerContext(topLevelCallContext, deprecationResolver, moduleDescriptor)
private val topLevelTrace = topLevelCallCheckerContext.trace private val topLevelTrace = topLevelCallCheckerContext.trace
@@ -142,7 +143,7 @@ class ResolvedAtomCompleter(
} }
val approximatedReturnType = val approximatedReturnType =
TypeApproximator(builtIns).approximateDeclarationType( typeApproximator.approximateDeclarationType(
returnType, returnType,
local = true, local = true,
languageVersionSettings = topLevelCallContext.languageVersionSettings languageVersionSettings = topLevelCallContext.languageVersionSettings
@@ -68,13 +68,16 @@ fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDesc
return substitute(TypeSubstitutor.create(wrappedSubstitution)) return substitute(TypeSubstitutor.create(wrappedSubstitution))
} }
fun CallableDescriptor.substituteAndApproximateCapturedTypes(substitutor: NewTypeSubstitutor): CallableDescriptor { fun CallableDescriptor.substituteAndApproximateCapturedTypes(
substitutor: NewTypeSubstitutor,
typeApproximator: TypeApproximator
): CallableDescriptor {
val wrappedSubstitution = object : TypeSubstitution() { val wrappedSubstitution = object : TypeSubstitution() {
override fun get(key: KotlinType): TypeProjection? = null override fun get(key: KotlinType): TypeProjection? = null
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType -> substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
TypeApproximator(builtIns).approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation) typeApproximator.approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation)
?: substitutedType ?: 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.*
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeApproximator
interface ImplicitScopeTower { interface ImplicitScopeTower {
val lexicalScope: LexicalScope val lexicalScope: LexicalScope
@@ -42,6 +43,8 @@ interface ImplicitScopeTower {
val isDebuggerContext: Boolean val isDebuggerContext: Boolean
val isNewInferenceEnabled: Boolean val isNewInferenceEnabled: Boolean
val typeApproximator: TypeApproximator
} }
interface ScopeTowerLevel { interface ScopeTowerLevel {
@@ -83,6 +83,7 @@ internal class MemberScopeTowerLevel(
private val syntheticScopes = scopeTower.syntheticScopes private val syntheticScopes = scopeTower.syntheticScopes
private val isNewInferenceEnabled = scopeTower.isNewInferenceEnabled private val isNewInferenceEnabled = scopeTower.isNewInferenceEnabled
private val typeApproximator = scopeTower.typeApproximator
private fun collectMembers( private fun collectMembers(
getMembers: ResolutionScope.(KotlinType?) -> Collection<CallableDescriptor> getMembers: ResolutionScope.(KotlinType?) -> Collection<CallableDescriptor>
@@ -108,9 +109,11 @@ internal class MemberScopeTowerLevel(
if (dispatchReceiver.possibleTypes.isNotEmpty()) { if (dispatchReceiver.possibleTypes.isNotEmpty()) {
if (unstableCandidates == null) { if (unstableCandidates == null) {
result.retainAll(result.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes() }) result.retainAll(result.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes(typeApproximator) })
} else { } 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. * 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. * And we should chose get(Int): String.
*/ */
private fun CallableDescriptor.approximateCapturedTypes(): CallableDescriptor { private fun CallableDescriptor.approximateCapturedTypes(approximator: TypeApproximator): CallableDescriptor {
if (!isNewInferenceEnabled) return this if (!isNewInferenceEnabled) return this
val approximator = TypeApproximator(builtIns)
val wrappedSubstitution = object : TypeSubstitution() { val wrappedSubstitution = object : TypeSubstitution() {
override fun get(key: KotlinType): TypeProjection? = null override fun get(key: KotlinType): TypeProjection? = null
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = when (position) { override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = when (position) {