FIR: Simplify callable references resolution
Also that fixes some bugs
This commit is contained in:
+2
-2
@@ -34,9 +34,9 @@ fun main() {
|
|||||||
<!AMBIGUITY!>foo3<!>(KotlinClass::baz)
|
<!AMBIGUITY!>foo3<!>(KotlinClass::baz)
|
||||||
|
|
||||||
// Type mismatch
|
// Type mismatch
|
||||||
foo1(KotlinClass::bar)
|
<!INAPPLICABLE_CANDIDATE!>foo1<!>(<!UNRESOLVED_REFERENCE!>KotlinClass::bar<!>)
|
||||||
foo2(KotlinClass::bar)
|
foo2(KotlinClass::bar)
|
||||||
<!AMBIGUITY!>foo3<!>(KotlinClass::bar)
|
foo3(KotlinClass::bar)
|
||||||
|
|
||||||
foo1(KotlinClass2::bar)
|
foo1(KotlinClass2::bar)
|
||||||
// Type mismatch
|
// Type mismatch
|
||||||
|
|||||||
+5
-5
@@ -50,13 +50,13 @@ FILE: main.kt
|
|||||||
public final fun foo3(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
|
public final fun foo3(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
|
||||||
}
|
}
|
||||||
public final fun main(): R|kotlin/Unit| {
|
public final fun main(): R|kotlin/Unit| {
|
||||||
R|/foo1|(Q|KotlinClass|::R|/KotlinClass.baz|)
|
R|/foo1|(Q|KotlinClass|::R|/KotlinClass.Companion.baz|)
|
||||||
R|/foo2|(Q|KotlinClass|::R|/KotlinClass.baz|)
|
R|/foo2|(Q|KotlinClass|::R|/KotlinClass.baz|)
|
||||||
<Ambiguity: foo3, [/foo3, /foo3]>#(Q|KotlinClass|::R|/KotlinClass.baz|)
|
<Ambiguity: foo3, [/foo3, /foo3]>#(Q|KotlinClass|::R|/KotlinClass.baz|)
|
||||||
R|/foo1|(Q|KotlinClass|::R|/JavaClass.bar|)
|
<Inapplicable(INAPPLICABLE): /foo1>#(Q|KotlinClass|::<Unresolved reference: bar>#)
|
||||||
R|/foo2|(Q|KotlinClass|::R|/JavaClass.bar|)
|
R|/foo2|(Q|KotlinClass|::R|/JavaClass.bar|)
|
||||||
<Ambiguity: foo3, [/foo3, /foo3]>#(Q|KotlinClass|::R|/JavaClass.bar|)
|
R|/foo3|(Q|KotlinClass|::R|/JavaClass.bar|)
|
||||||
R|/foo1|(Q|KotlinClass2|::R|/KotlinClass2.bar|)
|
R|/foo1|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|)
|
||||||
<Inapplicable(INAPPLICABLE): /foo2>#(Q|KotlinClass2|::<Unresolved reference: bar>#)
|
<Inapplicable(INAPPLICABLE): /foo2>#(Q|KotlinClass2|::<Unresolved reference: bar>#)
|
||||||
R|/foo3|(Q|KotlinClass2|::R|/KotlinClass2.bar|)
|
R|/foo3|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionStub
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedReifiedParameterReference
|
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedReifiedParameterReference
|
||||||
import org.jetbrains.kotlin.fir.references.*
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildBackingFieldReference
|
import org.jetbrains.kotlin.fir.references.builder.buildBackingFieldReference
|
||||||
@@ -400,7 +399,9 @@ class FirCallResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (constructorSymbol == null) return null
|
if (constructorSymbol == null) return null
|
||||||
val candidate = CandidateFactory(transformer.resolutionContext, callInfo).createCandidate(
|
val candidateFactory = CandidateFactory(transformer.resolutionContext, callInfo)
|
||||||
|
val candidate = candidateFactory.createCandidate(
|
||||||
|
callInfo,
|
||||||
constructorSymbol!!,
|
constructorSymbol!!,
|
||||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||||
scope = null
|
scope = null
|
||||||
@@ -471,12 +472,6 @@ class FirCallResolver(
|
|||||||
expectedType,
|
expectedType,
|
||||||
outerConstraintSystemBuilder,
|
outerConstraintSystemBuilder,
|
||||||
lhs,
|
lhs,
|
||||||
stubReceiver = if (lhs !is DoubleColonLHS.Type) null else buildExpressionStub {
|
|
||||||
source = callableReferenceAccess.source
|
|
||||||
typeRef = buildResolvedTypeRef {
|
|
||||||
type = lhs.type
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,7 +542,7 @@ class FirCallResolver(
|
|||||||
source: FirSourceElement?,
|
source: FirSourceElement?,
|
||||||
name: Name
|
name: Name
|
||||||
): FirErrorReferenceWithCandidate {
|
): FirErrorReferenceWithCandidate {
|
||||||
val candidate = CandidateFactory(transformer.resolutionContext, callInfo).createErrorCandidate(diagnostic)
|
val candidate = CandidateFactory(transformer.resolutionContext, callInfo).createErrorCandidate(callInfo, diagnostic)
|
||||||
components.resolutionStageRunner.processCandidate(candidate, transformer.resolutionContext, stopOnFirstError = false)
|
components.resolutionStageRunner.processCandidate(candidate, transformer.resolutionContext, stopOnFirstError = false)
|
||||||
return FirErrorReferenceWithCandidate(source, name, candidate, diagnostic)
|
return FirErrorReferenceWithCandidate(source, name, candidate, diagnostic)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,16 +52,12 @@ data class CallInfo(
|
|||||||
// Four 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 arguments: List<FirExpression> get() = argumentList.arguments
|
val arguments: List<FirExpression> get() = argumentList.arguments
|
||||||
|
|
||||||
val argumentCount get() = arguments.size
|
val argumentCount get() = arguments.size
|
||||||
|
|
||||||
fun noStubReceiver(): CallInfo =
|
|
||||||
if (stubReceiver == null) this else copy(stubReceiver = null)
|
|
||||||
|
|
||||||
fun replaceWithVariableAccess(): CallInfo =
|
fun replaceWithVariableAccess(): CallInfo =
|
||||||
copy(callKind = CallKind.VariableAccess, typeArguments = emptyList(), argumentList = FirEmptyArgumentList)
|
copy(callKind = CallKind.VariableAccess, typeArguments = emptyList(), argumentList = FirEmptyArgumentList)
|
||||||
|
|
||||||
|
|||||||
+3
-11
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
|||||||
|
|
||||||
class CandidateFactory private constructor(
|
class CandidateFactory private constructor(
|
||||||
val context: ResolutionContext,
|
val context: ResolutionContext,
|
||||||
val callInfo: CallInfo,
|
|
||||||
private val baseSystem: ConstraintStorage
|
private val baseSystem: ConstraintStorage
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@@ -37,17 +36,10 @@ class CandidateFactory private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(context: ResolutionContext, callInfo: CallInfo) :
|
constructor(context: ResolutionContext, callInfo: CallInfo) : this(context, buildBaseSystem(context, callInfo))
|
||||||
this(context, callInfo, buildBaseSystem(context, callInfo))
|
|
||||||
|
|
||||||
fun replaceCallInfo(callInfo: CallInfo): CandidateFactory {
|
|
||||||
if (this.callInfo.arguments.size != callInfo.arguments.size) {
|
|
||||||
throw AssertionError("Incorrect replacement of call info in CandidateFactory")
|
|
||||||
}
|
|
||||||
return CandidateFactory(context, callInfo, baseSystem)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createCandidate(
|
fun createCandidate(
|
||||||
|
callInfo: CallInfo,
|
||||||
symbol: AbstractFirBasedSymbol<*>,
|
symbol: AbstractFirBasedSymbol<*>,
|
||||||
explicitReceiverKind: ExplicitReceiverKind,
|
explicitReceiverKind: ExplicitReceiverKind,
|
||||||
scope: FirScope?,
|
scope: FirScope?,
|
||||||
@@ -65,7 +57,7 @@ class CandidateFactory private constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createErrorCandidate(diagnostic: ConeDiagnostic): Candidate {
|
fun createErrorCandidate(callInfo: CallInfo, diagnostic: ConeDiagnostic): Candidate {
|
||||||
val symbol: AbstractFirBasedSymbol<*> = when (callInfo.callKind) {
|
val symbol: AbstractFirBasedSymbol<*> = when (callInfo.callKind) {
|
||||||
is CallKind.VariableAccess -> createErrorPropertySymbol(diagnostic)
|
is CallKind.VariableAccess -> createErrorPropertySymbol(diagnostic)
|
||||||
is CallKind.Function,
|
is CallKind.Function,
|
||||||
|
|||||||
-4
@@ -245,7 +245,6 @@ internal class FirInvokeResolveTowerExtension(
|
|||||||
receiverGroup,
|
receiverGroup,
|
||||||
candidateFactoriesAndCollectors.resultCollector,
|
candidateFactoriesAndCollectors.resultCollector,
|
||||||
candidateFactory,
|
candidateFactory,
|
||||||
candidateFactoriesAndCollectors.stubReceiverCandidateFactory
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +306,6 @@ private class InvokeReceiverResolveTask(
|
|||||||
towerDataElementsForName,
|
towerDataElementsForName,
|
||||||
collector,
|
collector,
|
||||||
candidateFactory,
|
candidateFactory,
|
||||||
stubReceiverCandidateFactory = null
|
|
||||||
) {
|
) {
|
||||||
override fun interceptTowerGroup(towerGroup: TowerGroup): TowerGroup =
|
override fun interceptTowerGroup(towerGroup: TowerGroup): TowerGroup =
|
||||||
towerGroup.InvokeResolvePriority(InvokeResolvePriority.INVOKE_RECEIVER)
|
towerGroup.InvokeResolvePriority(InvokeResolvePriority.INVOKE_RECEIVER)
|
||||||
@@ -324,14 +322,12 @@ private class InvokeFunctionResolveTask(
|
|||||||
private val receiverGroup: TowerGroup,
|
private val receiverGroup: TowerGroup,
|
||||||
collector: CandidateCollector,
|
collector: CandidateCollector,
|
||||||
candidateFactory: CandidateFactory,
|
candidateFactory: CandidateFactory,
|
||||||
stubReceiverCandidateFactory: CandidateFactory? = null
|
|
||||||
) : FirBaseTowerResolveTask(
|
) : FirBaseTowerResolveTask(
|
||||||
components,
|
components,
|
||||||
manager,
|
manager,
|
||||||
towerDataElementsForName,
|
towerDataElementsForName,
|
||||||
collector,
|
collector,
|
||||||
candidateFactory,
|
candidateFactory,
|
||||||
stubReceiverCandidateFactory
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun interceptTowerGroup(towerGroup: TowerGroup): TowerGroup =
|
override fun interceptTowerGroup(towerGroup: TowerGroup): TowerGroup =
|
||||||
|
|||||||
+17
-9
@@ -9,12 +9,15 @@ import org.jetbrains.kotlin.fir.asReversedFrozen
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionStub
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirTowerDataContext
|
import org.jetbrains.kotlin.fir.resolve.FirTowerDataContext
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
@@ -53,8 +56,7 @@ internal abstract class FirBaseTowerResolveTask(
|
|||||||
private val manager: TowerResolveManager,
|
private val manager: TowerResolveManager,
|
||||||
protected val towerDataElementsForName: TowerDataElementsForName,
|
protected val towerDataElementsForName: TowerDataElementsForName,
|
||||||
private val collector: CandidateCollector,
|
private val collector: CandidateCollector,
|
||||||
private val candidateFactory: CandidateFactory,
|
private val candidateFactory: CandidateFactory
|
||||||
private val stubReceiverCandidateFactory: CandidateFactory? = null
|
|
||||||
) {
|
) {
|
||||||
protected val session get() = components.session
|
protected val session get() = components.session
|
||||||
|
|
||||||
@@ -131,7 +133,6 @@ internal abstract class FirBaseTowerResolveTask(
|
|||||||
val result = handler.handleLevel(
|
val result = handler.handleLevel(
|
||||||
collector,
|
collector,
|
||||||
candidateFactory,
|
candidateFactory,
|
||||||
stubReceiverCandidateFactory,
|
|
||||||
callInfo,
|
callInfo,
|
||||||
explicitReceiverKind,
|
explicitReceiverKind,
|
||||||
finalGroup,
|
finalGroup,
|
||||||
@@ -149,14 +150,12 @@ internal open class FirTowerResolveTask(
|
|||||||
towerDataElementsForName: TowerDataElementsForName,
|
towerDataElementsForName: TowerDataElementsForName,
|
||||||
collector: CandidateCollector,
|
collector: CandidateCollector,
|
||||||
candidateFactory: CandidateFactory,
|
candidateFactory: CandidateFactory,
|
||||||
stubReceiverCandidateFactory: CandidateFactory? = null
|
|
||||||
) : FirBaseTowerResolveTask(
|
) : FirBaseTowerResolveTask(
|
||||||
components,
|
components,
|
||||||
manager,
|
manager,
|
||||||
towerDataElementsForName,
|
towerDataElementsForName,
|
||||||
collector,
|
collector,
|
||||||
candidateFactory,
|
candidateFactory,
|
||||||
stubReceiverCandidateFactory
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend fun runResolverForQualifierReceiver(
|
suspend fun runResolverForQualifierReceiver(
|
||||||
@@ -178,8 +177,17 @@ internal open class FirTowerResolveTask(
|
|||||||
|
|
||||||
if (resolvedQualifier.symbol != null) {
|
if (resolvedQualifier.symbol != null) {
|
||||||
val typeRef = resolvedQualifier.typeRef
|
val typeRef = resolvedQualifier.typeRef
|
||||||
if (info.callKind == CallKind.CallableReference && info.stubReceiver != null ) {
|
if (info.callKind == CallKind.CallableReference && info.lhs is DoubleColonLHS.Type) {
|
||||||
runResolverForExpressionReceiver(info, info.stubReceiver, parentGroup = TowerGroup.QualifierValue)
|
val stubReceiver = buildExpressionStub {
|
||||||
|
source = info.explicitReceiver?.source
|
||||||
|
this.typeRef = buildResolvedTypeRef {
|
||||||
|
type = info.lhs.type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val stubReceiverInfo = info.replaceExplicitReceiver(stubReceiver)
|
||||||
|
|
||||||
|
runResolverForExpressionReceiver(stubReceiverInfo, stubReceiver, parentGroup = TowerGroup.QualifierValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NB: yet built-in Unit is used for "no-value" type
|
// NB: yet built-in Unit is used for "no-value" type
|
||||||
@@ -197,7 +205,7 @@ internal open class FirTowerResolveTask(
|
|||||||
val callableScope = qualifierReceiver.callableScope() ?: return
|
val callableScope = qualifierReceiver.callableScope() ?: return
|
||||||
processLevel(
|
processLevel(
|
||||||
callableScope.toScopeTowerLevel(includeInnerConstructors = false),
|
callableScope.toScopeTowerLevel(includeInnerConstructors = false),
|
||||||
info.noStubReceiver(), TowerGroup.Qualifier
|
info, TowerGroup.Qualifier
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,7 +220,7 @@ internal open class FirTowerResolveTask(
|
|||||||
val scope = qualifierReceiver.classifierScope() ?: return
|
val scope = qualifierReceiver.classifierScope() ?: return
|
||||||
val group = if (prioritized) TowerGroup.ClassifierPrioritized else TowerGroup.Classifier
|
val group = if (prioritized) TowerGroup.ClassifierPrioritized else TowerGroup.Classifier
|
||||||
processLevel(
|
processLevel(
|
||||||
scope.toScopeTowerLevel(includeInnerConstructors = false), info.noStubReceiver(),
|
scope.toScopeTowerLevel(includeInnerConstructors = false), info,
|
||||||
group
|
group
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-8
@@ -52,7 +52,6 @@ class FirTowerResolver(
|
|||||||
TowerDataElementsForName(info.name, components.towerDataContext),
|
TowerDataElementsForName(info.name, components.towerDataContext),
|
||||||
candidateFactoriesAndCollectors.resultCollector,
|
candidateFactoriesAndCollectors.resultCollector,
|
||||||
candidateFactoriesAndCollectors.candidateFactory,
|
candidateFactoriesAndCollectors.candidateFactory,
|
||||||
candidateFactoriesAndCollectors.stubReceiverCandidateFactory
|
|
||||||
)
|
)
|
||||||
when (val receiver = info.explicitReceiver) {
|
when (val receiver = info.explicitReceiver) {
|
||||||
is FirResolvedQualifier -> {
|
is FirResolvedQualifier -> {
|
||||||
@@ -103,6 +102,7 @@ class FirTowerResolver(
|
|||||||
resultCollector.consumeCandidate(
|
resultCollector.consumeCandidate(
|
||||||
TowerGroup.Member,
|
TowerGroup.Member,
|
||||||
candidateFactory.createCandidate(
|
candidateFactory.createCandidate(
|
||||||
|
info,
|
||||||
it,
|
it,
|
||||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||||
scope,
|
scope,
|
||||||
@@ -123,16 +123,10 @@ class FirTowerResolver(
|
|||||||
context: ResolutionContext
|
context: ResolutionContext
|
||||||
): CandidateFactoriesAndCollectors {
|
): CandidateFactoriesAndCollectors {
|
||||||
val candidateFactory = CandidateFactory(context, info)
|
val candidateFactory = CandidateFactory(context, info)
|
||||||
val stubReceiverCandidateFactory =
|
|
||||||
if (info.callKind == CallKind.CallableReference && info.stubReceiver != null)
|
|
||||||
candidateFactory.replaceCallInfo(info.replaceExplicitReceiver(info.stubReceiver))
|
|
||||||
else
|
|
||||||
null
|
|
||||||
|
|
||||||
return CandidateFactoriesAndCollectors(
|
return CandidateFactoriesAndCollectors(
|
||||||
candidateFactory,
|
candidateFactory,
|
||||||
collector,
|
collector
|
||||||
stubReceiverCandidateFactory
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-25
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls.tower
|
package org.jetbrains.kotlin.fir.resolve.calls.tower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
@@ -18,7 +17,6 @@ import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeStarProjection
|
import org.jetbrains.kotlin.fir.types.ConeStarProjection
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.fir.types.constructClassType
|
import org.jetbrains.kotlin.fir.types.constructClassType
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
@@ -27,9 +25,6 @@ internal class CandidateFactoriesAndCollectors(
|
|||||||
// Common calls
|
// Common calls
|
||||||
val candidateFactory: CandidateFactory,
|
val candidateFactory: CandidateFactory,
|
||||||
val resultCollector: CandidateCollector,
|
val resultCollector: CandidateCollector,
|
||||||
|
|
||||||
// Callable references
|
|
||||||
val stubReceiverCandidateFactory: CandidateFactory?,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -41,7 +36,6 @@ internal class TowerLevelHandler {
|
|||||||
fun handleLevel(
|
fun handleLevel(
|
||||||
collector: CandidateCollector,
|
collector: CandidateCollector,
|
||||||
candidateFactory: CandidateFactory,
|
candidateFactory: CandidateFactory,
|
||||||
stubReceiverCandidateFactory: CandidateFactory? = null,
|
|
||||||
info: CallInfo,
|
info: CallInfo,
|
||||||
explicitReceiverKind: ExplicitReceiverKind,
|
explicitReceiverKind: ExplicitReceiverKind,
|
||||||
group: TowerGroup,
|
group: TowerGroup,
|
||||||
@@ -50,7 +44,7 @@ internal class TowerLevelHandler {
|
|||||||
processResult = ProcessorAction.NONE
|
processResult = ProcessorAction.NONE
|
||||||
val processor =
|
val processor =
|
||||||
TowerScopeLevelProcessor(
|
TowerScopeLevelProcessor(
|
||||||
info.explicitReceiver,
|
info,
|
||||||
explicitReceiverKind,
|
explicitReceiverKind,
|
||||||
collector,
|
collector,
|
||||||
candidateFactory,
|
candidateFactory,
|
||||||
@@ -69,22 +63,7 @@ internal class TowerLevelHandler {
|
|||||||
towerLevel.processFunctions(info.name, processor)
|
towerLevel.processFunctions(info.name, processor)
|
||||||
}
|
}
|
||||||
CallKind.CallableReference -> {
|
CallKind.CallableReference -> {
|
||||||
val stubReceiver = info.stubReceiver
|
towerLevel.processFunctionsAndProperties(info.name, processor)
|
||||||
if (stubReceiver != null) {
|
|
||||||
val stubProcessor = TowerScopeLevelProcessor(
|
|
||||||
info.explicitReceiver,
|
|
||||||
explicitReceiverKind,
|
|
||||||
collector,
|
|
||||||
stubReceiverCandidateFactory!!, group
|
|
||||||
)
|
|
||||||
towerLevel.processFunctionsAndProperties(info.name, stubProcessor)
|
|
||||||
// NB: we don't perform this for implicit Unit
|
|
||||||
if (!collector.isSuccess() && info.explicitReceiver?.typeRef !is FirImplicitBuiltinTypeRef) {
|
|
||||||
towerLevel.processFunctionsAndProperties(info.name, processor)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
towerLevel.processFunctionsAndProperties(info.name, processor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
|
throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
|
||||||
@@ -135,7 +114,7 @@ internal class TowerLevelHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class TowerScopeLevelProcessor(
|
private class TowerScopeLevelProcessor(
|
||||||
val explicitReceiver: FirExpression?,
|
val callInfo: CallInfo,
|
||||||
val explicitReceiverKind: ExplicitReceiverKind,
|
val explicitReceiverKind: ExplicitReceiverKind,
|
||||||
val resultCollector: CandidateCollector,
|
val resultCollector: CandidateCollector,
|
||||||
val candidateFactory: CandidateFactory,
|
val candidateFactory: CandidateFactory,
|
||||||
@@ -151,7 +130,7 @@ private class TowerScopeLevelProcessor(
|
|||||||
// Check explicit extension receiver for default package members
|
// Check explicit extension receiver for default package members
|
||||||
if (symbol is FirNamedFunctionSymbol && dispatchReceiverValue == null &&
|
if (symbol is FirNamedFunctionSymbol && dispatchReceiverValue == null &&
|
||||||
extensionReceiverValue != null &&
|
extensionReceiverValue != null &&
|
||||||
explicitReceiver !is FirResolvedQualifier &&
|
callInfo.explicitReceiver !is FirResolvedQualifier &&
|
||||||
symbol.callableId.packageName.startsWith(defaultPackage)
|
symbol.callableId.packageName.startsWith(defaultPackage)
|
||||||
) {
|
) {
|
||||||
val extensionReceiverType = extensionReceiverValue.type as? ConeClassLikeType
|
val extensionReceiverType = extensionReceiverValue.type as? ConeClassLikeType
|
||||||
@@ -175,6 +154,7 @@ private class TowerScopeLevelProcessor(
|
|||||||
// ---
|
// ---
|
||||||
resultCollector.consumeCandidate(
|
resultCollector.consumeCandidate(
|
||||||
group, candidateFactory.createCandidate(
|
group, candidateFactory.createCandidate(
|
||||||
|
callInfo,
|
||||||
symbol,
|
symbol,
|
||||||
explicitReceiverKind,
|
explicitReceiverKind,
|
||||||
scope,
|
scope,
|
||||||
|
|||||||
+5
-2
@@ -172,12 +172,15 @@ class FirSyntheticCallGenerator(
|
|||||||
return FirNamedReferenceWithCandidate(null, name, candidate)
|
return FirNamedReferenceWithCandidate(null, name, candidate)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateCandidate(callInfo: CallInfo, function: FirSimpleFunction, context: ResolutionContext): Candidate =
|
private fun generateCandidate(callInfo: CallInfo, function: FirSimpleFunction, context: ResolutionContext): Candidate {
|
||||||
CandidateFactory(context, callInfo).createCandidate(
|
val candidateFactory = CandidateFactory(context, callInfo)
|
||||||
|
return candidateFactory.createCandidate(
|
||||||
|
callInfo,
|
||||||
symbol = function.symbol,
|
symbol = function.symbol,
|
||||||
explicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
explicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||||
scope = null
|
scope = null
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun generateCallInfo(name: Name, argumentList: FirArgumentList, callKind: CallKind) = CallInfo(
|
private fun generateCallInfo(name: Name, argumentList: FirArgumentList, callKind: CallKind) = CallInfo(
|
||||||
callKind = callKind,
|
callKind = callKind,
|
||||||
|
|||||||
-1
@@ -1,7 +1,6 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
// DONT_TARGET_EXACT_BACKEND: WASM
|
||||||
// WASM_MUTE_REASON: BINDING_RECEIVERS
|
// WASM_MUTE_REASON: BINDING_RECEIVERS
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ fun testA(a: A) {
|
|||||||
|
|
||||||
fun testB(b: B) {
|
fun testB(b: B) {
|
||||||
val call1 = call(B::foo)
|
val call1 = call(B::foo)
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>call1<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>call1<!>
|
||||||
|
|
||||||
val call2 = call(B()::foo)
|
val call2 = call(B()::foo)
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>call2<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>call2<!>
|
||||||
|
|||||||
Vendored
+1
-1
@@ -186,7 +186,7 @@ fun main() {
|
|||||||
// Should be error as `A3::foo1` is `KFunction2`, but the remaining arguments are `KFuncion1` or `Function1`
|
// Should be error as `A3::foo1` is `KFunction2`, but the remaining arguments are `KFuncion1` or `Function1`
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function<kotlin.Any>")!>select(A3(), <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<A3, kotlin.Int, kotlin.Unit>")!>A3::foo1<!>, { a -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>a<!> }, { it -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> })<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function<kotlin.Any>")!>select(A3(), <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<A3, kotlin.Int, kotlin.Unit>")!>A3::foo1<!>, { a -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>a<!> }, { it -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> })<!>
|
||||||
// It's OK because `A3::foo2` is from companion of `A3`
|
// It's OK because `A3::foo2` is from companion of `A3`
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function<kotlin.Any>")!>select(A3(), <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction2<A3, kotlin.Int, kotlin.Unit>")!>A3::foo2<!>, { a -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>a<!> }, { it -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> })<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.Int, kotlin.Any>")!>select(A3(), <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit>")!>A3::foo2<!>, { a -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>a<!> }, { it -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>it<!> })<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.Int, kotlin.Comparable<*> & java.io.Serializable>")!>select(A4(), { x: Number -> "" })<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.Int, kotlin.Comparable<*> & java.io.Serializable>")!>select(A4(), { x: Number -> "" })<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function2<kotlin.Int, kotlin.Int, kotlin.Comparable<*> & java.io.Serializable>")!>select(A5<Int, Int>(), { x: Number, y: Int -> "" })<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function2<kotlin.Int, kotlin.Int, kotlin.Comparable<*> & java.io.Serializable>")!>select(A5<Int, Int>(), { x: Number, y: Int -> "" })<!>
|
||||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function3<kotlin.Int, kotlin.String, kotlin.Float, kotlin.Float>")!>select(A2(), id { a, b, c -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>a<!>; <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>b<!>; <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>c<!> })<!>
|
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function3<kotlin.Int, kotlin.String, kotlin.Float, kotlin.Float>")!>select(A2(), id { a, b, c -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>a<!>; <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>b<!>; <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>c<!> })<!>
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ import libCase1.*
|
|||||||
import kotlin.text.format
|
import kotlin.text.format
|
||||||
|
|
||||||
fun case1() {
|
fun case1() {
|
||||||
val y2 : () ->String =(String)::format
|
val y2 : () ->String =<!UNRESOLVED_REFERENCE!>(String)::format<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILE: LibCase1.kt
|
// FILE: LibCase1.kt
|
||||||
|
|||||||
+1
@@ -65,6 +65,7 @@ class SingleCandidateResolver(
|
|||||||
val resolutionContext = stubBodyResolveTransformer.resolutionContext
|
val resolutionContext = stubBodyResolveTransformer.resolutionContext
|
||||||
|
|
||||||
val candidate = CandidateFactory(resolutionContext, callInfo).createCandidate(
|
val candidate = CandidateFactory(resolutionContext, callInfo).createCandidate(
|
||||||
|
callInfo,
|
||||||
resolutionParameters.callableSymbol,
|
resolutionParameters.callableSymbol,
|
||||||
explicitReceiverKind = explicitReceiverKind,
|
explicitReceiverKind = explicitReceiverKind,
|
||||||
dispatchReceiverValue = dispatchReceiverValue,
|
dispatchReceiverValue = dispatchReceiverValue,
|
||||||
|
|||||||
Reference in New Issue
Block a user