FIR invoke resolve: remove redundant candidates
This commit is contained in:
+1
-1
@@ -173,7 +173,7 @@ class ExplicitReceiverTowerDataConsumer<T : AbstractFirBasedSymbol<*>>(
|
|||||||
MemberScopeTowerLevel(
|
MemberScopeTowerLevel(
|
||||||
session, resultCollector.components, explicitReceiver,
|
session, resultCollector.components, explicitReceiver,
|
||||||
implicitExtensionReceiver = (towerScopeLevel as? TowerScopeLevel.OnlyImplicitReceiver)?.implicitReceiverValue,
|
implicitExtensionReceiver = (towerScopeLevel as? TowerScopeLevel.OnlyImplicitReceiver)?.implicitReceiverValue,
|
||||||
invokeOnly = towerScopeLevel is TowerScopeLevel.OnlyImplicitReceiver,
|
implicitExtensionInvokeMode = towerScopeLevel is TowerScopeLevel.OnlyImplicitReceiver,
|
||||||
scopeSession = candidateFactory.bodyResolveComponents.scopeSession
|
scopeSession = candidateFactory.bodyResolveComponents.scopeSession
|
||||||
).processElementsByName(
|
).processElementsByName(
|
||||||
token,
|
token,
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirImportImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirImportImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||||
@@ -49,7 +47,7 @@ interface TowerScopeLevel {
|
|||||||
symbol: T,
|
symbol: T,
|
||||||
dispatchReceiverValue: ClassDispatchReceiverValue?,
|
dispatchReceiverValue: ClassDispatchReceiverValue?,
|
||||||
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
||||||
builtInExtensionFunctionReceiverValue: ReceiverValue?
|
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
|
||||||
): ProcessorAction
|
): ProcessorAction
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,28 +95,28 @@ class MemberScopeTowerLevel(
|
|||||||
val bodyResolveComponents: BodyResolveComponents,
|
val bodyResolveComponents: BodyResolveComponents,
|
||||||
val dispatchReceiver: ReceiverValue,
|
val dispatchReceiver: ReceiverValue,
|
||||||
val implicitExtensionReceiver: ImplicitReceiverValue<*>? = null,
|
val implicitExtensionReceiver: ImplicitReceiverValue<*>? = null,
|
||||||
val invokeOnly: Boolean = false,
|
val implicitExtensionInvokeMode: Boolean = false,
|
||||||
val scopeSession: ScopeSession
|
val scopeSession: ScopeSession
|
||||||
) : SessionBasedTowerLevel(session) {
|
) : SessionBasedTowerLevel(session) {
|
||||||
private fun <T : AbstractFirBasedSymbol<*>> processMembers(
|
private fun <T : AbstractFirBasedSymbol<*>> processMembers(
|
||||||
output: TowerScopeLevel.TowerScopeLevelProcessor<T>,
|
output: TowerScopeLevel.TowerScopeLevelProcessor<T>,
|
||||||
explicitExtensionReceiver: ExpressionReceiverValue?,
|
explicitExtensionReceiver: ExpressionReceiverValue?,
|
||||||
isInvoke: Boolean,
|
|
||||||
processScopeMembers: FirScope.(processor: (T) -> ProcessorAction) -> ProcessorAction
|
processScopeMembers: FirScope.(processor: (T) -> ProcessorAction) -> ProcessorAction
|
||||||
): ProcessorAction {
|
): ProcessorAction {
|
||||||
if (implicitExtensionReceiver != null && explicitExtensionReceiver != null) return ProcessorAction.NEXT
|
if (implicitExtensionReceiver != null && explicitExtensionReceiver != null) return ProcessorAction.NEXT
|
||||||
val extensionReceiver = implicitExtensionReceiver ?: explicitExtensionReceiver
|
val extensionReceiver = implicitExtensionReceiver ?: explicitExtensionReceiver
|
||||||
val scope = dispatchReceiver.scope(session, scopeSession) ?: return ProcessorAction.NEXT
|
val scope = dispatchReceiver.scope(session, scopeSession) ?: return ProcessorAction.NEXT
|
||||||
if (scope.processScopeMembers { candidate ->
|
if (scope.processScopeMembers { candidate ->
|
||||||
if (candidate is FirCallableSymbol<*> && (invokeOnly || candidate.hasConsistentExtensionReceiver(extensionReceiver))) {
|
if (candidate is FirCallableSymbol<*> &&
|
||||||
|
(implicitExtensionInvokeMode || candidate.hasConsistentExtensionReceiver(extensionReceiver))
|
||||||
|
) {
|
||||||
// NB: we do not check dispatchReceiverValue != null here,
|
// NB: we do not check dispatchReceiverValue != null here,
|
||||||
// because of objects & constructors (see comments in dispatchReceiverValue() implementation)
|
// because of objects & constructors (see comments in dispatchReceiverValue() implementation)
|
||||||
val dispatchReceiverValue = candidate.dispatchReceiverValue()
|
val dispatchReceiverValue = candidate.dispatchReceiverValue()
|
||||||
if (invokeOnly) {
|
if (implicitExtensionInvokeMode) {
|
||||||
if (output.consumeCandidate(
|
if (output.consumeCandidate(
|
||||||
candidate, dispatchReceiverValue,
|
candidate, dispatchReceiverValue,
|
||||||
implicitExtensionReceiverValue = implicitExtensionReceiver,
|
implicitExtensionReceiverValue = implicitExtensionReceiver
|
||||||
builtInExtensionFunctionReceiverValue = null
|
|
||||||
).stop()
|
).stop()
|
||||||
) {
|
) {
|
||||||
ProcessorAction.STOP
|
ProcessorAction.STOP
|
||||||
@@ -130,27 +128,7 @@ class MemberScopeTowerLevel(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val builtInFunctionReceiverExpression =
|
output.consumeCandidate(candidate, dispatchReceiverValue, implicitExtensionReceiver, null)
|
||||||
if (!isInvoke || dispatchReceiver !is ExpressionReceiverValue) null
|
|
||||||
else (dispatchReceiver.explicitReceiverExpression as? FirQualifiedAccess)?.extensionReceiver
|
|
||||||
if (dispatchReceiver !is ExpressionReceiverValue ||
|
|
||||||
builtInFunctionReceiverExpression == null ||
|
|
||||||
builtInFunctionReceiverExpression is FirNoReceiverExpression
|
|
||||||
) {
|
|
||||||
output.consumeCandidate(candidate, dispatchReceiverValue, implicitExtensionReceiver, null)
|
|
||||||
} else {
|
|
||||||
if (output.consumeCandidate(candidate, dispatchReceiverValue, implicitExtensionReceiver, null).stop()) {
|
|
||||||
ProcessorAction.STOP
|
|
||||||
} else {
|
|
||||||
output.consumeCandidate(
|
|
||||||
candidate, dispatchReceiverValue,
|
|
||||||
implicitExtensionReceiverValue = null,
|
|
||||||
builtInExtensionFunctionReceiverValue = ExpressionReceiverValue(
|
|
||||||
builtInFunctionReceiverExpression, dispatchReceiver.typeProvider
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (candidate is FirClassLikeSymbol<*>) {
|
} else if (candidate is FirClassLikeSymbol<*>) {
|
||||||
output.consumeCandidate(candidate, null, implicitExtensionReceiver, null)
|
output.consumeCandidate(candidate, null, implicitExtensionReceiver, null)
|
||||||
@@ -172,18 +150,18 @@ class MemberScopeTowerLevel(
|
|||||||
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
|
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
|
||||||
): ProcessorAction {
|
): ProcessorAction {
|
||||||
val isInvoke = name == OperatorNameConventions.INVOKE && token == TowerScopeLevel.Token.Functions
|
val isInvoke = name == OperatorNameConventions.INVOKE && token == TowerScopeLevel.Token.Functions
|
||||||
if (invokeOnly && !isInvoke) {
|
if (implicitExtensionInvokeMode && !isInvoke) {
|
||||||
return ProcessorAction.NEXT
|
return ProcessorAction.NEXT
|
||||||
}
|
}
|
||||||
val explicitExtensionReceiver = if (dispatchReceiver == explicitReceiver) null else explicitReceiver
|
val explicitExtensionReceiver = if (dispatchReceiver == explicitReceiver) null else explicitReceiver
|
||||||
return when (token) {
|
return when (token) {
|
||||||
TowerScopeLevel.Token.Properties -> processMembers(processor, explicitExtensionReceiver, isInvoke) { symbol ->
|
TowerScopeLevel.Token.Properties -> processMembers(processor, explicitExtensionReceiver) { symbol ->
|
||||||
this.processPropertiesByName(name, symbol.cast())
|
this.processPropertiesByName(name, symbol.cast())
|
||||||
}
|
}
|
||||||
TowerScopeLevel.Token.Functions -> processMembers(processor, explicitExtensionReceiver, isInvoke) { symbol ->
|
TowerScopeLevel.Token.Functions -> processMembers(processor, explicitExtensionReceiver) { symbol ->
|
||||||
this.processFunctionsAndConstructorsByName(name, session, bodyResolveComponents, symbol.cast())
|
this.processFunctionsAndConstructorsByName(name, session, bodyResolveComponents, symbol.cast())
|
||||||
}
|
}
|
||||||
TowerScopeLevel.Token.Objects -> processMembers(processor, explicitExtensionReceiver, isInvoke) { symbol ->
|
TowerScopeLevel.Token.Objects -> processMembers(processor, explicitExtensionReceiver) { symbol ->
|
||||||
this.processClassifiersByName(name, symbol.cast())
|
this.processClassifiersByName(name, symbol.cast())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,8 +210,7 @@ class ScopeTowerLevel(
|
|||||||
}
|
}
|
||||||
processor.consumeCandidate(
|
processor.consumeCandidate(
|
||||||
candidate as T, dispatchReceiverValue = dispatchReceiverValue,
|
candidate as T, dispatchReceiverValue = dispatchReceiverValue,
|
||||||
implicitExtensionReceiverValue = implicitExtensionReceiver,
|
implicitExtensionReceiverValue = implicitExtensionReceiver
|
||||||
builtInExtensionFunctionReceiverValue = null
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
ProcessorAction.NEXT
|
ProcessorAction.NEXT
|
||||||
@@ -247,8 +224,7 @@ class ScopeTowerLevel(
|
|||||||
if (candidate.hasConsistentReceivers(extensionReceiver)) {
|
if (candidate.hasConsistentReceivers(extensionReceiver)) {
|
||||||
processor.consumeCandidate(
|
processor.consumeCandidate(
|
||||||
candidate as T, dispatchReceiverValue = candidate.dispatchReceiverValue(),
|
candidate as T, dispatchReceiverValue = candidate.dispatchReceiverValue(),
|
||||||
implicitExtensionReceiverValue = implicitExtensionReceiver,
|
implicitExtensionReceiverValue = implicitExtensionReceiver
|
||||||
builtInExtensionFunctionReceiverValue = null
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
ProcessorAction.NEXT
|
ProcessorAction.NEXT
|
||||||
@@ -257,8 +233,7 @@ class ScopeTowerLevel(
|
|||||||
TowerScopeLevel.Token.Objects -> scope.processClassifiersByName(name) {
|
TowerScopeLevel.Token.Objects -> scope.processClassifiersByName(name) {
|
||||||
processor.consumeCandidate(
|
processor.consumeCandidate(
|
||||||
it as T, dispatchReceiverValue = null,
|
it as T, dispatchReceiverValue = null,
|
||||||
implicitExtensionReceiverValue = null,
|
implicitExtensionReceiverValue = null
|
||||||
builtInExtensionFunctionReceiverValue = null
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ fun <T> fooT2() : (t : T) -> T {
|
|||||||
fun main(args : Array<String>) {
|
fun main(args : Array<String>) {
|
||||||
args.foo()()
|
args.foo()()
|
||||||
<!INAPPLICABLE_CANDIDATE!>args.foo1()()<!>
|
<!INAPPLICABLE_CANDIDATE!>args.foo1()()<!>
|
||||||
<!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>a<!>.foo1()()
|
<!INAPPLICABLE_CANDIDATE!><!UNRESOLVED_REFERENCE!>a<!>.foo1()()<!>
|
||||||
<!UNRESOLVED_REFERENCE!>a<!>.foo1()(<!UNRESOLVED_REFERENCE!>a<!>)
|
<!UNRESOLVED_REFERENCE!>a<!>.foo1()(<!UNRESOLVED_REFERENCE!>a<!>)
|
||||||
|
|
||||||
args.foo1()(1)
|
args.foo1()(1)
|
||||||
|
|||||||
Vendored
+1
-1
@@ -59,7 +59,7 @@ fun test(a: A, b: B) {
|
|||||||
|
|
||||||
b.(foo)()
|
b.(foo)()
|
||||||
|
|
||||||
(b.foo)()
|
<!INAPPLICABLE_CANDIDATE!>(b.foo)()<!>
|
||||||
|
|
||||||
foo(b)
|
foo(b)
|
||||||
(foo)(b)
|
(foo)(b)
|
||||||
|
|||||||
Reference in New Issue
Block a user