Refactoring & clarification: implement new FIR tower resolver
This commit is contained in:
@@ -209,9 +209,7 @@ class FirCallResolver(
|
|||||||
typeArguments.addAll(qualifiedAccess.typeArguments)
|
typeArguments.addAll(qualifiedAccess.typeArguments)
|
||||||
resultType = if (classId.isLocal) {
|
resultType = if (classId.isLocal) {
|
||||||
typeForQualifierByDeclaration(referencedSymbol.fir, resultType, session)
|
typeForQualifierByDeclaration(referencedSymbol.fir, resultType, session)
|
||||||
?: resultType.resolvedTypeFromPrototype(
|
?: session.builtinTypes.unitType
|
||||||
session.builtinTypes.unitType.type//StandardClassIds.Unit(symbolProvider).constructType(emptyArray(), isNullable = false)
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
typeForQualifier(this)
|
typeForQualifier(this)
|
||||||
}
|
}
|
||||||
@@ -252,7 +250,8 @@ class FirCallResolver(
|
|||||||
val result = towerResolver.runResolver(
|
val result = towerResolver.runResolver(
|
||||||
implicitReceiverStack.receiversAsReversed(),
|
implicitReceiverStack.receiversAsReversed(),
|
||||||
info,
|
info,
|
||||||
collector = CandidateCollector(this, resolutionStageRunner)
|
collector = CandidateCollector(this, resolutionStageRunner),
|
||||||
|
manager = TowerResolveManager(towerResolver)
|
||||||
)
|
)
|
||||||
val bestCandidates = result.bestCandidates()
|
val bestCandidates = result.bestCandidates()
|
||||||
val noSuccessfulCandidates = result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED
|
val noSuccessfulCandidates = result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED
|
||||||
@@ -316,7 +315,7 @@ class FirCallResolver(
|
|||||||
|
|
||||||
fun <T> selectCandidateFromGivenCandidates(call: T, name: Name, candidates: Collection<Candidate>): T where T : FirResolvable, T : FirCall {
|
fun <T> selectCandidateFromGivenCandidates(call: T, name: Name, candidates: Collection<Candidate>): T where T : FirResolvable, T : FirCall {
|
||||||
val result = CandidateCollector(this, resolutionStageRunner)
|
val result = CandidateCollector(this, resolutionStageRunner)
|
||||||
candidates.forEach { result.consumeCandidate(0, it) }
|
candidates.forEach { result.consumeCandidate(TowerGroup.Start, it) }
|
||||||
val bestCandidates = result.bestCandidates()
|
val bestCandidates = result.bestCandidates()
|
||||||
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||||
bestCandidates.toSet()
|
bestCandidates.toSet()
|
||||||
|
|||||||
@@ -325,9 +325,7 @@ fun BodyResolveComponents.typeForQualifier(resolvedQualifier: FirResolvedQualifi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Handle no value type here
|
// TODO: Handle no value type here
|
||||||
return resultType.resolvedTypeFromPrototype(
|
return session.builtinTypes.unitType
|
||||||
session.builtinTypes.unitType.type
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun typeForReifiedParameterReference(parameterReference: FirResolvedReifiedParameterReference): FirTypeRef {
|
internal fun typeForReifiedParameterReference(parameterReference: FirResolvedReifiedParameterReference): FirTypeRef {
|
||||||
@@ -361,7 +359,8 @@ internal fun typeForQualifierByDeclaration(declaration: FirDeclaration, resultTy
|
|||||||
fun <T : FirResolvable> BodyResolveComponents.typeFromCallee(access: T): FirResolvedTypeRef {
|
fun <T : FirResolvable> BodyResolveComponents.typeFromCallee(access: T): FirResolvedTypeRef {
|
||||||
val makeNullable: Boolean by lazy {
|
val makeNullable: Boolean by lazy {
|
||||||
if (access is FirQualifiedAccess && access.safe) {
|
if (access is FirQualifiedAccess && access.safe) {
|
||||||
val explicitReceiver = access.explicitReceiver!!
|
val explicitReceiver = access.explicitReceiver
|
||||||
|
?: throw AssertionError("Safe call without explicit receiver: ${access.render()}")
|
||||||
val receiverResultType = explicitReceiver.resultType
|
val receiverResultType = explicitReceiver.resultType
|
||||||
if (receiverResultType is FirResolvedTypeRef) {
|
if (receiverResultType is FirResolvedTypeRef) {
|
||||||
receiverResultType.type.isNullable
|
receiverResultType.type.isNullable
|
||||||
|
|||||||
@@ -46,22 +46,28 @@ data class CallInfo(
|
|||||||
) {
|
) {
|
||||||
val argumentCount get() = arguments.size
|
val argumentCount get() = arguments.size
|
||||||
|
|
||||||
|
fun noStubReceiver(): CallInfo =
|
||||||
|
if (stubReceiver == null) this else CallInfo(
|
||||||
|
callKind, name, explicitReceiver, arguments,
|
||||||
|
isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, null
|
||||||
|
)
|
||||||
|
|
||||||
fun replaceWithVariableAccess(): CallInfo =
|
fun replaceWithVariableAccess(): CallInfo =
|
||||||
CallInfo(
|
CallInfo(
|
||||||
CallKind.VariableAccess, name, explicitReceiver, emptyList(),
|
CallKind.VariableAccess, name, explicitReceiver, emptyList(),
|
||||||
isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs
|
isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, stubReceiver
|
||||||
)
|
)
|
||||||
|
|
||||||
fun replaceExplicitReceiver(explicitReceiver: FirExpression): CallInfo =
|
fun replaceExplicitReceiver(explicitReceiver: FirExpression?): CallInfo =
|
||||||
CallInfo(
|
CallInfo(
|
||||||
callKind, name, explicitReceiver, arguments,
|
callKind, name, explicitReceiver, arguments,
|
||||||
isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs
|
isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, stubReceiver
|
||||||
)
|
)
|
||||||
|
|
||||||
fun withReceiverAsArgument(receiverExpression: FirExpression): CallInfo =
|
fun withReceiverAsArgument(receiverExpression: FirExpression): CallInfo =
|
||||||
CallInfo(
|
CallInfo(
|
||||||
callKind, name, explicitReceiver, listOf(receiverExpression) + arguments,
|
callKind, name, explicitReceiver, listOf(receiverExpression) + arguments,
|
||||||
isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs
|
isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, stubReceiver
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-66
@@ -5,39 +5,34 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformQualifiedAccessUsingSmartcastInfo
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.types.isExtensionFunctionType
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
|
||||||
|
|
||||||
open class CandidateCollector(
|
open class CandidateCollector(
|
||||||
val components: BodyResolveComponents,
|
val components: BodyResolveComponents,
|
||||||
val resolutionStageRunner: ResolutionStageRunner
|
private val resolutionStageRunner: ResolutionStageRunner
|
||||||
) {
|
) {
|
||||||
private val groupNumbers = mutableListOf<Int>()
|
private val groupNumbers = mutableListOf<TowerGroup>()
|
||||||
private val candidates = mutableListOf<Candidate>()
|
private val candidates = mutableListOf<Candidate>()
|
||||||
|
|
||||||
var currentApplicability = CandidateApplicability.HIDDEN
|
var currentApplicability = CandidateApplicability.HIDDEN
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
private var currentGroup = TowerGroup.Start
|
||||||
|
|
||||||
fun newDataSet() {
|
fun newDataSet() {
|
||||||
groupNumbers.clear()
|
groupNumbers.clear()
|
||||||
candidates.clear()
|
candidates.clear()
|
||||||
currentApplicability = CandidateApplicability.HIDDEN
|
currentApplicability = CandidateApplicability.HIDDEN
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
open fun consumeCandidate(group: TowerGroup, candidate: Candidate): CandidateApplicability {
|
||||||
val applicability = resolutionStageRunner.processCandidate(candidate)
|
val applicability = resolutionStageRunner.processCandidate(candidate)
|
||||||
|
|
||||||
if (applicability > currentApplicability) {
|
if (applicability > currentApplicability) {
|
||||||
groupNumbers.clear()
|
groupNumbers.clear()
|
||||||
candidates.clear()
|
candidates.clear()
|
||||||
currentApplicability = applicability
|
currentApplicability = applicability
|
||||||
|
currentGroup = group
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applicability == currentApplicability) {
|
if (applicability == currentApplicability) {
|
||||||
@@ -71,58 +66,3 @@ open class CandidateCollector(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collects properties that potentially could be invoke receivers, like 'propertyName()',
|
|
||||||
// and initiates further invoke resolution by adding property-bound invoke consumers
|
|
||||||
class InvokeReceiverCandidateCollector(
|
|
||||||
private val towerResolver: FirTowerResolver,
|
|
||||||
private val invokeCallInfo: CallInfo,
|
|
||||||
components: BodyResolveComponents,
|
|
||||||
private val invokeConsumer: AccumulatingTowerDataConsumer,
|
|
||||||
resolutionStageRunner: ResolutionStageRunner
|
|
||||||
) : CandidateCollector(components, resolutionStageRunner) {
|
|
||||||
private fun createBoundInvokeConsumer(boundInvokeCallInfo: CallInfo): TowerDataConsumer {
|
|
||||||
return createSimpleFunctionConsumer(
|
|
||||||
components.session, OperatorNameConventions.INVOKE,
|
|
||||||
boundInvokeCallInfo, components, towerResolver.collector
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createExplicitReceiverForInvoke(candidate: Candidate): FirQualifiedAccessExpressionImpl {
|
|
||||||
val symbol = candidate.symbol as FirCallableSymbol<*>
|
|
||||||
return FirQualifiedAccessExpressionImpl(null).apply {
|
|
||||||
calleeReference = FirNamedReferenceWithCandidate(
|
|
||||||
null,
|
|
||||||
symbol.callableId.callableName,
|
|
||||||
candidate
|
|
||||||
)
|
|
||||||
dispatchReceiver = candidate.dispatchReceiverExpression()
|
|
||||||
typeRef = towerResolver.typeCalculator.tryCalculateReturnType(symbol.firUnsafe())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
|
||||||
val applicability = super.consumeCandidate(group, candidate)
|
|
||||||
|
|
||||||
if (applicability >= CandidateApplicability.SYNTHETIC_RESOLVED) {
|
|
||||||
val symbol = candidate.symbol as FirCallableSymbol<*>
|
|
||||||
val extensionReceiverExpression = candidate.extensionReceiverExpression()
|
|
||||||
val useExtensionReceiverAsArgument =
|
|
||||||
symbol.fir.receiverTypeRef == null &&
|
|
||||||
candidate.explicitReceiverKind == ExplicitReceiverKind.EXTENSION_RECEIVER &&
|
|
||||||
symbol.fir.returnTypeRef.isExtensionFunctionType()
|
|
||||||
val explicitReceiver = createExplicitReceiverForInvoke(candidate).apply {
|
|
||||||
extensionReceiver = extensionReceiverExpression.takeIf { !useExtensionReceiverAsArgument } ?: FirNoReceiverExpression
|
|
||||||
}.let {
|
|
||||||
components.transformQualifiedAccessUsingSmartcastInfo(it)
|
|
||||||
}
|
|
||||||
val boundInvokeCallInfo = invokeCallInfo.replaceExplicitReceiver(explicitReceiver).let {
|
|
||||||
if (useExtensionReceiverAsArgument) it.withReceiverAsArgument(extensionReceiverExpression)
|
|
||||||
else it
|
|
||||||
}
|
|
||||||
|
|
||||||
invokeConsumer.addConsumerAndProcessAccumulatedData(createBoundInvokeConsumer(boundInvokeCallInfo))
|
|
||||||
}
|
|
||||||
|
|
||||||
return applicability
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+20
-9
@@ -13,19 +13,30 @@ import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
|
|
||||||
class CandidateFactory(
|
class CandidateFactory private constructor(
|
||||||
val bodyResolveComponents: BodyResolveComponents,
|
val bodyResolveComponents: BodyResolveComponents,
|
||||||
private val callInfo: CallInfo
|
val callInfo: CallInfo,
|
||||||
|
private val baseSystem: ConstraintStorage
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val baseSystem: ConstraintStorage
|
companion object {
|
||||||
|
private fun buildBaseSystem(bodyResolveComponents: BodyResolveComponents, callInfo: CallInfo): ConstraintStorage {
|
||||||
init {
|
val system = bodyResolveComponents.inferenceComponents.createConstraintSystem()
|
||||||
val system = bodyResolveComponents.inferenceComponents.createConstraintSystem()
|
callInfo.arguments.forEach {
|
||||||
callInfo.arguments.forEach {
|
system.addSubsystemFromExpression(it)
|
||||||
system.addSubsystemFromExpression(it)
|
}
|
||||||
|
return system.asReadOnlyStorage()
|
||||||
}
|
}
|
||||||
baseSystem = system.asReadOnlyStorage()
|
}
|
||||||
|
|
||||||
|
constructor(bodyResolveComponents: BodyResolveComponents, callInfo: CallInfo) :
|
||||||
|
this(bodyResolveComponents, callInfo, buildBaseSystem(bodyResolveComponents, 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(bodyResolveComponents, callInfo, baseSystem)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createCandidate(
|
fun createCandidate(
|
||||||
|
|||||||
@@ -1,125 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
|
|
||||||
fun createVariableAndObjectConsumer(
|
|
||||||
session: FirSession,
|
|
||||||
name: Name,
|
|
||||||
callInfo: CallInfo,
|
|
||||||
bodyResolveComponents: BodyResolveComponents,
|
|
||||||
resultCollector: CandidateCollector
|
|
||||||
): TowerDataConsumer {
|
|
||||||
return PrioritizedTowerDataConsumer(
|
|
||||||
resultCollector,
|
|
||||||
createSimpleConsumer(
|
|
||||||
session,
|
|
||||||
name,
|
|
||||||
TowerScopeLevel.Token.Properties,
|
|
||||||
callInfo,
|
|
||||||
bodyResolveComponents,
|
|
||||||
resultCollector
|
|
||||||
),
|
|
||||||
createSimpleConsumer(
|
|
||||||
session,
|
|
||||||
name,
|
|
||||||
TowerScopeLevel.Token.Objects,
|
|
||||||
callInfo,
|
|
||||||
bodyResolveComponents,
|
|
||||||
resultCollector
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createSimpleFunctionConsumer(
|
|
||||||
session: FirSession,
|
|
||||||
name: Name,
|
|
||||||
callInfo: CallInfo,
|
|
||||||
bodyResolveComponents: BodyResolveComponents,
|
|
||||||
resultCollector: CandidateCollector
|
|
||||||
): TowerDataConsumer {
|
|
||||||
return createSimpleConsumer(
|
|
||||||
session,
|
|
||||||
name,
|
|
||||||
TowerScopeLevel.Token.Functions,
|
|
||||||
callInfo,
|
|
||||||
bodyResolveComponents,
|
|
||||||
resultCollector
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createFunctionConsumer(
|
|
||||||
session: FirSession,
|
|
||||||
name: Name,
|
|
||||||
callInfo: CallInfo,
|
|
||||||
bodyResolveComponents: BodyResolveComponents,
|
|
||||||
resultCollector: CandidateCollector,
|
|
||||||
towerResolver: FirTowerResolver
|
|
||||||
): TowerDataConsumer {
|
|
||||||
val varCallInfo = callInfo.replaceWithVariableAccess()
|
|
||||||
return PrioritizedTowerDataConsumer(
|
|
||||||
resultCollector,
|
|
||||||
createSimpleConsumer(
|
|
||||||
session,
|
|
||||||
name,
|
|
||||||
TowerScopeLevel.Token.Functions,
|
|
||||||
callInfo,
|
|
||||||
bodyResolveComponents,
|
|
||||||
resultCollector
|
|
||||||
),
|
|
||||||
AccumulatingTowerDataConsumer(resultCollector).apply {
|
|
||||||
initialConsumer = createSimpleConsumer(
|
|
||||||
session,
|
|
||||||
name,
|
|
||||||
TowerScopeLevel.Token.Properties,
|
|
||||||
varCallInfo,
|
|
||||||
bodyResolveComponents,
|
|
||||||
InvokeReceiverCandidateCollector(
|
|
||||||
towerResolver,
|
|
||||||
invokeCallInfo = callInfo,
|
|
||||||
components = bodyResolveComponents,
|
|
||||||
invokeConsumer = this,
|
|
||||||
resolutionStageRunner = resultCollector.resolutionStageRunner
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createSimpleConsumer(
|
|
||||||
session: FirSession,
|
|
||||||
name: Name,
|
|
||||||
token: TowerScopeLevel.Token<*>,
|
|
||||||
callInfo: CallInfo,
|
|
||||||
bodyResolveComponents: BodyResolveComponents,
|
|
||||||
resultCollector: CandidateCollector
|
|
||||||
): TowerDataConsumer {
|
|
||||||
val factory = CandidateFactory(bodyResolveComponents, callInfo)
|
|
||||||
val explicitReceiver = callInfo.explicitReceiver
|
|
||||||
return if (explicitReceiver != null) {
|
|
||||||
ExplicitReceiverTowerDataConsumer(session, name, token, qualifierOrExpressionReceiver(explicitReceiver), factory, resultCollector)
|
|
||||||
} else {
|
|
||||||
NoExplicitReceiverTowerDataConsumer(session, name, token, factory, resultCollector)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createCallableReferencesConsumer(
|
|
||||||
session: FirSession,
|
|
||||||
name: Name,
|
|
||||||
callInfo: CallInfo,
|
|
||||||
bodyResolveComponents: BodyResolveComponents,
|
|
||||||
resultCollector: CandidateCollector
|
|
||||||
): TowerDataConsumer {
|
|
||||||
// TODO: Use SamePriorityConsumer
|
|
||||||
return PrioritizedTowerDataConsumer(
|
|
||||||
resultCollector,
|
|
||||||
createSimpleConsumer(session, name, TowerScopeLevel.Token.Functions, callInfo, bodyResolveComponents, resultCollector),
|
|
||||||
createSimpleConsumer(session, name, TowerScopeLevel.Token.Properties, callInfo, bodyResolveComponents, resultCollector)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
|
||||||
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl
|
||||||
@@ -17,10 +16,8 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirThisReceiverExpressionImpl
|
|||||||
import org.jetbrains.kotlin.fir.references.impl.FirImplicitThisReference
|
import org.jetbrains.kotlin.fir.references.impl.FirImplicitThisReference
|
||||||
import org.jetbrains.kotlin.fir.renderWithType
|
import org.jetbrains.kotlin.fir.renderWithType
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||||
import org.jetbrains.kotlin.fir.scopes.scope
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
@@ -57,9 +54,11 @@ class ClassDispatchReceiverValue(klassSymbol: FirClassSymbol<*>) : ReceiverValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: should inherit just Receiver, not ReceiverValue
|
// TODO: should inherit just Receiver, not ReceiverValue
|
||||||
abstract class AbstractExplicitReceiver<E : FirExpression> : ReceiverValue {
|
abstract class AbstractExplicitReceiver<E : FirExpression> : Receiver {
|
||||||
abstract val explicitReceiver: FirExpression
|
abstract val explicitReceiver: FirExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AbstractExplicitReceiverValue<E : FirExpression> : AbstractExplicitReceiver<E>(), ReceiverValue {
|
||||||
override val type: ConeKotlinType
|
override val type: ConeKotlinType
|
||||||
get() = explicitReceiver.typeRef.coneTypeSafe()
|
get() = explicitReceiver.typeRef.coneTypeSafe()
|
||||||
?: ConeKotlinErrorType("No type calculated for: ${explicitReceiver.renderWithType()}") // TODO: assert here
|
?: ConeKotlinErrorType("No type calculated for: ${explicitReceiver.renderWithType()}") // TODO: assert here
|
||||||
@@ -68,11 +67,6 @@ abstract class AbstractExplicitReceiver<E : FirExpression> : ReceiverValue {
|
|||||||
get() = explicitReceiver
|
get() = explicitReceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
fun qualifierOrExpressionReceiver(explicitReceiver: FirExpression): AbstractExplicitReceiver<*> {
|
|
||||||
if (explicitReceiver is FirResolvedQualifier) return QualifierReceiver(explicitReceiver)
|
|
||||||
return ExpressionReceiverValue(explicitReceiver)
|
|
||||||
}
|
|
||||||
|
|
||||||
class QualifierReceiver(override val explicitReceiver: FirResolvedQualifier) : AbstractExplicitReceiver<FirResolvedQualifier>() {
|
class QualifierReceiver(override val explicitReceiver: FirResolvedQualifier) : AbstractExplicitReceiver<FirResolvedQualifier>() {
|
||||||
private fun getClassSymbolWithCallablesScope(
|
private fun getClassSymbolWithCallablesScope(
|
||||||
classId: ClassId,
|
classId: ClassId,
|
||||||
@@ -95,7 +89,7 @@ class QualifierReceiver(override val explicitReceiver: FirResolvedQualifier) : A
|
|||||||
return null to null
|
return null to null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
|
fun qualifierScope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
|
||||||
val classId = explicitReceiver.classId ?: return null
|
val classId = explicitReceiver.classId ?: return null
|
||||||
|
|
||||||
val (classSymbol, callablesScope) = getClassSymbolWithCallablesScope(classId, useSiteSession, scopeSession)
|
val (classSymbol, callablesScope) = getClassSymbolWithCallablesScope(classId, useSiteSession, scopeSession)
|
||||||
@@ -107,22 +101,21 @@ class QualifierReceiver(override val explicitReceiver: FirResolvedQualifier) : A
|
|||||||
useSiteSession.firSymbolProvider.getNestedClassifierScope(classId)
|
useSiteSession.firSymbolProvider.getNestedClassifierScope(classId)
|
||||||
}
|
}
|
||||||
|
|
||||||
val qualifierScope = FirQualifierScope(callablesScope, classifierScope)
|
return FirQualifierScope(callablesScope, classifierScope)
|
||||||
if ((klass as? FirRegularClass)?.companionObject == null) {
|
|
||||||
return qualifierScope
|
|
||||||
}
|
|
||||||
val companionScope = super.scope(useSiteSession, scopeSession) ?: return qualifierScope
|
|
||||||
return FirCompositeScope(qualifierScope, companionScope)
|
|
||||||
}
|
}
|
||||||
return super.scope(useSiteSession, scopeSession)
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
|
||||||
|
return qualifierScope(useSiteSession, scopeSession)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ExpressionReceiverValue(
|
internal class ExpressionReceiverValue(
|
||||||
override val explicitReceiver: FirExpression
|
override val explicitReceiver: FirExpression
|
||||||
) : AbstractExplicitReceiver<FirExpression>(), ReceiverValue
|
) : AbstractExplicitReceiverValue<FirExpression>(), ReceiverValue
|
||||||
|
|
||||||
abstract class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
|
sealed class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
|
||||||
val boundSymbol: S,
|
val boundSymbol: S,
|
||||||
type: ConeKotlinType,
|
type: ConeKotlinType,
|
||||||
private val useSiteSession: FirSession,
|
private val useSiteSession: FirSession,
|
||||||
@@ -148,20 +141,29 @@ abstract class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ImplicitDispatchReceiverValue(
|
internal enum class ImplicitDispatchReceiverKind {
|
||||||
|
REGULAR,
|
||||||
|
COMPANION,
|
||||||
|
COMPANION_FROM_SUPERTYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
class ImplicitDispatchReceiverValue internal constructor(
|
||||||
boundSymbol: FirClassSymbol<*>,
|
boundSymbol: FirClassSymbol<*>,
|
||||||
type: ConeKotlinType,
|
type: ConeKotlinType,
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
scopeSession: ScopeSession
|
scopeSession: ScopeSession,
|
||||||
|
private val kind: ImplicitDispatchReceiverKind = ImplicitDispatchReceiverKind.REGULAR
|
||||||
) : ImplicitReceiverValue<FirClassSymbol<*>>(boundSymbol, type, useSiteSession, scopeSession) {
|
) : ImplicitReceiverValue<FirClassSymbol<*>>(boundSymbol, type, useSiteSession, scopeSession) {
|
||||||
val implicitCompanionScopes: List<FirScope> = run {
|
internal constructor(
|
||||||
val klass = boundSymbol.fir as? FirRegularClass ?: return@run emptyList()
|
boundSymbol: FirClassSymbol<*>, useSiteSession: FirSession, scopeSession: ScopeSession, kind: ImplicitDispatchReceiverKind
|
||||||
listOfNotNull(klass.companionObject?.scope(ConeSubstitutor.Empty, useSiteSession, scopeSession)) +
|
) : this(
|
||||||
lookupSuperTypes(klass, lookupInterfaces = false, deep = true, useSiteSession = useSiteSession).mapNotNull {
|
boundSymbol, boundSymbol.constructType(typeArguments = emptyArray(), isNullable = false),
|
||||||
val superClass = (it as? ConeClassLikeType)?.lookupTag?.toSymbol(useSiteSession)?.fir as? FirRegularClass
|
useSiteSession, scopeSession, kind
|
||||||
superClass?.companionObject?.scope(ConeSubstitutor.Empty, useSiteSession, scopeSession)
|
)
|
||||||
}
|
|
||||||
}
|
val implicitCompanion: Boolean get() = kind != ImplicitDispatchReceiverKind.REGULAR
|
||||||
|
|
||||||
|
val companionFromSupertype: Boolean get() = kind == ImplicitDispatchReceiverKind.COMPANION_FROM_SUPERTYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
class ImplicitExtensionReceiverValue(
|
class ImplicitExtensionReceiverValue(
|
||||||
|
|||||||
+404
-341
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -10,396 +10,459 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
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.declarations.isCompanion
|
||||||
import org.jetbrains.kotlin.fir.declarations.isInner
|
import org.jetbrains.kotlin.fir.declarations.isInner
|
||||||
|
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.expressions.impl.FirQualifiedAccessExpressionImpl
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.TowerDataKind.*
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformQualifiedAccessUsingSmartcastInfo
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
|
||||||
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
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.scopes.impl.FirStaticScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType
|
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
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
|
import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
|
||||||
|
|
||||||
enum class TowerDataKind {
|
|
||||||
EMPTY, // Corresponds to stub tower level which is replaced by receiver-related level
|
|
||||||
TOWER_LEVEL // Corresponds to real tower level which may process elements itself
|
|
||||||
}
|
|
||||||
|
|
||||||
class FirTowerResolver(
|
class FirTowerResolver(
|
||||||
val typeCalculator: ReturnTypeCalculator,
|
val typeCalculator: ReturnTypeCalculator,
|
||||||
val components: BodyResolveComponents,
|
val components: BodyResolveComponents,
|
||||||
resolutionStageRunner: ResolutionStageRunner,
|
resolutionStageRunner: ResolutionStageRunner,
|
||||||
val topLevelScopes: List<FirScope>,
|
private val topLevelScopes: List<FirScope>,
|
||||||
val localScopes: List<FirLocalScope>
|
private val localScopes: List<FirLocalScope>
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val session: FirSession get() = components.session
|
private val session: FirSession get() = components.session
|
||||||
|
private val collector = CandidateCollector(components, resolutionStageRunner)
|
||||||
|
private val manager = TowerResolveManager(this)
|
||||||
|
private lateinit var implicitReceivers: List<ImplicitReceiver>
|
||||||
|
|
||||||
private fun processImplicitReceiver(
|
private data class ImplicitReceiver(val receiver: ImplicitReceiverValue<*>, val usableAsValue: Boolean, val depth: Int)
|
||||||
towerDataConsumer: TowerDataConsumer,
|
|
||||||
implicitReceiverValue: ImplicitReceiverValue<*>,
|
|
||||||
nonEmptyLocalScopes: List<FirLocalScope>,
|
|
||||||
oldGroup: Int
|
|
||||||
): Int {
|
|
||||||
var group = oldGroup
|
|
||||||
// Member (no explicit receiver) / extension member (with explicit receiver) access via implicit receiver
|
|
||||||
// class Foo(val x: Int) {
|
|
||||||
// fun Bar.baz() {}
|
|
||||||
// fun test() { x }
|
|
||||||
// fun test(b: Bar) { b.baz() }
|
|
||||||
// }
|
|
||||||
towerDataConsumer.consume(
|
|
||||||
TOWER_LEVEL,
|
|
||||||
MemberScopeTowerLevel(session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession),
|
|
||||||
group++
|
|
||||||
)
|
|
||||||
|
|
||||||
// class Foo {
|
private fun prepareImplicitReceivers(implicitReceiverValues: List<ImplicitReceiverValue<*>>): List<ImplicitReceiver> {
|
||||||
// fun foo(block: Foo.() -> Unit) {
|
var depth = 0
|
||||||
// block()
|
var firstDispatchValue = true
|
||||||
// }
|
val explicitCompanions = mutableListOf<FirRegularClassSymbol>()
|
||||||
// }
|
implicitReceivers = implicitReceiverValues.mapNotNull {
|
||||||
// invokeExtension on local variable
|
val usableAsValue = when (it) {
|
||||||
towerDataConsumer.consume(
|
is ImplicitExtensionReceiverValue -> true
|
||||||
EMPTY,
|
is ImplicitDispatchReceiverValue -> {
|
||||||
TowerScopeLevel.OnlyImplicitReceiver(implicitReceiverValue),
|
val symbol = it.boundSymbol
|
||||||
group++
|
val klass = symbol.fir as? FirRegularClass
|
||||||
)
|
if (!it.implicitCompanion && klass?.isCompanion == true) {
|
||||||
//TowerData.OnlyImplicitReceiver(implicitReceiver).process()?.let { return it }
|
explicitCompanions += klass.symbol
|
||||||
|
}
|
||||||
// Same receiver is dispatch & extension
|
if (firstDispatchValue) {
|
||||||
// class Foo {
|
if (!it.implicitCompanion &&
|
||||||
// fun Foo.bar() {}
|
klass?.isInner == false &&
|
||||||
// fun test() { bar() }
|
!symbol.classId.isLocal
|
||||||
// }
|
) {
|
||||||
towerDataConsumer.consume(
|
firstDispatchValue = false
|
||||||
TOWER_LEVEL,
|
}
|
||||||
MemberScopeTowerLevel(
|
true
|
||||||
session, components,
|
} else {
|
||||||
dispatchReceiver = implicitReceiverValue,
|
symbol.fir.classKind == ClassKind.OBJECT
|
||||||
implicitExtensionReceiver = implicitReceiverValue,
|
}
|
||||||
scopeSession = components.scopeSession
|
|
||||||
),
|
|
||||||
group++
|
|
||||||
)
|
|
||||||
|
|
||||||
for (scope in nonEmptyLocalScopes) {
|
|
||||||
// Local scope extensions via implicit receiver
|
|
||||||
// class Foo {
|
|
||||||
// fun test() {
|
|
||||||
// fun Foo.bar() {}
|
|
||||||
// bar()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
towerDataConsumer.consume(
|
|
||||||
TOWER_LEVEL,
|
|
||||||
ScopeTowerLevel(session, components, scope, implicitExtensionReceiver = implicitReceiverValue),
|
|
||||||
group++
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
var blockDispatchReceivers = false
|
|
||||||
|
|
||||||
for (implicitDispatchReceiverValue in implicitReceiverValues) {
|
|
||||||
val implicitScope = implicitDispatchReceiverValue.implicitScope
|
|
||||||
if (implicitScope != null) {
|
|
||||||
// Extensions in outer object
|
|
||||||
// object Outer {
|
|
||||||
// fun Nested.foo() {}
|
|
||||||
// class Nested {
|
|
||||||
// fun test() { foo() }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
towerDataConsumer.consume(
|
|
||||||
TOWER_LEVEL,
|
|
||||||
ScopeTowerLevel(session, components, implicitScope, implicitExtensionReceiver = implicitReceiverValue),
|
|
||||||
group++
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (implicitDispatchReceiverValue is ImplicitDispatchReceiverValue) {
|
|
||||||
val implicitCompanionScopes = implicitDispatchReceiverValue.implicitCompanionScopes
|
|
||||||
for (implicitCompanionScope in implicitCompanionScopes) {
|
|
||||||
// Extension in companion
|
|
||||||
// class My {
|
|
||||||
// companion object { fun My.foo() {} }
|
|
||||||
// fun test() { foo() }
|
|
||||||
// }
|
|
||||||
towerDataConsumer.consume(
|
|
||||||
TOWER_LEVEL,
|
|
||||||
ScopeTowerLevel(session, components, implicitCompanionScope, implicitExtensionReceiver = implicitReceiverValue),
|
|
||||||
group++
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (blockDispatchReceivers) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if ((implicitDispatchReceiverValue.boundSymbol.fir as? FirRegularClass)?.isInner == false) {
|
|
||||||
blockDispatchReceivers = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (implicitDispatchReceiverValue !== implicitReceiverValue) {
|
if (it is ImplicitDispatchReceiverValue && it.implicitCompanion && it.boundSymbol in explicitCompanions) null
|
||||||
// Two different implicit receivers (dispatch & extension)
|
else ImplicitReceiver(it, usableAsValue, depth++)
|
||||||
// class A
|
|
||||||
// class B {
|
|
||||||
// fun A.foo() {}
|
|
||||||
// }
|
|
||||||
// fun test(a: A, b: B) {
|
|
||||||
// with(a) { with(b) { foo() } }
|
|
||||||
// }
|
|
||||||
towerDataConsumer.consume(
|
|
||||||
TOWER_LEVEL,
|
|
||||||
MemberScopeTowerLevel(
|
|
||||||
session, components,
|
|
||||||
scopeSession = components.scopeSession,
|
|
||||||
dispatchReceiver = implicitDispatchReceiverValue,
|
|
||||||
implicitExtensionReceiver = implicitReceiverValue
|
|
||||||
),
|
|
||||||
group++
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return implicitReceivers
|
||||||
return group
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processTopLevelScope(
|
private fun runResolverForQualifierReceiver(
|
||||||
towerDataConsumer: TowerDataConsumer,
|
|
||||||
topLevelScope: FirScope,
|
|
||||||
oldGroup: Int,
|
|
||||||
extensionsOnly: Boolean = false
|
|
||||||
): Int {
|
|
||||||
var group = oldGroup
|
|
||||||
// Top-level extensions via implicit receiver
|
|
||||||
// fun Foo.bar() {}
|
|
||||||
// class Foo {
|
|
||||||
// fun test() { bar() }
|
|
||||||
// }
|
|
||||||
for (implicitReceiverValue in implicitReceiverValues) {
|
|
||||||
if (towerDataConsumer.consume(
|
|
||||||
TOWER_LEVEL,
|
|
||||||
ScopeTowerLevel(
|
|
||||||
session, components, topLevelScope,
|
|
||||||
implicitExtensionReceiver = implicitReceiverValue,
|
|
||||||
extensionsOnly = extensionsOnly
|
|
||||||
),
|
|
||||||
group++
|
|
||||||
) == NONE
|
|
||||||
) {
|
|
||||||
return group
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Member of top-level scope & importing scope
|
|
||||||
// val x = 0
|
|
||||||
// fun test() { x }
|
|
||||||
towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, topLevelScope), group++)
|
|
||||||
return group
|
|
||||||
}
|
|
||||||
|
|
||||||
fun reset() {
|
|
||||||
collector.newDataSet()
|
|
||||||
}
|
|
||||||
|
|
||||||
val collector = CandidateCollector(components, resolutionStageRunner)
|
|
||||||
private lateinit var towerDataConsumer: TowerDataConsumer
|
|
||||||
private lateinit var implicitReceiverValues: List<ImplicitReceiverValue<*>>
|
|
||||||
|
|
||||||
private fun towerDataConsumer(info: CallInfo, collector: CandidateCollector): TowerDataConsumer {
|
|
||||||
return when (info.callKind) {
|
|
||||||
CallKind.VariableAccess -> {
|
|
||||||
createVariableAndObjectConsumer(session, info.name, info, components, collector)
|
|
||||||
}
|
|
||||||
CallKind.Function -> {
|
|
||||||
createFunctionConsumer(session, info.name, info, components, collector, this)
|
|
||||||
}
|
|
||||||
CallKind.CallableReference -> {
|
|
||||||
if (info.stubReceiver == null) {
|
|
||||||
createCallableReferencesConsumer(session, info.name, info, components, collector)
|
|
||||||
} else {
|
|
||||||
PrioritizedTowerDataConsumer(
|
|
||||||
collector,
|
|
||||||
createCallableReferencesConsumer(
|
|
||||||
session, info.name, info.replaceExplicitReceiver(info.stubReceiver), components, collector
|
|
||||||
),
|
|
||||||
createCallableReferencesConsumer(
|
|
||||||
session, info.name, info, components, collector
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createExplicitReceiverForInvoke(candidate: Candidate): FirQualifiedAccessExpressionImpl {
|
|
||||||
val symbol = candidate.symbol as FirCallableSymbol<*>
|
|
||||||
return FirQualifiedAccessExpressionImpl(null).apply {
|
|
||||||
calleeReference = FirNamedReferenceWithCandidate(
|
|
||||||
null,
|
|
||||||
symbol.callableId.callableName,
|
|
||||||
candidate
|
|
||||||
)
|
|
||||||
dispatchReceiver = candidate.dispatchReceiverExpression()
|
|
||||||
typeRef = typeCalculator.tryCalculateReturnType(symbol.firUnsafe())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only case when qualifiedReceiver is a package (no classId) is handled here
|
|
||||||
private fun runResolverForFullyQualifiedReceiver(
|
|
||||||
implicitReceiverValues: List<ImplicitReceiverValue<*>>,
|
|
||||||
info: CallInfo,
|
info: CallInfo,
|
||||||
collector: CandidateCollector,
|
collector: CandidateCollector,
|
||||||
qualifiedReceiver: FirResolvedQualifier
|
resolvedQualifier: FirResolvedQualifier,
|
||||||
|
manager: TowerResolveManager
|
||||||
): CandidateCollector {
|
): CandidateCollector {
|
||||||
val qualifierScope = FirExplicitSimpleImportingScope(
|
val qualifierScope = if (resolvedQualifier.classId == null) {
|
||||||
listOf(
|
FirExplicitSimpleImportingScope(
|
||||||
FirResolvedImportImpl(
|
listOf(
|
||||||
FirImportImpl(null, FqName.topLevel(info.name), false, null),
|
FirResolvedImportImpl(
|
||||||
qualifiedReceiver.packageFqName,
|
FirImportImpl(source = null, importedFqName = FqName.topLevel(info.name), isAllUnder = false, aliasName = null),
|
||||||
qualifiedReceiver.relativeClassFqName
|
resolvedQualifier.packageFqName,
|
||||||
)
|
relativeClassName = null
|
||||||
), session, components.scopeSession
|
)
|
||||||
)
|
), session, components.scopeSession
|
||||||
val candidateFactory = CandidateFactory(components, info)
|
)
|
||||||
|
} else {
|
||||||
|
QualifierReceiver(resolvedQualifier).qualifierScope(session, components.scopeSession)
|
||||||
|
}
|
||||||
|
|
||||||
when (info.callKind) {
|
if (qualifierScope != null) {
|
||||||
CallKind.VariableAccess -> {
|
manager.processLevel(
|
||||||
qualifierScope.processPropertiesByName(info.name) {
|
ScopeTowerLevel(session, components, qualifierScope), info.noStubReceiver(), TowerGroup.Qualifier
|
||||||
collector.consumeCandidate(0, candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER))
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolvedQualifier.classId != null) {
|
||||||
|
val typeRef = resolvedQualifier.typeRef
|
||||||
|
// NB: yet built-in Unit is used for "no-value" type
|
||||||
|
if (info.callKind == CallKind.CallableReference) {
|
||||||
|
if (info.stubReceiver != null || typeRef !is FirImplicitBuiltinTypeRef) {
|
||||||
|
runResolverForExpressionReceiver(info, collector, resolvedQualifier, manager)
|
||||||
}
|
}
|
||||||
qualifierScope.processClassifiersByName(info.name) {
|
} else {
|
||||||
if (it is FirClassSymbol<*> && it.fir.classKind == ClassKind.OBJECT) {
|
if (typeRef !is FirImplicitBuiltinTypeRef) {
|
||||||
collector.consumeCandidate(0, candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER))
|
runResolverForExpressionReceiver(info, collector, resolvedQualifier, manager)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.processQueuedLevelsForInvoke(groupLimit = TowerGroup.Last)
|
||||||
|
return collector
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runResolverForNoReceiver(
|
||||||
|
info: CallInfo,
|
||||||
|
collector: CandidateCollector,
|
||||||
|
manager: TowerResolveManager
|
||||||
|
): CandidateCollector {
|
||||||
|
val shouldProcessExtensionsBeforeMembers =
|
||||||
|
info.callKind == CallKind.Function && info.name in HIDES_MEMBERS_NAME_LIST
|
||||||
|
if (shouldProcessExtensionsBeforeMembers) {
|
||||||
|
// Special case (extension hides member)
|
||||||
|
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
|
for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) {
|
||||||
|
if (!usableAsValue) continue
|
||||||
|
manager.processLevel(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session, components, topLevelScope, extensionReceiver = implicitReceiverValue, extensionsOnly = true
|
||||||
|
), info, TowerGroup.TopPrioritized(index).Implicit(depth)
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val nonEmptyLocalScopes = mutableListOf<FirLocalScope>()
|
||||||
|
val emptyTopLevelScopes = mutableSetOf<FirScope>()
|
||||||
|
for ((index, localScope) in localScopes.withIndex()) {
|
||||||
|
val result = manager.processLevel(
|
||||||
|
ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index)
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
if (result != ProcessorAction.NONE) {
|
||||||
|
nonEmptyLocalScopes += localScope
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val implicitReceiverValuesWithEmptyScopes = mutableSetOf<ImplicitReceiverValue<*>>()
|
||||||
|
for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) {
|
||||||
|
// NB: companions are processed via implicitReceiverValues!
|
||||||
|
val parentGroup = TowerGroup.Implicit(depth)
|
||||||
|
|
||||||
|
if (usableAsValue) {
|
||||||
|
val implicitResult = manager.processLevel(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession
|
||||||
|
), info, parentGroup.Member
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
if (implicitResult == ProcessorAction.NONE) {
|
||||||
|
implicitReceiverValuesWithEmptyScopes += implicitReceiverValue
|
||||||
|
}
|
||||||
|
for ((localIndex, localScope) in nonEmptyLocalScopes.withIndex()) {
|
||||||
|
manager.processLevel(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session, components, localScope, extensionReceiver = implicitReceiverValue
|
||||||
|
), info, parentGroup.Local(localIndex)
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
}
|
||||||
|
for ((implicitDispatchReceiverValue, usable, dispatchDepth) in implicitReceivers) {
|
||||||
|
if (!usable) continue
|
||||||
|
if (implicitDispatchReceiverValue in implicitReceiverValuesWithEmptyScopes) continue
|
||||||
|
manager.processLevel(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session,
|
||||||
|
components,
|
||||||
|
dispatchReceiver = implicitDispatchReceiverValue,
|
||||||
|
extensionReceiver = implicitReceiverValue,
|
||||||
|
scopeSession = components.scopeSession
|
||||||
|
), info, parentGroup.Implicit(dispatchDepth)
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
}
|
||||||
|
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
|
if (topLevelScope in emptyTopLevelScopes) continue
|
||||||
|
val result = manager.processLevel(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session, components, topLevelScope, extensionReceiver = implicitReceiverValue
|
||||||
|
), info, parentGroup.Top(topIndex)
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
if (result == ProcessorAction.NONE) {
|
||||||
|
emptyTopLevelScopes += topLevelScope
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CallKind.Function -> {
|
|
||||||
qualifierScope.processFunctionsAndConstructorsByName(info.name, session, components) {
|
|
||||||
collector.consumeCandidate(0, candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER))
|
|
||||||
}
|
|
||||||
|
|
||||||
val invokeReceiverCollector = CandidateCollector(components, components.resolutionStageRunner)
|
if (implicitReceiverValue is ImplicitDispatchReceiverValue) {
|
||||||
val invokeReceiverCandidateFactory = CandidateFactory(
|
val scope = implicitReceiverValue.scope(session, components.scopeSession)
|
||||||
components,
|
if (scope != null) {
|
||||||
info.replaceWithVariableAccess()
|
manager.processLevel(
|
||||||
)
|
ScopeTowerLevel(
|
||||||
|
session,
|
||||||
qualifierScope.processPropertiesByName(info.name) {
|
components,
|
||||||
invokeReceiverCollector.consumeCandidate(
|
FirStaticScope(scope)
|
||||||
0, invokeReceiverCandidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER)
|
), info, parentGroup.Static(depth)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (invokeReceiverCollector.isSuccess()) {
|
|
||||||
for (invokeReceiverCandidate in invokeReceiverCollector.bestCandidates()) {
|
|
||||||
val invokeReceiverExpression = createExplicitReceiverForInvoke(invokeReceiverCandidate).let {
|
|
||||||
components.transformQualifiedAccessUsingSmartcastInfo(it)
|
|
||||||
}
|
|
||||||
runResolver(
|
|
||||||
implicitReceiverValues,
|
|
||||||
info.copy(explicitReceiver = invokeReceiverExpression, name = OperatorNameConventions.INVOKE),
|
|
||||||
collector
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
CallKind.CallableReference -> return collector
|
|
||||||
else -> throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
|
// NB: this check does not work for variables
|
||||||
|
// because we do not search for objects if we have extension receiver
|
||||||
|
if (info.callKind != CallKind.VariableAccess && topLevelScope in emptyTopLevelScopes) continue
|
||||||
|
manager.processLevel(
|
||||||
|
ScopeTowerLevel(session, components, topLevelScope), info, TowerGroup.Top(index)
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.processQueuedLevelsForInvoke(groupLimit = TowerGroup.Last)
|
||||||
return collector
|
return collector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun runResolverForExpressionReceiver(
|
||||||
|
info: CallInfo,
|
||||||
|
collector: CandidateCollector,
|
||||||
|
receiver: FirExpression,
|
||||||
|
manager: TowerResolveManager
|
||||||
|
): CandidateCollector {
|
||||||
|
val explicitReceiverValue = ExpressionReceiverValue(receiver)
|
||||||
|
|
||||||
|
val shouldProcessExtensionsBeforeMembers =
|
||||||
|
info.callKind == CallKind.Function && info.name in HIDES_MEMBERS_NAME_LIST
|
||||||
|
if (shouldProcessExtensionsBeforeMembers) {
|
||||||
|
// Special case (extension hides member)
|
||||||
|
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
|
manager.processLevel(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session, components, topLevelScope, extensionReceiver = explicitReceiverValue, extensionsOnly = true
|
||||||
|
), info, TowerGroup.TopPrioritized(index), ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.processLevel(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session, components, dispatchReceiver = explicitReceiverValue, scopeSession = components.scopeSession
|
||||||
|
), info, TowerGroup.Member, ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
|
||||||
|
val shouldProcessExplicitReceiverScopeOnly =
|
||||||
|
info.callKind == CallKind.Function && info.explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
|
||||||
|
if (shouldProcessExplicitReceiverScopeOnly) {
|
||||||
|
// Special case (integer literal type)
|
||||||
|
return collector
|
||||||
|
}
|
||||||
|
|
||||||
|
val nonEmptyLocalScopes = mutableListOf<FirLocalScope>()
|
||||||
|
for ((index, localScope) in localScopes.withIndex()) {
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index),
|
||||||
|
InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||||
|
)
|
||||||
|
val result = manager.processLevel(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session, components, localScope, extensionReceiver = explicitReceiverValue
|
||||||
|
), info, TowerGroup.Local(index), ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
if (result != ProcessorAction.NONE) {
|
||||||
|
nonEmptyLocalScopes += localScope
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) {
|
||||||
|
if (!usableAsValue) continue
|
||||||
|
// NB: companions are processed via implicitReceiverValues!
|
||||||
|
val parentGroup = TowerGroup.Implicit(depth)
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession
|
||||||
|
), info, parentGroup.Member, InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||||
|
)
|
||||||
|
manager.processLevel(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session, components,
|
||||||
|
dispatchReceiver = implicitReceiverValue, extensionReceiver = explicitReceiverValue,
|
||||||
|
scopeSession = components.scopeSession
|
||||||
|
), info, parentGroup.Member, ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
for ((localIndex, localScope) in nonEmptyLocalScopes.withIndex()) {
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session, components, localScope, extensionReceiver = implicitReceiverValue
|
||||||
|
), info, parentGroup.Local(localIndex), InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
for ((implicitDispatchReceiverValue, usable, dispatchDepth) in implicitReceivers) {
|
||||||
|
if (!usable) continue
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session,
|
||||||
|
components,
|
||||||
|
dispatchReceiver = implicitDispatchReceiverValue,
|
||||||
|
extensionReceiver = implicitReceiverValue,
|
||||||
|
scopeSession = components.scopeSession
|
||||||
|
), info, parentGroup.Implicit(dispatchDepth),
|
||||||
|
InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session, components, topLevelScope, extensionReceiver = implicitReceiverValue
|
||||||
|
), info, parentGroup.Top(topIndex), InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
ScopeTowerLevel(session, components, topLevelScope), info, TowerGroup.Top(index),
|
||||||
|
InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||||
|
)
|
||||||
|
manager.processLevel(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session, components, topLevelScope, extensionReceiver = explicitReceiverValue
|
||||||
|
), info, TowerGroup.Top(index), ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
|
)
|
||||||
|
if (collector.isSuccess()) return collector
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.processQueuedLevelsForInvoke(groupLimit = TowerGroup.Last)
|
||||||
|
return collector
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun enqueueResolverForInvoke(
|
||||||
|
info: CallInfo,
|
||||||
|
invokeReceiverValue: ExpressionReceiverValue,
|
||||||
|
manager: TowerResolveManager
|
||||||
|
) {
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session, components, dispatchReceiver = invokeReceiverValue, scopeSession = components.scopeSession
|
||||||
|
), info, TowerGroup.Member,
|
||||||
|
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||||
|
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||||
|
)
|
||||||
|
for ((index, localScope) in localScopes.withIndex()) {
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session, components, localScope, extensionReceiver = invokeReceiverValue
|
||||||
|
), info, TowerGroup.Local(index),
|
||||||
|
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||||
|
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
|
)
|
||||||
|
}
|
||||||
|
for ((implicitReceiverValue, usable, depth) in implicitReceivers) {
|
||||||
|
if (!usable) continue
|
||||||
|
// NB: companions are processed via implicitReceiverValues!
|
||||||
|
val parentGroup = TowerGroup.Implicit(depth)
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session, components,
|
||||||
|
dispatchReceiver = implicitReceiverValue, extensionReceiver = invokeReceiverValue,
|
||||||
|
scopeSession = components.scopeSession
|
||||||
|
), info, parentGroup.Member,
|
||||||
|
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||||
|
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
|
)
|
||||||
|
}
|
||||||
|
for ((index, topLevelScope) in topLevelScopes.withIndex()) {
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
ScopeTowerLevel(
|
||||||
|
session, components, topLevelScope, extensionReceiver = invokeReceiverValue
|
||||||
|
), info, TowerGroup.Top(index),
|
||||||
|
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||||
|
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here we already know extension receiver for invoke, and it's stated in info as first argument
|
||||||
|
internal fun enqueueResolverForBuiltinInvokeExtensionWithExplicitArgument(
|
||||||
|
info: CallInfo,
|
||||||
|
invokeReceiverValue: ExpressionReceiverValue,
|
||||||
|
manager: TowerResolveManager
|
||||||
|
) {
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session, components, dispatchReceiver = invokeReceiverValue,
|
||||||
|
scopeSession = components.scopeSession
|
||||||
|
), info, TowerGroup.Member,
|
||||||
|
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||||
|
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here we don't know extension receiver for invoke, assuming it's one of implicit receivers
|
||||||
|
internal fun enqueueResolverForBuiltinInvokeExtensionWithImplicitArgument(
|
||||||
|
info: CallInfo,
|
||||||
|
invokeReceiverValue: ExpressionReceiverValue,
|
||||||
|
manager: TowerResolveManager
|
||||||
|
) {
|
||||||
|
for ((implicitReceiverValue, usable, depth) in implicitReceivers) {
|
||||||
|
if (!usable) continue
|
||||||
|
val parentGroup = TowerGroup.Implicit(depth)
|
||||||
|
manager.enqueueLevelForInvoke(
|
||||||
|
MemberScopeTowerLevel(
|
||||||
|
session, components, dispatchReceiver = invokeReceiverValue,
|
||||||
|
extensionReceiver = implicitReceiverValue,
|
||||||
|
implicitExtensionInvokeMode = true,
|
||||||
|
scopeSession = components.scopeSession
|
||||||
|
), info, parentGroup.InvokeExtension,
|
||||||
|
InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||||
|
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun runResolver(
|
fun runResolver(
|
||||||
implicitReceiverValues: List<ImplicitReceiverValue<*>>,
|
implicitReceiverValues: List<ImplicitReceiverValue<*>>,
|
||||||
info: CallInfo,
|
info: CallInfo,
|
||||||
collector: CandidateCollector = this.collector
|
collector: CandidateCollector = this.collector,
|
||||||
|
manager: TowerResolveManager = this.manager
|
||||||
): CandidateCollector {
|
): CandidateCollector {
|
||||||
this.implicitReceiverValues = implicitReceiverValues
|
// TODO: add flag receiver / non-receiver position
|
||||||
|
prepareImplicitReceivers(implicitReceiverValues)
|
||||||
val receiver = info.explicitReceiver
|
val candidateFactory = CandidateFactory(components, info)
|
||||||
if (receiver is FirResolvedQualifier && receiver.classId == null) {
|
manager.candidateFactory = candidateFactory
|
||||||
return runResolverForFullyQualifiedReceiver(implicitReceiverValues, info, collector, receiver)
|
if (info.callKind == CallKind.CallableReference && info.stubReceiver != null) {
|
||||||
|
manager.stubReceiverCandidateFactory = candidateFactory.replaceCallInfo(info.replaceExplicitReceiver(info.stubReceiver))
|
||||||
}
|
}
|
||||||
|
manager.resultCollector = collector
|
||||||
towerDataConsumer = towerDataConsumer(info, collector)
|
if (info.callKind == CallKind.Function) {
|
||||||
val shouldProcessExtensionsBeforeMembers =
|
manager.invokeReceiverCollector = CandidateCollector(components, components.resolutionStageRunner)
|
||||||
info.callKind == CallKind.Function && info.name in HIDES_MEMBERS_NAME_LIST
|
manager.invokeReceiverCandidateFactory = CandidateFactory(components, info.replaceWithVariableAccess())
|
||||||
val shouldProcessExplicitReceiverScopeOnly =
|
if (info.explicitReceiver != null) {
|
||||||
info.callKind == CallKind.Function && info.explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
|
with(manager.invokeReceiverCandidateFactory) {
|
||||||
|
manager.invokeBuiltinExtensionReceiverCandidateFactory = replaceCallInfo(callInfo.replaceExplicitReceiver(null))
|
||||||
var group = 0
|
|
||||||
|
|
||||||
// Specific case when extension should be processed before members (Kotlin forEach vs Java forEach)
|
|
||||||
if (shouldProcessExtensionsBeforeMembers) {
|
|
||||||
for (topLevelScope in topLevelScopes) {
|
|
||||||
group = processTopLevelScope(towerDataConsumer, topLevelScope, group, extensionsOnly = true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Member of explicit receiver' type (this stage does nothing without explicit receiver)
|
|
||||||
// class Foo(val x: Int)
|
|
||||||
// fun test(f: Foo) { f.x }
|
|
||||||
towerDataConsumer.consume(EMPTY, TowerScopeLevel.Empty, group++)
|
|
||||||
|
|
||||||
if (shouldProcessExplicitReceiverScopeOnly) {
|
|
||||||
return collector
|
|
||||||
}
|
|
||||||
|
|
||||||
// Member of local scope
|
|
||||||
// fun test(x: Int) = x
|
|
||||||
val nonEmptyLocalScopes = mutableListOf<FirLocalScope>()
|
|
||||||
for (scope in localScopes) {
|
|
||||||
if (towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, scope), group++) != NONE) {
|
|
||||||
nonEmptyLocalScopes += scope
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var blockDispatchReceivers = false
|
|
||||||
|
|
||||||
// Member of implicit receiver' type *and* relevant scope
|
|
||||||
for (implicitReceiverValue in implicitReceiverValues) {
|
|
||||||
if (!blockDispatchReceivers || implicitReceiverValue !is ImplicitDispatchReceiverValue) {
|
|
||||||
// Direct use of implicit receiver (see inside)
|
|
||||||
group = processImplicitReceiver(towerDataConsumer, implicitReceiverValue, nonEmptyLocalScopes, group)
|
|
||||||
}
|
|
||||||
val implicitScope = implicitReceiverValue.implicitScope
|
|
||||||
if (implicitScope != null) {
|
|
||||||
// Regular implicit receiver scope (outer objects, statics)
|
|
||||||
// object Outer {
|
|
||||||
// val x = 0
|
|
||||||
// class Nested { val y = x }
|
|
||||||
// }
|
|
||||||
towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, implicitScope), group++)
|
|
||||||
}
|
|
||||||
if (implicitReceiverValue is ImplicitDispatchReceiverValue) {
|
|
||||||
val implicitCompanionScopes = implicitReceiverValue.implicitCompanionScopes
|
|
||||||
for (implicitCompanionScope in implicitCompanionScopes) {
|
|
||||||
// Companion scope bound to implicit receiver scope
|
|
||||||
// class Outer {
|
|
||||||
// companion object { val x = 0 }
|
|
||||||
// class Nested { val y = x }
|
|
||||||
// }
|
|
||||||
towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, implicitCompanionScope), group++)
|
|
||||||
}
|
|
||||||
if ((implicitReceiverValue.boundSymbol.fir as? FirRegularClass)?.isInner == false) {
|
|
||||||
blockDispatchReceivers = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (topLevelScope in topLevelScopes) {
|
return when (val receiver = info.explicitReceiver) {
|
||||||
group = processTopLevelScope(towerDataConsumer, topLevelScope, group)
|
is FirResolvedQualifier -> runResolverForQualifierReceiver(info, collector, receiver, manager)
|
||||||
|
null -> runResolverForNoReceiver(info, collector, manager)
|
||||||
|
else -> runResolverForExpressionReceiver(info, collector, receiver, manager)
|
||||||
}
|
}
|
||||||
|
|
||||||
return collector
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
fun reset() {
|
||||||
|
collector.newDataSet()
|
||||||
|
manager.reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -74,7 +74,8 @@ class PostponedArgumentsAnalyzer(
|
|||||||
|
|
||||||
val callableReferenceAccess = atom.reference
|
val callableReferenceAccess = atom.reference
|
||||||
atom.analyzed = true
|
atom.analyzed = true
|
||||||
val (candidate, applicability) = atom.resultingCandidate ?: Pair(null, CandidateApplicability.INAPPLICABLE)
|
val (candidate, applicability) = atom.resultingCandidate
|
||||||
|
?: Pair(null, CandidateApplicability.INAPPLICABLE)
|
||||||
|
|
||||||
val namedReference = when {
|
val namedReference = when {
|
||||||
candidate == null || applicability < CandidateApplicability.SYNTHETIC_RESOLVED ->
|
candidate == null || applicability < CandidateApplicability.SYNTHETIC_RESOLVED ->
|
||||||
|
|||||||
@@ -40,14 +40,19 @@ internal object CheckExplicitReceiverConsistency : ResolutionStage() {
|
|||||||
// TODO: add invoke cases
|
// TODO: add invoke cases
|
||||||
when (receiverKind) {
|
when (receiverKind) {
|
||||||
NO_EXPLICIT_RECEIVER -> {
|
NO_EXPLICIT_RECEIVER -> {
|
||||||
if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier)
|
if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier) {
|
||||||
return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER)
|
return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EXTENSION_RECEIVER, DISPATCH_RECEIVER -> {
|
EXTENSION_RECEIVER, DISPATCH_RECEIVER -> {
|
||||||
if (explicitReceiver == null) return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER)
|
if (explicitReceiver == null) {
|
||||||
|
return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BOTH_RECEIVERS -> {
|
BOTH_RECEIVERS -> {
|
||||||
if (explicitReceiver == null) return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER)
|
if (explicitReceiver == null) {
|
||||||
|
return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER)
|
||||||
|
}
|
||||||
// Here we should also check additional invoke receiver
|
// Here we should also check additional invoke receiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,13 +289,11 @@ internal object CheckVisibility : CheckerStage() {
|
|||||||
private fun ImplicitReceiverStack.canSeePrivateMemberOf(ownerId: ClassId): Boolean {
|
private fun ImplicitReceiverStack.canSeePrivateMemberOf(ownerId: ClassId): Boolean {
|
||||||
for (implicitReceiverValue in receiversAsReversed()) {
|
for (implicitReceiverValue in receiversAsReversed()) {
|
||||||
if (implicitReceiverValue !is ImplicitDispatchReceiverValue) continue
|
if (implicitReceiverValue !is ImplicitDispatchReceiverValue) continue
|
||||||
|
if (implicitReceiverValue.companionFromSupertype) continue
|
||||||
val boundSymbol = implicitReceiverValue.boundSymbol
|
val boundSymbol = implicitReceiverValue.boundSymbol
|
||||||
if (boundSymbol.classId.isSame(ownerId)) {
|
if (boundSymbol.classId.isSame(ownerId)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (boundSymbol is FirRegularClassSymbol && boundSymbol.fir.companionObject?.symbol?.classId?.isSame(ownerId) == true) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -316,6 +319,7 @@ internal object CheckVisibility : CheckerStage() {
|
|||||||
val visited = mutableSetOf<ClassId>()
|
val visited = mutableSetOf<ClassId>()
|
||||||
for (implicitReceiverValue in receiversAsReversed()) {
|
for (implicitReceiverValue in receiversAsReversed()) {
|
||||||
if (implicitReceiverValue !is ImplicitDispatchReceiverValue) continue
|
if (implicitReceiverValue !is ImplicitDispatchReceiverValue) continue
|
||||||
|
if (implicitReceiverValue.companionFromSupertype) continue
|
||||||
val boundSymbol = implicitReceiverValue.boundSymbol
|
val boundSymbol = implicitReceiverValue.boundSymbol
|
||||||
val superTypes = boundSymbol.fir.superConeTypes
|
val superTypes = boundSymbol.fir.superConeTypes
|
||||||
for (superType in superTypes) {
|
for (superType in superTypes) {
|
||||||
|
|||||||
-266
@@ -1,266 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.constructClassType
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
|
||||||
import org.jetbrains.kotlin.fir.types.ConeStarProjection
|
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
|
||||||
|
|
||||||
abstract class TowerDataConsumer {
|
|
||||||
abstract val resultCollector: CandidateCollector
|
|
||||||
|
|
||||||
abstract fun consume(
|
|
||||||
kind: TowerDataKind,
|
|
||||||
towerScopeLevel: TowerScopeLevel,
|
|
||||||
group: Int
|
|
||||||
): ProcessorAction
|
|
||||||
|
|
||||||
private var stopGroup = Int.MAX_VALUE
|
|
||||||
|
|
||||||
fun skipGroup(group: Int): Boolean {
|
|
||||||
if (stopGroup == Int.MAX_VALUE && resultCollector.isSuccess()) {
|
|
||||||
stopGroup = group
|
|
||||||
}
|
|
||||||
if (group >= stopGroup) return true
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PrioritizedTowerDataConsumer(
|
|
||||||
override val resultCollector: CandidateCollector,
|
|
||||||
private vararg val consumers: TowerDataConsumer
|
|
||||||
) : TowerDataConsumer() {
|
|
||||||
override fun consume(
|
|
||||||
kind: TowerDataKind,
|
|
||||||
towerScopeLevel: TowerScopeLevel,
|
|
||||||
group: Int
|
|
||||||
): ProcessorAction {
|
|
||||||
if (skipGroup(group)) return ProcessorAction.NEXT
|
|
||||||
var empty = true
|
|
||||||
for ((index, consumer) in consumers.withIndex()) {
|
|
||||||
when (val action = consumer.consume(kind, towerScopeLevel, group * consumers.size + index)) {
|
|
||||||
ProcessorAction.STOP -> return action
|
|
||||||
ProcessorAction.NEXT -> empty = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Yet is used exclusively for invokes:
|
|
||||||
// - initialConsumer consumes property which is invoke receiver
|
|
||||||
// - additionalConsumers consume invoke calls themselves
|
|
||||||
class AccumulatingTowerDataConsumer(
|
|
||||||
override val resultCollector: CandidateCollector
|
|
||||||
) : TowerDataConsumer() {
|
|
||||||
lateinit var initialConsumer: TowerDataConsumer
|
|
||||||
|
|
||||||
private val additionalConsumers = mutableListOf<TowerDataConsumer>()
|
|
||||||
|
|
||||||
private data class TowerData(val kind: TowerDataKind, val level: TowerScopeLevel, val group: Int)
|
|
||||||
|
|
||||||
private val accumulatedTowerData = mutableListOf<TowerData>()
|
|
||||||
|
|
||||||
override fun consume(
|
|
||||||
kind: TowerDataKind,
|
|
||||||
towerScopeLevel: TowerScopeLevel,
|
|
||||||
group: Int
|
|
||||||
): ProcessorAction {
|
|
||||||
if (skipGroup(group)) return ProcessorAction.NEXT
|
|
||||||
accumulatedTowerData += TowerData(kind, towerScopeLevel, group)
|
|
||||||
|
|
||||||
var empty = true
|
|
||||||
when (val action = initialConsumer.consume(kind, towerScopeLevel, group)) {
|
|
||||||
ProcessorAction.STOP -> return action
|
|
||||||
ProcessorAction.NEXT -> empty = false
|
|
||||||
}
|
|
||||||
for (consumer in additionalConsumers) {
|
|
||||||
when (val action = consumer.consume(kind, towerScopeLevel, group)) {
|
|
||||||
ProcessorAction.STOP -> return action
|
|
||||||
ProcessorAction.NEXT -> empty = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addConsumerAndProcessAccumulatedData(consumer: TowerDataConsumer): ProcessorAction {
|
|
||||||
additionalConsumers += consumer
|
|
||||||
if (accumulatedTowerData.isEmpty()) return ProcessorAction.NEXT
|
|
||||||
for ((kind, level, group) in accumulatedTowerData.asSequence().take(accumulatedTowerData.size - 1)) {
|
|
||||||
if (consumer.consume(kind, level, group).stop()) {
|
|
||||||
return ProcessorAction.STOP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ProcessorAction.NEXT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ExplicitReceiverTowerDataConsumer<T : AbstractFirBasedSymbol<*>>(
|
|
||||||
val session: FirSession,
|
|
||||||
val name: Name,
|
|
||||||
val token: TowerScopeLevel.Token<T>,
|
|
||||||
val explicitReceiver: AbstractExplicitReceiver<*>,
|
|
||||||
val candidateFactory: CandidateFactory,
|
|
||||||
override val resultCollector: CandidateCollector
|
|
||||||
) : TowerDataConsumer() {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val defaultPackage = Name.identifier("kotlin")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun consume(
|
|
||||||
kind: TowerDataKind,
|
|
||||||
towerScopeLevel: TowerScopeLevel,
|
|
||||||
group: Int
|
|
||||||
): ProcessorAction {
|
|
||||||
if (skipGroup(group)) return ProcessorAction.NEXT
|
|
||||||
return when (kind) {
|
|
||||||
TowerDataKind.EMPTY -> {
|
|
||||||
MemberScopeTowerLevel(
|
|
||||||
session, resultCollector.components, explicitReceiver,
|
|
||||||
implicitExtensionReceiver = (towerScopeLevel as? TowerScopeLevel.OnlyImplicitReceiver)?.implicitReceiverValue,
|
|
||||||
implicitExtensionInvokeMode = towerScopeLevel is TowerScopeLevel.OnlyImplicitReceiver,
|
|
||||||
scopeSession = candidateFactory.bodyResolveComponents.scopeSession
|
|
||||||
).processElementsByName(
|
|
||||||
token,
|
|
||||||
name,
|
|
||||||
explicitReceiver = null,
|
|
||||||
processor = EmptyKindTowerProcessor(group)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
TowerDataKind.TOWER_LEVEL -> {
|
|
||||||
if (token == TowerScopeLevel.Token.Objects) return ProcessorAction.NEXT
|
|
||||||
towerScopeLevel.processElementsByName(
|
|
||||||
token,
|
|
||||||
name,
|
|
||||||
explicitReceiver = explicitReceiver,
|
|
||||||
processor = TowerLevelKindTowerProcessor(group)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private inner class EmptyKindTowerProcessor(val group: Int) : TowerScopeLevel.TowerScopeLevelProcessor<T> {
|
|
||||||
override fun consumeCandidate(
|
|
||||||
symbol: T,
|
|
||||||
dispatchReceiverValue: ReceiverValue?,
|
|
||||||
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
|
||||||
builtInExtensionFunctionReceiverValue: ReceiverValue?
|
|
||||||
) {
|
|
||||||
resultCollector.consumeCandidate(
|
|
||||||
group,
|
|
||||||
candidateFactory.createCandidate(
|
|
||||||
symbol,
|
|
||||||
ExplicitReceiverKind.DISPATCH_RECEIVER,
|
|
||||||
dispatchReceiverValue,
|
|
||||||
implicitExtensionReceiverValue,
|
|
||||||
builtInExtensionFunctionReceiverValue
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class TowerLevelKindTowerProcessor(val group: Int) : TowerScopeLevel.TowerScopeLevelProcessor<T> {
|
|
||||||
override fun consumeCandidate(
|
|
||||||
symbol: T,
|
|
||||||
dispatchReceiverValue: ReceiverValue?,
|
|
||||||
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
|
||||||
builtInExtensionFunctionReceiverValue: ReceiverValue?
|
|
||||||
) {
|
|
||||||
if (symbol is FirNamedFunctionSymbol && symbol.callableId.packageName.startsWith(defaultPackage)) {
|
|
||||||
val explicitReceiverType = explicitReceiver.type
|
|
||||||
if (dispatchReceiverValue == null && explicitReceiverType is ConeClassLikeType) {
|
|
||||||
val declarationReceiverTypeRef =
|
|
||||||
(symbol as? FirCallableSymbol<*>)?.fir?.receiverTypeRef as? FirResolvedTypeRef
|
|
||||||
val declarationReceiverType = declarationReceiverTypeRef?.type
|
|
||||||
if (declarationReceiverType is ConeClassLikeType) {
|
|
||||||
if (!AbstractTypeChecker.isSubtypeOf(
|
|
||||||
candidateFactory.bodyResolveComponents.inferenceComponents.ctx,
|
|
||||||
explicitReceiverType,
|
|
||||||
declarationReceiverType.lookupTag.constructClassType(
|
|
||||||
declarationReceiverType.typeArguments.map { ConeStarProjection }.toTypedArray(),
|
|
||||||
isNullable = true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val candidate = candidateFactory.createCandidate(
|
|
||||||
symbol,
|
|
||||||
ExplicitReceiverKind.EXTENSION_RECEIVER,
|
|
||||||
dispatchReceiverValue,
|
|
||||||
implicitExtensionReceiverValue,
|
|
||||||
builtInExtensionFunctionReceiverValue
|
|
||||||
)
|
|
||||||
|
|
||||||
resultCollector.consumeCandidate(
|
|
||||||
group,
|
|
||||||
candidate
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NoExplicitReceiverTowerDataConsumer<T : AbstractFirBasedSymbol<*>>(
|
|
||||||
val session: FirSession,
|
|
||||||
val name: Name,
|
|
||||||
val token: TowerScopeLevel.Token<T>,
|
|
||||||
val candidateFactory: CandidateFactory,
|
|
||||||
override val resultCollector: CandidateCollector
|
|
||||||
) : TowerDataConsumer() {
|
|
||||||
override fun consume(
|
|
||||||
kind: TowerDataKind,
|
|
||||||
towerScopeLevel: TowerScopeLevel,
|
|
||||||
group: Int
|
|
||||||
): ProcessorAction {
|
|
||||||
if (skipGroup(group)) return ProcessorAction.NEXT
|
|
||||||
return when (kind) {
|
|
||||||
|
|
||||||
TowerDataKind.TOWER_LEVEL -> {
|
|
||||||
towerScopeLevel.processElementsByName(
|
|
||||||
token,
|
|
||||||
name,
|
|
||||||
explicitReceiver = null,
|
|
||||||
processor = TowerLevelProcessorImpl(group)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else -> ProcessorAction.NEXT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class TowerLevelProcessorImpl(val group: Int) : TowerScopeLevel.TowerScopeLevelProcessor<T> {
|
|
||||||
override fun consumeCandidate(
|
|
||||||
symbol: T,
|
|
||||||
dispatchReceiverValue: ReceiverValue?,
|
|
||||||
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
|
||||||
builtInExtensionFunctionReceiverValue: ReceiverValue?
|
|
||||||
) {
|
|
||||||
resultCollector.consumeCandidate(
|
|
||||||
group,
|
|
||||||
candidateFactory.createCandidate(
|
|
||||||
symbol,
|
|
||||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
|
||||||
dispatchReceiverValue,
|
|
||||||
implicitExtensionReceiverValue,
|
|
||||||
builtInExtensionFunctionReceiverValue
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
|
sealed class TowerGroupKind(private val index: Int) : Comparable<TowerGroupKind> {
|
||||||
|
abstract class WithDepth(index: Int, val depth: Int) : TowerGroupKind(index)
|
||||||
|
|
||||||
|
object Start : TowerGroupKind(Integer.MIN_VALUE)
|
||||||
|
|
||||||
|
class Weakened(depth: Int) : WithDepth(-10, depth)
|
||||||
|
|
||||||
|
object Qualifier : TowerGroupKind(0)
|
||||||
|
|
||||||
|
class TopPrioritized(depth: Int) : WithDepth(1, depth)
|
||||||
|
|
||||||
|
object Member : TowerGroupKind(2)
|
||||||
|
|
||||||
|
class Local(depth: Int) : WithDepth(3, depth)
|
||||||
|
|
||||||
|
class Implicit(depth: Int) : WithDepth(4, depth)
|
||||||
|
|
||||||
|
object InvokeExtension : TowerGroupKind(5)
|
||||||
|
|
||||||
|
class Top(depth: Int) : WithDepth(6, depth)
|
||||||
|
|
||||||
|
class Static(depth: Int) : WithDepth(7, depth)
|
||||||
|
|
||||||
|
object Last : TowerGroupKind(Integer.MAX_VALUE)
|
||||||
|
|
||||||
|
override fun compareTo(other: TowerGroupKind): Int {
|
||||||
|
val indexResult = index.compareTo(other.index)
|
||||||
|
if (indexResult != 0) return indexResult
|
||||||
|
if (this is WithDepth && other is WithDepth) {
|
||||||
|
return depth.compareTo(other.depth)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("FunctionName", "unused", "PropertyName")
|
||||||
|
class TowerGroup private constructor(private val list: List<TowerGroupKind>) : Comparable<TowerGroup> {
|
||||||
|
companion object {
|
||||||
|
private fun kindOf(kind: TowerGroupKind): TowerGroup = TowerGroup(listOf(kind))
|
||||||
|
|
||||||
|
val Start = kindOf(TowerGroupKind.Start)
|
||||||
|
|
||||||
|
val Qualifier = kindOf(TowerGroupKind.Qualifier)
|
||||||
|
|
||||||
|
val Member = kindOf(TowerGroupKind.Member)
|
||||||
|
|
||||||
|
fun Local(depth: Int) = kindOf(TowerGroupKind.Local(depth))
|
||||||
|
|
||||||
|
fun Implicit(depth: Int) = kindOf(TowerGroupKind.Implicit(depth))
|
||||||
|
|
||||||
|
fun Top(depth: Int) = kindOf(TowerGroupKind.Top(depth))
|
||||||
|
|
||||||
|
fun TopPrioritized(depth: Int) = kindOf(TowerGroupKind.TopPrioritized(depth))
|
||||||
|
|
||||||
|
fun Static(depth: Int) = kindOf(TowerGroupKind.Static(depth))
|
||||||
|
|
||||||
|
val Last = kindOf(TowerGroupKind.Last)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun kindOf(kind: TowerGroupKind): TowerGroup = TowerGroup(list + kind)
|
||||||
|
|
||||||
|
fun Weakened(depth: Int) = kindOf(TowerGroupKind.Weakened(depth))
|
||||||
|
|
||||||
|
val Qualifier get() = kindOf(TowerGroupKind.Qualifier)
|
||||||
|
|
||||||
|
val Member get() = kindOf(TowerGroupKind.Member)
|
||||||
|
|
||||||
|
fun Local(depth: Int) = kindOf(TowerGroupKind.Local(depth))
|
||||||
|
|
||||||
|
fun Implicit(depth: Int) = kindOf(TowerGroupKind.Implicit(depth))
|
||||||
|
|
||||||
|
val InvokeExtension get() = kindOf(TowerGroupKind.InvokeExtension)
|
||||||
|
|
||||||
|
fun Top(depth: Int) = kindOf(TowerGroupKind.Top(depth))
|
||||||
|
|
||||||
|
fun Static(depth: Int) = kindOf(TowerGroupKind.Static(depth))
|
||||||
|
|
||||||
|
override fun compareTo(other: TowerGroup): Int {
|
||||||
|
var index = 0
|
||||||
|
while (index < list.size) {
|
||||||
|
if (index >= other.list.size) return 1
|
||||||
|
when {
|
||||||
|
list[index] < other.list[index] -> return -1
|
||||||
|
list[index] > other.list[index] -> return 1
|
||||||
|
}
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
if (index < other.list.size) return -1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
println(TowerGroup.Member < TowerGroup.Last)
|
||||||
|
println(TowerGroup.Member < TowerGroup.Member.Weakened(1))
|
||||||
|
println(TowerGroup.Member.Weakened(1) < TowerGroup.Member)
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
|
|
||||||
|
internal class TowerInvokeResolveQuery(
|
||||||
|
val towerLevel: SessionBasedTowerLevel,
|
||||||
|
val callInfo: CallInfo,
|
||||||
|
val explicitReceiverKind: ExplicitReceiverKind,
|
||||||
|
val group: TowerGroup,
|
||||||
|
val mode: InvokeResolveMode
|
||||||
|
) : Comparable<TowerInvokeResolveQuery> {
|
||||||
|
override fun compareTo(other: TowerInvokeResolveQuery): Int {
|
||||||
|
return group.compareTo(other.group)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class InvokeResolveMode {
|
||||||
|
IMPLICIT_CALL_ON_GIVEN_RECEIVER,
|
||||||
|
RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||||
|
}
|
||||||
@@ -6,10 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.isStatic
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
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
|
||||||
@@ -18,11 +15,11 @@ import org.jetbrains.kotlin.fir.resolve.withNullability
|
|||||||
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.scopes.impl.FirAbstractImportingScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.FirQualifierScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeNullability
|
import org.jetbrains.kotlin.fir.types.ConeNullability
|
||||||
import org.jetbrains.kotlin.fir.types.isExtensionFunctionType
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
@@ -39,7 +36,6 @@ interface TowerScopeLevel {
|
|||||||
fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
|
fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
|
||||||
token: Token<T>,
|
token: Token<T>,
|
||||||
name: Name,
|
name: Name,
|
||||||
explicitReceiver: AbstractExplicitReceiver<*>?,
|
|
||||||
processor: TowerScopeLevelProcessor<T>
|
processor: TowerScopeLevelProcessor<T>
|
||||||
): ProcessorAction
|
): ProcessorAction
|
||||||
|
|
||||||
@@ -51,19 +47,6 @@ interface TowerScopeLevel {
|
|||||||
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
|
builtInExtensionFunctionReceiverValue: ReceiverValue? = null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class StubTowerScopeLevel : TowerScopeLevel {
|
|
||||||
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
|
|
||||||
token: Token<T>,
|
|
||||||
name: Name,
|
|
||||||
explicitReceiver: AbstractExplicitReceiver<*>?,
|
|
||||||
processor: TowerScopeLevelProcessor<T>
|
|
||||||
): ProcessorAction = ProcessorAction.NEXT
|
|
||||||
}
|
|
||||||
|
|
||||||
object Empty : StubTowerScopeLevel()
|
|
||||||
|
|
||||||
class OnlyImplicitReceiver(val implicitReceiverValue: ImplicitReceiverValue<*>) : StubTowerScopeLevel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel {
|
abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel {
|
||||||
@@ -77,12 +60,11 @@ abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun FirCallableSymbol<*>.hasConsistentExtensionReceiver(extensionReceiver: ReceiverValue?): Boolean {
|
protected fun FirCallableSymbol<*>.hasConsistentExtensionReceiver(extensionReceiver: Receiver?): Boolean {
|
||||||
return when {
|
return (extensionReceiver != null) == hasExtensionReceiver()
|
||||||
extensionReceiver != null -> hasExtensionReceiver()
|
|
||||||
else -> fir.receiverTypeRef == null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun replaceReceiverValue(receiverValue: ReceiverValue) = this
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is more like "dispatch receiver-based tower level"
|
// This is more like "dispatch receiver-based tower level"
|
||||||
@@ -93,73 +75,82 @@ abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel
|
|||||||
// or given implicit or explicit receiver, otherwise
|
// or given implicit or explicit receiver, otherwise
|
||||||
class MemberScopeTowerLevel(
|
class MemberScopeTowerLevel(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
val bodyResolveComponents: BodyResolveComponents,
|
private val bodyResolveComponents: BodyResolveComponents,
|
||||||
val dispatchReceiver: ReceiverValue,
|
val dispatchReceiver: ReceiverValue,
|
||||||
val implicitExtensionReceiver: ImplicitReceiverValue<*>? = null,
|
val extensionReceiver: ReceiverValue? = null,
|
||||||
val implicitExtensionInvokeMode: 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: AbstractExplicitReceiver<*>?,
|
|
||||||
processScopeMembers: FirScope.(processor: (T) -> Unit) -> Unit
|
processScopeMembers: FirScope.(processor: (T) -> Unit) -> Unit
|
||||||
) {
|
): ProcessorAction {
|
||||||
if (implicitExtensionReceiver != null && explicitExtensionReceiver != null) return
|
var empty = true
|
||||||
val extensionReceiver = implicitExtensionReceiver ?: explicitExtensionReceiver
|
val scope = dispatchReceiver.scope(session, scopeSession) ?: return ProcessorAction.NONE
|
||||||
val scope = dispatchReceiver.scope(session, scopeSession) ?: return
|
|
||||||
scope.processScopeMembers { candidate ->
|
scope.processScopeMembers { candidate ->
|
||||||
|
empty = false
|
||||||
if (candidate is FirCallableSymbol<*> &&
|
if (candidate is FirCallableSymbol<*> &&
|
||||||
(implicitExtensionInvokeMode || candidate.hasConsistentExtensionReceiver(extensionReceiver))
|
(implicitExtensionInvokeMode || candidate.hasConsistentExtensionReceiver(extensionReceiver))
|
||||||
) {
|
) {
|
||||||
|
val fir = candidate.fir
|
||||||
|
if ((fir as? FirCallableMemberDeclaration<*>)?.isStatic == true || (fir as? FirConstructor)?.isInner == false) {
|
||||||
|
return@processScopeMembers
|
||||||
|
}
|
||||||
val dispatchReceiverValue = NotNullableReceiverValue(dispatchReceiver)
|
val dispatchReceiverValue = NotNullableReceiverValue(dispatchReceiver)
|
||||||
if (implicitExtensionInvokeMode) {
|
if (implicitExtensionInvokeMode) {
|
||||||
output.consumeCandidate(
|
output.consumeCandidate(
|
||||||
candidate, dispatchReceiverValue,
|
candidate, dispatchReceiverValue,
|
||||||
implicitExtensionReceiverValue = implicitExtensionReceiver
|
implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>
|
||||||
)
|
)
|
||||||
output.consumeCandidate(
|
output.consumeCandidate(
|
||||||
candidate, dispatchReceiverValue,
|
candidate, dispatchReceiverValue,
|
||||||
implicitExtensionReceiverValue = null,
|
implicitExtensionReceiverValue = null,
|
||||||
builtInExtensionFunctionReceiverValue = implicitExtensionReceiver
|
builtInExtensionFunctionReceiverValue = this.extensionReceiver
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
output.consumeCandidate(candidate, dispatchReceiverValue, implicitExtensionReceiver, null)
|
output.consumeCandidate(candidate, dispatchReceiverValue, extensionReceiver as? ImplicitReceiverValue<*>)
|
||||||
}
|
}
|
||||||
} else if (candidate is FirClassLikeSymbol<*>) {
|
} else if (candidate is FirClassLikeSymbol<*>) {
|
||||||
output.consumeCandidate(candidate, null, implicitExtensionReceiver, null)
|
output.consumeCandidate(candidate, null, extensionReceiver as? ImplicitReceiverValue<*>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val withSynthetic = FirSyntheticPropertiesScope(session, scope)
|
val withSynthetic = FirSyntheticPropertiesScope(session, scope)
|
||||||
withSynthetic.processScopeMembers { symbol ->
|
withSynthetic.processScopeMembers { symbol ->
|
||||||
output.consumeCandidate(symbol, NotNullableReceiverValue(dispatchReceiver), implicitExtensionReceiver, null)
|
output.consumeCandidate(symbol, NotNullableReceiverValue(dispatchReceiver), extensionReceiver as? ImplicitReceiverValue<*>)
|
||||||
}
|
}
|
||||||
|
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
|
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
|
||||||
token: TowerScopeLevel.Token<T>,
|
token: TowerScopeLevel.Token<T>,
|
||||||
name: Name,
|
name: Name,
|
||||||
explicitReceiver: AbstractExplicitReceiver<*>?,
|
|
||||||
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 (implicitExtensionInvokeMode && !isInvoke) {
|
if (implicitExtensionInvokeMode && !isInvoke) {
|
||||||
return ProcessorAction.NEXT
|
return ProcessorAction.NEXT
|
||||||
}
|
}
|
||||||
val explicitExtensionReceiver = if (dispatchReceiver == explicitReceiver) null else explicitReceiver
|
return when (token) {
|
||||||
val noInnerConstructors = dispatchReceiver is QualifierReceiver
|
TowerScopeLevel.Token.Properties -> processMembers(processor) { symbol ->
|
||||||
when (token) {
|
|
||||||
TowerScopeLevel.Token.Properties -> processMembers(processor, explicitExtensionReceiver) { symbol ->
|
|
||||||
this.processPropertiesByName(name, symbol.cast())
|
this.processPropertiesByName(name, symbol.cast())
|
||||||
}
|
}
|
||||||
TowerScopeLevel.Token.Functions -> processMembers(processor, explicitExtensionReceiver) { symbol ->
|
TowerScopeLevel.Token.Functions -> processMembers(processor) { symbol ->
|
||||||
this.processFunctionsAndConstructorsByName(name, session, bodyResolveComponents, noInnerConstructors, symbol.cast())
|
this.processFunctionsAndConstructorsByName(
|
||||||
|
name, session, bodyResolveComponents,
|
||||||
|
noInnerConstructors = false, processor = symbol.cast()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
TowerScopeLevel.Token.Objects -> processMembers(processor, explicitExtensionReceiver) { symbol ->
|
TowerScopeLevel.Token.Objects -> processMembers(processor) { symbol ->
|
||||||
this.processClassifiersByName(name, symbol.cast())
|
this.processClassifiersByName(name, symbol.cast())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ProcessorAction.NEXT
|
}
|
||||||
|
|
||||||
|
override fun replaceReceiverValue(receiverValue: ReceiverValue): SessionBasedTowerLevel {
|
||||||
|
return MemberScopeTowerLevel(
|
||||||
|
session, bodyResolveComponents, receiverValue, extensionReceiver, implicitExtensionInvokeMode, scopeSession
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,10 +165,10 @@ class ScopeTowerLevel(
|
|||||||
session: FirSession,
|
session: FirSession,
|
||||||
private val bodyResolveComponents: BodyResolveComponents,
|
private val bodyResolveComponents: BodyResolveComponents,
|
||||||
val scope: FirScope,
|
val scope: FirScope,
|
||||||
val implicitExtensionReceiver: ImplicitReceiverValue<*>? = null,
|
val extensionReceiver: ReceiverValue? = null,
|
||||||
private val extensionsOnly: Boolean = false
|
private val extensionsOnly: Boolean = false
|
||||||
) : SessionBasedTowerLevel(session) {
|
) : SessionBasedTowerLevel(session) {
|
||||||
private fun FirCallableSymbol<*>.hasConsistentReceivers(extensionReceiver: ReceiverValue?): Boolean =
|
private fun FirCallableSymbol<*>.hasConsistentReceivers(extensionReceiver: Receiver?): Boolean =
|
||||||
when {
|
when {
|
||||||
extensionsOnly && !hasExtensionReceiver() -> false
|
extensionsOnly && !hasExtensionReceiver() -> false
|
||||||
!hasConsistentExtensionReceiver(extensionReceiver) -> false
|
!hasConsistentExtensionReceiver(extensionReceiver) -> false
|
||||||
@@ -188,43 +179,43 @@ class ScopeTowerLevel(
|
|||||||
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
|
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
|
||||||
token: TowerScopeLevel.Token<T>,
|
token: TowerScopeLevel.Token<T>,
|
||||||
name: Name,
|
name: Name,
|
||||||
explicitReceiver: AbstractExplicitReceiver<*>?,
|
|
||||||
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
|
processor: TowerScopeLevel.TowerScopeLevelProcessor<T>
|
||||||
): ProcessorAction {
|
): ProcessorAction {
|
||||||
if (explicitReceiver != null && implicitExtensionReceiver != null) {
|
var empty = true
|
||||||
return ProcessorAction.NEXT
|
|
||||||
}
|
|
||||||
val extensionReceiver = explicitReceiver ?: implicitExtensionReceiver
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
when (token) {
|
when (token) {
|
||||||
TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name) { candidate ->
|
TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name) { candidate ->
|
||||||
|
empty = false
|
||||||
if (candidate.hasConsistentReceivers(extensionReceiver)) {
|
if (candidate.hasConsistentReceivers(extensionReceiver)) {
|
||||||
processor.consumeCandidate(
|
processor.consumeCandidate(
|
||||||
candidate as T, dispatchReceiverValue = null,
|
candidate as T, dispatchReceiverValue = null,
|
||||||
implicitExtensionReceiverValue = implicitExtensionReceiver
|
implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TowerScopeLevel.Token.Functions -> scope.processFunctionsAndConstructorsByName(
|
TowerScopeLevel.Token.Functions -> scope.processFunctionsAndConstructorsByName(
|
||||||
name,
|
name,
|
||||||
session,
|
session,
|
||||||
bodyResolveComponents
|
bodyResolveComponents,
|
||||||
|
noInnerConstructors = scope is FirQualifierScope
|
||||||
) { candidate ->
|
) { candidate ->
|
||||||
|
empty = false
|
||||||
if (candidate.hasConsistentReceivers(extensionReceiver)) {
|
if (candidate.hasConsistentReceivers(extensionReceiver)) {
|
||||||
processor.consumeCandidate(
|
processor.consumeCandidate(
|
||||||
candidate as T, dispatchReceiverValue = null,
|
candidate as T, dispatchReceiverValue = null,
|
||||||
implicitExtensionReceiverValue = implicitExtensionReceiver
|
implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TowerScopeLevel.Token.Objects -> scope.processClassifiersByName(name) {
|
TowerScopeLevel.Token.Objects -> scope.processClassifiersByName(name) {
|
||||||
|
empty = false
|
||||||
processor.consumeCandidate(
|
processor.consumeCandidate(
|
||||||
it as T, dispatchReceiverValue = null,
|
it as T, dispatchReceiverValue = null,
|
||||||
implicitExtensionReceiverValue = null
|
implicitExtensionReceiverValue = null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ProcessorAction.NEXT
|
return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,6 +237,5 @@ fun FirCallableDeclaration<*>.dispatchReceiverValue(session: FirSession): ClassD
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun FirCallableSymbol<*>.hasExtensionReceiver(): Boolean {
|
private fun FirCallableSymbol<*>.hasExtensionReceiver(): Boolean {
|
||||||
if (fir.receiverTypeRef != null) return true
|
return fir.receiverTypeRef != null
|
||||||
return fir.returnTypeRef.isExtensionFunctionType()
|
|
||||||
}
|
}
|
||||||
|
|||||||
+306
@@ -0,0 +1,306 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.constructClassType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformQualifiedAccessUsingSmartcastInfo
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class TowerResolveManager internal constructor(private val towerResolver: FirTowerResolver) {
|
||||||
|
private val queue = PriorityQueue<TowerInvokeResolveQuery>()
|
||||||
|
|
||||||
|
private var group = TowerGroup.Start
|
||||||
|
|
||||||
|
lateinit var candidateFactory: CandidateFactory
|
||||||
|
|
||||||
|
lateinit var invokeOnGivenReceiverCandidateFactory: CandidateFactory
|
||||||
|
|
||||||
|
lateinit var invokeReceiverCandidateFactory: CandidateFactory
|
||||||
|
|
||||||
|
lateinit var invokeBuiltinExtensionReceiverCandidateFactory: CandidateFactory
|
||||||
|
|
||||||
|
lateinit var stubReceiverCandidateFactory: CandidateFactory
|
||||||
|
|
||||||
|
lateinit var resultCollector: CandidateCollector
|
||||||
|
|
||||||
|
lateinit var invokeReceiverCollector: CandidateCollector
|
||||||
|
|
||||||
|
private class TowerScopeLevelProcessor(
|
||||||
|
val explicitReceiver: FirExpression?,
|
||||||
|
val explicitReceiverKind: ExplicitReceiverKind,
|
||||||
|
val resultCollector: CandidateCollector,
|
||||||
|
val candidateFactory: CandidateFactory,
|
||||||
|
val group: TowerGroup
|
||||||
|
) : TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>> {
|
||||||
|
override fun consumeCandidate(
|
||||||
|
symbol: AbstractFirBasedSymbol<*>,
|
||||||
|
dispatchReceiverValue: ReceiverValue?,
|
||||||
|
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
||||||
|
builtInExtensionFunctionReceiverValue: ReceiverValue?
|
||||||
|
) {
|
||||||
|
// Check explicit extension receiver for default package members
|
||||||
|
if (symbol is FirNamedFunctionSymbol && dispatchReceiverValue == null &&
|
||||||
|
(implicitExtensionReceiverValue == null) != (explicitReceiver == null) &&
|
||||||
|
explicitReceiver !is FirResolvedQualifier &&
|
||||||
|
symbol.callableId.packageName.startsWith(defaultPackage)
|
||||||
|
) {
|
||||||
|
val extensionReceiverType = explicitReceiver?.typeRef?.coneTypeSafe()
|
||||||
|
?: implicitExtensionReceiverValue?.type as? ConeClassLikeType
|
||||||
|
if (extensionReceiverType != null) {
|
||||||
|
val declarationReceiverTypeRef =
|
||||||
|
(symbol as? FirCallableSymbol<*>)?.fir?.receiverTypeRef as? FirResolvedTypeRef
|
||||||
|
val declarationReceiverType = declarationReceiverTypeRef?.type
|
||||||
|
if (declarationReceiverType is ConeClassLikeType) {
|
||||||
|
if (!AbstractTypeChecker.isSubtypeOf(
|
||||||
|
candidateFactory.bodyResolveComponents.inferenceComponents.ctx,
|
||||||
|
extensionReceiverType,
|
||||||
|
declarationReceiverType.lookupTag.constructClassType(
|
||||||
|
declarationReceiverType.typeArguments.map { ConeStarProjection }.toTypedArray(),
|
||||||
|
isNullable = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ---
|
||||||
|
resultCollector.consumeCandidate(
|
||||||
|
group, candidateFactory.createCandidate(
|
||||||
|
symbol,
|
||||||
|
explicitReceiverKind,
|
||||||
|
dispatchReceiverValue,
|
||||||
|
implicitExtensionReceiverValue,
|
||||||
|
builtInExtensionFunctionReceiverValue
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val defaultPackage = Name.identifier("kotlin")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private inner class LevelHandler(
|
||||||
|
val info: CallInfo,
|
||||||
|
val explicitReceiverKind: ExplicitReceiverKind,
|
||||||
|
val group: TowerGroup
|
||||||
|
) {
|
||||||
|
private fun createExplicitReceiverForInvoke(candidate: Candidate): FirQualifiedAccessExpressionImpl {
|
||||||
|
val symbol = candidate.symbol as FirCallableSymbol<*>
|
||||||
|
return FirQualifiedAccessExpressionImpl(null).apply {
|
||||||
|
calleeReference = FirNamedReferenceWithCandidate(
|
||||||
|
null,
|
||||||
|
symbol.callableId.callableName,
|
||||||
|
candidate
|
||||||
|
)
|
||||||
|
dispatchReceiver = candidate.dispatchReceiverExpression()
|
||||||
|
typeRef = towerResolver.typeCalculator.tryCalculateReturnType(symbol.firUnsafe())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun SessionBasedTowerLevel.handleLevel(invokeResolveMode: InvokeResolveMode? = null): ProcessorAction {
|
||||||
|
var result = ProcessorAction.NONE
|
||||||
|
val processor =
|
||||||
|
TowerScopeLevelProcessor(
|
||||||
|
info.explicitReceiver,
|
||||||
|
explicitReceiverKind,
|
||||||
|
resultCollector,
|
||||||
|
// TODO: performance?
|
||||||
|
if (invokeResolveMode == InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER) {
|
||||||
|
invokeOnGivenReceiverCandidateFactory
|
||||||
|
} else candidateFactory,
|
||||||
|
group
|
||||||
|
)
|
||||||
|
when (info.callKind) {
|
||||||
|
CallKind.VariableAccess -> {
|
||||||
|
result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor)
|
||||||
|
// TODO: more accurate condition, or process properties/object in some other way
|
||||||
|
if (!resultCollector.isSuccess() &&
|
||||||
|
(this !is ScopeTowerLevel || this.extensionReceiver == null)
|
||||||
|
) {
|
||||||
|
result += processElementsByName(TowerScopeLevel.Token.Objects, info.name, processor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CallKind.Function -> {
|
||||||
|
val invokeBuiltinExtensionMode =
|
||||||
|
invokeResolveMode == InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION
|
||||||
|
if (!invokeBuiltinExtensionMode) {
|
||||||
|
result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor)
|
||||||
|
}
|
||||||
|
if (invokeResolveMode == InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER ||
|
||||||
|
resultCollector.isSuccess()
|
||||||
|
) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
val invokeReceiverProcessor = TowerScopeLevelProcessor(
|
||||||
|
info.explicitReceiver,
|
||||||
|
explicitReceiverKind,
|
||||||
|
invokeReceiverCollector,
|
||||||
|
if (invokeBuiltinExtensionMode) invokeBuiltinExtensionReceiverCandidateFactory
|
||||||
|
else invokeReceiverCandidateFactory,
|
||||||
|
group
|
||||||
|
)
|
||||||
|
invokeReceiverCollector.newDataSet()
|
||||||
|
result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, invokeReceiverProcessor)
|
||||||
|
|
||||||
|
if (invokeReceiverCollector.isSuccess()) {
|
||||||
|
for (invokeReceiverCandidate in invokeReceiverCollector.bestCandidates()) {
|
||||||
|
|
||||||
|
val symbol = invokeReceiverCandidate.symbol as FirCallableSymbol<*>
|
||||||
|
val isExtensionFunctionType = symbol.fir.returnTypeRef.isExtensionFunctionType()
|
||||||
|
if (invokeBuiltinExtensionMode && !isExtensionFunctionType) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val extensionReceiverExpression = invokeReceiverCandidate.extensionReceiverExpression()
|
||||||
|
val useImplicitReceiverAsBuiltinInvokeArgument =
|
||||||
|
!invokeBuiltinExtensionMode && isExtensionFunctionType &&
|
||||||
|
invokeReceiverCandidate.explicitReceiverKind == ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||||
|
|
||||||
|
val invokeReceiverExpression = createExplicitReceiverForInvoke(invokeReceiverCandidate).let {
|
||||||
|
if (!invokeBuiltinExtensionMode) {
|
||||||
|
it.extensionReceiver = extensionReceiverExpression
|
||||||
|
// NB: this should fix problem in DFA (KT-36014)
|
||||||
|
it.explicitReceiver = info.explicitReceiver
|
||||||
|
it.safe = info.isSafeCall
|
||||||
|
}
|
||||||
|
towerResolver.components.transformQualifiedAccessUsingSmartcastInfo(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
val invokeFunctionInfo =
|
||||||
|
info.copy(explicitReceiver = invokeReceiverExpression, name = OperatorNameConventions.INVOKE).let {
|
||||||
|
when {
|
||||||
|
invokeBuiltinExtensionMode -> it.withReceiverAsArgument(info.explicitReceiver!!)
|
||||||
|
else -> it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val explicitReceiver = ExpressionReceiverValue(invokeReceiverExpression)
|
||||||
|
invokeOnGivenReceiverCandidateFactory = CandidateFactory(towerResolver.components, invokeFunctionInfo)
|
||||||
|
when {
|
||||||
|
invokeBuiltinExtensionMode -> {
|
||||||
|
towerResolver.enqueueResolverForBuiltinInvokeExtensionWithExplicitArgument(
|
||||||
|
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||||
|
)
|
||||||
|
}
|
||||||
|
useImplicitReceiverAsBuiltinInvokeArgument -> {
|
||||||
|
towerResolver.enqueueResolverForBuiltinInvokeExtensionWithImplicitArgument(
|
||||||
|
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||||
|
)
|
||||||
|
towerResolver.enqueueResolverForInvoke(
|
||||||
|
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
towerResolver.enqueueResolverForInvoke(
|
||||||
|
invokeFunctionInfo, explicitReceiver, this@TowerResolveManager
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processQueuedLevelsForInvoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CallKind.CallableReference -> {
|
||||||
|
val stubReceiver = info.stubReceiver
|
||||||
|
if (stubReceiver != null) {
|
||||||
|
val stubReceiverValue = ExpressionReceiverValue(stubReceiver)
|
||||||
|
val stubProcessor = TowerScopeLevelProcessor(
|
||||||
|
info.explicitReceiver,
|
||||||
|
if (this is MemberScopeTowerLevel && dispatchReceiver is AbstractExplicitReceiver<*>) {
|
||||||
|
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||||
|
} else {
|
||||||
|
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
|
},
|
||||||
|
resultCollector,
|
||||||
|
stubReceiverCandidateFactory, group
|
||||||
|
)
|
||||||
|
val towerLevelWithStubReceiver = replaceReceiverValue(stubReceiverValue)
|
||||||
|
with(towerLevelWithStubReceiver) {
|
||||||
|
result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, stubProcessor)
|
||||||
|
result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, stubProcessor)
|
||||||
|
}
|
||||||
|
// NB: we don't perform this for implicit Unit
|
||||||
|
if (!resultCollector.isSuccess() && info.explicitReceiver?.typeRef !is FirImplicitBuiltinTypeRef) {
|
||||||
|
result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor)
|
||||||
|
result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor)
|
||||||
|
result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
|
queue.clear()
|
||||||
|
group = TowerGroup.Start
|
||||||
|
}
|
||||||
|
|
||||||
|
fun processLevel(
|
||||||
|
towerLevel: SessionBasedTowerLevel,
|
||||||
|
callInfo: CallInfo,
|
||||||
|
group: TowerGroup,
|
||||||
|
explicitReceiverKind: ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||||
|
): ProcessorAction {
|
||||||
|
assert(group > this.group) {
|
||||||
|
"Incorrect TowerGroup processing order (c) Mikhail Glukhikh"
|
||||||
|
}
|
||||||
|
this.group = group
|
||||||
|
val result = with(LevelHandler(callInfo, explicitReceiverKind, group)) {
|
||||||
|
towerLevel.handleLevel()
|
||||||
|
}
|
||||||
|
processQueuedLevelsForInvoke()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enqueueLevelForInvoke(
|
||||||
|
towerLevel: SessionBasedTowerLevel,
|
||||||
|
callInfo: CallInfo,
|
||||||
|
group: TowerGroup,
|
||||||
|
mode: InvokeResolveMode,
|
||||||
|
explicitReceiverKind: ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||||
|
) {
|
||||||
|
if (callInfo.callKind == CallKind.Function) {
|
||||||
|
queue.add(TowerInvokeResolveQuery(towerLevel, callInfo, explicitReceiverKind, group, mode))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun processQueuedLevelsForInvoke(groupLimit: TowerGroup = this.group) {
|
||||||
|
while (queue.isNotEmpty()) {
|
||||||
|
if (queue.peek().group > groupLimit) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
val query = queue.poll()
|
||||||
|
with(LevelHandler(query.callInfo, query.explicitReceiverKind, query.group)) {
|
||||||
|
query.towerLevel.handleLevel(invokeResolveMode = query.mode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
-2
@@ -15,8 +15,7 @@ import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.extractLambdaInfoFromFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.calls.extractLambdaInfoFromFunctionalType
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
||||||
@@ -493,8 +492,24 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
|||||||
type: ConeKotlinType,
|
type: ConeKotlinType,
|
||||||
block: () -> T
|
block: () -> T
|
||||||
): T {
|
): T {
|
||||||
|
val implicitCompanionValues = mutableListOf<ImplicitReceiverValue<*>>()
|
||||||
val implicitReceiverValue = when (owner) {
|
val implicitReceiverValue = when (owner) {
|
||||||
is FirClass<*> -> {
|
is FirClass<*> -> {
|
||||||
|
// Questionable: performance
|
||||||
|
(owner as? FirRegularClass)?.companionObject?.let { companion ->
|
||||||
|
implicitCompanionValues += ImplicitDispatchReceiverValue(
|
||||||
|
companion.symbol, session, scopeSession, kind = ImplicitDispatchReceiverKind.COMPANION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
lookupSuperTypes(owner, lookupInterfaces = false, deep = true, useSiteSession = session).mapNotNull {
|
||||||
|
val superClass = (it as? ConeClassLikeType)?.lookupTag?.toSymbol(session)?.fir as? FirRegularClass
|
||||||
|
superClass?.companionObject?.let { companion ->
|
||||||
|
implicitCompanionValues += ImplicitDispatchReceiverValue(
|
||||||
|
companion.symbol, session, scopeSession, kind = ImplicitDispatchReceiverKind.COMPANION_FROM_SUPERTYPE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ---
|
||||||
ImplicitDispatchReceiverValue(owner.symbol, type, session, scopeSession)
|
ImplicitDispatchReceiverValue(owner.symbol, type, session, scopeSession)
|
||||||
}
|
}
|
||||||
is FirFunction<*> -> {
|
is FirFunction<*> -> {
|
||||||
@@ -507,9 +522,15 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
|||||||
throw IllegalArgumentException("Incorrect label & receiver owner: ${owner.javaClass}")
|
throw IllegalArgumentException("Incorrect label & receiver owner: ${owner.javaClass}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (implicitCompanionValue in implicitCompanionValues.asReversed()) {
|
||||||
|
implicitReceiverStack.add(null, implicitCompanionValue)
|
||||||
|
}
|
||||||
implicitReceiverStack.add(labelName, implicitReceiverValue)
|
implicitReceiverStack.add(labelName, implicitReceiverValue)
|
||||||
val result = block()
|
val result = block()
|
||||||
implicitReceiverStack.pop(labelName)
|
implicitReceiverStack.pop(labelName)
|
||||||
|
for (implicitCompanionValue in implicitCompanionValues) {
|
||||||
|
implicitReceiverStack.pop(null)
|
||||||
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-4
@@ -14,10 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.*
|
|||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirFunctionCallImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirFunctionCallImpl
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirVariableAssignmentImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirVariableAssignmentImpl
|
||||||
import org.jetbrains.kotlin.fir.references.FirDelegateFieldReference
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl
|
import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirExplicitThisReference
|
import org.jetbrains.kotlin.fir.references.impl.FirExplicitThisReference
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||||
|
|||||||
@@ -81,8 +81,6 @@ class KotlinScopeProvider(
|
|||||||
): FirScope? {
|
): FirScope? {
|
||||||
return when (klass.classKind) {
|
return when (klass.classKind) {
|
||||||
ClassKind.ENUM_CLASS -> FirStaticScope(declaredMemberScope(klass))
|
ClassKind.ENUM_CLASS -> FirStaticScope(declaredMemberScope(klass))
|
||||||
// TODO: should be wrapped with FirStaticScope, non-static callables should be processed separately
|
|
||||||
ClassKind.OBJECT -> getUseSiteMemberScope(klass, ConeSubstitutor.Empty, useSiteSession, scopeSession)
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,18 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
|||||||
import org.jetbrains.kotlin.fir.declarations.isStatic
|
import org.jetbrains.kotlin.fir.declarations.isStatic
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
class FirStaticScope(private val delegateScope: FirScope) : FirScope() {
|
class FirStaticScope(private val delegateScope: FirScope) : FirScope() {
|
||||||
|
|
||||||
|
override fun processClassifiersByName(name: Name, processor: (FirClassifierSymbol<*>) -> Unit) {
|
||||||
|
delegateScope.processClassifiersByName(name) {
|
||||||
|
processor(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun processFunctionsByName(
|
override fun processFunctionsByName(
|
||||||
name: Name,
|
name: Name,
|
||||||
processor: (FirFunctionSymbol<*>) -> Unit
|
processor: (FirFunctionSymbol<*>) -> Unit
|
||||||
|
|||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
package org.jetbrains.kotlin.codegen.range.inExpression
|
||||||
|
|
||||||
|
class CallBasedInExpressionGenerator(
|
||||||
|
val codegen: ExpressionCodegen,
|
||||||
|
operatorReference: KtSimpleNameExpression
|
||||||
|
) : InExpressionGenerator {
|
||||||
|
private val resolvedCall = operatorReference.<!UNRESOLVED_REFERENCE!>getResolvedCallWithAssert<!>(codegen.<!UNRESOLVED_REFERENCE!>bindingContext<!>)
|
||||||
|
private val isInverted = operatorReference.<!UNRESOLVED_REFERENCE!>getReferencedNameElementType<!>() == <!UNRESOLVED_REFERENCE!>KtTokens<!>.<!UNRESOLVED_REFERENCE!>NOT_IN<!>
|
||||||
|
|
||||||
|
override fun generate(argument: StackValue): BranchedValue =
|
||||||
|
gen(argument).<!INAPPLICABLE_CANDIDATE!>let<!> { if (isInverted) <!UNRESOLVED_REFERENCE!>Invert<!>(<!UNRESOLVED_REFERENCE!>it<!>) else <!UNRESOLVED_REFERENCE!>it<!> }
|
||||||
|
|
||||||
|
private fun gen(argument: StackValue): BranchedValue =
|
||||||
|
object : BranchedValue(argument, null, argument.<!UNRESOLVED_REFERENCE!>type<!>, <!UNRESOLVED_REFERENCE!>Opcodes<!>.<!UNRESOLVED_REFERENCE!>IFEQ<!>) {
|
||||||
|
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||||
|
invokeFunction(v)
|
||||||
|
<!UNRESOLVED_REFERENCE!>coerceTo<!>(type, kotlinType, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
||||||
|
invokeFunction(v)
|
||||||
|
v.<!UNRESOLVED_REFERENCE!>visitJumpInsn<!>(if (jumpIfFalse) <!UNRESOLVED_REFERENCE!>Opcodes<!>.<!UNRESOLVED_REFERENCE!>IFEQ<!> else <!UNRESOLVED_REFERENCE!>Opcodes<!>.<!UNRESOLVED_REFERENCE!>IFNE<!>, jumpLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun invokeFunction(v: InstructionAdapter) {
|
||||||
|
val result = codegen.<!UNRESOLVED_REFERENCE!>invokeFunction<!>(resolvedCall.<!UNRESOLVED_REFERENCE!>call<!>, resolvedCall, <!UNRESOLVED_REFERENCE!>none<!>())
|
||||||
|
result.<!UNRESOLVED_REFERENCE!>put<!>(result.<!UNRESOLVED_REFERENCE!>type<!>, result.<!UNRESOLVED_REFERENCE!>kotlinType<!>, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
FILE: CallBasedInExpressionGenerator.kt
|
||||||
|
public final class CallBasedInExpressionGenerator : R|class error: Symbol not found, for `InExpressionGenerator`| {
|
||||||
|
public constructor(codegen: R|class error: Symbol not found, for `ExpressionCodegen`|, operatorReference: R|class error: Symbol not found, for `KtSimpleNameExpression`|): R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val codegen: R|class error: Symbol not found, for `ExpressionCodegen`| = R|<local>/codegen|
|
||||||
|
public get(): R|class error: Symbol not found, for `ExpressionCodegen`|
|
||||||
|
|
||||||
|
private final val resolvedCall: <ERROR TYPE REF: Unresolved name: getResolvedCallWithAssert> = R|<local>/operatorReference|.<Unresolved name: getResolvedCallWithAssert>#(R|<local>/codegen|.<Unresolved name: bindingContext>#)
|
||||||
|
private get(): <ERROR TYPE REF: Unresolved name: getResolvedCallWithAssert>
|
||||||
|
|
||||||
|
private final val isInverted: R|kotlin/Boolean| = ==(R|<local>/operatorReference|.<Unresolved name: getReferencedNameElementType>#(), <Unresolved name: KtTokens>#.<Unresolved name: NOT_IN>#)
|
||||||
|
private get(): R|kotlin/Boolean|
|
||||||
|
|
||||||
|
public final override fun generate(argument: R|class error: Symbol not found, for `StackValue`|): R|class error: Symbol not found, for `BranchedValue`| {
|
||||||
|
^generate R?C|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.gen|(R|<local>/argument|).<Inapplicable(WRONG_RECEIVER): [kotlin/let]>#(<L> = let@fun <anonymous>(): R|class error: Can't resolve when expression| {
|
||||||
|
when () {
|
||||||
|
this@R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator|.R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.isInverted| -> {
|
||||||
|
<Unresolved name: Invert>#(<Unresolved name: it>#)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
<Unresolved name: it>#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private final fun gen(argument: R|class error: Symbol not found, for `StackValue`|): R|class error: Symbol not found, for `BranchedValue`| {
|
||||||
|
^gen object : R|class error: Symbol not found, for `BranchedValue`| {
|
||||||
|
private constructor(): R|class error: Symbol not found, for `BranchedValue`| {
|
||||||
|
super<R|class error: Symbol not found, for `BranchedValue`|>(R|<local>/argument|, Null(null), R|<local>/argument|.<Unresolved name: type>#, <Unresolved name: Opcodes>#.<Unresolved name: IFEQ>#)
|
||||||
|
}
|
||||||
|
|
||||||
|
public final override fun putSelector(type: R|class error: Symbol not found, for `Type`|, kotlinType: R|class error: Symbol not found, for `KotlinType?`|, v: R|class error: Symbol not found, for `InstructionAdapter`|): R|kotlin/Unit| {
|
||||||
|
this@R|/anonymous|.R|/anonymous.invokeFunction|(R|<local>/v|)
|
||||||
|
<Unresolved name: coerceTo>#(R|<local>/type|, R|<local>/kotlinType|, R|<local>/v|)
|
||||||
|
}
|
||||||
|
|
||||||
|
public final override fun condJump(jumpLabel: R|class error: Symbol not found, for `Label`|, v: R|class error: Symbol not found, for `InstructionAdapter`|, jumpIfFalse: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||||
|
this@R|/anonymous|.R|/anonymous.invokeFunction|(R|<local>/v|)
|
||||||
|
R|<local>/v|.<Unresolved name: visitJumpInsn>#(when () {
|
||||||
|
R|<local>/jumpIfFalse| -> {
|
||||||
|
<Unresolved name: Opcodes>#.<Unresolved name: IFEQ>#
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
<Unresolved name: Opcodes>#.<Unresolved name: IFNE>#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, R|<local>/jumpLabel|)
|
||||||
|
}
|
||||||
|
|
||||||
|
private final fun invokeFunction(v: R|class error: Symbol not found, for `InstructionAdapter`|): R|kotlin/Unit| {
|
||||||
|
lval result: <ERROR TYPE REF: Unresolved name: invokeFunction> = this@R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator|.R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.codegen|.<Unresolved name: invokeFunction>#(this@R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator|.R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.resolvedCall|.<Unresolved name: call>#, this@R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator|.R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.resolvedCall|, <Unresolved name: none>#())
|
||||||
|
R|<local>/result|.<Unresolved name: put>#(R|<local>/result|.<Unresolved name: type>#, R|<local>/result|.<Unresolved name: kotlinType>#, R|<local>/v|)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
class Factory {
|
||||||
|
sealed class Function {
|
||||||
|
object Default
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val f = Function
|
||||||
|
val x = Function.Default
|
||||||
|
}
|
||||||
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
FILE: classifierAccessFromCompanion.kt
|
||||||
|
public final class Factory : R|kotlin/Any| {
|
||||||
|
public constructor(): R|Factory| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class Function : R|kotlin/Any| {
|
||||||
|
public constructor(): R|Factory.Function| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final object Default : R|kotlin/Any| {
|
||||||
|
private constructor(): R|Factory.Function.Default| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public final companion object Companion : R|kotlin/Any| {
|
||||||
|
private constructor(): R|Factory.Companion| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val f: R|kotlin/Unit| = Q|Factory.Function|
|
||||||
|
public get(): R|kotlin/Unit|
|
||||||
|
|
||||||
|
public final val x: R|Factory.Function.Default| = Q|Factory.Function.Default|
|
||||||
|
public get(): R|Factory.Function.Default|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ FILE: companion.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun bar(): R|kotlin/Unit| {
|
public final fun bar(): R|kotlin/Unit| {
|
||||||
R|/A.Companion.foo|()
|
this@R|/A.Companion|.R|/A.Companion.foo|()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ FILE: companionExtension.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun test(): R|kotlin/Unit| {
|
public final fun test(): R|kotlin/Unit| {
|
||||||
this@R|/My|.R|/My.Companion.foo|()
|
(this@R|/My.Companion|, this@R|/My|).R|/My.Companion.foo|()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ class My {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun Your.foo() {
|
fun Your.foo() {
|
||||||
val x = ::Nested // Still should be error
|
val x = <!UNRESOLVED_REFERENCE!>::Nested<!> // Still should be error
|
||||||
}
|
}
|
||||||
@@ -23,5 +23,5 @@ FILE: errCallable.kt
|
|||||||
|
|
||||||
}
|
}
|
||||||
public final fun R|Your|.foo(): R|kotlin/Unit| {
|
public final fun R|Your|.foo(): R|kotlin/Unit| {
|
||||||
lval x: R|kotlin/reflect/KFunction0<Your.Nested>| = ::R|/Your.Nested.Nested|
|
lval x: <ERROR TYPE REF: No result type for initializer> = ::<Unresolved name: Nested>#
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
open class Base {
|
||||||
|
companion object {
|
||||||
|
val some = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Outer {
|
||||||
|
val codegen = ""
|
||||||
|
|
||||||
|
inner class Inner : Base() {
|
||||||
|
val c = codegen
|
||||||
|
}
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
FILE: innerWithSuperCompanion.kt
|
||||||
|
public open class Base : R|kotlin/Any| {
|
||||||
|
public constructor(): R|Base| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final companion object Companion : R|kotlin/Any| {
|
||||||
|
private constructor(): R|Base.Companion| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val some: R|kotlin/Int| = Int(0)
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class Outer : R|kotlin/Any| {
|
||||||
|
public constructor(): R|Outer| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val codegen: R|kotlin/String| = String()
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
|
||||||
|
public final inner class Inner : R|Base| {
|
||||||
|
public constructor(): R|Outer.Inner| {
|
||||||
|
super<R|Base|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val c: R|kotlin/String| = this@R|/Outer|.R|/Outer.codegen|
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
object X
|
||||||
|
|
||||||
|
class Y {
|
||||||
|
fun f(op: X.() -> Unit) {
|
||||||
|
X.op()
|
||||||
|
|
||||||
|
val x = X
|
||||||
|
x.op()
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
FILE: extensionOnObject.kt
|
||||||
|
public final object X : R|kotlin/Any| {
|
||||||
|
private constructor(): R|X| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class Y : R|kotlin/Any| {
|
||||||
|
public constructor(): R|Y| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun f(op: R|X.() -> kotlin/Unit|): R|kotlin/Unit| {
|
||||||
|
R|<local>/op|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(Q|X|)
|
||||||
|
lval x: R|X| = Q|X|
|
||||||
|
R|<local>/op|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(R|<local>/x|)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+4
-2
@@ -1,8 +1,10 @@
|
|||||||
fun String.invoke() = this
|
operator fun String.invoke() = this
|
||||||
|
|
||||||
val some = ""
|
val some = ""
|
||||||
fun sss() {
|
fun sss() {
|
||||||
val some = 10
|
val some = 10
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>some<!>() // Should be inapplicable
|
// Should be resolved to top-level some,
|
||||||
|
// because with local some invoke isn't applicable
|
||||||
|
some()
|
||||||
}
|
}
|
||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
FILE: incorrectInvokeReceiver.kt
|
FILE: incorrectInvokeReceiver.kt
|
||||||
public final fun R|kotlin/String|.invoke(): R|kotlin/String| {
|
public final operator fun R|kotlin/String|.invoke(): R|kotlin/String| {
|
||||||
^invoke this@R|/invoke|
|
^invoke this@R|/invoke|
|
||||||
}
|
}
|
||||||
public final val some: R|kotlin/String| = String()
|
public final val some: R|kotlin/String| = String()
|
||||||
public get(): R|kotlin/String|
|
public get(): R|kotlin/String|
|
||||||
public final fun sss(): R|kotlin/Unit| {
|
public final fun sss(): R|kotlin/Unit| {
|
||||||
lval some: R|kotlin/Int| = Int(10)
|
lval some: R|kotlin/Int| = Int(10)
|
||||||
<Inapplicable(WRONG_RECEIVER): [/invoke]>#()
|
R|/some|.R|/invoke|()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -12,10 +12,11 @@ class Foo {
|
|||||||
val Buz.foobar: Bar get() = Bar()
|
val Buz.foobar: Bar get() = Bar()
|
||||||
|
|
||||||
fun FooBar.chk(buz: Buz) {
|
fun FooBar.chk(buz: Buz) {
|
||||||
|
// NB: really this example is unresolvable (in old FE too)
|
||||||
// local/buz is extension receiver of foobar
|
// local/buz is extension receiver of foobar
|
||||||
// this@Foo is dispatch receiver of foobar
|
// this@Foo is dispatch receiver of foobar
|
||||||
// Foo/foobar is dispatch receiver of invoke
|
// Foo/foobar is dispatch receiver of invoke
|
||||||
// this@chk is extension receiver of invoke
|
// this@chk is extension receiver of invoke
|
||||||
buz.foobar()
|
buz.<!UNRESOLVED_REFERENCE!>foobar<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ FILE: threeReceivers.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun R|FooBar|.chk(buz: R|Buz|): R|kotlin/Unit| {
|
public final fun R|FooBar|.chk(buz: R|Buz|): R|kotlin/Unit| {
|
||||||
((this@R|/Foo|, R|<local>/buz|).R|/Foo.foobar|, this@R|/Foo.chk|).R|/Bar.invoke|()
|
R|<local>/buz|.<Unresolved name: foobar>#()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
class C
|
||||||
|
|
||||||
|
class B
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val B.foo: C.() -> Unit get() = null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, R> with(arg: T, f: T.() -> R): R = arg.f()
|
||||||
|
|
||||||
|
fun test(a: A, b: B, c: C) {
|
||||||
|
with(a) {
|
||||||
|
with(c) {
|
||||||
|
b.foo(c)
|
||||||
|
// [this@a,b].foo.invoke(c)
|
||||||
|
}
|
||||||
|
with(b) {
|
||||||
|
c.foo()
|
||||||
|
// [this@a,this@b].foo.invoke(c)
|
||||||
|
with(c) {
|
||||||
|
foo()
|
||||||
|
// [this@a,this@b].foo.invoke(this@c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
FILE: threeReceiversCorrect.kt
|
||||||
|
public final class C : R|kotlin/Any| {
|
||||||
|
public constructor(): R|C| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class B : R|kotlin/Any| {
|
||||||
|
public constructor(): R|B| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class A : R|kotlin/Any| {
|
||||||
|
public constructor(): R|A| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val R|B|.foo: R|C.() -> kotlin/Unit|
|
||||||
|
public get(): R|C.() -> kotlin/Unit| {
|
||||||
|
^ Null(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final fun <T, R> with(arg: R|T|, f: R|T.() -> R|): R|R| {
|
||||||
|
^with R|<local>/f|.R|FakeOverride<kotlin/Function1.invoke: R|R|>|(R|<local>/arg|)
|
||||||
|
}
|
||||||
|
public final fun test(a: R|A|, b: R|B|, c: R|C|): R|kotlin/Unit| {
|
||||||
|
R|/with|<R|A|, R|kotlin/Unit|>(R|<local>/a|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Unit| {
|
||||||
|
R|/with|<R|C|, R|kotlin/Unit|>(R|<local>/c|, <L> = with@fun R|C|.<anonymous>(): R|kotlin/Unit| {
|
||||||
|
(this@R|special/anonymous|, R|<local>/b|).R|/A.foo|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(R|<local>/c|)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
R|/with|<R|B|, R|kotlin/Unit|>(R|<local>/b|, <L> = with@fun R|B|.<anonymous>(): R|kotlin/Unit| {
|
||||||
|
this@R|special/anonymous|.R|/A.foo|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(R|<local>/c|)
|
||||||
|
R|/with|<R|C|, R|kotlin/Unit|>(R|<local>/c|, <L> = with@fun R|C|.<anonymous>(): R|kotlin/Unit| {
|
||||||
|
(this@R|special/anonymous|, this@R|special/anonymous|).R|/A.foo|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(this@R|special/anonymous|)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
FILE: test.kt
|
FILE: test.kt
|
||||||
public final fun test(): R|kotlin/Unit| {
|
public final fun test(): R|kotlin/Unit| {
|
||||||
lval staticReference: R|kotlin/reflect/KMutableProperty1<JavaClass, ft<kotlin/String, kotlin/String?>!>| = Q|JavaClass|::R|/JavaClass.staticField|
|
lval staticReference: R|kotlin/reflect/KMutableProperty0<ft<kotlin/String, kotlin/String?>!>| = Q|JavaClass|::R|/JavaClass.staticField|
|
||||||
lval nonStaticReference: R|kotlin/reflect/KMutableProperty1<JavaClass, ft<kotlin/String, kotlin/String?>!>| = Q|JavaClass|::R|/JavaClass.nonStaticField|
|
lval nonStaticReference: R|kotlin/reflect/KMutableProperty1<JavaClass, ft<kotlin/String, kotlin/String?>!>| = Q|JavaClass|::R|/JavaClass.nonStaticField|
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
class Outer {
|
||||||
|
fun foo() {
|
||||||
|
class Local {
|
||||||
|
fun bar() {
|
||||||
|
val x = y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val y = ""
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
FILE: localClassAccessesContainingClass.kt
|
||||||
|
public final class Outer : R|kotlin/Any| {
|
||||||
|
public constructor(): R|Outer| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
|
local final class Local : R|kotlin/Any| {
|
||||||
|
public constructor(): R|Outer.Local| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun bar(): R|kotlin/Unit| {
|
||||||
|
lval x: R|kotlin/String| = this@R|/Outer|.R|/Outer.y|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val y: R|kotlin/String| = String()
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class A {
|
||||||
|
class Nested
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val x = ::Nested
|
||||||
|
val y = A::Nested
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
FILE: nestedConstructorCallable.kt
|
||||||
|
public final class A : R|kotlin/Any| {
|
||||||
|
public constructor(): R|A| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Nested : R|kotlin/Any| {
|
||||||
|
public constructor(): R|A.Nested| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
lval x: R|kotlin/reflect/KFunction0<A.Nested>| = ::R|/A.Nested.Nested|
|
||||||
|
lval y: R|kotlin/reflect/KFunction0<A.Nested>| = Q|A|::R|/A.Nested.Nested|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
object A {
|
||||||
|
object B {
|
||||||
|
object A
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object B
|
||||||
|
|
||||||
|
val err = B.<!UNRESOLVED_REFERENCE!>A<!>.<!UNRESOLVED_REFERENCE!>B<!>
|
||||||
|
val correct = A.B.A
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
FILE: nestedObjects.kt
|
||||||
|
public final object A : R|kotlin/Any| {
|
||||||
|
private constructor(): R|A| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final object B : R|kotlin/Any| {
|
||||||
|
private constructor(): R|A.B| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final object A : R|kotlin/Any| {
|
||||||
|
private constructor(): R|A.B.A| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final object B : R|kotlin/Any| {
|
||||||
|
private constructor(): R|B| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final val err: <ERROR TYPE REF: Unresolved name: B> = Q|B|.<Unresolved name: A>#.<Unresolved name: B>#
|
||||||
|
public get(): <ERROR TYPE REF: Unresolved name: B>
|
||||||
|
public final val correct: R|A.B.A| = Q|A.B.A|
|
||||||
|
public get(): R|A.B.A|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
// FILE: Base.java
|
||||||
|
|
||||||
|
public class Base {
|
||||||
|
protected String foo() { return ""; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: O.kt
|
||||||
|
|
||||||
|
open class Wrapper(val b: Boolean)
|
||||||
|
|
||||||
|
object O {
|
||||||
|
private class Derived(private val bar: Int) : Base() {
|
||||||
|
private inner class Some(val z: Boolean) {
|
||||||
|
fun test() {
|
||||||
|
val x = bar
|
||||||
|
val o = object : Wrapper(z) {
|
||||||
|
fun local() {
|
||||||
|
val y = foo()
|
||||||
|
}
|
||||||
|
val oo = object {
|
||||||
|
val zz = z
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun test() {
|
||||||
|
val x = bar
|
||||||
|
val o = object {
|
||||||
|
fun local() {
|
||||||
|
val y = foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Generator(val codegen: Any) {
|
||||||
|
private fun gen(): Any =
|
||||||
|
object : Wrapper(true) {
|
||||||
|
private fun invokeFunction() {
|
||||||
|
val c = codegen
|
||||||
|
val cc = codegen.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
FILE: O.kt
|
||||||
|
public open class Wrapper : R|kotlin/Any| {
|
||||||
|
public constructor(b: R|kotlin/Boolean|): R|Wrapper| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val b: R|kotlin/Boolean| = R|<local>/b|
|
||||||
|
public get(): R|kotlin/Boolean|
|
||||||
|
|
||||||
|
}
|
||||||
|
public final object O : R|kotlin/Any| {
|
||||||
|
private constructor(): R|O| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class Derived : R|Base| {
|
||||||
|
public constructor(bar: R|kotlin/Int|): R|O.Derived| {
|
||||||
|
super<R|Base|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
private final val bar: R|kotlin/Int| = R|<local>/bar|
|
||||||
|
private get(): R|kotlin/Int|
|
||||||
|
|
||||||
|
private final inner class Some : R|kotlin/Any| {
|
||||||
|
public constructor(z: R|kotlin/Boolean|): R|O.Derived.Some| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val z: R|kotlin/Boolean| = R|<local>/z|
|
||||||
|
public get(): R|kotlin/Boolean|
|
||||||
|
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
lval x: R|kotlin/Int| = this@R|/O.Derived|.R|/O.Derived.bar|
|
||||||
|
lval o: R|anonymous| = object : R|Wrapper| {
|
||||||
|
private constructor(): R|Wrapper| {
|
||||||
|
super<R|Wrapper|>(this@R|/O.Derived.Some|.R|/O.Derived.Some.z|)
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun local(): R|kotlin/Unit| {
|
||||||
|
lval y: R|ft<kotlin/String, kotlin/String?>!| = this@R|/O.Derived|.R|/Base.foo|()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val oo: R|anonymous| = object : R|kotlin/Any| {
|
||||||
|
private constructor(): R|kotlin/Any| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val zz: R|kotlin/Boolean| = R|<local>/z|
|
||||||
|
public get(): R|kotlin/Boolean|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public get(): R|anonymous|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
lval x: R|kotlin/Int| = this@R|/O.Derived|.R|/O.Derived.bar|
|
||||||
|
lval o: R|anonymous| = object : R|kotlin/Any| {
|
||||||
|
private constructor(): R|kotlin/Any| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun local(): R|kotlin/Unit| {
|
||||||
|
lval y: R|ft<kotlin/String, kotlin/String?>!| = this@R|/O.Derived|.R|/Base.foo|()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class Generator : R|kotlin/Any| {
|
||||||
|
public constructor(codegen: R|kotlin/Any|): R|Generator| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val codegen: R|kotlin/Any| = R|<local>/codegen|
|
||||||
|
public get(): R|kotlin/Any|
|
||||||
|
|
||||||
|
private final fun gen(): R|kotlin/Any| {
|
||||||
|
^gen object : R|Wrapper| {
|
||||||
|
private constructor(): R|Wrapper| {
|
||||||
|
super<R|Wrapper|>(Boolean(true))
|
||||||
|
}
|
||||||
|
|
||||||
|
private final fun invokeFunction(): R|kotlin/Unit| {
|
||||||
|
lval c: R|kotlin/Any| = this@R|/Generator|.R|/Generator.codegen|
|
||||||
|
lval cc: R|kotlin/Int| = this@R|/Generator|.R|/Generator.codegen|.R|kotlin/Any.hashCode|()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,11 +15,11 @@ FILE: outerObject.kt
|
|||||||
super<R|kotlin/Any|>()
|
super<R|kotlin/Any|>()
|
||||||
}
|
}
|
||||||
|
|
||||||
public final val y: R|kotlin/Int| = R|/Outer.x|
|
public final val y: R|kotlin/Int| = this@R|/Outer|.R|/Outer.x|
|
||||||
public get(): R|kotlin/Int|
|
public get(): R|kotlin/Int|
|
||||||
|
|
||||||
public final fun test(): R|kotlin/Unit| {
|
public final fun test(): R|kotlin/Unit| {
|
||||||
this@R|/Outer.Nested|.R|/Outer.foo|()
|
(this@R|/Outer|, this@R|/Outer.Nested|).R|/Outer.foo|()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ FILE: first.kt
|
|||||||
|
|
||||||
public final fun baz(): R|kotlin/Unit| {
|
public final fun baz(): R|kotlin/Unit| {
|
||||||
this@R|/Private|.R|/Private.bar|()
|
this@R|/Private|.R|/Private.bar|()
|
||||||
this@R|/Private|.R|/Private.Nested.Nested|()
|
R|/Private.Nested.Nested|()
|
||||||
R|/Private.Companion.fromCompanion|()
|
this@R|/Private.Companion|.R|/Private.Companion.fromCompanion|()
|
||||||
Q|Private.NotCompanion|.<Inapplicable(HIDDEN): [/Private.NotCompanion.foo]>#()
|
Q|Private.NotCompanion|.<Inapplicable(HIDDEN): [/Private.NotCompanion.foo]>#()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ FILE: first.kt
|
|||||||
|
|
||||||
public final fun foo(): R|kotlin/Unit| {
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
this@R|/Private|.R|/Private.bar|()
|
this@R|/Private|.R|/Private.bar|()
|
||||||
R|/Private.Companion.fromCompanion|()
|
this@R|/Private.Companion|.R|/Private.Companion.fromCompanion|()
|
||||||
Q|Private.NotCompanion|.<Inapplicable(HIDDEN): [/Private.NotCompanion.foo]>#()
|
Q|Private.NotCompanion|.<Inapplicable(HIDDEN): [/Private.NotCompanion.foo]>#()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ FILE: first.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun foo(): R|kotlin/Unit| {
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
R|/Private.Companion.fromCompanion|()
|
this@R|/Private.Companion|.R|/Private.Companion.fromCompanion|()
|
||||||
Q|Private.NotCompanion|.<Inapplicable(HIDDEN): [/Private.NotCompanion.foo]>#()
|
Q|Private.NotCompanion|.<Inapplicable(HIDDEN): [/Private.NotCompanion.foo]>#()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ FILE: protectedVisibility.kt
|
|||||||
|
|
||||||
public final fun baz(): R|kotlin/Unit| {
|
public final fun baz(): R|kotlin/Unit| {
|
||||||
this@R|/Protected|.R|/Protected.bar|()
|
this@R|/Protected|.R|/Protected.bar|()
|
||||||
this@R|/Protected|.R|/Protected.Nested.Nested|().R|/Protected.Nested.foo|()
|
R|/Protected.Nested.Nested|().R|/Protected.Nested.foo|()
|
||||||
}
|
}
|
||||||
|
|
||||||
public final inner class Inner : R|kotlin/Any| {
|
public final inner class Inner : R|kotlin/Any| {
|
||||||
@@ -58,9 +58,9 @@ FILE: protectedVisibility.kt
|
|||||||
|
|
||||||
public final fun foo(): R|kotlin/Unit| {
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
this@R|/Derived|.R|/Protected.bar|()
|
this@R|/Derived|.R|/Protected.bar|()
|
||||||
this@R|/Derived|.R|/Protected.Nested.Nested|().R|/Protected.Nested.foo|()
|
R|/Protected.Nested.Nested|().R|/Protected.Nested.foo|()
|
||||||
this@R|/Derived|.R|/Protected.Nested.Nested|().<Inapplicable(HIDDEN): [/Protected.Nested.bar]>#()
|
R|/Protected.Nested.Nested|().<Inapplicable(HIDDEN): [/Protected.Nested.bar]>#()
|
||||||
R|/Protected.Companion.fromCompanion|()
|
this@R|/Protected.Companion|.R|/Protected.Companion.fromCompanion|()
|
||||||
<Inapplicable(HIDDEN): [/Protected.Companion.protectedFromCompanion]>#()
|
<Inapplicable(HIDDEN): [/Protected.Companion.protectedFromCompanion]>#()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val ab = A.B // property
|
val ab = A.B // property
|
||||||
val abc = A.B.<!UNRESOLVED_REFERENCE!>C<!> // object
|
val abc = A.B.C // object
|
||||||
|
|
||||||
object D {
|
object D {
|
||||||
class E {
|
class E {
|
||||||
@@ -34,5 +34,5 @@ enum class G {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val gh = G.<!AMBIGUITY!>H<!> // companion property
|
val gh = G.H // companion property
|
||||||
val gv = G.<!AMBIGUITY!>values<!>() // static function
|
val gv = G.values() // static function
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ FILE: qualifierPriority.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public final val ab: R|kotlin/String| = Q|A|.R|/A.Companion.B|
|
public final val ab: R|A.B| = Q|A.B|
|
||||||
public get(): R|kotlin/String|
|
public get(): R|A.B|
|
||||||
public final val abc: <ERROR TYPE REF: Unresolved name: C> = Q|A|.R|/A.Companion.B|.<Unresolved name: C>#
|
public final val abc: R|A.B.C| = Q|A.B.C|
|
||||||
public get(): <ERROR TYPE REF: Unresolved name: C>
|
public get(): R|A.B.C|
|
||||||
public final object D : R|kotlin/Any| {
|
public final object D : R|kotlin/Any| {
|
||||||
private constructor(): R|D| {
|
private constructor(): R|D| {
|
||||||
super<R|kotlin/Any|>()
|
super<R|kotlin/Any|>()
|
||||||
@@ -94,7 +94,7 @@ FILE: qualifierPriority.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public final val gh: <ERROR TYPE REF: Ambiguity: H, [/G.H, /G.Companion.H]> = Q|G|.<Ambiguity: H, [/G.H, /G.Companion.H]>#
|
public final val gh: R|G| = Q|G|.R|/G.H|
|
||||||
public get(): <ERROR TYPE REF: Ambiguity: H, [/G.H, /G.Companion.H]>
|
public get(): R|G|
|
||||||
public final val gv: <ERROR TYPE REF: Ambiguity: values, [/G.values, /G.Companion.values]> = Q|G|.<Ambiguity: values, [/G.values, /G.Companion.values]>#()
|
public final val gv: R|kotlin/Array<G>| = Q|G|.R|/G.values|()
|
||||||
public get(): <ERROR TYPE REF: Ambiguity: values, [/G.values, /G.Companion.values]>
|
public get(): R|kotlin/Array<G>|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class C {
|
|||||||
|
|
||||||
class Nested {
|
class Nested {
|
||||||
fun test() {
|
fun test() {
|
||||||
err()
|
<!UNRESOLVED_REFERENCE!>err<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ FILE: receiverConsistency.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun test(): R|kotlin/Unit| {
|
public final fun test(): R|kotlin/Unit| {
|
||||||
R|/C.err|()
|
<Unresolved name: err>#()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ FILE: enums.kt
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final val g: R|kotlin/Double| = R|/Planet.Companion.G|.R|kotlin/Double.times|(R|<local>/m|).R|kotlin/Double.div|(R|<local>/r|.R|kotlin/Double.times|(R|<local>/r|))
|
public final val g: R|kotlin/Double| = this@R|/Planet.Companion|.R|/Planet.Companion.G|.R|kotlin/Double.times|(R|<local>/m|).R|kotlin/Double.div|(R|<local>/r|.R|kotlin/Double.times|(R|<local>/r|))
|
||||||
public get(): R|kotlin/Double|
|
public get(): R|kotlin/Double|
|
||||||
|
|
||||||
public abstract fun sayHello(): R|kotlin/Unit|
|
public abstract fun sayHello(): R|kotlin/Unit|
|
||||||
|
|||||||
+2
-2
@@ -64,14 +64,14 @@ FILE: localObject.kt
|
|||||||
^ Int(1)
|
^ Int(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
public final val z: R|kotlin/Int| = R|/run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| {
|
public final val z: R|kotlin/Int| = this@R|/TestProperty|.R|kotlin/run|<R|TestProperty|, R|kotlin/Int|>(<L> = run@fun R|TestProperty|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||||
lval obj: R|anonymous| = object : R|Foo| {
|
lval obj: R|anonymous| = object : R|Foo| {
|
||||||
private constructor(): R|kotlin/Any| {
|
private constructor(): R|kotlin/Any| {
|
||||||
super<R|kotlin/Any|>()
|
super<R|kotlin/Any|>()
|
||||||
}
|
}
|
||||||
|
|
||||||
public final override fun foo(): R|kotlin/Int| {
|
public final override fun foo(): R|kotlin/Int| {
|
||||||
^foo this@R|/TestProperty|.R|/TestProperty.x|.R|kotlin/Int.plus|(Int(1))
|
^foo this@R|special/anonymous|.R|/TestProperty.x|.R|kotlin/Int.plus|(Int(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ class Owner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun err() {
|
fun err() {
|
||||||
foo()
|
<!UNRESOLVED_REFERENCE!>foo<!>()
|
||||||
this.<!UNRESOLVED_REFERENCE!>foo<!>()
|
this.<!UNRESOLVED_REFERENCE!>foo<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -10,7 +10,7 @@ FILE: simple.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun bar(): R|kotlin/Unit| {
|
public final fun bar(): R|kotlin/Unit| {
|
||||||
lval n: R|Owner.Nested| = this@R|/Owner|.R|/Owner.Nested.Nested|()
|
lval n: R|Owner.Nested| = R|/Owner.Nested.Nested|()
|
||||||
R|<local>/n|.R|/Owner.Nested.baz|()
|
R|<local>/n|.R|/Owner.Nested.baz|()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ FILE: simple.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun err(): R|kotlin/Unit| {
|
public final fun err(): R|kotlin/Unit| {
|
||||||
R|/Owner.foo|()
|
<Unresolved name: foo>#()
|
||||||
this@R|/Owner.Nested|.<Unresolved name: foo>#()
|
this@R|/Owner.Nested|.<Unresolved name: foo>#()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ FILE: nestedClassNameClash.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun test_5(): R|kotlin/Unit| {
|
public final fun test_5(): R|kotlin/Unit| {
|
||||||
lval result: R|Foo.Result| = this@R|/Foo|.R|/Foo.Result.Result|()
|
lval result: R|Foo.Result| = R|/Foo.Result.Result|()
|
||||||
this@R|/Foo|.R|/Foo.saveResult|(R|<local>/result|)
|
this@R|/Foo|.R|/Foo.saveResult|(R|<local>/result|)
|
||||||
}
|
}
|
||||||
|
|
||||||
private final fun getResult(): R|Foo.Result| {
|
private final fun getResult(): R|Foo.Result| {
|
||||||
^getResult this@R|/Foo|.R|/Foo.Result.Result|()
|
^getResult R|/Foo.Result.Result|()
|
||||||
}
|
}
|
||||||
|
|
||||||
private final fun saveResults(results: R|kotlin/collections/List<Foo.Result>|): R|kotlin/Unit| {
|
private final fun saveResults(results: R|kotlin/collections/List<Foo.Result>|): R|kotlin/Unit| {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ FILE: nestedReturnType.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun foo(): R|Some.Nested| {
|
public final fun foo(): R|Some.Nested| {
|
||||||
^foo this@R|/Some|.R|/Some.Nested.Nested|()
|
^foo R|/Some.Nested.Nested|()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ FILE: nestedClassContructor.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun copy(): R|A.B| {
|
public final fun copy(): R|A.B| {
|
||||||
^copy this@R|/A.B|.R|/A.B.B|()
|
^copy R|/A.B.B|()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ FILE: nestedClassContructor.kt
|
|||||||
|
|
||||||
public final fun foo(): R|kotlin/Unit| {
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
lval a: R|A| = R|/A.A|()
|
lval a: R|A| = R|/A.A|()
|
||||||
lval c: R|A.C| = this@R|/E|.R|/A.C.C|()
|
lval c: R|A.C| = R|/A.C.C|()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,5 +24,5 @@ FILE: qualifierWithCompanion.kt
|
|||||||
local final fun R|my/A|.invoke(): R|kotlin/Unit| {
|
local final fun R|my/A|.invoke(): R|kotlin/Unit| {
|
||||||
}
|
}
|
||||||
|
|
||||||
R|my/xx|.R|<local>/invoke|()
|
Q|my|.R|my/xx|.R|<local>/invoke|()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,16 @@ fun foo3(x: (String) -> Int) {}
|
|||||||
fun main() {
|
fun main() {
|
||||||
foo1(KotlinClass::baz)
|
foo1(KotlinClass::baz)
|
||||||
foo2(KotlinClass::baz)
|
foo2(KotlinClass::baz)
|
||||||
|
// Ambiguity (companion/class)
|
||||||
<!AMBIGUITY!>foo3<!>(KotlinClass::baz)
|
<!AMBIGUITY!>foo3<!>(KotlinClass::baz)
|
||||||
|
|
||||||
|
// Type mismatch
|
||||||
<!INAPPLICABLE_CANDIDATE!>foo1<!>(KotlinClass::bar)
|
<!INAPPLICABLE_CANDIDATE!>foo1<!>(KotlinClass::bar)
|
||||||
foo2(KotlinClass::bar)
|
foo2(KotlinClass::bar)
|
||||||
foo3(KotlinClass::bar)
|
foo3(KotlinClass::bar)
|
||||||
|
|
||||||
foo1(KotlinClass2::bar)
|
foo1(KotlinClass2::bar)
|
||||||
|
// Type mismatch
|
||||||
<!INAPPLICABLE_CANDIDATE!>foo2<!>(KotlinClass2::bar)
|
<!INAPPLICABLE_CANDIDATE!>foo2<!>(KotlinClass2::bar)
|
||||||
foo3(KotlinClass2::bar)
|
foo3(KotlinClass2::bar)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -57,6 +57,6 @@ FILE: main.kt
|
|||||||
R|/foo2|(Q|KotlinClass|::R|/JavaClass.bar|)
|
R|/foo2|(Q|KotlinClass|::R|/JavaClass.bar|)
|
||||||
R|/foo3|(Q|KotlinClass|::R|/JavaClass.bar|)
|
R|/foo3|(Q|KotlinClass|::R|/JavaClass.bar|)
|
||||||
R|/foo1|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|)
|
R|/foo1|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|)
|
||||||
<Inapplicable(INAPPLICABLE): [/foo2]>#(Q|KotlinClass2|::R|/JavaClass.bar|)
|
<Inapplicable(INAPPLICABLE): [/foo2]>#(Q|KotlinClass2|::R|/KotlinClass2.bar|)
|
||||||
R|/foo3|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|)
|
R|/foo3|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ FILE: hashTableWithForEach.kt
|
|||||||
R|/DEBUG| -> {
|
R|/DEBUG| -> {
|
||||||
^ Q|java/util/Collections|.R|java/util/Collections.unmodifiableSet|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>(R|kotlin/collections/mutableSetOf|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>().R|kotlin/apply|<R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|>(<L> = apply@fun R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
^ Q|java/util/Collections|.R|java/util/Collections.unmodifiableSet|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>(R|kotlin/collections/mutableSetOf|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>().R|kotlin/apply|<R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|>(<L> = apply@fun R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||||
this@R|/SomeHashTable|.R|FakeOverride</SomeHashTable.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|K|, value: R|V|): R|kotlin/Unit| {
|
this@R|/SomeHashTable|.R|FakeOverride</SomeHashTable.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|K|, value: R|V|): R|kotlin/Unit| {
|
||||||
this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableSet.add: R|kotlin/Boolean|>|(this@R|/SomeHashTable|.R|/SomeHashTable.Entry.Entry|<R|K|, R|V|>(R|<local>/key|, R|<local>/value|))
|
this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableSet.add: R|kotlin/Boolean|>|(R|/SomeHashTable.Entry.Entry|<R|K|, R|V|>(R|<local>/key|, R|<local>/value|))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ FILE: implicitReceiverOrder.kt
|
|||||||
R|kotlin/with|<R|B|, R|kotlin/Int|>(R|<local>/b|, <L> = with@fun R|B|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
R|kotlin/with|<R|B|, R|kotlin/Int|>(R|<local>/b|, <L> = with@fun R|B|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||||
R|kotlin/with|<R|A|, R|kotlin/Int|>(R|<local>/a|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
R|kotlin/with|<R|A|, R|kotlin/Int|>(R|<local>/a|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||||
this@R|special/anonymous|.R|/A.foo|()
|
this@R|special/anonymous|.R|/A.foo|()
|
||||||
this@R|special/anonymous|.R|/B.bar|()
|
(this@R|special/anonymous|, this@R|special/anonymous|).R|/B.bar|()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ FILE: implicitReceiverOrder.kt
|
|||||||
R|kotlin/with|<R|A|, R|kotlin/Int|>(R|<local>/a|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
R|kotlin/with|<R|A|, R|kotlin/Int|>(R|<local>/a|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||||
R|kotlin/with|<R|B|, R|kotlin/Int|>(R|<local>/b|, <L> = with@fun R|B|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
R|kotlin/with|<R|B|, R|kotlin/Int|>(R|<local>/b|, <L> = with@fun R|B|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||||
this@R|special/anonymous|.R|/B.foo|()
|
this@R|special/anonymous|.R|/B.foo|()
|
||||||
this@R|special/anonymous|.R|/A.bar|()
|
(this@R|special/anonymous|, this@R|special/anonymous|).R|/A.bar|()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ FILE: User.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final fun foo(): R|kotlin/Unit| {
|
public final fun foo(): R|kotlin/Unit| {
|
||||||
lval sc: R|AbstractClass.StaticClass| = this@R|/User|.R|/AbstractClass.StaticClass.StaticClass|()
|
lval sc: R|AbstractClass.StaticClass| = R|/AbstractClass.StaticClass.StaticClass|()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ FILE: multipleImplicitReceivers.kt
|
|||||||
public final fun test(fooImpl: R|IFoo|, invokeImpl: R|IInvoke|): R|kotlin/Unit| {
|
public final fun test(fooImpl: R|IFoo|, invokeImpl: R|IInvoke|): R|kotlin/Unit| {
|
||||||
R|kotlin/with|<R|A|, R|kotlin/Int|>(Q|A|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
R|kotlin/with|<R|A|, R|kotlin/Int|>(Q|A|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||||
R|kotlin/with|<R|IFoo|, R|kotlin/Int|>(R|<local>/fooImpl|, <L> = with@fun R|IFoo|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
R|kotlin/with|<R|IFoo|, R|kotlin/Int|>(R|<local>/fooImpl|, <L> = with@fun R|IFoo|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||||
this@R|special/anonymous|.R|/IFoo.foo|
|
(this@R|special/anonymous|, this@R|special/anonymous|).R|/IFoo.foo|
|
||||||
R|kotlin/with|<R|IInvoke|, R|kotlin/Int|>(R|<local>/invokeImpl|, <L> = with@fun R|IInvoke|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
R|kotlin/with|<R|IInvoke|, R|kotlin/Int|>(R|<local>/invokeImpl|, <L> = with@fun R|IInvoke|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||||
(this@R|special/anonymous|, this@R|special/anonymous|.R|/IFoo.foo|).R|/IInvoke.invoke|()
|
(this@R|special/anonymous|, (this@R|special/anonymous|, this@R|special/anonymous|).R|/IFoo.foo|).R|/IInvoke.invoke|()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+45
@@ -434,11 +434,21 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/baseQualifier.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/baseQualifier.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("CallBasedInExpressionGenerator.kt")
|
||||||
|
public void testCallBasedInExpressionGenerator() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("checkArguments.kt")
|
@TestMetadata("checkArguments.kt")
|
||||||
public void testCheckArguments() throws Exception {
|
public void testCheckArguments() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/checkArguments.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/checkArguments.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("classifierAccessFromCompanion.kt")
|
||||||
|
public void testClassifierAccessFromCompanion() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/classifierAccessFromCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("companion.kt")
|
@TestMetadata("companion.kt")
|
||||||
public void testCompanion() throws Exception {
|
public void testCompanion() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/companion.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/companion.kt");
|
||||||
@@ -514,6 +524,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/innerQualifier.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/innerQualifier.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerWithSuperCompanion.kt")
|
||||||
|
public void testInnerWithSuperCompanion() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/innerWithSuperCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("javaFieldCallable.kt")
|
@TestMetadata("javaFieldCallable.kt")
|
||||||
public void testJavaFieldCallable() throws Exception {
|
public void testJavaFieldCallable() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.kt");
|
||||||
@@ -529,6 +544,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/lambdaWithReceiver.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/lambdaWithReceiver.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localClassAccessesContainingClass.kt")
|
||||||
|
public void testLocalClassAccessesContainingClass() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/localClassAccessesContainingClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("localConstructor.kt")
|
@TestMetadata("localConstructor.kt")
|
||||||
public void testLocalConstructor() throws Exception {
|
public void testLocalConstructor() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/localConstructor.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/localConstructor.kt");
|
||||||
@@ -574,6 +594,16 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/memberExtension.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/memberExtension.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedConstructorCallable.kt")
|
||||||
|
public void testNestedConstructorCallable() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedConstructorCallable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedObjects.kt")
|
||||||
|
public void testNestedObjects() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedObjects.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("nestedVisibility.kt")
|
@TestMetadata("nestedVisibility.kt")
|
||||||
public void testNestedVisibility() throws Exception {
|
public void testNestedVisibility() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedVisibility.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedVisibility.kt");
|
||||||
@@ -594,6 +624,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/objects.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/objects.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outerMemberAccesses.kt")
|
||||||
|
public void testOuterMemberAccesses() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/outerMemberAccesses.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("outerObject.kt")
|
@TestMetadata("outerObject.kt")
|
||||||
public void testOuterObject() throws Exception {
|
public void testOuterObject() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/outerObject.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/outerObject.kt");
|
||||||
@@ -724,6 +759,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/extension.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/extension.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionOnObject.kt")
|
||||||
|
public void testExtensionOnObject() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/extensionOnObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("farInvokeExtension.kt")
|
@TestMetadata("farInvokeExtension.kt")
|
||||||
public void testFarInvokeExtension() throws Exception {
|
public void testFarInvokeExtension() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/farInvokeExtension.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/farInvokeExtension.kt");
|
||||||
@@ -763,6 +803,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
public void testThreeReceivers() throws Exception {
|
public void testThreeReceivers() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("threeReceiversCorrect.kt")
|
||||||
|
public void testThreeReceiversCorrect() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceiversCorrect.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/fir/resolve/testData/resolve/expresssions/operators")
|
@TestMetadata("compiler/fir/resolve/testData/resolve/expresssions/operators")
|
||||||
|
|||||||
Generated
+45
@@ -434,11 +434,21 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/baseQualifier.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/baseQualifier.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("CallBasedInExpressionGenerator.kt")
|
||||||
|
public void testCallBasedInExpressionGenerator() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("checkArguments.kt")
|
@TestMetadata("checkArguments.kt")
|
||||||
public void testCheckArguments() throws Exception {
|
public void testCheckArguments() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/checkArguments.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/checkArguments.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("classifierAccessFromCompanion.kt")
|
||||||
|
public void testClassifierAccessFromCompanion() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/classifierAccessFromCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("companion.kt")
|
@TestMetadata("companion.kt")
|
||||||
public void testCompanion() throws Exception {
|
public void testCompanion() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/companion.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/companion.kt");
|
||||||
@@ -514,6 +524,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/innerQualifier.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/innerQualifier.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerWithSuperCompanion.kt")
|
||||||
|
public void testInnerWithSuperCompanion() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/innerWithSuperCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("javaFieldCallable.kt")
|
@TestMetadata("javaFieldCallable.kt")
|
||||||
public void testJavaFieldCallable() throws Exception {
|
public void testJavaFieldCallable() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.kt");
|
||||||
@@ -529,6 +544,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/lambdaWithReceiver.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/lambdaWithReceiver.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localClassAccessesContainingClass.kt")
|
||||||
|
public void testLocalClassAccessesContainingClass() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/localClassAccessesContainingClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("localConstructor.kt")
|
@TestMetadata("localConstructor.kt")
|
||||||
public void testLocalConstructor() throws Exception {
|
public void testLocalConstructor() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/localConstructor.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/localConstructor.kt");
|
||||||
@@ -574,6 +594,16 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/memberExtension.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/memberExtension.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedConstructorCallable.kt")
|
||||||
|
public void testNestedConstructorCallable() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedConstructorCallable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nestedObjects.kt")
|
||||||
|
public void testNestedObjects() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedObjects.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("nestedVisibility.kt")
|
@TestMetadata("nestedVisibility.kt")
|
||||||
public void testNestedVisibility() throws Exception {
|
public void testNestedVisibility() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedVisibility.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedVisibility.kt");
|
||||||
@@ -594,6 +624,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/objects.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/objects.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outerMemberAccesses.kt")
|
||||||
|
public void testOuterMemberAccesses() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/outerMemberAccesses.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("outerObject.kt")
|
@TestMetadata("outerObject.kt")
|
||||||
public void testOuterObject() throws Exception {
|
public void testOuterObject() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/outerObject.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/outerObject.kt");
|
||||||
@@ -724,6 +759,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/extension.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/extension.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionOnObject.kt")
|
||||||
|
public void testExtensionOnObject() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/extensionOnObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("farInvokeExtension.kt")
|
@TestMetadata("farInvokeExtension.kt")
|
||||||
public void testFarInvokeExtension() throws Exception {
|
public void testFarInvokeExtension() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/farInvokeExtension.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/farInvokeExtension.kt");
|
||||||
@@ -763,6 +803,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
public void testThreeReceivers() throws Exception {
|
public void testThreeReceivers() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt");
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("threeReceiversCorrect.kt")
|
||||||
|
public void testThreeReceiversCorrect() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceiversCorrect.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/fir/resolve/testData/resolve/expresssions/operators")
|
@TestMetadata("compiler/fir/resolve/testData/resolve/expresssions/operators")
|
||||||
|
|||||||
@@ -43,4 +43,9 @@ enum class ProcessorAction {
|
|||||||
|
|
||||||
fun stop() = this == STOP
|
fun stop() = this == STOP
|
||||||
fun next() = this != STOP
|
fun next() = this != STOP
|
||||||
|
|
||||||
|
operator fun plus(other: ProcessorAction): ProcessorAction {
|
||||||
|
if (this == NEXT || other == NEXT) return NEXT
|
||||||
|
return this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ fun bar(doIt: Int.() -> Int) {
|
|||||||
1.doIt()
|
1.doIt()
|
||||||
1?.doIt()
|
1?.doIt()
|
||||||
val i: Int? = 1
|
val i: Int? = 1
|
||||||
i.<!UNRESOLVED_REFERENCE!>doIt<!>()
|
i.doIt()
|
||||||
i?.doIt()
|
i?.doIt()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class X {}
|
|||||||
val s = java
|
val s = java
|
||||||
val ss = System
|
val ss = System
|
||||||
val sss = X
|
val sss = X
|
||||||
val x = "${System}"
|
val x = "${<!UNRESOLVED_REFERENCE!>System<!>}"
|
||||||
val xs = java.lang
|
val xs = java.lang
|
||||||
val xss = java.lang.System
|
val xss = java.lang.System
|
||||||
val xsss = foo.X
|
val xsss = foo.X
|
||||||
|
|||||||
+1
-1
@@ -5,5 +5,5 @@ class Outer {
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
Outer()::Inner
|
Outer()::Inner
|
||||||
Outer()::Nested
|
<!UNRESOLVED_REFERENCE!>Outer()::Nested<!>
|
||||||
}
|
}
|
||||||
|
|||||||
compiler/testData/diagnostics/tests/callableReference/bound/referenceToStaticMethodOnInstance.fir.kt
Vendored
+2
-2
@@ -9,6 +9,6 @@ public class A {
|
|||||||
enum class E { EN }
|
enum class E { EN }
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
A()::test
|
<!UNRESOLVED_REFERENCE!>A()::test<!>
|
||||||
E.EN::valueOf
|
<!UNRESOLVED_REFERENCE!>E.EN::valueOf<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -16,6 +16,6 @@ fun test() {
|
|||||||
|
|
||||||
Outer.Companion::Wrapper
|
Outer.Companion::Wrapper
|
||||||
(Outer.Companion)::Wrapper
|
(Outer.Companion)::Wrapper
|
||||||
Outer::Wrapper
|
<!UNRESOLVED_REFERENCE!>Outer::Wrapper<!>
|
||||||
(Outer)::Wrapper
|
<!UNRESOLVED_REFERENCE!>(Outer)::Wrapper<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -15,5 +15,5 @@ fun take(f: () -> Unit) {}
|
|||||||
fun test() {
|
fun test() {
|
||||||
B::foo checkType { <!UNRESOLVED_REFERENCE!>_<!><KFunction1<B, Unit>>() }
|
B::foo checkType { <!UNRESOLVED_REFERENCE!>_<!><KFunction1<B, Unit>>() }
|
||||||
|
|
||||||
take(B::foo)
|
<!INAPPLICABLE_CANDIDATE!>take<!>(B::foo)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -18,7 +18,7 @@ import test.A
|
|||||||
|
|
||||||
fun foo(args: Array<String>) {
|
fun foo(args: Array<String>) {
|
||||||
val main2 = A::main
|
val main2 = A::main
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KFunction1<Array<String>, Unit>>(main2)
|
checkSubtype<KFunction1<Array<String>, Unit>>(main2)
|
||||||
<!INAPPLICABLE_CANDIDATE!>main2<!>(args)
|
main2(args)
|
||||||
<!INAPPLICABLE_CANDIDATE!>(A::main)(args)<!>
|
(A::main)(args)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+3
-3
@@ -10,7 +10,7 @@ class A {
|
|||||||
val y = A::Nested
|
val y = A::Nested
|
||||||
|
|
||||||
checkSubtype<KFunction0<Nested>>(x)
|
checkSubtype<KFunction0<Nested>>(x)
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KFunction0<Nested>>(y)
|
checkSubtype<KFunction0<Nested>>(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -18,7 +18,7 @@ class A {
|
|||||||
::Nested
|
::Nested
|
||||||
val y = A::Nested
|
val y = A::Nested
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KFunction0<A.Nested>>(y)
|
checkSubtype<KFunction0<A.Nested>>(y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,6 +28,6 @@ class B {
|
|||||||
<!UNRESOLVED_REFERENCE!>::Nested<!>
|
<!UNRESOLVED_REFERENCE!>::Nested<!>
|
||||||
val y = A::Nested
|
val y = A::Nested
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KFunction0<A.Nested>>(y)
|
checkSubtype<KFunction0<A.Nested>>(y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromExtension.fir.kt
Vendored
+3
-3
@@ -7,15 +7,15 @@ class A {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun A.main() {
|
fun A.main() {
|
||||||
::Nested
|
<!UNRESOLVED_REFERENCE!>::Nested<!>
|
||||||
val y = A::Nested
|
val y = A::Nested
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KFunction0<A.Nested>>(y)
|
checkSubtype<KFunction0<A.Nested>>(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Int.main() {
|
fun Int.main() {
|
||||||
<!UNRESOLVED_REFERENCE!>::Nested<!>
|
<!UNRESOLVED_REFERENCE!>::Nested<!>
|
||||||
val y = A::Nested
|
val y = A::Nested
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KFunction0<A.Nested>>(y)
|
checkSubtype<KFunction0<A.Nested>>(y)
|
||||||
}
|
}
|
||||||
Vendored
+1
-1
@@ -9,5 +9,5 @@ class A {
|
|||||||
fun main() {
|
fun main() {
|
||||||
val x = A::Nested
|
val x = A::Nested
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><KFunction0<A.Nested>>(x)
|
checkSubtype<KFunction0<A.Nested>>(x)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package foo
|
package foo
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
<!UNRESOLVED_REFERENCE!>foo::test<!>
|
foo::test
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILE: qualifiedName.kt
|
// FILE: qualifiedName.kt
|
||||||
@@ -12,5 +12,5 @@ fun test() {
|
|||||||
package foo.bar
|
package foo.bar
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
<!UNRESOLVED_REFERENCE!>foo.bar::test<!>
|
foo.bar::test
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -14,14 +14,14 @@ class A {
|
|||||||
|
|
||||||
fun A.foo(): String = "A"
|
fun A.foo(): String = "A"
|
||||||
|
|
||||||
val x0 = A::foo
|
val x0 = <!UNRESOLVED_REFERENCE!>A::foo<!>
|
||||||
|
|
||||||
val x1 = ofType<(A) -> Unit>(A::foo)
|
val x1 = ofType<(A) -> Unit>(A::foo)
|
||||||
val x2 = ofType<KProperty1<A, Int>>(A::foo)
|
val x2 = ofType<KProperty1<A, Int>>(A::foo)
|
||||||
val x3: KProperty1<A, Int> = A::foo
|
val x3: KProperty1<A, Int> = A::foo
|
||||||
val x4: (A) -> String = A::foo
|
val x4: (A) -> String = A::foo
|
||||||
|
|
||||||
val y0 = A::bar
|
val y0 = <!UNRESOLVED_REFERENCE!>A::bar<!>
|
||||||
val y1 = ofType<(A) -> Unit>(A::bar)
|
val y1 = ofType<(A) -> Unit>(A::bar)
|
||||||
val y2 = ofType<KProperty1<A, Int>>(A::bar)
|
val y2 = ofType<KProperty1<A, Int>>(A::bar)
|
||||||
val y3: KProperty1<A, Int> = A::bar
|
val y3: KProperty1<A, Int> = A::bar
|
||||||
|
|||||||
+1
-1
@@ -4,6 +4,6 @@ class A() {
|
|||||||
val x = 1
|
val x = 1
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val y = x
|
val y = <!UNRESOLVED_REFERENCE!>x<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -21,7 +21,7 @@ enum class C {
|
|||||||
C.A()
|
C.A()
|
||||||
A()
|
A()
|
||||||
//TODO: should be resolved with error
|
//TODO: should be resolved with error
|
||||||
this.A()
|
this.<!UNRESOLVED_REFERENCE!>A<!>()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ enum class C {
|
|||||||
|
|
||||||
fun f() {
|
fun f() {
|
||||||
C.E1.A
|
C.E1.A
|
||||||
C.E1.A()
|
C.E1.<!UNRESOLVED_REFERENCE!>A<!>()
|
||||||
C.E2.B()
|
C.E2.B()
|
||||||
|
|
||||||
C.E2.O
|
C.E2.O
|
||||||
|
|||||||
+2
-2
@@ -21,7 +21,7 @@ enum class C {
|
|||||||
C.A()
|
C.A()
|
||||||
A()
|
A()
|
||||||
//TODO: should be resolved with error
|
//TODO: should be resolved with error
|
||||||
this.A()
|
this.<!UNRESOLVED_REFERENCE!>A<!>()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ enum class C {
|
|||||||
|
|
||||||
fun f() {
|
fun f() {
|
||||||
C.E1.A
|
C.E1.A
|
||||||
C.E1.A()
|
C.E1.<!UNRESOLVED_REFERENCE!>A<!>()
|
||||||
C.E2.B()
|
C.E2.B()
|
||||||
|
|
||||||
C.E2.O
|
C.E2.O
|
||||||
|
|||||||
+1
-1
@@ -4,6 +4,6 @@ class Test {
|
|||||||
fun test(): Int = 12
|
fun test(): Int = 12
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val a = test() // Check if resolver will be able to infer type of a variable
|
val a = <!UNRESOLVED_REFERENCE!>test<!>() // Check if resolver will be able to infer type of a variable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -8,7 +8,7 @@ class My {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val y = foo()
|
val y = <!UNRESOLVED_REFERENCE!>foo<!>()
|
||||||
|
|
||||||
val u = bar()
|
val u = bar()
|
||||||
|
|
||||||
|
|||||||
@@ -14,5 +14,5 @@ class TopLevel {
|
|||||||
fun useNested() {
|
fun useNested() {
|
||||||
val d = TopLevel.Nested.use()
|
val d = TopLevel.Nested.use()
|
||||||
TopLevel.Nested.Nested2()
|
TopLevel.Nested.Nested2()
|
||||||
TopLevel.Nested.CompanionNested2()
|
TopLevel.Nested.<!UNRESOLVED_REFERENCE!>CompanionNested2<!>()
|
||||||
}
|
}
|
||||||
Vendored
+1
-1
@@ -2,7 +2,7 @@ enum class A {
|
|||||||
A1,
|
A1,
|
||||||
A2;
|
A2;
|
||||||
|
|
||||||
fun valueOf(s: String): A = <!AMBIGUITY!>valueOf<!>(s)
|
fun valueOf(s: String): A = valueOf(s)
|
||||||
|
|
||||||
fun valueOf() = "OK"
|
fun valueOf() = "OK"
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ public enum A {
|
|||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val c: A = A.ENTRY
|
val c: A = A.ENTRY
|
||||||
val c2: String? = c.<!AMBIGUITY!>ENTRY<!>
|
val c2: String? = c.ENTRY
|
||||||
val c3: String? = A.ANOTHER.<!AMBIGUITY!>ENTRY<!>
|
val c3: String? = A.ANOTHER.ENTRY
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ public class A {
|
|||||||
// FILE: B.kt
|
// FILE: B.kt
|
||||||
fun Any?.bar() = 42
|
fun Any?.bar() = 42
|
||||||
|
|
||||||
fun f1() = A.bar()
|
fun f1() = A.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||||
fun f2() = A.Nested.bar()
|
fun f2() = A.Nested.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||||
|
|||||||
+1
-1
@@ -12,5 +12,5 @@ fun <V, T : V?> G<T>.foo(vararg values: V2<V?>) = build()
|
|||||||
fun forReference(ref: Any?) {}
|
fun forReference(ref: Any?) {}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
forReference(<!UNRESOLVED_REFERENCE!>G<Int?>::foo<!>)
|
<!INAPPLICABLE_CANDIDATE!>forReference<!>(<!UNRESOLVED_REFERENCE!>G<Int?>::foo<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,6 @@ class Outer {
|
|||||||
|
|
||||||
fun Outer.foo() {
|
fun Outer.foo() {
|
||||||
Outer()
|
Outer()
|
||||||
Nested()
|
<!UNRESOLVED_REFERENCE!>Nested<!>()
|
||||||
Inner()
|
Inner()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ class Test {
|
|||||||
fun more(): InnerClass {
|
fun more(): InnerClass {
|
||||||
val b = InnerClass()
|
val b = InnerClass()
|
||||||
|
|
||||||
val testVal = inClass
|
val testVal = <!UNRESOLVED_REFERENCE!>inClass<!>
|
||||||
foo()
|
<!UNRESOLVED_REFERENCE!>foo<!>()
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ class Test {
|
|||||||
fun more(): InnerClass {
|
fun more(): InnerClass {
|
||||||
val b = InnerClass()
|
val b = InnerClass()
|
||||||
|
|
||||||
val testVal = inClass
|
val testVal = <!UNRESOLVED_REFERENCE!>inClass<!>
|
||||||
foo()
|
<!UNRESOLVED_REFERENCE!>foo<!>()
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ class Outer {
|
|||||||
class Nested {
|
class Nested {
|
||||||
fun foo() {
|
fun foo() {
|
||||||
class Local {
|
class Local {
|
||||||
val state = outerState
|
val state = <!UNRESOLVED_REFERENCE!>outerState<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -24,30 +24,30 @@ object Obj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test(with: WithClassObject, without: WithoutClassObject, obj: Obj) {
|
fun test(with: WithClassObject, without: WithoutClassObject, obj: Obj) {
|
||||||
with.Nested()
|
with.<!UNRESOLVED_REFERENCE!>Nested<!>()
|
||||||
with.NestedWithClassObject
|
with.NestedWithClassObject
|
||||||
with.NestedWithClassObject()
|
with.<!UNRESOLVED_REFERENCE!>NestedWithClassObject<!>()
|
||||||
with.NestedWithClassObject.foo()
|
with.NestedWithClassObject.foo()
|
||||||
with.NestedEnum.A
|
with.NestedEnum.A
|
||||||
with.NestedObj
|
with.NestedObj
|
||||||
with.<!INAPPLICABLE_CANDIDATE!>NestedObj<!>()
|
with.<!UNRESOLVED_REFERENCE!>NestedObj<!>()
|
||||||
with.NestedObj.foo()
|
with.NestedObj.foo()
|
||||||
|
|
||||||
without.Nested()
|
without.<!UNRESOLVED_REFERENCE!>Nested<!>()
|
||||||
without.NestedWithClassObject
|
without.NestedWithClassObject
|
||||||
without.NestedWithClassObject()
|
without.<!UNRESOLVED_REFERENCE!>NestedWithClassObject<!>()
|
||||||
without.NestedWithClassObject.foo()
|
without.NestedWithClassObject.foo()
|
||||||
without.NestedEnum.A
|
without.NestedEnum.A
|
||||||
without.NestedObj
|
without.NestedObj
|
||||||
without.<!INAPPLICABLE_CANDIDATE!>NestedObj<!>()
|
without.<!UNRESOLVED_REFERENCE!>NestedObj<!>()
|
||||||
without.NestedObj.foo()
|
without.NestedObj.foo()
|
||||||
|
|
||||||
obj.Nested()
|
obj.<!UNRESOLVED_REFERENCE!>Nested<!>()
|
||||||
obj.NestedWithClassObject
|
obj.NestedWithClassObject
|
||||||
obj.NestedWithClassObject()
|
obj.<!UNRESOLVED_REFERENCE!>NestedWithClassObject<!>()
|
||||||
obj.NestedWithClassObject.foo()
|
obj.NestedWithClassObject.foo()
|
||||||
obj.NestedEnum.A
|
obj.NestedEnum.A
|
||||||
obj.NestedObj
|
obj.NestedObj
|
||||||
obj.<!INAPPLICABLE_CANDIDATE!>NestedObj<!>()
|
obj.<!UNRESOLVED_REFERENCE!>NestedObj<!>()
|
||||||
obj.NestedObj.foo()
|
obj.NestedObj.foo()
|
||||||
}
|
}
|
||||||
+2
-2
@@ -5,8 +5,8 @@ class Outer {
|
|||||||
val property = ""
|
val property = ""
|
||||||
|
|
||||||
class Nested {
|
class Nested {
|
||||||
fun f() = function()
|
fun f() = <!UNRESOLVED_REFERENCE!>function<!>()
|
||||||
fun g() = property
|
fun g() = <!UNRESOLVED_REFERENCE!>property<!>
|
||||||
fun h() = this@Outer.function()
|
fun h() = this@Outer.function()
|
||||||
fun i() = this@Outer.property
|
fun i() = this@Outer.property
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ open class Base {
|
|||||||
|
|
||||||
class Derived : Base() {
|
class Derived : Base() {
|
||||||
class Nested {
|
class Nested {
|
||||||
fun bar() = foo()
|
fun bar() = <!UNRESOLVED_REFERENCE!>foo<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vendored
+2
-2
@@ -119,8 +119,8 @@ class C : O.B() {
|
|||||||
val b = O.A::foo
|
val b = O.A::foo
|
||||||
|
|
||||||
// DEPRECATED: Classifiers from companions of direct superclasses
|
// DEPRECATED: Classifiers from companions of direct superclasses
|
||||||
val e = <!UNRESOLVED_REFERENCE!>O.A.<!AMBIGUITY!>Companion<!>.<!UNRESOLVED_REFERENCE!>FromCompanionA<!>::foo<!>
|
val e = O.A.Companion.FromCompanionA::foo
|
||||||
val f = <!UNRESOLVED_REFERENCE!>O.B.<!AMBIGUITY!>Companion<!>.<!UNRESOLVED_REFERENCE!>FromCompanionB<!>::foo<!>
|
val f = O.B.Companion.FromCompanionB::foo
|
||||||
|
|
||||||
// INVISIBLE: "cousin" supertypes themselves
|
// INVISIBLE: "cousin" supertypes themselves
|
||||||
val g = O.Alpha::foo
|
val g = O.Alpha::foo
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user