[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.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<CallableDescriptor>(
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
)
}
}
@@ -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
@@ -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<D : CallableDescriptor>() : ResolvedCall<D>
class NewResolvedCallImpl<D : CallableDescriptor>(
val resolvedCallAtom: ResolvedCallAtom,
substitutor: NewTypeSubstitutor?,
private var diagnostics: Collection<KotlinCallDiagnostic>
private var diagnostics: Collection<KotlinCallDiagnostic>,
private val typeApproximator: TypeApproximator
) : NewAbstractResolvedCall<D>() {
var isCompleted = false
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,
// 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<D : CallableDescriptor>(
typeArguments = resolvedCallAtom.substitutor.freshVariables.map {
val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
TypeApproximator(substituted.constructor.builtIns)
typeApproximator
.approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation)
?: substituted
}
@@ -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<ReceiverValue, ReceiverValueWithSmartCastInfo>()
@@ -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<ReceiverParameterDescriptor, ReceiverValueWithSmartCastInfo>()
override fun getImplicitReceiver(scope: LexicalScope): ReceiverValueWithSmartCastInfo? {
@@ -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
@@ -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) {