[NI] Refactoring: KotlinCallContext to stateless component (1)

This commit is contained in:
Stanislav Erokhin
2017-07-10 11:02:08 +03:00
parent 9bbfac11b4
commit e88c1b4f0a
12 changed files with 64 additions and 45 deletions
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.calls.tower.KotlinResolutionExternalPredicatesImpl import org.jetbrains.kotlin.resolve.calls.tower.KotlinResolutionStatelessCallbacksImpl
import org.jetbrains.kotlin.resolve.lazy.* import org.jetbrains.kotlin.resolve.lazy.*
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
@@ -61,7 +61,7 @@ fun StorageComponentContainer.configureModule(
private fun StorageComponentContainer.configurePlatformIndependentComponents() { private fun StorageComponentContainer.configurePlatformIndependentComponents() {
useImpl<SupertypeLoopCheckerImpl>() useImpl<SupertypeLoopCheckerImpl>()
useImpl<KotlinResolutionExternalPredicatesImpl>() useImpl<KotlinResolutionStatelessCallbacksImpl>()
} }
fun StorageComponentContainer.configureModule( fun StorageComponentContainer.configureModule(
@@ -24,14 +24,14 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isSuperOrDelegatingConstructorCall import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isSuperOrDelegatingConstructorCall
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionExternalPredicates import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionStatelessCallbacks
import org.jetbrains.kotlin.resolve.calls.model.KotlinCall import org.jetbrains.kotlin.resolve.calls.model.KotlinCall
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
import org.jetbrains.kotlin.resolve.isHiddenInResolution import org.jetbrains.kotlin.resolve.isHiddenInResolution
class KotlinResolutionExternalPredicatesImpl( class KotlinResolutionStatelessCallbacksImpl(
private val languageVersionSettings: LanguageVersionSettings private val languageVersionSettings: LanguageVersionSettings
) : KotlinResolutionExternalPredicates { ) : KotlinResolutionStatelessCallbacks {
override fun isDescriptorFromSource(descriptor: CallableDescriptor) = override fun isDescriptorFromSource(descriptor: CallableDescriptor) =
DescriptorToSourceUtils.descriptorToDeclaration(descriptor) != null DescriptorToSourceUtils.descriptorToDeclaration(descriptor) != null
@@ -71,7 +71,7 @@ class PSICallResolver(
private val dynamicCallableDescriptors: DynamicCallableDescriptors, private val dynamicCallableDescriptors: DynamicCallableDescriptors,
private val syntheticScopes: SyntheticScopes, private val syntheticScopes: SyntheticScopes,
private val argumentsToParametersMapper: ArgumentsToParametersMapper, private val argumentsToParametersMapper: ArgumentsToParametersMapper,
private val externalPredicates: KotlinResolutionExternalPredicates, private val statelessCallbacks: KotlinResolutionStatelessCallbacks,
private val typeArgumentsToParametersMapper: TypeArgumentsToParametersMapper, private val typeArgumentsToParametersMapper: TypeArgumentsToParametersMapper,
private val resultTypeResolver: ResultTypeResolver, private val resultTypeResolver: ResultTypeResolver,
private val callableReferenceResolver: CallableReferenceResolver, private val callableReferenceResolver: CallableReferenceResolver,
@@ -98,14 +98,14 @@ class PSICallResolver(
val lambdaAnalyzer = createLambdaAnalyzer(context) val lambdaAnalyzer = createLambdaAnalyzer(context)
val callContext = createCallContext(scopeTower, lambdaAnalyzer) val callContext = createCallContext(scopeTower, lambdaAnalyzer)
val factoryProviderForInvoke = FactoryProviderForInvoke(context, callContext, kotlinCall) val factoryProviderForInvoke = FactoryProviderForInvoke(context, callContext, scopeTower, kotlinCall)
val expectedType = calculateExpectedType(context) val expectedType = calculateExpectedType(context)
var result = kotlinCallResolver.resolveCall(callContext, kotlinCall, expectedType, factoryProviderForInvoke) var result = kotlinCallResolver.resolveCall(callContext, kotlinCall, expectedType, factoryProviderForInvoke)
val shouldUseOperatorRem = languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem) val shouldUseOperatorRem = languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem)
if (isBinaryRemOperator && shouldUseOperatorRem && (result.isEmpty() || result.areAllCompletedAndInapplicable())) { if (isBinaryRemOperator && shouldUseOperatorRem && (result.isEmpty() || result.areAllCompletedAndInapplicable())) {
result = resolveToDeprecatedMod(name, context, resolutionKind, tracingStrategy, callContext, expectedType) result = resolveToDeprecatedMod(name, context, resolutionKind, tracingStrategy, callContext, scopeTower, expectedType)
} }
if (result.isEmpty() && reportAdditionalDiagnosticIfNoCandidates(context, scopeTower, resolutionKind.kotlinCallKind, kotlinCall)) { if (result.isEmpty() && reportAdditionalDiagnosticIfNoCandidates(context, scopeTower, resolutionKind.kotlinCallKind, kotlinCall)) {
@@ -129,7 +129,7 @@ class PSICallResolver(
val callContext = createCallContext(scopeTower, lambdaAnalyzer) val callContext = createCallContext(scopeTower, lambdaAnalyzer)
val givenCandidates = resolutionCandidates.map { val givenCandidates = resolutionCandidates.map {
GivenCandidate(it.descriptor as FunctionDescriptor, GivenCandidate(scopeTower, it.descriptor as FunctionDescriptor,
it.dispatchReceiver?.let { context.transformToReceiverWithSmartCastInfo(it) }, it.dispatchReceiver?.let { context.transformToReceiverWithSmartCastInfo(it) },
it.knownTypeParametersResultingSubstitutor) it.knownTypeParametersResultingSubstitutor)
} }
@@ -143,12 +143,14 @@ class PSICallResolver(
remOperatorName: Name, remOperatorName: Name,
context: BasicCallResolutionContext, context: BasicCallResolutionContext,
resolutionKind: NewResolutionOldInference.ResolutionKind<D>, resolutionKind: NewResolutionOldInference.ResolutionKind<D>,
tracingStrategy: TracingStrategy, callContext: KotlinCallContext, tracingStrategy: TracingStrategy,
callContext: KotlinCallContext,
scopeTower: ImplicitScopeTower,
expectedType: UnwrappedType? expectedType: UnwrappedType?
): Collection<ResolvedKotlinCall> { ): Collection<ResolvedKotlinCall> {
val deprecatedName = OperatorConventions.REM_TO_MOD_OPERATION_NAMES[remOperatorName]!! val deprecatedName = OperatorConventions.REM_TO_MOD_OPERATION_NAMES[remOperatorName]!!
val callWithDeprecatedName = toKotlinCall(context, resolutionKind.kotlinCallKind, context.call, deprecatedName, tracingStrategy) val callWithDeprecatedName = toKotlinCall(context, resolutionKind.kotlinCallKind, context.call, deprecatedName, tracingStrategy)
val refinedProviderForInvokeFactory = FactoryProviderForInvoke(context, callContext, callWithDeprecatedName) val refinedProviderForInvokeFactory = FactoryProviderForInvoke(context, callContext, scopeTower, callWithDeprecatedName)
return kotlinCallResolver.resolveCall(callContext, callWithDeprecatedName, expectedType, refinedProviderForInvokeFactory) return kotlinCallResolver.resolveCall(callContext, callWithDeprecatedName, expectedType, refinedProviderForInvokeFactory)
} }
@@ -176,7 +178,7 @@ class PSICallResolver(
} }
private fun createCallContext(scopeTower: ASTScopeTower, resolutionCallbacks: KotlinResolutionCallbacks) = private fun createCallContext(scopeTower: ASTScopeTower, resolutionCallbacks: KotlinResolutionCallbacks) =
KotlinCallContext(scopeTower, resolutionCallbacks, externalPredicates, argumentsToParametersMapper, KotlinCallContext(scopeTower, resolutionCallbacks, statelessCallbacks, argumentsToParametersMapper,
typeArgumentsToParametersMapper, resultTypeResolver, typeArgumentsToParametersMapper, resultTypeResolver,
callableReferenceResolver, constraintInjector, reflectionTypes) callableReferenceResolver, constraintInjector, reflectionTypes)
@@ -290,6 +292,7 @@ class PSICallResolver(
private inner class FactoryProviderForInvoke( private inner class FactoryProviderForInvoke(
val context: BasicCallResolutionContext, val context: BasicCallResolutionContext,
val callContext: KotlinCallContext, val callContext: KotlinCallContext,
val scopeTower: ImplicitScopeTower,
val kotlinCall: PSIKotlinCallImpl val kotlinCall: PSIKotlinCallImpl
) : CandidateFactoryProviderForInvoke<KotlinResolutionCandidate> { ) : CandidateFactoryProviderForInvoke<KotlinResolutionCandidate> {
@@ -314,7 +317,7 @@ class PSICallResolver(
override fun factoryForVariable(stripExplicitReceiver: Boolean): CandidateFactory<SimpleKotlinResolutionCandidate> { override fun factoryForVariable(stripExplicitReceiver: Boolean): CandidateFactory<SimpleKotlinResolutionCandidate> {
val explicitReceiver = if (stripExplicitReceiver) null else kotlinCall.explicitReceiver val explicitReceiver = if (stripExplicitReceiver) null else kotlinCall.explicitReceiver
val variableCall = PSIKotlinCallForVariable(kotlinCall, explicitReceiver, kotlinCall.name) val variableCall = PSIKotlinCallForVariable(kotlinCall, explicitReceiver, kotlinCall.name)
return SimpleCandidateFactory(callContext, variableCall) return SimpleCandidateFactory(callContext, scopeTower, variableCall)
} }
override fun factoryForInvoke(variable: KotlinResolutionCandidate, useExplicitReceiver: Boolean): override fun factoryForInvoke(variable: KotlinResolutionCandidate, useExplicitReceiver: Boolean):
@@ -338,7 +341,7 @@ class PSICallResolver(
PSIKotlinCallForInvoke(kotlinCall, variableCallArgument, null) PSIKotlinCallForInvoke(kotlinCall, variableCallArgument, null)
} }
return variableCallArgument.receiver to SimpleCandidateFactory(callContext, callForInvoke) return variableCallArgument.receiver to SimpleCandidateFactory(callContext, scopeTower, callForInvoke)
} }
// todo: create special check that there is no invoke on variable // todo: create special check that there is no invoke on variable
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.calls package org.jetbrains.kotlin.resolve.calls
import org.jetbrains.kotlin.resolve.calls.components.KotlinCallCompleter import org.jetbrains.kotlin.resolve.calls.components.KotlinCallCompleter
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionCallbacks
import org.jetbrains.kotlin.resolve.calls.components.NewOverloadingConflictResolver import org.jetbrains.kotlin.resolve.calls.components.NewOverloadingConflictResolver
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.model.*
@@ -42,7 +43,7 @@ class KotlinCallResolver(
kotlinCall.checkCallInvariants() kotlinCall.checkCallInvariants()
val candidateFactory = SimpleCandidateFactory(callContext, kotlinCall) val candidateFactory = SimpleCandidateFactory(callContext, scopeTower, kotlinCall)
val processor = when(kotlinCall.callKind) { val processor = when(kotlinCall.callKind) {
KotlinCallKind.VARIABLE -> { KotlinCallKind.VARIABLE -> {
createVariableAndObjectProcessor(scopeTower, kotlinCall.name, candidateFactory, kotlinCall.explicitReceiver?.receiver) createVariableAndObjectProcessor(scopeTower, kotlinCall.name, candidateFactory, kotlinCall.explicitReceiver?.receiver)
@@ -55,7 +56,7 @@ class KotlinCallResolver(
val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = kotlinCall.callKind != KotlinCallKind.UNSUPPORTED) val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = kotlinCall.callKind != KotlinCallKind.UNSUPPORTED)
return choseMostSpecific(callContext, expectedType, candidates) return choseMostSpecific(callContext.resolutionCallbacks, expectedType, candidates)
} }
fun resolveGivenCandidates( fun resolveGivenCandidates(
@@ -70,6 +71,7 @@ class KotlinCallResolver(
val resolutionCandidates = givenCandidates.map { val resolutionCandidates = givenCandidates.map {
SimpleKotlinResolutionCandidate(callContext, SimpleKotlinResolutionCandidate(callContext,
it.scopeTower,
kotlinCall, kotlinCall,
if (it.dispatchReceiver == null) ExplicitReceiverKind.NO_EXPLICIT_RECEIVER else ExplicitReceiverKind.DISPATCH_RECEIVER, if (it.dispatchReceiver == null) ExplicitReceiverKind.NO_EXPLICIT_RECEIVER else ExplicitReceiverKind.DISPATCH_RECEIVER,
it.dispatchReceiver?.let { ReceiverExpressionKotlinCallArgument(it, isSafeCall) }, it.dispatchReceiver?.let { ReceiverExpressionKotlinCallArgument(it, isSafeCall) },
@@ -82,30 +84,31 @@ class KotlinCallResolver(
val candidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolutionCandidates), val candidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolutionCandidates),
TowerResolver.SuccessfulResultCollector { it.status }, TowerResolver.SuccessfulResultCollector { it.status },
useOrder = true) useOrder = true)
return choseMostSpecific(callContext, expectedType, candidates) return choseMostSpecific(callContext.resolutionCallbacks, expectedType, candidates)
} }
private fun choseMostSpecific( private fun choseMostSpecific(
callContext: KotlinCallContext, resolutionCallbacks: KotlinResolutionCallbacks,
expectedType: UnwrappedType?, expectedType: UnwrappedType?,
candidates: Collection<KotlinResolutionCandidate> candidates: Collection<KotlinResolutionCandidate>
): Collection<ResolvedKotlinCall> { ): Collection<ResolvedKotlinCall> {
val isDebuggerContext = (candidates.firstOrNull() ?: return emptyList()).lastCall.scopeTower.isDebuggerContext
val maximallySpecificCandidates = overloadingConflictResolver.chooseMaximallySpecificCandidates( val maximallySpecificCandidates = overloadingConflictResolver.chooseMaximallySpecificCandidates(
candidates, candidates,
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
discriminateGenerics = true, // todo discriminateGenerics = true, // todo
isDebuggerContext = callContext.scopeTower.isDebuggerContext) isDebuggerContext = isDebuggerContext)
val singleResult = maximallySpecificCandidates.singleOrNull()?.let { val singleResult = maximallySpecificCandidates.singleOrNull()?.let {
kotlinCallCompleter.completeCallIfNecessary(it, expectedType, callContext.resolutionCallbacks) kotlinCallCompleter.completeCallIfNecessary(it, expectedType, resolutionCallbacks)
} }
if (singleResult != null) { if (singleResult != null) {
return listOf(singleResult) return listOf(singleResult)
} }
return maximallySpecificCandidates.map { return maximallySpecificCandidates.map {
kotlinCallCompleter.transformWhenAmbiguity(it, callContext.resolutionCallbacks) kotlinCallCompleter.transformWhenAmbiguity(it, resolutionCallbacks)
} }
} }
} }
@@ -153,12 +153,13 @@ private fun ConstraintSystemOperation.addReceiverConstraint(
class CallableReferencesCandidateFactory( class CallableReferencesCandidateFactory(
val argument: CallableReferenceKotlinCallArgument, val argument: CallableReferenceKotlinCallArgument,
val outerCallContext: KotlinCallContext, val outerCallContext: KotlinCallContext,
val scopeTower: ImplicitScopeTower,
val compatibilityChecker: ((ConstraintSystemOperation) -> Unit) -> Unit, val compatibilityChecker: ((ConstraintSystemOperation) -> Unit) -> Unit,
val expectedType: UnwrappedType? val expectedType: UnwrappedType?
) : CandidateFactory<CallableReferenceCandidate> { ) : CandidateFactory<CallableReferenceCandidate> {
fun createCallableProcessor(explicitReceiver: DetailedReceiver?) = fun createCallableProcessor(explicitReceiver: DetailedReceiver?) =
createCallableReferenceProcessor(outerCallContext.scopeTower, argument.rhsName, this, explicitReceiver) createCallableReferenceProcessor(scopeTower, argument.rhsName, this, explicitReceiver)
override fun createCandidate( override fun createCandidate(
towerCandidate: CandidateWithBoundDispatchReceiver, towerCandidate: CandidateWithBoundDispatchReceiver,
@@ -189,7 +190,7 @@ class CallableReferencesCandidateFactory(
if (it.hasContradiction) return@compatibilityChecker if (it.hasContradiction) return@compatibilityChecker
val (_, visibilityError) = it.checkCallableReference(argument, dispatchCallableReceiver, extensionCallableReceiver, candidateDescriptor, val (_, visibilityError) = it.checkCallableReference(argument, dispatchCallableReceiver, extensionCallableReceiver, candidateDescriptor,
reflectionCandidateType, expectedType, outerCallContext.scopeTower.lexicalScope.ownerDescriptor) reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor)
diagnostics.addIfNotNull(visibilityError) diagnostics.addIfNotNull(visibilityError)
@@ -273,7 +274,7 @@ class CallableReferencesCandidateFactory(
val mutable = descriptor.isVar && run { val mutable = descriptor.isVar && run {
val setter = descriptor.setter val setter = descriptor.setter
setter == null || Visibilities.isVisible(dispatchReceiver?.asReceiverValueForVisibilityChecks, setter, setter == null || Visibilities.isVisible(dispatchReceiver?.asReceiverValueForVisibilityChecks, setter,
outerCallContext.scopeTower.lexicalScope.ownerDescriptor) scopeTower.lexicalScope.ownerDescriptor)
} }
return outerCallContext.reflectionTypes.getKPropertyType(Annotations.EMPTY, argumentsAndReceivers, descriptorReturnType, mutable) to 0 return outerCallContext.reflectionTypes.getKPropertyType(Annotations.EMPTY, argumentsAndReceivers, descriptorReturnType, mutable) to 0
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.results.FlatSignature import org.jetbrains.kotlin.resolve.calls.results.FlatSignature
import org.jetbrains.kotlin.resolve.calls.results.OverloadingConflictResolver import org.jetbrains.kotlin.resolve.calls.results.OverloadingConflictResolver
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
import org.jetbrains.kotlin.resolve.calls.tower.TowerResolver import org.jetbrains.kotlin.resolve.calls.tower.TowerResolver
import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.UnwrappedType
@@ -34,7 +35,7 @@ import org.jetbrains.kotlin.types.UnwrappedType
class CallableReferenceOverloadConflictResolver( class CallableReferenceOverloadConflictResolver(
builtIns: KotlinBuiltIns, builtIns: KotlinBuiltIns,
specificityComparator: TypeSpecificityComparator, specificityComparator: TypeSpecificityComparator,
externalPredicates: KotlinResolutionExternalPredicates, statelessCallbacks: KotlinResolutionStatelessCallbacks,
constraintInjector: ConstraintInjector, constraintInjector: ConstraintInjector,
typeResolver: ResultTypeResolver typeResolver: ResultTypeResolver
) : OverloadingConflictResolver<CallableReferenceCandidate>( ) : OverloadingConflictResolver<CallableReferenceCandidate>(
@@ -44,7 +45,7 @@ class CallableReferenceOverloadConflictResolver(
{ SimpleConstraintSystemImpl(constraintInjector, typeResolver) }, { SimpleConstraintSystemImpl(constraintInjector, typeResolver) },
Companion::createFlatSignature, Companion::createFlatSignature,
{ null }, { null },
{ externalPredicates.isDescriptorFromSource(it) } { statelessCallbacks.isDescriptorFromSource(it) }
) { ) {
companion object { companion object {
private fun createFlatSignature(candidate: CallableReferenceCandidate) = private fun createFlatSignature(candidate: CallableReferenceCandidate) =
@@ -54,6 +55,7 @@ class CallableReferenceOverloadConflictResolver(
fun processCallableReferenceArgument( fun processCallableReferenceArgument(
callContext: KotlinCallContext, callContext: KotlinCallContext,
scopeTower: ImplicitScopeTower,
csBuilder: ConstraintSystemBuilder, csBuilder: ConstraintSystemBuilder,
postponedArgument: PostponedCallableReferenceArgument postponedArgument: PostponedCallableReferenceArgument
): KotlinCallDiagnostic? { ): KotlinCallDiagnostic? {
@@ -64,7 +66,7 @@ fun processCallableReferenceArgument(
if (subLHSCall != null) { if (subLHSCall != null) {
csBuilder.addInnerCall(subLHSCall.resolvedCall) csBuilder.addInnerCall(subLHSCall.resolvedCall)
} }
val candidates = callContext.callableReferenceResolver.runRLSResolution(callContext, argument, expectedType) { checkCallableReference -> val candidates = callContext.callableReferenceResolver.runRLSResolution(callContext, scopeTower, argument, expectedType) { checkCallableReference ->
csBuilder.runTransaction { checkCallableReference(this); false } csBuilder.runTransaction { checkCallableReference(this); false }
} }
val chosenCandidate = when (candidates.size) { val chosenCandidate = when (candidates.size) {
@@ -74,7 +76,7 @@ fun processCallableReferenceArgument(
} }
val (toFreshSubstitutor, diagnostic) = with(chosenCandidate) { val (toFreshSubstitutor, diagnostic) = with(chosenCandidate) {
csBuilder.checkCallableReference(argument, dispatchReceiver, extensionReceiver, candidate, csBuilder.checkCallableReference(argument, dispatchReceiver, extensionReceiver, candidate,
reflectionCandidateType, expectedType, callContext.scopeTower.lexicalScope.ownerDescriptor) reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor)
} }
postponedArgument.analyzedAndThereIsResult = true postponedArgument.analyzedAndThereIsResult = true
@@ -92,16 +94,17 @@ class CallableReferenceResolver(
fun runRLSResolution( fun runRLSResolution(
outerCallContext: KotlinCallContext, outerCallContext: KotlinCallContext,
scopeTower: ImplicitScopeTower,
callableReference: CallableReferenceKotlinCallArgument, callableReference: CallableReferenceKotlinCallArgument,
expectedType: UnwrappedType?, // this type can have not fixed type variable inside expectedType: UnwrappedType?, // this type can have not fixed type variable inside
compatibilityChecker: ((ConstraintSystemOperation) -> Unit) -> Unit // you can run anything throw this operation and all this operation will be roll backed compatibilityChecker: ((ConstraintSystemOperation) -> Unit) -> Unit // you can run anything throw this operation and all this operation will be roll backed
): Set<CallableReferenceCandidate> { ): Set<CallableReferenceCandidate> {
val factory = CallableReferencesCandidateFactory(callableReference, outerCallContext, compatibilityChecker, expectedType) val factory = CallableReferencesCandidateFactory(callableReference, outerCallContext, scopeTower, compatibilityChecker, expectedType)
val processor = createCallableReferenceProcessor(factory) val processor = createCallableReferenceProcessor(factory)
val candidates = towerResolver.runResolve(outerCallContext.scopeTower, processor, useOrder = true) val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = true)
return callableReferenceOverloadConflictResolver.chooseMaximallySpecificCandidates(candidates, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, return callableReferenceOverloadConflictResolver.chooseMaximallySpecificCandidates(candidates, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
discriminateGenerics = false, discriminateGenerics = false,
isDebuggerContext = outerCallContext.scopeTower.isDebuggerContext) isDebuggerContext = scopeTower.isDebuggerContext)
} }
} }
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.UnwrappedType
// stateless component // stateless component
interface KotlinResolutionExternalPredicates { interface KotlinResolutionStatelessCallbacks {
fun isDescriptorFromSource(descriptor: CallableDescriptor): Boolean fun isDescriptorFromSource(descriptor: CallableDescriptor): Boolean
fun isInfixCall(kotlinCall: KotlinCall): Boolean fun isInfixCall(kotlinCall: KotlinCall): Boolean
fun isOperatorCall(kotlinCall: KotlinCall): Boolean fun isOperatorCall(kotlinCall: KotlinCall): Boolean
@@ -93,7 +93,7 @@ class KotlinCallCompleter(
private fun resolveCallableReferenceArguments(c: Context, topLevelCall: SimpleKotlinResolutionCandidate) { private fun resolveCallableReferenceArguments(c: Context, topLevelCall: SimpleKotlinResolutionCandidate) {
for (callableReferenceArgument in c.postponedArguments) { for (callableReferenceArgument in c.postponedArguments) {
if (callableReferenceArgument !is PostponedCallableReferenceArgument) continue if (callableReferenceArgument !is PostponedCallableReferenceArgument) continue
processCallableReferenceArgument(topLevelCall.callContext, c.getBuilder(), callableReferenceArgument) processCallableReferenceArgument(topLevelCall.callContext, topLevelCall.scopeTower, c.getBuilder(), callableReferenceArgument)
} }
} }
@@ -31,7 +31,7 @@ import java.util.*
class NewOverloadingConflictResolver( class NewOverloadingConflictResolver(
builtIns: KotlinBuiltIns, builtIns: KotlinBuiltIns,
specificityComparator: TypeSpecificityComparator, specificityComparator: TypeSpecificityComparator,
externalPredicates: KotlinResolutionExternalPredicates, statelessCallbacks: KotlinResolutionStatelessCallbacks,
constraintInjector: ConstraintInjector, constraintInjector: ConstraintInjector,
typeResolver: ResultTypeResolver typeResolver: ResultTypeResolver
) : OverloadingConflictResolver<KotlinResolutionCandidate>( ) : OverloadingConflictResolver<KotlinResolutionCandidate>(
@@ -45,7 +45,7 @@ class NewOverloadingConflictResolver(
{ SimpleConstraintSystemImpl(constraintInjector, typeResolver) }, { SimpleConstraintSystemImpl(constraintInjector, typeResolver) },
Companion::createFlatSignature, Companion::createFlatSignature,
{ (it as? VariableAsFunctionKotlinResolutionCandidate)?.resolvedVariable }, { (it as? VariableAsFunctionKotlinResolutionCandidate)?.resolvedVariable },
{ externalPredicates.isDescriptorFromSource(it) } { statelessCallbacks.isDescriptorFromSource(it) }
) { ) {
companion object { companion object {
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
internal object CheckInstantiationOfAbstractClass : ResolutionPart { internal object CheckInstantiationOfAbstractClass : ResolutionPart {
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> { override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
if (candidateDescriptor is ConstructorDescriptor && !callContext.externalPredicates.isSuperOrDelegatingConstructorCall(kotlinCall)) { if (candidateDescriptor is ConstructorDescriptor && !callContext.statelessCallbacks.isSuperOrDelegatingConstructorCall(kotlinCall)) {
if (candidateDescriptor.constructedClass.modality == Modality.ABSTRACT) { if (candidateDescriptor.constructedClass.modality == Modality.ABSTRACT) {
return listOf(InstantiationOfAbstractClass) return listOf(InstantiationOfAbstractClass)
} }
@@ -62,7 +62,7 @@ internal object CheckVisibility : ResolutionPart {
return listOf(VisibilityError(invisibleMember)) return listOf(VisibilityError(invisibleMember))
} }
private val SimpleKotlinResolutionCandidate.containingDescriptor: DeclarationDescriptor get() = callContext.scopeTower.lexicalScope.ownerDescriptor private val SimpleKotlinResolutionCandidate.containingDescriptor: DeclarationDescriptor get() = scopeTower.lexicalScope.ownerDescriptor
} }
internal object MapTypeArguments : ResolutionPart { internal object MapTypeArguments : ResolutionPart {
@@ -253,7 +253,7 @@ internal object CheckArguments : ResolutionPart {
internal object CheckInfixResolutionPart : ResolutionPart { internal object CheckInfixResolutionPart : ResolutionPart {
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> { override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
if (callContext.externalPredicates.isInfixCall(kotlinCall) && if (callContext.statelessCallbacks.isInfixCall(kotlinCall) &&
(candidateDescriptor !is FunctionDescriptor || !candidateDescriptor.isInfix)) { (candidateDescriptor !is FunctionDescriptor || !candidateDescriptor.isInfix)) {
return listOf(InfixCallNoInfixModifier) return listOf(InfixCallNoInfixModifier)
} }
@@ -264,7 +264,7 @@ internal object CheckInfixResolutionPart : ResolutionPart {
internal object CheckOperatorResolutionPart : ResolutionPart { internal object CheckOperatorResolutionPart : ResolutionPart {
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> { override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
if (callContext.externalPredicates.isOperatorCall(kotlinCall) && if (callContext.statelessCallbacks.isOperatorCall(kotlinCall) &&
(candidateDescriptor !is FunctionDescriptor || !candidateDescriptor.isOperator)) { (candidateDescriptor !is FunctionDescriptor || !candidateDescriptor.isOperator)) {
return listOf(InvokeConventionCallNoOperatorModifier) return listOf(InvokeConventionCallNoOperatorModifier)
} }
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.types.isDynamic
class KotlinCallContext( class KotlinCallContext(
val scopeTower: ImplicitScopeTower, val scopeTower: ImplicitScopeTower,
val resolutionCallbacks: KotlinResolutionCallbacks, val resolutionCallbacks: KotlinResolutionCallbacks,
val externalPredicates: KotlinResolutionExternalPredicates, val statelessCallbacks: KotlinResolutionStatelessCallbacks,
val argumentsToParametersMapper: ArgumentsToParametersMapper, val argumentsToParametersMapper: ArgumentsToParametersMapper,
val typeArgumentsToParametersMapper: TypeArgumentsToParametersMapper, val typeArgumentsToParametersMapper: TypeArgumentsToParametersMapper,
val resultTypeResolver: ResultTypeResolver, val resultTypeResolver: ResultTypeResolver,
@@ -42,7 +42,11 @@ class KotlinCallContext(
val reflectionTypes: ReflectionTypes val reflectionTypes: ReflectionTypes
) )
class SimpleCandidateFactory(val callContext: KotlinCallContext, val kotlinCall: KotlinCall): CandidateFactory<SimpleKotlinResolutionCandidate> { class SimpleCandidateFactory(
val callContext: KotlinCallContext,
val scopeTower: ImplicitScopeTower,
val kotlinCall: KotlinCall
): CandidateFactory<SimpleKotlinResolutionCandidate> {
// todo: try something else, because current method is ugly and unstable // todo: try something else, because current method is ugly and unstable
private fun createReceiverArgument( private fun createReceiverArgument(
@@ -73,11 +77,11 @@ class SimpleCandidateFactory(val callContext: KotlinCallContext, val kotlinCall:
val extensionArgumentReceiver = createReceiverArgument(kotlinCall.getExplicitExtensionReceiver(explicitReceiverKind), extensionReceiver) val extensionArgumentReceiver = createReceiverArgument(kotlinCall.getExplicitExtensionReceiver(explicitReceiverKind), extensionReceiver)
if (ErrorUtils.isError(towerCandidate.descriptor)) { if (ErrorUtils.isError(towerCandidate.descriptor)) {
return ErrorKotlinResolutionCandidate(callContext, kotlinCall, explicitReceiverKind, dispatchArgumentReceiver, extensionArgumentReceiver, towerCandidate.descriptor) return ErrorKotlinResolutionCandidate(callContext, scopeTower, kotlinCall, explicitReceiverKind, dispatchArgumentReceiver, extensionArgumentReceiver, towerCandidate.descriptor)
} }
val candidateDiagnostics = towerCandidate.diagnostics.toMutableList() val candidateDiagnostics = towerCandidate.diagnostics.toMutableList()
if (callContext.externalPredicates.isHiddenInResolution(towerCandidate.descriptor, kotlinCall)) { if (callContext.statelessCallbacks.isHiddenInResolution(towerCandidate.descriptor, kotlinCall)) {
candidateDiagnostics.add(HiddenDescriptor) candidateDiagnostics.add(HiddenDescriptor)
} }
@@ -91,7 +95,7 @@ class SimpleCandidateFactory(val callContext: KotlinCallContext, val kotlinCall:
} }
} }
return SimpleKotlinResolutionCandidate(callContext, kotlinCall, explicitReceiverKind, dispatchArgumentReceiver, extensionArgumentReceiver, return SimpleKotlinResolutionCandidate(callContext, scopeTower, kotlinCall, explicitReceiverKind, dispatchArgumentReceiver, extensionArgumentReceiver,
towerCandidate.descriptor, null, candidateDiagnostics) towerCandidate.descriptor, null, candidateDiagnostics)
} }
} }
@@ -126,6 +130,7 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
} }
class GivenCandidate( class GivenCandidate(
val scopeTower: ImplicitScopeTower,
val descriptor: FunctionDescriptor, val descriptor: FunctionDescriptor,
val dispatchReceiver: ReceiverValueWithSmartCastInfo?, val dispatchReceiver: ReceiverValueWithSmartCastInfo?,
val knownTypeParametersResultingSubstitutor: TypeSubstitutor? val knownTypeParametersResultingSubstitutor: TypeSubstitutor?
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImp
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tower.Candidate import org.jetbrains.kotlin.resolve.calls.tower.Candidate
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateStatus import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateStatus
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.TypeSubstitutor
@@ -105,6 +106,7 @@ sealed class AbstractSimpleKotlinResolutionCandidate(
open class SimpleKotlinResolutionCandidate( open class SimpleKotlinResolutionCandidate(
val callContext: KotlinCallContext, val callContext: KotlinCallContext,
val scopeTower: ImplicitScopeTower,
override val kotlinCall: KotlinCall, override val kotlinCall: KotlinCall,
val explicitReceiverKind: ExplicitReceiverKind, val explicitReceiverKind: ExplicitReceiverKind,
val dispatchReceiverArgument: SimpleKotlinCallArgument?, val dispatchReceiverArgument: SimpleKotlinCallArgument?,
@@ -133,12 +135,14 @@ open class SimpleKotlinResolutionCandidate(
class ErrorKotlinResolutionCandidate( class ErrorKotlinResolutionCandidate(
callContext: KotlinCallContext, callContext: KotlinCallContext,
scopeTower: ImplicitScopeTower,
kotlinCall: KotlinCall, kotlinCall: KotlinCall,
explicitReceiverKind: ExplicitReceiverKind, explicitReceiverKind: ExplicitReceiverKind,
dispatchReceiverArgument: SimpleKotlinCallArgument?, dispatchReceiverArgument: SimpleKotlinCallArgument?,
extensionReceiver: SimpleKotlinCallArgument?, extensionReceiver: SimpleKotlinCallArgument?,
candidateDescriptor: CallableDescriptor candidateDescriptor: CallableDescriptor
) : SimpleKotlinResolutionCandidate(callContext, kotlinCall, explicitReceiverKind, dispatchReceiverArgument, extensionReceiver, candidateDescriptor, null, listOf()) { ) : SimpleKotlinResolutionCandidate(callContext, scopeTower, kotlinCall, explicitReceiverKind, dispatchReceiverArgument,
extensionReceiver, candidateDescriptor, null, listOf()) {
override val resolutionSequence: List<ResolutionPart> get() = emptyList() override val resolutionSequence: List<ResolutionPart> get() = emptyList()
init { init {