From 5f76918c90dc7d9f2383cf7a91bcfa95568b6569 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Tue, 6 Aug 2019 09:39:07 +0300 Subject: [PATCH] [NI] Use approximator as a component, don't recreate it during resolve --- .../calls/inference/CoroutineInferenceSession.kt | 6 ++++-- .../calls/tower/KotlinResolutionCallbacksImpl.kt | 2 +- .../tower/KotlinToResolvedCallTransformer.kt | 16 +++++++++------- .../calls/tower/NewResolutionOldInference.kt | 11 ++++++++--- .../resolve/calls/tower/PSICallResolver.kt | 1 + .../resolve/calls/tower/ResolvedAtomCompleter.kt | 5 +++-- .../resolve/calls/inference/InferenceUtils.kt | 7 +++++-- .../resolve/calls/tower/ImplicitScopeTower.kt | 3 +++ .../kotlin/resolve/calls/tower/TowerLevels.kt | 10 ++++++---- 9 files changed, 40 insertions(+), 21 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt index d96fb3e3f9d..0c2f4ddce05 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.* import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.types.StubType +import org.jetbrains.kotlin.types.TypeApproximator import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver @@ -47,7 +48,8 @@ class CoroutineInferenceSession( private val argumentTypeResolver: ArgumentTypeResolver, private val doubleColonExpressionResolver: DoubleColonExpressionResolver, private val deprecationResolver: DeprecationResolver, - private val moduleDescriptor: ModuleDescriptor + private val moduleDescriptor: ModuleDescriptor, + private val typeApproximator: TypeApproximator ) : ManyCandidatesResolver( psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns ) { @@ -220,7 +222,7 @@ class CoroutineInferenceSession( return ResolvedAtomCompleter( resultSubstitutor, context, kotlinToResolvedCallTransformer, expressionTypingServices, argumentTypeResolver, doubleColonExpressionResolver, builtIns, - deprecationResolver, moduleDescriptor, context.dataFlowValueFactory + deprecationResolver, moduleDescriptor, context.dataFlowValueFactory, typeApproximator ) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt index 6ac93fef347..95629abafee 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt @@ -161,7 +161,7 @@ class KotlinResolutionCallbacksImpl( psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns, topLevelCallContext, stubsForPostponedVariables, trace, kotlinToResolvedCallTransformer, expressionTypingServices, argumentTypeResolver, - doubleColonExpressionResolver, deprecationResolver, moduleDescriptor + doubleColonExpressionResolver, deprecationResolver, moduleDescriptor, typeApproximator ) } else { null diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index 1dd6625299c..9a32c1f0383 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -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.constants.CompileTimeConstant 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.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver @@ -71,7 +70,8 @@ class KotlinToResolvedCallTransformer( private val dataFlowValueFactory: DataFlowValueFactory, private val builtIns: KotlinBuiltIns, private val typeSystemContext: TypeSystemInferenceExtensionContextDelegate, - private val smartCastManager: SmartCastManager + private val smartCastManager: SmartCastManager, + private val typeApproximator: TypeApproximator ) { companion object { private val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC @@ -128,7 +128,8 @@ class KotlinToResolvedCallTransformer( val ktPrimitiveCompleter = ResolvedAtomCompleter( resultSubstitutor, context, this, expressionTypingServices, argumentTypeResolver, - doubleColonExpressionResolver, builtIns, deprecationResolver, moduleDescriptor, dataFlowValueFactory + doubleColonExpressionResolver, builtIns, deprecationResolver, moduleDescriptor, dataFlowValueFactory, + typeApproximator ) if (!ErrorUtils.isError(candidate.candidateDescriptor)) { @@ -209,7 +210,7 @@ class KotlinToResolvedCallTransformer( return storedResolvedCall } } - return NewResolvedCallImpl(completedSimpleAtom, resultSubstitutor, diagnostics) + return NewResolvedCallImpl(completedSimpleAtom, resultSubstitutor, diagnostics, typeApproximator) } fun runCallCheckers(resolvedCall: ResolvedCall<*>, callCheckerContext: CallCheckerContext) { @@ -609,7 +610,8 @@ sealed class NewAbstractResolvedCall() : ResolvedCall class NewResolvedCallImpl( val resolvedCallAtom: ResolvedCallAtom, substitutor: NewTypeSubstitutor?, - private var diagnostics: Collection + private var diagnostics: Collection, + private val typeApproximator: TypeApproximator ) : NewAbstractResolvedCall() { var isCompleted = false private set @@ -702,7 +704,7 @@ class NewResolvedCallImpl( // 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. candidateDescriptor.substitute(resolvedCallAtom.substitutor).substituteAndApproximateCapturedTypes( - substitutor ?: FreshVariableNewTypeSubstitutor.Empty + substitutor ?: FreshVariableNewTypeSubstitutor.Empty, typeApproximator ) else -> candidateDescriptor @@ -711,7 +713,7 @@ class NewResolvedCallImpl( typeArguments = resolvedCallAtom.substitutor.freshVariables.map { val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType) - TypeApproximator(substituted.constructor.builtIns) + typeApproximator .approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation) ?: substituted } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt index a3fba4ef814..df8920cda48 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewResolutionOldInference.kt @@ -57,6 +57,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.* import org.jetbrains.kotlin.resolve.scopes.utils.canBeResolvedWithoutDeprecation import org.jetbrains.kotlin.types.DeferredType import org.jetbrains.kotlin.types.ErrorUtils +import org.jetbrains.kotlin.types.TypeApproximator import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.isDynamic import org.jetbrains.kotlin.util.OperatorNameConventions @@ -72,7 +73,8 @@ class NewResolutionOldInference( private val syntheticScopes: SyntheticScopes, private val languageVersionSettings: LanguageVersionSettings, private val coroutineInferenceSupport: CoroutineInferenceSupport, - private val deprecationResolver: DeprecationResolver + private val deprecationResolver: DeprecationResolver, + private val typeApproximator: TypeApproximator ) { sealed class ResolutionKind { abstract internal fun createTowerProcessor( @@ -170,7 +172,9 @@ class NewResolutionOldInference( } 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 isBinaryRemOperator = isBinaryRemOperator(context.call) @@ -353,7 +357,8 @@ class NewResolutionOldInference( val resolutionContext: ResolutionContext<*>, override val dynamicScope: MemberScope, override val syntheticScopes: SyntheticScopes, - override val location: LookupLocation + override val location: LookupLocation, + override val typeApproximator: TypeApproximator ) : ImplicitScopeTower { private val cache = HashMap() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index 1414156b4c0..38af1d835ab 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -375,6 +375,7 @@ class PSICallResolver( override val isDebuggerContext: Boolean get() = context.isDebuggerContext override val isNewInferenceEnabled: Boolean get() = context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference) override val lexicalScope: LexicalScope get() = context.scope + override val typeApproximator: TypeApproximator get() = this@PSICallResolver.typeApproximator private val cache = HashMap() override fun getImplicitReceiver(scope: LexicalScope): ReceiverValueWithSmartCastInfo? { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt index e1cd0f4d445..070501f554f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/ResolvedAtomCompleter.kt @@ -50,7 +50,8 @@ class ResolvedAtomCompleter( private val builtIns: KotlinBuiltIns, private val deprecationResolver: DeprecationResolver, 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 topLevelTrace = topLevelCallCheckerContext.trace @@ -142,7 +143,7 @@ class ResolvedAtomCompleter( } val approximatedReturnType = - TypeApproximator(builtIns).approximateDeclarationType( + typeApproximator.approximateDeclarationType( returnType, local = true, languageVersionSettings = topLevelCallContext.languageVersionSettings diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt index e7528ab7bb1..0bbdd866bb6 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt @@ -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 } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt index 9dd6f831a24..58211e54faa 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt @@ -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 { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt index 6bbddb5ca2d..66d5c79cf38 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt @@ -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 @@ -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, 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) {