FIR: Simplify resolution for invokeExtension on implicit extension

This commit is contained in:
Denis.Zharkov
2022-02-21 10:17:37 +03:00
committed by teamcity
parent 9a070ad4f6
commit 8f013db94d
6 changed files with 9 additions and 39 deletions
@@ -50,7 +50,6 @@ class CandidateFactory private constructor(
scope: FirScope?, scope: FirScope?,
dispatchReceiverValue: ReceiverValue? = null, dispatchReceiverValue: ReceiverValue? = null,
extensionReceiverValue: ReceiverValue? = null, extensionReceiverValue: ReceiverValue? = null,
builtInExtensionFunctionReceiverValue: ReceiverValue? = null,
objectsByName: Boolean = false objectsByName: Boolean = false
): Candidate { ): Candidate {
@Suppress("NAME_SHADOWING") @Suppress("NAME_SHADOWING")
@@ -59,9 +58,7 @@ class CandidateFactory private constructor(
val result = Candidate( val result = Candidate(
symbol, dispatchReceiverValue, extensionReceiverValue, symbol, dispatchReceiverValue, extensionReceiverValue,
explicitReceiverKind, context.inferenceComponents.constraintSystemFactory, baseSystem, explicitReceiverKind, context.inferenceComponents.constraintSystemFactory, baseSystem,
builtInExtensionFunctionReceiverValue?.receiverExpression?.let { callInfo,
callInfo.withReceiverAsArgument(it)
} ?: callInfo,
scope, scope,
isFromCompanionObjectTypeScope = when (explicitReceiverKind) { isFromCompanionObjectTypeScope = when (explicitReceiverKind) {
ExplicitReceiverKind.EXTENSION_RECEIVER -> extensionReceiverValue.isCandidateFromCompanionObjectTypeScope() ExplicitReceiverKind.EXTENSION_RECEIVER -> extensionReceiverValue.isCandidateFromCompanionObjectTypeScope()
@@ -424,12 +424,9 @@ private class InvokeFunctionResolveTask(
.InvokeResolvePriority(InvokeResolvePriority.INVOKE_EXTENSION) .InvokeResolvePriority(InvokeResolvePriority.INVOKE_EXTENSION)
processLevel( processLevel(
invokeReceiverValue.toMemberScopeTowerLevel( invokeReceiverValue.toMemberScopeTowerLevel(),
// Try to supply `implicitReceiverValue` as an "x" in "f.invoke(x)" // Try to supply `implicitReceiverValue` as an "x" in "f.invoke(x)"
extensionReceiver = implicitReceiverValue, info.withReceiverAsArgument(implicitReceiverValue.receiverExpression), towerGroup,
implicitExtensionInvokeMode = true
),
info, towerGroup,
ExplicitReceiverKind.DISPATCH_RECEIVER ExplicitReceiverKind.DISPATCH_RECEIVER
) )
} }
@@ -87,11 +87,10 @@ internal abstract class FirBaseTowerResolveTask(
) )
protected fun ReceiverValue.toMemberScopeTowerLevel( protected fun ReceiverValue.toMemberScopeTowerLevel(
extensionReceiver: ReceiverValue? = null, extensionReceiver: ReceiverValue? = null
implicitExtensionInvokeMode: Boolean = false
) = MemberScopeTowerLevel( ) = MemberScopeTowerLevel(
components, this, components, this,
extensionReceiver, implicitExtensionInvokeMode, extensionReceiver,
) )
protected inline fun enumerateTowerLevels( protected inline fun enumerateTowerLevels(
@@ -116,8 +116,7 @@ class FirTowerResolver(
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
scope, scope,
dispatchReceiver, dispatchReceiver,
extensionReceiverValue = null, extensionReceiverValue = null
builtInExtensionFunctionReceiverValue = null
), ),
context context
) )
@@ -76,7 +76,6 @@ private class TowerScopeLevelProcessor(
dispatchReceiverValue: ReceiverValue?, dispatchReceiverValue: ReceiverValue?,
extensionReceiverValue: ReceiverValue?, extensionReceiverValue: ReceiverValue?,
scope: FirScope, scope: FirScope,
builtInExtensionFunctionReceiverValue: ReceiverValue?,
objectsByName: Boolean objectsByName: Boolean
) { ) {
resultCollector.consumeCandidate( resultCollector.consumeCandidate(
@@ -87,7 +86,6 @@ private class TowerScopeLevelProcessor(
scope, scope,
dispatchReceiverValue, dispatchReceiverValue,
extensionReceiverValue, extensionReceiverValue,
builtInExtensionFunctionReceiverValue,
objectsByName objectsByName
), candidateFactory.context ), candidateFactory.context
) )
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.HidesMembers import org.jetbrains.kotlin.name.StandardClassIds.Annotations.HidesMembers
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
enum class ProcessResult { enum class ProcessResult {
@@ -59,7 +58,6 @@ abstract class TowerScopeLevel {
dispatchReceiverValue: ReceiverValue?, dispatchReceiverValue: ReceiverValue?,
extensionReceiverValue: ReceiverValue?, extensionReceiverValue: ReceiverValue?,
scope: FirScope, scope: FirScope,
builtInExtensionFunctionReceiverValue: ReceiverValue? = null,
objectsByName: Boolean = false objectsByName: Boolean = false
) )
} }
@@ -76,7 +74,6 @@ class MemberScopeTowerLevel(
private val bodyResolveComponents: BodyResolveComponents, private val bodyResolveComponents: BodyResolveComponents,
val dispatchReceiverValue: ReceiverValue, val dispatchReceiverValue: ReceiverValue,
private val extensionReceiver: ReceiverValue? = null, private val extensionReceiver: ReceiverValue? = null,
private val implicitExtensionInvokeMode: Boolean = false,
) : TowerScopeLevel() { ) : TowerScopeLevel() {
private val scopeSession: ScopeSession get() = bodyResolveComponents.scopeSession private val scopeSession: ScopeSession get() = bodyResolveComponents.scopeSession
private val session: FirSession get() = bodyResolveComponents.session private val session: FirSession get() = bodyResolveComponents.session
@@ -106,9 +103,7 @@ class MemberScopeTowerLevel(
val result = mutableListOf<T>() val result = mutableListOf<T>()
processScopeMembers { candidate -> processScopeMembers { candidate ->
empty = false empty = false
if (candidate is FirCallableSymbol<*> && if (candidate is FirCallableSymbol<*> && candidate.hasConsistentExtensionReceiver(extensionReceiver)) {
(implicitExtensionInvokeMode || candidate.hasConsistentExtensionReceiver(extensionReceiver))
) {
val fir = candidate.fir val fir = candidate.fir
if ((fir as? FirConstructor)?.isInner == false) { if ((fir as? FirConstructor)?.isInner == false) {
return@processScopeMembers return@processScopeMembers
@@ -126,23 +121,12 @@ class MemberScopeTowerLevel(
candidatesWithScope: List<Pair<FirScope, T>> candidatesWithScope: List<Pair<FirScope, T>>
) { ) {
for ((scope, candidate) in candidatesWithScope) { for ((scope, candidate) in candidatesWithScope) {
if (candidate is FirCallableSymbol<*> && if (candidate is FirCallableSymbol<*> && candidate.hasConsistentExtensionReceiver(extensionReceiver)) {
(implicitExtensionInvokeMode || candidate.hasConsistentExtensionReceiver(extensionReceiver))
) {
output.consumeCandidate( output.consumeCandidate(
candidate, dispatchReceiverValue, candidate, dispatchReceiverValue,
extensionReceiverValue = extensionReceiver, extensionReceiverValue = extensionReceiver,
scope scope
) )
if (implicitExtensionInvokeMode) {
output.consumeCandidate(
candidate, dispatchReceiverValue,
extensionReceiverValue = null,
scope,
builtInExtensionFunctionReceiverValue = this.extensionReceiver
)
}
} else if (candidate is FirClassLikeSymbol<*>) { } else if (candidate is FirClassLikeSymbol<*>) {
output.consumeCandidate(candidate, null, extensionReceiver, scope) output.consumeCandidate(candidate, null, extensionReceiver, scope)
} }
@@ -153,10 +137,6 @@ class MemberScopeTowerLevel(
info: CallInfo, info: CallInfo,
processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>> processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>
): ProcessResult { ): ProcessResult {
val isInvoke = info.name == OperatorNameConventions.INVOKE
if (implicitExtensionInvokeMode && !isInvoke) {
return ProcessResult.FOUND
}
val lookupTracker = session.lookupTracker val lookupTracker = session.lookupTracker
return processMembers(processor) { consumer -> return processMembers(processor) { consumer ->
withMemberCallLookup(lookupTracker, info) { lookupCtx -> withMemberCallLookup(lookupTracker, info) { lookupCtx ->