[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.inference.ConstraintSystemBuilder
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST
|
|
||||||
|
|
||||||
class FirCallResolver(
|
class FirCallResolver(
|
||||||
components: BodyResolveComponents,
|
components: BodyResolveComponents,
|
||||||
@@ -118,7 +117,6 @@ class FirCallResolver(
|
|||||||
val explicitReceiver = functionCall.explicitReceiver
|
val explicitReceiver = functionCall.explicitReceiver
|
||||||
val arguments = functionCall.arguments
|
val arguments = functionCall.arguments
|
||||||
val typeArguments = functionCall.typeArguments
|
val typeArguments = functionCall.typeArguments
|
||||||
val name = functionCall.calleeReference.name
|
|
||||||
|
|
||||||
val info = CallInfo(
|
val info = CallInfo(
|
||||||
CallKind.Function,
|
CallKind.Function,
|
||||||
@@ -131,13 +129,10 @@ class FirCallResolver(
|
|||||||
transformer.components.implicitReceiverStack
|
transformer.components.implicitReceiverStack
|
||||||
)
|
)
|
||||||
towerResolver.reset()
|
towerResolver.reset()
|
||||||
|
|
||||||
val consumer = createFunctionConsumer(session, name, info, this, towerResolver.collector, towerResolver)
|
|
||||||
val result = towerResolver.runResolver(
|
val result = towerResolver.runResolver(
|
||||||
consumer,
|
|
||||||
implicitReceiverStack.receiversAsReversed(),
|
implicitReceiverStack.receiversAsReversed(),
|
||||||
shouldProcessExtensionsBeforeMembers = name in HIDES_MEMBERS_NAME_LIST,
|
functionCall.calleeReference.name,
|
||||||
shouldProcessExplicitReceiverScopeOnly = explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
|
info
|
||||||
)
|
)
|
||||||
val bestCandidates = result.bestCandidates()
|
val bestCandidates = result.bestCandidates()
|
||||||
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||||
@@ -168,14 +163,11 @@ class FirCallResolver(
|
|||||||
transformer.components.implicitReceiverStack
|
transformer.components.implicitReceiverStack
|
||||||
)
|
)
|
||||||
towerResolver.reset()
|
towerResolver.reset()
|
||||||
|
val result = towerResolver.runResolver(
|
||||||
val consumer = createVariableAndObjectConsumer(
|
implicitReceiverStack.receiversAsReversed(),
|
||||||
session,
|
|
||||||
callee.name,
|
callee.name,
|
||||||
info, this,
|
info
|
||||||
towerResolver.collector
|
|
||||||
)
|
)
|
||||||
val result = towerResolver.runResolver(consumer, implicitReceiverStack.receiversAsReversed())
|
|
||||||
|
|
||||||
val bestCandidates = result.bestCandidates()
|
val bestCandidates = result.bestCandidates()
|
||||||
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||||
@@ -247,15 +239,17 @@ class FirCallResolver(
|
|||||||
val coneSubstitutor = constraintSystemBuilder.buildCurrentSubstitutor() as ConeSubstitutor
|
val coneSubstitutor = constraintSystemBuilder.buildCurrentSubstitutor() as ConeSubstitutor
|
||||||
val expectedType = resolvedCallableReferenceAtom.expectedType?.let(coneSubstitutor::substituteOrSelf)
|
val expectedType = resolvedCallableReferenceAtom.expectedType?.let(coneSubstitutor::substituteOrSelf)
|
||||||
|
|
||||||
val result = CandidateCollector(this, resolutionStageRunner)
|
val info = createCallableReferencesInfoForLHS(
|
||||||
val consumer =
|
callableReferenceAccess, lhs,
|
||||||
createCallableReferencesConsumerForLHS(
|
expectedType, constraintSystemBuilder
|
||||||
callableReferenceAccess, lhs,
|
)
|
||||||
result, expectedType,
|
// No reset here!
|
||||||
constraintSystemBuilder
|
val result = towerResolver.runResolver(
|
||||||
)
|
implicitReceiverStack.receiversAsReversed(),
|
||||||
|
callableReferenceAccess.calleeReference.name,
|
||||||
towerResolver.runResolver(consumer, implicitReceiverStack.receiversAsReversed())
|
info,
|
||||||
|
collector = CandidateCollector(this, resolutionStageRunner)
|
||||||
|
)
|
||||||
val bestCandidates = result.bestCandidates()
|
val bestCandidates = result.bestCandidates()
|
||||||
val noSuccessfulCandidates = result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED
|
val noSuccessfulCandidates = result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED
|
||||||
val reducedCandidates = if (noSuccessfulCandidates) {
|
val reducedCandidates = if (noSuccessfulCandidates) {
|
||||||
@@ -336,79 +330,29 @@ class FirCallResolver(
|
|||||||
return call.transformCalleeReference(StoreNameReference, nameReference) as T
|
return call.transformCalleeReference(StoreNameReference, nameReference) as T
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createCallableReferencesConsumerForLHS(
|
private fun createCallableReferencesInfoForLHS(
|
||||||
callableReferenceAccess: FirCallableReferenceAccess,
|
callableReferenceAccess: FirCallableReferenceAccess,
|
||||||
lhs: DoubleColonLHS?,
|
lhs: DoubleColonLHS?,
|
||||||
resultCollector: CandidateCollector,
|
|
||||||
expectedType: ConeKotlinType?,
|
expectedType: ConeKotlinType?,
|
||||||
outerConstraintSystemBuilder: ConstraintSystemBuilder?
|
outerConstraintSystemBuilder: ConstraintSystemBuilder?
|
||||||
): TowerDataConsumer {
|
): CallInfo {
|
||||||
val name = callableReferenceAccess.calleeReference.name
|
return CallInfo(
|
||||||
|
|
||||||
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(
|
|
||||||
CallKind.CallableReference,
|
CallKind.CallableReference,
|
||||||
receiver,
|
callableReferenceAccess.explicitReceiver,
|
||||||
emptyList(),
|
emptyList(),
|
||||||
false,
|
false,
|
||||||
emptyList(),
|
emptyList(),
|
||||||
session,
|
session,
|
||||||
file,
|
file,
|
||||||
transformer.components.implicitReceiverStack,
|
transformer.components.implicitReceiverStack,
|
||||||
|
// Additional things for callable reference resolve
|
||||||
expectedType,
|
expectedType,
|
||||||
outerConstraintSystemBuilder,
|
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(
|
private fun createResolvedNamedReference(
|
||||||
|
|||||||
@@ -36,10 +36,11 @@ class CallInfo(
|
|||||||
val containingFile: FirFile,
|
val containingFile: FirFile,
|
||||||
val implicitReceiverStack: ImplicitReceiverStack,
|
val implicitReceiverStack: ImplicitReceiverStack,
|
||||||
|
|
||||||
// Three properties for callable references only
|
// Four properties for callable references only
|
||||||
val expectedType: ConeKotlinType? = null,
|
val expectedType: ConeKotlinType? = null,
|
||||||
val outerCSBuilder: ConstraintSystemBuilder? = null,
|
val outerCSBuilder: ConstraintSystemBuilder? = null,
|
||||||
val lhs: DoubleColonLHS? = null
|
val lhs: DoubleColonLHS? = null,
|
||||||
|
val stubReceiver: FirExpression? = null
|
||||||
) {
|
) {
|
||||||
val argumentCount get() = arguments.size
|
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.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NONE
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NONE
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
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 {
|
enum class TowerDataKind {
|
||||||
EMPTY, // Corresponds to stub tower level which is replaced by receiver-related level
|
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<*>>
|
private lateinit var implicitReceiverValues: List<ImplicitReceiverValue<*>>
|
||||||
|
|
||||||
fun runResolver(
|
fun runResolver(
|
||||||
consumer: TowerDataConsumer,
|
implicitReceiverValues: List<ImplicitReceiverValue<*>>, name: Name, info: CallInfo,
|
||||||
implicitReceiverValues: List<ImplicitReceiverValue<*>>,
|
collector: CandidateCollector = this.collector
|
||||||
shouldProcessExtensionsBeforeMembers: Boolean = false,
|
|
||||||
shouldProcessExplicitReceiverScopeOnly: Boolean = false
|
|
||||||
): CandidateCollector {
|
): CandidateCollector {
|
||||||
this.implicitReceiverValues = implicitReceiverValues
|
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
|
var group = 0
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user