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

This commit is contained in:
Stanislav Erokhin
2017-07-10 11:15:54 +03:00
parent e88c1b4f0a
commit 2b01b91315
8 changed files with 83 additions and 103 deletions
@@ -30,20 +30,20 @@ import java.lang.UnsupportedOperationException
class KotlinCallResolver(
private val towerResolver: TowerResolver,
private val kotlinCallCompleter: KotlinCallCompleter,
private val overloadingConflictResolver: NewOverloadingConflictResolver
private val overloadingConflictResolver: NewOverloadingConflictResolver,
private val callComponents: KotlinCallComponents
) {
fun resolveCall(
callContext: KotlinCallContext,
scopeTower: ImplicitScopeTower,
resolutionCallbacks: KotlinResolutionCallbacks,
kotlinCall: KotlinCall,
expectedType: UnwrappedType?,
factoryProviderForInvoke: CandidateFactoryProviderForInvoke<KotlinResolutionCandidate>
): Collection<ResolvedKotlinCall> {
val scopeTower = callContext.scopeTower
kotlinCall.checkCallInvariants()
val candidateFactory = SimpleCandidateFactory(callContext, scopeTower, kotlinCall)
val candidateFactory = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall)
val processor = when(kotlinCall.callKind) {
KotlinCallKind.VARIABLE -> {
createVariableAndObjectProcessor(scopeTower, kotlinCall.name, candidateFactory, kotlinCall.explicitReceiver?.receiver)
@@ -56,11 +56,11 @@ class KotlinCallResolver(
val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = kotlinCall.callKind != KotlinCallKind.UNSUPPORTED)
return choseMostSpecific(callContext.resolutionCallbacks, expectedType, candidates)
return choseMostSpecific(resolutionCallbacks, expectedType, candidates)
}
fun resolveGivenCandidates(
callContext: KotlinCallContext,
resolutionCallbacks: KotlinResolutionCallbacks,
kotlinCall: KotlinCall,
expectedType: UnwrappedType?,
givenCandidates: Collection<GivenCandidate>
@@ -70,7 +70,7 @@ class KotlinCallResolver(
val isSafeCall = (kotlinCall.explicitReceiver as? SimpleKotlinCallArgument)?.isSafeCall ?: false
val resolutionCandidates = givenCandidates.map {
SimpleKotlinResolutionCandidate(callContext,
SimpleKotlinResolutionCandidate(callComponents,
it.scopeTower,
kotlinCall,
if (it.dispatchReceiver == null) ExplicitReceiverKind.NO_EXPLICIT_RECEIVER else ExplicitReceiverKind.DISPATCH_RECEIVER,
@@ -84,7 +84,7 @@ class KotlinCallResolver(
val candidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolutionCandidates),
TowerResolver.SuccessfulResultCollector { it.status },
useOrder = true)
return choseMostSpecific(callContext.resolutionCallbacks, expectedType, candidates)
return choseMostSpecific(resolutionCallbacks, expectedType, candidates)
}
private fun choseMostSpecific(
@@ -152,7 +152,7 @@ private fun ConstraintSystemOperation.addReceiverConstraint(
class CallableReferencesCandidateFactory(
val argument: CallableReferenceKotlinCallArgument,
val outerCallContext: KotlinCallContext,
val callComponents: KotlinCallComponents,
val scopeTower: ImplicitScopeTower,
val compatibilityChecker: ((ConstraintSystemOperation) -> Unit) -> Unit,
val expectedType: UnwrappedType?
@@ -224,7 +224,7 @@ class CallableReferencesCandidateFactory(
if (expectedArgumentCount < 0) return null
val fakeArguments = (0..(expectedArgumentCount - 1)).map { FakeKotlinCallArgumentForCallableReference(it) }
val argumentMapping = outerCallContext.argumentsToParametersMapper.mapArguments(fakeArguments, externalArgument = null, descriptor = descriptor)
val argumentMapping = callComponents.argumentsToParametersMapper.mapArguments(fakeArguments, externalArgument = null, descriptor = descriptor)
if (argumentMapping.diagnostics.any { !it.candidateApplicability.isSuccess }) return null
/**
@@ -277,7 +277,7 @@ class CallableReferencesCandidateFactory(
scopeTower.lexicalScope.ownerDescriptor)
}
return outerCallContext.reflectionTypes.getKPropertyType(Annotations.EMPTY, argumentsAndReceivers, descriptorReturnType, mutable) to 0
return callComponents.reflectionTypes.getKPropertyType(Annotations.EMPTY, argumentsAndReceivers, descriptorReturnType, mutable) to 0
}
is FunctionDescriptor -> {
val returnType: KotlinType
@@ -298,8 +298,8 @@ class CallableReferencesCandidateFactory(
returnType = if (coercion == CoercionStrategy.COERCION_TO_UNIT) descriptor.builtIns.unitType else descriptorReturnType
}
return outerCallContext.reflectionTypes.getKFunctionType(Annotations.EMPTY, null, argumentsAndReceivers, null,
returnType, descriptor.builtIns) to defaults
return callComponents.reflectionTypes.getKFunctionType(Annotations.EMPTY, null, argumentsAndReceivers, null,
returnType, descriptor.builtIns) to defaults
}
else -> error("Unsupported descriptor type: $descriptor")
}
@@ -53,53 +53,53 @@ class CallableReferenceOverloadConflictResolver(
}
}
fun processCallableReferenceArgument(
callContext: KotlinCallContext,
scopeTower: ImplicitScopeTower,
csBuilder: ConstraintSystemBuilder,
postponedArgument: PostponedCallableReferenceArgument
): KotlinCallDiagnostic? {
val argument = postponedArgument.argument
val expectedType = postponedArgument.expectedType
val subLHSCall = ((argument.lhsResult as? LHSResult.Expression)?.lshCallArgument as? SubKotlinCallArgument)
if (subLHSCall != null) {
csBuilder.addInnerCall(subLHSCall.resolvedCall)
}
val candidates = callContext.callableReferenceResolver.runRLSResolution(callContext, scopeTower, argument, expectedType) { checkCallableReference ->
csBuilder.runTransaction { checkCallableReference(this); false }
}
val chosenCandidate = when (candidates.size) {
0 -> return NoneCallableReferenceCandidates(argument)
1 -> candidates.single()
else -> return CallableReferenceCandidatesAmbiguity(argument, candidates)
}
val (toFreshSubstitutor, diagnostic) = with(chosenCandidate) {
csBuilder.checkCallableReference(argument, dispatchReceiver, extensionReceiver, candidate,
reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor)
}
postponedArgument.analyzedAndThereIsResult = true
postponedArgument.myTypeVariables = toFreshSubstitutor.freshVariables
postponedArgument.callableResolutionCandidate = chosenCandidate
return diagnostic
}
class CallableReferenceResolver(
val towerResolver: TowerResolver,
val callableReferenceOverloadConflictResolver: CallableReferenceOverloadConflictResolver
private val towerResolver: TowerResolver,
private val callableReferenceOverloadConflictResolver: CallableReferenceOverloadConflictResolver,
private val callComponents: KotlinCallComponents
) {
fun runRLSResolution(
outerCallContext: KotlinCallContext,
fun processCallableReferenceArgument(
scopeTower: ImplicitScopeTower,
csBuilder: ConstraintSystemBuilder,
postponedArgument: PostponedCallableReferenceArgument
): KotlinCallDiagnostic? {
val argument = postponedArgument.argument
val expectedType = postponedArgument.expectedType
val subLHSCall = ((argument.lhsResult as? LHSResult.Expression)?.lshCallArgument as? SubKotlinCallArgument)
if (subLHSCall != null) {
csBuilder.addInnerCall(subLHSCall.resolvedCall)
}
val candidates = runRLSResolution(scopeTower, argument, expectedType) { checkCallableReference ->
csBuilder.runTransaction { checkCallableReference(this); false }
}
val chosenCandidate = when (candidates.size) {
0 -> return NoneCallableReferenceCandidates(argument)
1 -> candidates.single()
else -> return CallableReferenceCandidatesAmbiguity(argument, candidates)
}
val (toFreshSubstitutor, diagnostic) = with(chosenCandidate) {
csBuilder.checkCallableReference(argument, dispatchReceiver, extensionReceiver, candidate,
reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor)
}
postponedArgument.analyzedAndThereIsResult = true
postponedArgument.myTypeVariables = toFreshSubstitutor.freshVariables
postponedArgument.callableResolutionCandidate = chosenCandidate
return diagnostic
}
private fun runRLSResolution(
scopeTower: ImplicitScopeTower,
callableReference: CallableReferenceKotlinCallArgument,
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
): Set<CallableReferenceCandidate> {
val factory = CallableReferencesCandidateFactory(callableReference, outerCallContext, scopeTower, compatibilityChecker, expectedType)
val factory = CallableReferencesCandidateFactory(callableReference, callComponents, scopeTower, compatibilityChecker, expectedType)
val processor = createCallableReferenceProcessor(factory)
val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = true)
return callableReferenceOverloadConflictResolver.chooseMaximallySpecificCandidates(candidates, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
@@ -39,7 +39,8 @@ import org.jetbrains.kotlin.types.typeUtil.contains
class KotlinCallCompleter(
private val fixationOrderCalculator: FixationOrderCalculator,
private val additionalDiagnosticReporter: AdditionalDiagnosticReporter,
private val inferenceStepResolver: InferenceStepResolver
private val inferenceStepResolver: InferenceStepResolver,
private val callableReferenceResolver: CallableReferenceResolver
) {
interface Context {
val innerCalls: List<ResolvedKotlinCall.OnlyResolvedKotlinCall>
@@ -93,7 +94,7 @@ class KotlinCallCompleter(
private fun resolveCallableReferenceArguments(c: Context, topLevelCall: SimpleKotlinResolutionCandidate) {
for (callableReferenceArgument in c.postponedArguments) {
if (callableReferenceArgument !is PostponedCallableReferenceArgument) continue
processCallableReferenceArgument(topLevelCall.callContext, topLevelCall.scopeTower, c.getBuilder(), callableReferenceArgument)
callableReferenceResolver.processCallableReferenceArgument(topLevelCall.scopeTower, c.getBuilder(), callableReferenceArgument)
}
}
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
internal object CheckInstantiationOfAbstractClass : ResolutionPart {
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
if (candidateDescriptor is ConstructorDescriptor && !callContext.statelessCallbacks.isSuperOrDelegatingConstructorCall(kotlinCall)) {
if (candidateDescriptor is ConstructorDescriptor && !callComponents.statelessCallbacks.isSuperOrDelegatingConstructorCall(kotlinCall)) {
if (candidateDescriptor.constructedClass.modality == Modality.ABSTRACT) {
return listOf(InstantiationOfAbstractClass)
}
@@ -67,7 +67,7 @@ internal object CheckVisibility : ResolutionPart {
internal object MapTypeArguments : ResolutionPart {
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
typeArgumentMappingByOriginal = callContext.typeArgumentsToParametersMapper.mapTypeArguments(kotlinCall, candidateDescriptor.original)
typeArgumentMappingByOriginal = callComponents.typeArgumentsToParametersMapper.mapTypeArguments(kotlinCall, candidateDescriptor.original)
return typeArgumentMappingByOriginal.diagnostics
}
}
@@ -84,7 +84,7 @@ internal object NoTypeArguments : ResolutionPart {
internal object MapArguments : ResolutionPart {
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
val mapping = callContext.argumentsToParametersMapper.mapArguments(kotlinCall, candidateDescriptor)
val mapping = callComponents.argumentsToParametersMapper.mapArguments(kotlinCall, candidateDescriptor)
argumentMappingByOriginal = mapping.parameterToCallArgumentMap
return mapping.diagnostics
}
@@ -253,7 +253,7 @@ internal object CheckArguments : ResolutionPart {
internal object CheckInfixResolutionPart : ResolutionPart {
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
if (callContext.statelessCallbacks.isInfixCall(kotlinCall) &&
if (callComponents.statelessCallbacks.isInfixCall(kotlinCall) &&
(candidateDescriptor !is FunctionDescriptor || !candidateDescriptor.isInfix)) {
return listOf(InfixCallNoInfixModifier)
}
@@ -264,7 +264,7 @@ internal object CheckInfixResolutionPart : ResolutionPart {
internal object CheckOperatorResolutionPart : ResolutionPart {
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
if (callContext.statelessCallbacks.isOperatorCall(kotlinCall) &&
if (callComponents.statelessCallbacks.isOperatorCall(kotlinCall) &&
(candidateDescriptor !is FunctionDescriptor || !candidateDescriptor.isOperator)) {
return listOf(InvokeConventionCallNoOperatorModifier)
}
@@ -275,7 +275,7 @@ internal object CheckOperatorResolutionPart : ResolutionPart {
internal object CheckAbstractSuperCallPart : ResolutionPart {
override fun SimpleKotlinResolutionCandidate.process(): List<KotlinCallDiagnostic> {
if (callContext.externalPredicates.isSuperExpression(dispatchReceiverArgument)) {
if (callComponents.statelessCallbacks.isSuperExpression(dispatchReceiverArgument)) {
if (candidateDescriptor is MemberDescriptor && candidateDescriptor.modality == Modality.ABSTRACT) {
return listOf(AbstractSuperCall)
}
@@ -30,20 +30,17 @@ import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.isDynamic
class KotlinCallContext(
val scopeTower: ImplicitScopeTower,
val resolutionCallbacks: KotlinResolutionCallbacks,
class KotlinCallComponents(
val statelessCallbacks: KotlinResolutionStatelessCallbacks,
val argumentsToParametersMapper: ArgumentsToParametersMapper,
val typeArgumentsToParametersMapper: TypeArgumentsToParametersMapper,
val resultTypeResolver: ResultTypeResolver,
val callableReferenceResolver: CallableReferenceResolver,
val constraintInjector: ConstraintInjector,
val reflectionTypes: ReflectionTypes
)
class SimpleCandidateFactory(
val callContext: KotlinCallContext,
val callComponents: KotlinCallComponents,
val scopeTower: ImplicitScopeTower,
val kotlinCall: KotlinCall
): CandidateFactory<SimpleKotlinResolutionCandidate> {
@@ -77,11 +74,11 @@ class SimpleCandidateFactory(
val extensionArgumentReceiver = createReceiverArgument(kotlinCall.getExplicitExtensionReceiver(explicitReceiverKind), extensionReceiver)
if (ErrorUtils.isError(towerCandidate.descriptor)) {
return ErrorKotlinResolutionCandidate(callContext, scopeTower, kotlinCall, explicitReceiverKind, dispatchArgumentReceiver, extensionArgumentReceiver, towerCandidate.descriptor)
return ErrorKotlinResolutionCandidate(callComponents, scopeTower, kotlinCall, explicitReceiverKind, dispatchArgumentReceiver, extensionArgumentReceiver, towerCandidate.descriptor)
}
val candidateDiagnostics = towerCandidate.diagnostics.toMutableList()
if (callContext.statelessCallbacks.isHiddenInResolution(towerCandidate.descriptor, kotlinCall)) {
if (callComponents.statelessCallbacks.isHiddenInResolution(towerCandidate.descriptor, kotlinCall)) {
candidateDiagnostics.add(HiddenDescriptor)
}
@@ -95,7 +92,7 @@ class SimpleCandidateFactory(
}
}
return SimpleKotlinResolutionCandidate(callContext, scopeTower, kotlinCall, explicitReceiverKind, dispatchArgumentReceiver, extensionArgumentReceiver,
return SimpleKotlinResolutionCandidate(callComponents, scopeTower, kotlinCall, explicitReceiverKind, dispatchArgumentReceiver, extensionArgumentReceiver,
towerCandidate.descriptor, null, candidateDiagnostics)
}
}
@@ -105,7 +105,7 @@ sealed class AbstractSimpleKotlinResolutionCandidate(
}
open class SimpleKotlinResolutionCandidate(
val callContext: KotlinCallContext,
val callComponents: KotlinCallComponents,
val scopeTower: ImplicitScopeTower,
override val kotlinCall: KotlinCall,
val explicitReceiverKind: ExplicitReceiverKind,
@@ -114,7 +114,7 @@ open class SimpleKotlinResolutionCandidate(
val candidateDescriptor: CallableDescriptor,
val knownTypeParametersResultingSubstitutor: TypeSubstitutor?,
initialDiagnostics: Collection<KotlinCallDiagnostic>
) : AbstractSimpleKotlinResolutionCandidate(NewConstraintSystemImpl(callContext.constraintInjector, callContext.resultTypeResolver), initialDiagnostics) {
) : AbstractSimpleKotlinResolutionCandidate(NewConstraintSystemImpl(callComponents.constraintInjector, callComponents.resultTypeResolver), initialDiagnostics) {
val csBuilder: ConstraintSystemBuilder get() = constraintSystem.getBuilder()
lateinit var typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
@@ -134,14 +134,14 @@ open class SimpleKotlinResolutionCandidate(
}
class ErrorKotlinResolutionCandidate(
callContext: KotlinCallContext,
callComponents: KotlinCallComponents,
scopeTower: ImplicitScopeTower,
kotlinCall: KotlinCall,
explicitReceiverKind: ExplicitReceiverKind,
dispatchReceiverArgument: SimpleKotlinCallArgument?,
extensionReceiver: SimpleKotlinCallArgument?,
candidateDescriptor: CallableDescriptor
) : SimpleKotlinResolutionCandidate(callContext, scopeTower, kotlinCall, explicitReceiverKind, dispatchReceiverArgument,
) : SimpleKotlinResolutionCandidate(callComponents, scopeTower, kotlinCall, explicitReceiverKind, dispatchReceiverArgument,
extensionReceiver, candidateDescriptor, null, listOf()) {
override val resolutionSequence: List<ResolutionPart> get() = emptyList()