[FIR] Refactoring: create consumer inside tower resolver
This commit is contained in:
@@ -40,7 +40,6 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST
|
||||
|
||||
class FirCallResolver(
|
||||
components: BodyResolveComponents,
|
||||
@@ -118,7 +117,6 @@ class FirCallResolver(
|
||||
val explicitReceiver = functionCall.explicitReceiver
|
||||
val arguments = functionCall.arguments
|
||||
val typeArguments = functionCall.typeArguments
|
||||
val name = functionCall.calleeReference.name
|
||||
|
||||
val info = CallInfo(
|
||||
CallKind.Function,
|
||||
@@ -131,13 +129,10 @@ class FirCallResolver(
|
||||
transformer.components.implicitReceiverStack
|
||||
)
|
||||
towerResolver.reset()
|
||||
|
||||
val consumer = createFunctionConsumer(session, name, info, this, towerResolver.collector, towerResolver)
|
||||
val result = towerResolver.runResolver(
|
||||
consumer,
|
||||
implicitReceiverStack.receiversAsReversed(),
|
||||
shouldProcessExtensionsBeforeMembers = name in HIDES_MEMBERS_NAME_LIST,
|
||||
shouldProcessExplicitReceiverScopeOnly = explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
|
||||
functionCall.calleeReference.name,
|
||||
info
|
||||
)
|
||||
val bestCandidates = result.bestCandidates()
|
||||
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||
@@ -168,14 +163,11 @@ class FirCallResolver(
|
||||
transformer.components.implicitReceiverStack
|
||||
)
|
||||
towerResolver.reset()
|
||||
|
||||
val consumer = createVariableAndObjectConsumer(
|
||||
session,
|
||||
val result = towerResolver.runResolver(
|
||||
implicitReceiverStack.receiversAsReversed(),
|
||||
callee.name,
|
||||
info, this,
|
||||
towerResolver.collector
|
||||
info
|
||||
)
|
||||
val result = towerResolver.runResolver(consumer, implicitReceiverStack.receiversAsReversed())
|
||||
|
||||
val bestCandidates = result.bestCandidates()
|
||||
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||
@@ -247,15 +239,17 @@ class FirCallResolver(
|
||||
val coneSubstitutor = constraintSystemBuilder.buildCurrentSubstitutor() as ConeSubstitutor
|
||||
val expectedType = resolvedCallableReferenceAtom.expectedType?.let(coneSubstitutor::substituteOrSelf)
|
||||
|
||||
val result = CandidateCollector(this, resolutionStageRunner)
|
||||
val consumer =
|
||||
createCallableReferencesConsumerForLHS(
|
||||
callableReferenceAccess, lhs,
|
||||
result, expectedType,
|
||||
constraintSystemBuilder
|
||||
)
|
||||
|
||||
towerResolver.runResolver(consumer, implicitReceiverStack.receiversAsReversed())
|
||||
val info = createCallableReferencesInfoForLHS(
|
||||
callableReferenceAccess, lhs,
|
||||
expectedType, constraintSystemBuilder
|
||||
)
|
||||
// No reset here!
|
||||
val result = towerResolver.runResolver(
|
||||
implicitReceiverStack.receiversAsReversed(),
|
||||
callableReferenceAccess.calleeReference.name,
|
||||
info,
|
||||
collector = CandidateCollector(this, resolutionStageRunner)
|
||||
)
|
||||
val bestCandidates = result.bestCandidates()
|
||||
val noSuccessfulCandidates = result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED
|
||||
val reducedCandidates = if (noSuccessfulCandidates) {
|
||||
@@ -336,79 +330,29 @@ class FirCallResolver(
|
||||
return call.transformCalleeReference(StoreNameReference, nameReference) as T
|
||||
}
|
||||
|
||||
private fun createCallableReferencesConsumerForLHS(
|
||||
private fun createCallableReferencesInfoForLHS(
|
||||
callableReferenceAccess: FirCallableReferenceAccess,
|
||||
lhs: DoubleColonLHS?,
|
||||
resultCollector: CandidateCollector,
|
||||
expectedType: ConeKotlinType?,
|
||||
outerConstraintSystemBuilder: ConstraintSystemBuilder?
|
||||
): TowerDataConsumer {
|
||||
val name = callableReferenceAccess.calleeReference.name
|
||||
|
||||
return when (lhs) {
|
||||
is DoubleColonLHS.Expression, null -> createCallableReferencesConsumerForReceiver(
|
||||
name, resultCollector, callableReferenceAccess.explicitReceiver, expectedType, outerConstraintSystemBuilder,
|
||||
lhs
|
||||
)
|
||||
is DoubleColonLHS.Type -> createCallableReferencesConsumerForReceivers(
|
||||
name,
|
||||
resultCollector,
|
||||
expectedType,
|
||||
outerConstraintSystemBuilder,
|
||||
lhs,
|
||||
FirExpressionStub(callableReferenceAccess.source).apply { replaceTypeRef(FirResolvedTypeRefImpl(null, lhs.type)) },
|
||||
callableReferenceAccess.explicitReceiver
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createCallableReferencesConsumerForReceivers(
|
||||
name: Name,
|
||||
resultCollector: CandidateCollector,
|
||||
expectedType: ConeKotlinType?,
|
||||
outerConstraintSystemBuilder: ConstraintSystemBuilder?,
|
||||
lhs: DoubleColonLHS?,
|
||||
vararg receivers: FirExpression?
|
||||
): TowerDataConsumer {
|
||||
if (receivers.size == 1) {
|
||||
return createCallableReferencesConsumerForReceiver(
|
||||
name, resultCollector, receivers[0], expectedType, outerConstraintSystemBuilder, lhs
|
||||
)
|
||||
}
|
||||
|
||||
return PrioritizedTowerDataConsumer(
|
||||
resultCollector,
|
||||
*Array(receivers.size) { index ->
|
||||
createCallableReferencesConsumerForReceiver(
|
||||
name, resultCollector, receivers[index], expectedType, outerConstraintSystemBuilder, lhs
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun createCallableReferencesConsumerForReceiver(
|
||||
name: Name,
|
||||
resultCollector: CandidateCollector,
|
||||
receiver: FirExpression?,
|
||||
expectedType: ConeKotlinType?,
|
||||
outerConstraintSystemBuilder: ConstraintSystemBuilder?,
|
||||
lhs: DoubleColonLHS?
|
||||
): TowerDataConsumer {
|
||||
val info = CallInfo(
|
||||
): CallInfo {
|
||||
return CallInfo(
|
||||
CallKind.CallableReference,
|
||||
receiver,
|
||||
callableReferenceAccess.explicitReceiver,
|
||||
emptyList(),
|
||||
false,
|
||||
emptyList(),
|
||||
session,
|
||||
file,
|
||||
transformer.components.implicitReceiverStack,
|
||||
// Additional things for callable reference resolve
|
||||
expectedType,
|
||||
outerConstraintSystemBuilder,
|
||||
lhs
|
||||
lhs,
|
||||
stubReceiver = if (lhs !is DoubleColonLHS.Type) null else FirExpressionStub(callableReferenceAccess.source).apply {
|
||||
replaceTypeRef(FirResolvedTypeRefImpl(null, lhs.type))
|
||||
}
|
||||
)
|
||||
|
||||
return createCallableReferencesConsumer(session, name, info, this, resultCollector)
|
||||
}
|
||||
|
||||
private fun createResolvedNamedReference(
|
||||
|
||||
@@ -36,10 +36,11 @@ class CallInfo(
|
||||
val containingFile: FirFile,
|
||||
val implicitReceiverStack: ImplicitReceiverStack,
|
||||
|
||||
// Three properties for callable references only
|
||||
// Four properties for callable references only
|
||||
val expectedType: ConeKotlinType? = null,
|
||||
val outerCSBuilder: ConstraintSystemBuilder? = null,
|
||||
val lhs: DoubleColonLHS? = null
|
||||
val lhs: DoubleColonLHS? = null,
|
||||
val stubReceiver: FirExpression? = null
|
||||
) {
|
||||
val argumentCount get() = arguments.size
|
||||
|
||||
|
||||
+34
-5
@@ -14,6 +14,10 @@ import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NONE
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST
|
||||
|
||||
enum class TowerDataKind {
|
||||
EMPTY, // Corresponds to stub tower level which is replaced by receiver-related level
|
||||
@@ -199,13 +203,38 @@ class FirTowerResolver(
|
||||
private lateinit var implicitReceiverValues: List<ImplicitReceiverValue<*>>
|
||||
|
||||
fun runResolver(
|
||||
consumer: TowerDataConsumer,
|
||||
implicitReceiverValues: List<ImplicitReceiverValue<*>>,
|
||||
shouldProcessExtensionsBeforeMembers: Boolean = false,
|
||||
shouldProcessExplicitReceiverScopeOnly: Boolean = false
|
||||
implicitReceiverValues: List<ImplicitReceiverValue<*>>, name: Name, info: CallInfo,
|
||||
collector: CandidateCollector = this.collector
|
||||
): CandidateCollector {
|
||||
this.implicitReceiverValues = implicitReceiverValues
|
||||
towerDataConsumer = consumer
|
||||
towerDataConsumer = when (info.callKind) {
|
||||
CallKind.VariableAccess -> {
|
||||
createVariableAndObjectConsumer(session, name, info, components, collector)
|
||||
}
|
||||
CallKind.Function -> {
|
||||
createFunctionConsumer(session, name, info, components, collector, this)
|
||||
}
|
||||
CallKind.CallableReference -> {
|
||||
if (info.stubReceiver == null) {
|
||||
createCallableReferencesConsumer(session, name, info, components, collector)
|
||||
} else {
|
||||
PrioritizedTowerDataConsumer(
|
||||
collector,
|
||||
createCallableReferencesConsumer(
|
||||
session, name, info.replaceExplicitReceiver(info.stubReceiver), components, collector
|
||||
),
|
||||
createCallableReferencesConsumer(
|
||||
session, name, info, components, collector
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
|
||||
}
|
||||
val shouldProcessExtensionsBeforeMembers =
|
||||
info.callKind == CallKind.Function && name in HIDES_MEMBERS_NAME_LIST
|
||||
val shouldProcessExplicitReceiverScopeOnly =
|
||||
info.callKind == CallKind.Function && info.explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
|
||||
|
||||
var group = 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user