FIR: partially implement invoke resolution
This commit is contained in:
@@ -12,6 +12,8 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirImportImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
|
||||
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.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.constructClassType
|
||||
@@ -96,7 +98,8 @@ class Candidate(
|
||||
val implicitExtensionReceiverValue: ImplicitReceiverValue?,
|
||||
val explicitReceiverKind: ExplicitReceiverKind,
|
||||
private val inferenceComponents: InferenceComponents,
|
||||
private val baseSystem: ConstraintStorage
|
||||
private val baseSystem: ConstraintStorage,
|
||||
val callInfo: CallInfo
|
||||
) {
|
||||
val system by lazy {
|
||||
val system = inferenceComponents.createConstraintSystem()
|
||||
@@ -281,7 +284,8 @@ class ScopeTowerLevel(
|
||||
if (candidate.hasConsistentExtensionReceiver(extensionReceiver) && candidate.dispatchReceiverValue() == null) {
|
||||
processor.consumeCandidate(
|
||||
candidate as T, dispatchReceiverValue = null,
|
||||
implicitExtensionReceiverValue = implicitExtensionReceiver)
|
||||
implicitExtensionReceiverValue = implicitExtensionReceiver
|
||||
)
|
||||
} else {
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
@@ -342,15 +346,15 @@ class QualifiedReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
val name: Name,
|
||||
val token: TowerScopeLevel.Token<T>,
|
||||
val explicitReceiver: ExpressionReceiverValue,
|
||||
val candidateFactory: CandidateFactory
|
||||
val candidateFactory: CandidateFactory,
|
||||
val resultCollector: CandidateCollector
|
||||
) : TowerDataConsumer() {
|
||||
override fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
resultCollector: CandidateCollector,
|
||||
group: Int
|
||||
): ProcessorAction {
|
||||
if (checkSkip(group, resultCollector)) return ProcessorAction.NEXT
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
if (kind != TowerDataKind.EMPTY) return ProcessorAction.NEXT
|
||||
|
||||
return QualifiedReceiverTowerLevel(session).processElementsByName(
|
||||
@@ -385,16 +389,16 @@ abstract class TowerDataConsumer {
|
||||
abstract fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
resultCollector: CandidateCollector,
|
||||
// resultCollector: CandidateCollector,
|
||||
group: Int
|
||||
): ProcessorAction
|
||||
|
||||
private var stopGroup = Int.MAX_VALUE
|
||||
fun checkSkip(group: Int, resultCollector: CandidateCollector): Boolean {
|
||||
fun skipGroup(group: Int, resultCollector: CandidateCollector): Boolean {
|
||||
if (resultCollector.isSuccess() && stopGroup == Int.MAX_VALUE) {
|
||||
stopGroup = group
|
||||
}
|
||||
return group > stopGroup
|
||||
} else if (group > stopGroup) return true
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,39 +407,94 @@ fun createVariableAndObjectConsumer(
|
||||
session: FirSession,
|
||||
name: Name,
|
||||
callInfo: CallInfo,
|
||||
inferenceComponents: InferenceComponents
|
||||
inferenceComponents: InferenceComponents,
|
||||
resultCollector: CandidateCollector
|
||||
): TowerDataConsumer {
|
||||
return PrioritizedTowerDataConsumer(
|
||||
resultCollector,
|
||||
createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Properties,
|
||||
callInfo,
|
||||
inferenceComponents
|
||||
inferenceComponents,
|
||||
resultCollector
|
||||
),
|
||||
createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Objects,
|
||||
callInfo,
|
||||
inferenceComponents
|
||||
inferenceComponents,
|
||||
resultCollector
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
fun createFunctionConsumer(
|
||||
fun createSimpleFunctionConsumer(
|
||||
session: FirSession,
|
||||
name: Name,
|
||||
callInfo: CallInfo,
|
||||
inferenceComponents: InferenceComponents
|
||||
inferenceComponents: InferenceComponents,
|
||||
resultCollector: CandidateCollector
|
||||
): TowerDataConsumer {
|
||||
return createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Functions,
|
||||
callInfo,
|
||||
inferenceComponents
|
||||
inferenceComponents,
|
||||
resultCollector
|
||||
)
|
||||
}
|
||||
|
||||
fun createFunctionConsumer(
|
||||
session: FirSession,
|
||||
name: Name,
|
||||
callInfo: CallInfo,
|
||||
inferenceComponents: InferenceComponents,
|
||||
resultCollector: CandidateCollector,
|
||||
callResolver: CallResolver
|
||||
): TowerDataConsumer {
|
||||
val varCallInfo = CallInfo(
|
||||
CallKind.VariableAccess,
|
||||
callInfo.explicitReceiver,
|
||||
emptyList(),
|
||||
callInfo.isSafeCall,
|
||||
callInfo.typeArguments,
|
||||
inferenceComponents.session,
|
||||
callInfo.containingFile,
|
||||
callInfo.container,
|
||||
callInfo.typeProvider
|
||||
)
|
||||
return PrioritizedTowerDataConsumer(
|
||||
resultCollector,
|
||||
createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Functions,
|
||||
callInfo,
|
||||
inferenceComponents,
|
||||
resultCollector
|
||||
),
|
||||
MultiplexerTowerDataConsumer(resultCollector).apply {
|
||||
addConsumer(
|
||||
createSimpleConsumer(
|
||||
session,
|
||||
name,
|
||||
TowerScopeLevel.Token.Properties,
|
||||
varCallInfo,
|
||||
inferenceComponents,
|
||||
InvokeCandidateCollector(
|
||||
callResolver,
|
||||
invokeCallInfo = callInfo,
|
||||
components = inferenceComponents,
|
||||
multiplexer = this
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -445,7 +504,8 @@ fun createSimpleConsumer(
|
||||
name: Name,
|
||||
token: TowerScopeLevel.Token<*>,
|
||||
callInfo: CallInfo,
|
||||
inferenceComponents: InferenceComponents
|
||||
inferenceComponents: InferenceComponents,
|
||||
resultCollector: CandidateCollector
|
||||
): TowerDataConsumer {
|
||||
val factory = CandidateFactory(inferenceComponents, callInfo)
|
||||
val explicitReceiver = callInfo.explicitReceiver
|
||||
@@ -453,39 +513,40 @@ fun createSimpleConsumer(
|
||||
val receiverValue = ExpressionReceiverValue(explicitReceiver, callInfo.typeProvider)
|
||||
if (explicitReceiver is FirResolvedQualifier) {
|
||||
val qualified =
|
||||
QualifiedReceiverTowerDataConsumer(session, name, token, receiverValue, factory)
|
||||
QualifiedReceiverTowerDataConsumer(session, name, token, receiverValue, factory, resultCollector)
|
||||
|
||||
if (explicitReceiver.classId != null) {
|
||||
PrioritizedTowerDataConsumer(
|
||||
resultCollector,
|
||||
qualified,
|
||||
ExplicitReceiverTowerDataConsumer(session, name, token, receiverValue, factory)
|
||||
ExplicitReceiverTowerDataConsumer(session, name, token, receiverValue, factory, resultCollector)
|
||||
)
|
||||
} else {
|
||||
qualified
|
||||
}
|
||||
|
||||
} else {
|
||||
ExplicitReceiverTowerDataConsumer(session, name, token, receiverValue, factory)
|
||||
ExplicitReceiverTowerDataConsumer(session, name, token, receiverValue, factory, resultCollector)
|
||||
}
|
||||
} else {
|
||||
NoExplicitReceiverTowerDataConsumer(session, name, token, factory)
|
||||
NoExplicitReceiverTowerDataConsumer(session, name, token, factory, resultCollector)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PrioritizedTowerDataConsumer(
|
||||
val resultCollector: CandidateCollector,
|
||||
vararg val consumers: TowerDataConsumer
|
||||
) : TowerDataConsumer() {
|
||||
|
||||
override fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
resultCollector: CandidateCollector,
|
||||
group: Int
|
||||
): ProcessorAction {
|
||||
if (checkSkip(group, resultCollector)) return ProcessorAction.NEXT
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
for ((index, consumer) in consumers.withIndex()) {
|
||||
val action = consumer.consume(kind, towerScopeLevel, resultCollector, group * consumers.size + index)
|
||||
val action = consumer.consume(kind, towerScopeLevel, group * consumers.size + index)
|
||||
if (action.stop()) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
@@ -494,12 +555,57 @@ class PrioritizedTowerDataConsumer(
|
||||
}
|
||||
}
|
||||
|
||||
class MultiplexerTowerDataConsumer(
|
||||
val resultCollector: CandidateCollector
|
||||
) : TowerDataConsumer() {
|
||||
|
||||
val consumers = mutableListOf<TowerDataConsumer>()
|
||||
val newConsumers = mutableListOf<TowerDataConsumer>()
|
||||
|
||||
data class TowerData(val kind: TowerDataKind, val level: TowerScopeLevel, val group: Int)
|
||||
|
||||
val datas = mutableListOf<TowerData>()
|
||||
|
||||
override fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
group: Int
|
||||
): ProcessorAction {
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
consumers += newConsumers
|
||||
newConsumers.clear()
|
||||
datas += TowerData(kind, towerScopeLevel, group)
|
||||
|
||||
for (consumer in consumers) {
|
||||
val action = consumer.consume(kind, towerScopeLevel, group)
|
||||
if (action.stop()) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
}
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
fun addConsumer(consumer: TowerDataConsumer): ProcessorAction =
|
||||
run {
|
||||
for ((kind, level, group) in datas) {
|
||||
if (consumer.consume(kind, level, group).stop()) {
|
||||
return@run ProcessorAction.STOP
|
||||
}
|
||||
}
|
||||
return@run ProcessorAction.NEXT
|
||||
}.also {
|
||||
newConsumers += consumer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ExplicitReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
val session: FirSession,
|
||||
val name: Name,
|
||||
val token: TowerScopeLevel.Token<T>,
|
||||
val explicitReceiver: ExpressionReceiverValue,
|
||||
val candidateFactory: CandidateFactory
|
||||
val candidateFactory: CandidateFactory,
|
||||
val resultCollector: CandidateCollector
|
||||
) : TowerDataConsumer() {
|
||||
|
||||
companion object {
|
||||
@@ -510,10 +616,9 @@ class ExplicitReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
override fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
resultCollector: CandidateCollector,
|
||||
group: Int
|
||||
): ProcessorAction {
|
||||
if (checkSkip(group, resultCollector)) return ProcessorAction.NEXT
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
return when (kind) {
|
||||
TowerDataKind.EMPTY ->
|
||||
MemberScopeTowerLevel(session, explicitReceiver, scopeSession = candidateFactory.inferenceComponents.scopeSession)
|
||||
@@ -598,17 +703,17 @@ class NoExplicitReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
val session: FirSession,
|
||||
val name: Name,
|
||||
val token: TowerScopeLevel.Token<T>,
|
||||
val candidateFactory: CandidateFactory
|
||||
val candidateFactory: CandidateFactory,
|
||||
val resultCollector: CandidateCollector
|
||||
) : TowerDataConsumer() {
|
||||
|
||||
|
||||
override fun consume(
|
||||
kind: TowerDataKind,
|
||||
towerScopeLevel: TowerScopeLevel,
|
||||
resultCollector: CandidateCollector,
|
||||
group: Int
|
||||
): ProcessorAction {
|
||||
if (checkSkip(group, resultCollector)) return ProcessorAction.NEXT
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
return when (kind) {
|
||||
|
||||
TowerDataKind.TOWER_LEVEL -> {
|
||||
@@ -639,7 +744,6 @@ class NoExplicitReceiverTowerDataConsumer<T : ConeSymbol>(
|
||||
else -> ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CallResolver(val typeCalculator: ReturnTypeCalculator, val components: InferenceComponents) {
|
||||
@@ -660,36 +764,41 @@ class CallResolver(val typeCalculator: ReturnTypeCalculator, val components: Inf
|
||||
towerDataConsumer.consume(
|
||||
TowerDataKind.TOWER_LEVEL,
|
||||
MemberScopeTowerLevel(session, implicitReceiverValue, scopeSession = components.scopeSession),
|
||||
collector, group++
|
||||
group++
|
||||
)
|
||||
|
||||
// This is an equivalent to the old "BothTowerLevelAndImplicitReceiver"
|
||||
towerDataConsumer.consume(
|
||||
TowerDataKind.TOWER_LEVEL,
|
||||
MemberScopeTowerLevel(session, implicitReceiverValue, implicitReceiverValue, components.scopeSession),
|
||||
collector, group++
|
||||
group++
|
||||
)
|
||||
|
||||
for (scope in scopes!!) {
|
||||
towerDataConsumer.consume(
|
||||
TowerDataKind.TOWER_LEVEL,
|
||||
ScopeTowerLevel(session, scope, implicitReceiverValue),
|
||||
collector, group++
|
||||
group++
|
||||
)
|
||||
}
|
||||
|
||||
return group
|
||||
}
|
||||
|
||||
fun runTowerResolver(towerDataConsumer: TowerDataConsumer, implicitReceiverValues: List<ImplicitReceiverValue>): CandidateCollector {
|
||||
val collector = CandidateCollector(callInfo!!, components)
|
||||
val collector by lazy { CandidateCollector(components) }
|
||||
lateinit var towerDataConsumer: TowerDataConsumer
|
||||
private lateinit var implicitReceiverValues: List<ImplicitReceiverValue>
|
||||
|
||||
fun runTowerResolver(consumer: TowerDataConsumer, implicitReceiverValues: List<ImplicitReceiverValue>): CandidateCollector {
|
||||
this.implicitReceiverValues = implicitReceiverValues
|
||||
towerDataConsumer = consumer
|
||||
|
||||
var group = 0
|
||||
|
||||
towerDataConsumer.consume(TowerDataKind.EMPTY, TowerScopeLevel.Empty, collector, group++)
|
||||
towerDataConsumer.consume(TowerDataKind.EMPTY, TowerScopeLevel.Empty, group++)
|
||||
|
||||
for (scope in scopes!!) {
|
||||
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, scope), collector, group++)
|
||||
towerDataConsumer.consume(TowerDataKind.TOWER_LEVEL, ScopeTowerLevel(session, scope), group++)
|
||||
}
|
||||
|
||||
var blockDispatchReceivers = false
|
||||
@@ -702,13 +811,14 @@ class CallResolver(val typeCalculator: ReturnTypeCalculator, val components: Inf
|
||||
blockDispatchReceivers = true
|
||||
}
|
||||
}
|
||||
processImplicitReceiver(towerDataConsumer, implicitReceiverValue, collector, group)
|
||||
group = processImplicitReceiver(towerDataConsumer, implicitReceiverValue, collector, group)
|
||||
}
|
||||
|
||||
|
||||
|
||||
return collector
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -721,7 +831,7 @@ enum class CandidateApplicability {
|
||||
RESOLVED
|
||||
}
|
||||
|
||||
class CandidateCollector(val callInfo: CallInfo, val components: InferenceComponents) {
|
||||
open class CandidateCollector(val components: InferenceComponents) {
|
||||
|
||||
val groupNumbers = mutableListOf<Int>()
|
||||
val candidates = mutableListOf<Candidate>()
|
||||
@@ -744,8 +854,8 @@ class CandidateCollector(val callInfo: CallInfo, val components: InferenceCompon
|
||||
val sink = CheckerSinkImpl(components)
|
||||
var finished = false
|
||||
sink.continuation = suspend {
|
||||
for (stage in callInfo.callKind.sequence()) {
|
||||
stage.check(candidate, sink, callInfo)
|
||||
for (stage in candidate.callInfo.callKind.sequence()) {
|
||||
stage.check(candidate, sink, candidate.callInfo)
|
||||
}
|
||||
}.createCoroutineUnintercepted(completion = object : Continuation<Unit> {
|
||||
override val context: CoroutineContext
|
||||
@@ -769,7 +879,7 @@ class CandidateCollector(val callInfo: CallInfo, val components: InferenceCompon
|
||||
return sink.current
|
||||
}
|
||||
|
||||
fun consumeCandidate(group: Int, candidate: Candidate) {
|
||||
open fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
||||
val applicability = getApplicability(group, candidate)
|
||||
|
||||
if (applicability > currentApplicability) {
|
||||
@@ -783,6 +893,8 @@ class CandidateCollector(val callInfo: CallInfo, val components: InferenceCompon
|
||||
candidates.add(candidate)
|
||||
groupNumbers.add(group)
|
||||
}
|
||||
|
||||
return applicability
|
||||
}
|
||||
|
||||
|
||||
@@ -808,6 +920,47 @@ class CandidateCollector(val callInfo: CallInfo, val components: InferenceCompon
|
||||
}
|
||||
}
|
||||
|
||||
class InvokeCandidateCollector(
|
||||
val callResolver: CallResolver,
|
||||
val invokeCallInfo: CallInfo,
|
||||
components: InferenceComponents,
|
||||
val multiplexer: MultiplexerTowerDataConsumer
|
||||
) : CandidateCollector(components) {
|
||||
override fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
||||
val applicability = super.consumeCandidate(group, candidate)
|
||||
|
||||
if (applicability >= CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||
|
||||
val session = components.session
|
||||
val boundInvokeCallInfo = CallInfo(
|
||||
invokeCallInfo.callKind,
|
||||
FirQualifiedAccessExpressionImpl(session, null, false).apply {
|
||||
calleeReference = FirNamedReferenceWithCandidate(
|
||||
session,
|
||||
null,
|
||||
(candidate.symbol as ConeCallableSymbol).callableId.callableName,
|
||||
candidate
|
||||
)
|
||||
typeRef = callResolver.typeCalculator.tryCalculateReturnType(candidate.symbol.firUnsafe())
|
||||
},
|
||||
invokeCallInfo.arguments,
|
||||
invokeCallInfo.isSafeCall,
|
||||
invokeCallInfo.typeArguments,
|
||||
session,
|
||||
invokeCallInfo.containingFile,
|
||||
invokeCallInfo.container,
|
||||
invokeCallInfo.typeProvider
|
||||
)
|
||||
val invokeConsumer =
|
||||
createSimpleFunctionConsumer(session, Name.identifier("invoke"), boundInvokeCallInfo, components, callResolver.collector)
|
||||
|
||||
multiplexer.addConsumer(invokeConsumer)
|
||||
}
|
||||
|
||||
return applicability
|
||||
}
|
||||
}
|
||||
|
||||
fun FirCallableDeclaration.dispatchReceiverValue(session: FirSession): ClassDispatchReceiverValue? {
|
||||
// TODO: this is not true at least for inner class constructors
|
||||
if (this is FirConstructor) return null
|
||||
|
||||
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
|
||||
class CandidateFactory(
|
||||
val inferenceComponents: InferenceComponents,
|
||||
callInfo: CallInfo
|
||||
val callInfo: CallInfo
|
||||
) {
|
||||
|
||||
val baseSystem: ConstraintStorage
|
||||
@@ -35,7 +35,7 @@ class CandidateFactory(
|
||||
): Candidate {
|
||||
return Candidate(
|
||||
symbol, dispatchReceiverValue, implicitExtensionReceiverValue,
|
||||
explicitReceiverKind, inferenceComponents, baseSystem
|
||||
explicitReceiverKind, inferenceComponents, baseSystem, callInfo
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+78
-9
@@ -15,8 +15,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirEnumEntryImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.deserialization.FirBuiltinAnnotationDeserializer
|
||||
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext
|
||||
import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol
|
||||
@@ -24,11 +23,12 @@ import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassDeclaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.builtins.BuiltInsBinaryVersion
|
||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
||||
@@ -38,6 +38,8 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoBasedClassDataFinder
|
||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
import java.io.InputStream
|
||||
|
||||
@@ -168,15 +170,82 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider(
|
||||
this,
|
||||
relativeClassName.shortName(),
|
||||
Visibilities.PUBLIC,
|
||||
Modality.OPEN,
|
||||
Modality.ABSTRACT,
|
||||
isExpect = false,
|
||||
isActual = false,
|
||||
classKind = ClassKind.CLASS,
|
||||
classKind = ClassKind.INTERFACE,
|
||||
isInner = false,
|
||||
isCompanion = false,
|
||||
isData = false,
|
||||
isInline = false
|
||||
)
|
||||
).apply klass@{
|
||||
typeParameters.addAll((1..arity).map {
|
||||
FirTypeParameterImpl(
|
||||
session,
|
||||
null,
|
||||
FirTypeParameterSymbol(),
|
||||
Name.identifier("P$it"),
|
||||
Variance.IN_VARIANCE,
|
||||
false
|
||||
)
|
||||
})
|
||||
typeParameters.add(
|
||||
FirTypeParameterImpl(
|
||||
session,
|
||||
null,
|
||||
FirTypeParameterSymbol(),
|
||||
Name.identifier("R"),
|
||||
Variance.OUT_VARIANCE,
|
||||
false
|
||||
)
|
||||
)
|
||||
val name = Name.identifier("invoke")
|
||||
addDeclaration(
|
||||
FirMemberFunctionImpl(
|
||||
session,
|
||||
null,
|
||||
FirFunctionSymbol(CallableId(packageFqName, relativeClassName, name)),
|
||||
name,
|
||||
Visibilities.PUBLIC,
|
||||
Modality.ABSTRACT,
|
||||
isExpect = false,
|
||||
isActual = false,
|
||||
isOverride = false,
|
||||
isOperator = true,
|
||||
isInfix = false,
|
||||
isInline = false,
|
||||
isTailRec = false,
|
||||
isExternal = false,
|
||||
isSuspend = false,
|
||||
receiverTypeRef = null,
|
||||
returnTypeRef = FirResolvedTypeRefImpl(
|
||||
session,
|
||||
null,
|
||||
ConeTypeParameterTypeImpl(
|
||||
typeParameters.last().symbol.toLookupTag(),
|
||||
false
|
||||
)
|
||||
)
|
||||
).apply {
|
||||
valueParameters += this@klass.typeParameters.dropLast(1).map { typeParameter ->
|
||||
FirValueParameterImpl(
|
||||
session,
|
||||
null,
|
||||
Name.identifier(typeParameter.name.asString().toLowerCase()),
|
||||
FirResolvedTypeRefImpl(
|
||||
session,
|
||||
null,
|
||||
ConeTypeParameterTypeImpl(typeParameter.symbol.toLookupTag(), false)
|
||||
),
|
||||
defaultValue = null,
|
||||
isCrossinline = false,
|
||||
isNoinline = false,
|
||||
isVararg = false
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-6
@@ -335,7 +335,8 @@ open class FirBodyResolveTransformer(
|
||||
val consumer = createVariableAndObjectConsumer(
|
||||
session,
|
||||
callee.name,
|
||||
info, inferenceComponents
|
||||
info, inferenceComponents,
|
||||
resolver.collector
|
||||
)
|
||||
val result = resolver.runTowerResolver(consumer, implicitReceiverStack.asReversed())
|
||||
|
||||
@@ -550,7 +551,7 @@ open class FirBodyResolveTransformer(
|
||||
resolver.callInfo = info
|
||||
resolver.scopes = (scopes + localScopes).asReversed()
|
||||
|
||||
val consumer = createFunctionConsumer(session, name, info, inferenceComponents)
|
||||
val consumer = createFunctionConsumer(session, name, info, inferenceComponents, resolver.collector, resolver)
|
||||
val result = resolver.runTowerResolver(consumer, implicitReceiverStack.asReversed())
|
||||
val bestCandidates = result.bestCandidates()
|
||||
val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) {
|
||||
@@ -596,11 +597,23 @@ open class FirBodyResolveTransformer(
|
||||
)
|
||||
|
||||
val resultExpression = functionCall.transformCalleeReference(StoreNameReference, nameReference) as FirFunctionCall
|
||||
val typeRef = typeFromCallee(functionCall)
|
||||
if (typeRef.type is ConeKotlinErrorType) {
|
||||
functionCall.resultType = typeRef
|
||||
val candidate = resultExpression.candidate()
|
||||
|
||||
// We need desugaring
|
||||
val resultFunctionCall = if (candidate != null && candidate.callInfo != info) {
|
||||
functionCall.copy(
|
||||
explicitReceiver = candidate.callInfo.explicitReceiver,
|
||||
arguments = candidate.callInfo.arguments,
|
||||
safe = candidate.callInfo.isSafeCall
|
||||
)
|
||||
} else {
|
||||
resultExpression
|
||||
}
|
||||
return resultExpression
|
||||
val typeRef = typeFromCallee(resultFunctionCall)
|
||||
if (typeRef.type is ConeKotlinErrorType) {
|
||||
resultFunctionCall.resultType = typeRef
|
||||
}
|
||||
return resultFunctionCall
|
||||
}
|
||||
|
||||
data class LambdaResolution(val expectedReturnTypeRef: FirResolvedTypeRef?)
|
||||
@@ -1270,6 +1283,18 @@ internal object StoreType : FirTransformer<FirTypeRef>() {
|
||||
}
|
||||
}
|
||||
|
||||
internal object StoreExplicitReceiver : FirTransformer<FirExpression>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: FirExpression): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformExpression(expression: FirExpression, data: FirExpression): CompositeTransformResult<FirStatement> {
|
||||
return data.compose()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private object ReplaceInArguments : FirTransformer<Map<FirElement, FirElement>>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Map<FirElement, FirElement>): CompositeTransformResult<E> {
|
||||
return ((data[element] ?: element) as E).compose()
|
||||
|
||||
+2
-2
@@ -13,8 +13,8 @@ FILE: explicitReceiver.kt
|
||||
^invoke this#
|
||||
}
|
||||
|
||||
public final fun bar(): R|kotlin/Unit| {
|
||||
^bar R|/x|()
|
||||
public final fun bar(): R|Foo| {
|
||||
^bar R|/Foo.x|.R|/Foo.invoke|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -23,8 +23,8 @@ FILE: explicitReceiver2.kt
|
||||
public final val x: R|Bar| = R|/Bar.Bar|()
|
||||
public get(): R|Bar|
|
||||
|
||||
public final fun bar(): R|kotlin/Unit| {
|
||||
^bar R|/x|()
|
||||
public final fun bar(): R|Foo| {
|
||||
^bar R|/Foo.x|.R|/Bar.invoke|()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,5 +7,5 @@ class Foo {
|
||||
|
||||
val x = 0
|
||||
|
||||
fun foo() = x()
|
||||
fun foo() = x() // should resolve to invoke
|
||||
}
|
||||
+1
-1
@@ -8,5 +8,5 @@ class Foo {
|
||||
|
||||
val x = 0
|
||||
|
||||
fun foo() = x()
|
||||
fun foo() = x() // should resolve to fun x
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
|
||||
class A {
|
||||
fun bar() = foo()
|
||||
fun bar() = foo() // should resolve to invoke
|
||||
|
||||
fun invoke() = this
|
||||
}
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ FILE: implicitTypeOrder.kt
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final fun bar(): <ERROR TYPE REF: Unresolved name: foo> {
|
||||
^bar <Unresolved name: foo>#()
|
||||
public final fun bar(): R|A| {
|
||||
^bar R|/foo|.R|/A.invoke|()
|
||||
}
|
||||
|
||||
public final fun invoke(): R|A| {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class Simple {
|
||||
operator fun invoke(): String = "invoke"
|
||||
}
|
||||
|
||||
fun test(s: Simple) {
|
||||
val result = s()
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
FILE: simple.kt
|
||||
public final class Simple : R|kotlin/Any| {
|
||||
public constructor(): R|Simple| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final operator fun invoke(): R|kotlin/String| {
|
||||
^invoke String(invoke)
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test(s: R|Simple|): R|kotlin/Unit| {
|
||||
lval result: R|kotlin/String| = R|<local>/s|.R|/Simple.invoke|()
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
fun <T> simpleRun(f: (T) -> Unit): Unit = f()
|
||||
fun <T> simpleRun(f: (T) -> Unit): Unit = f(return)
|
||||
|
||||
fun <T, R> List<T>.simpleMap(f: (T) -> R): R {
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
FILE: functionTypes.kt
|
||||
public final fun <T> simpleRun(f: R|kotlin/Function1<T, kotlin/Unit>|): R|kotlin/Unit| {
|
||||
^simpleRun <Unresolved name: f>#()
|
||||
^simpleRun R|<local>/f|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(^simpleRun Unit)
|
||||
}
|
||||
public final fun <T, R> R|kotlin/collections/List<T>|.simpleMap(f: R|kotlin/Function1<T, R>|): R|R| {
|
||||
}
|
||||
|
||||
+5
@@ -372,6 +372,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/implicitTypeOrder.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("threeReceivers.kt")
|
||||
public void testThreeReceivers() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt");
|
||||
|
||||
@@ -32,7 +32,7 @@ FILE fqName:<root> fileName:/outerClassAccess.kt
|
||||
FUN name:test3 visibility:public modality:FINAL <> ($this:<root>.Outer.Inner.Inner2) returnType:kotlin.Unit
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Outer.Inner.Inner2
|
||||
BLOCK_BODY
|
||||
ERROR_CALL 'Unresolved reference: <Ambiguity: foo, [/Outer.foo, /Outer.foo]>#' type=IrErrorType
|
||||
CALL 'public final fun foo (): kotlin.Unit declared in <root>.Outer' type=kotlin.Unit origin=null
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
|
||||
overridden:
|
||||
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
|
||||
|
||||
+5
-4
@@ -42,7 +42,8 @@ FILE fqName:<root> fileName:/augmentedAssignmentWithExpression.kt
|
||||
FUN name:test4 visibility:public modality:FINAL <> (a:kotlin.Function0<<root>.Host>) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<<root>.Host>
|
||||
BLOCK_BODY
|
||||
VAR name:<complex-set> type:IrErrorType [val]
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: a>#' type=IrErrorType
|
||||
SET_VAR 'val <complex-set>: IrErrorType [val] declared in <root>.test4' type=IrErrorType origin=null
|
||||
CONST Int type=IrErrorType value=1
|
||||
VAR name:<complex-set> type:<root>.Host [val]
|
||||
CALL 'public abstract fun invoke (): <root>.Host declared in kotlin.Function0' type=<root>.Host origin=null
|
||||
$this: GET_VAR 'a: kotlin.Function0<<root>.Host> declared in <root>.test4' type=kotlin.Function0<<root>.Host> origin=null
|
||||
SET_VAR 'val <complex-set>: <root>.Host [val] declared in <root>.test4' type=<root>.Host origin=null
|
||||
CONST Int type=<root>.Host value=1
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
FILE fqName:<root> fileName:/catchParameterAccess.kt
|
||||
FUN name:test visibility:public modality:FINAL <> (f:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Nothing?
|
||||
FUN name:test visibility:public modality:FINAL <> (f:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:f index:0 type:kotlin.Function0<kotlin.Unit>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test (f: kotlin.Function0<kotlin.Unit>): kotlin.Nothing? declared in <root>'
|
||||
TRY type=kotlin.Nothing?
|
||||
try: ERROR_CALL 'Unresolved reference: <Unresolved name: f>#' type=IrErrorType
|
||||
RETURN type=kotlin.Nothing from='public final fun test (f: kotlin.Function0<kotlin.Unit>): kotlin.Unit declared in <root>'
|
||||
TRY type=kotlin.Unit
|
||||
try: CALL 'public abstract fun invoke (): kotlin.Unit declared in kotlin.Function0' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'f: kotlin.Function0<kotlin.Unit> declared in <root>.test' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
CATCH parameter=val e: java.lang.Exception [val] declared in <root>.test
|
||||
VAR name:e type:java.lang.Exception [val]
|
||||
THROW type=kotlin.Nothing
|
||||
|
||||
@@ -81,5 +81,5 @@ FILE fqName:<root> fileName:/enumEntryAsReceiver.kt
|
||||
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: value>#' type=IrErrorType
|
||||
|
||||
CALL 'public abstract fun invoke (): kotlin.String declared in kotlin.Function0' type=kotlin.String origin=null
|
||||
$this: CALL 'public abstract fun <get-value> (): kotlin.Function0<kotlin.String> declared in <root>.X' type=kotlin.Function0<kotlin.String> origin=null
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
FILE fqName:<root> fileName:/extFunInvokeAsFun.kt
|
||||
FUN name:with1 visibility:public modality:FINAL <> (receiver:kotlin.Any?, block:kotlin.Function1<kotlin.Any?, kotlin.Unit>) returnType:IrErrorType
|
||||
FUN name:with1 visibility:public modality:FINAL <> (receiver:kotlin.Any?, block:kotlin.Function1<kotlin.Any?, kotlin.Unit>) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:receiver index:0 type:kotlin.Any?
|
||||
VALUE_PARAMETER name:block index:1 type:kotlin.Function1<kotlin.Any?, kotlin.Unit>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun with1 (receiver: kotlin.Any?, block: kotlin.Function1<kotlin.Any?, kotlin.Unit>): IrErrorType declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: block>#' type=IrErrorType
|
||||
GET_VAR 'receiver: kotlin.Any? declared in <root>.with1' type=kotlin.Any? origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun with1 (receiver: kotlin.Any?, block: kotlin.Function1<kotlin.Any?, kotlin.Unit>): kotlin.Unit declared in <root>'
|
||||
CALL 'public abstract fun invoke (p1: kotlin.Any?): kotlin.Unit declared in kotlin.Function1' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'block: kotlin.Function1<kotlin.Any?, kotlin.Unit> declared in <root>.with1' type=kotlin.Function1<kotlin.Any?, kotlin.Unit> origin=null
|
||||
p1: GET_VAR 'receiver: kotlin.Any? declared in <root>.with1' type=kotlin.Any? origin=null
|
||||
FUN name:with2 visibility:public modality:FINAL <> (receiver:kotlin.Any?, block:kotlin.Function1<kotlin.Any?, kotlin.Unit>) returnType:IrErrorType
|
||||
VALUE_PARAMETER name:receiver index:0 type:kotlin.Any?
|
||||
VALUE_PARAMETER name:block index:1 type:kotlin.Function1<kotlin.Any?, kotlin.Unit>
|
||||
|
||||
+2
-1
@@ -19,7 +19,8 @@ FILE fqName:<root> fileName:/genericConstructorCallWithTypeArguments.kt
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.Int) returnType:T of kotlin.Array
|
||||
VALUE_PARAMETER name:it index:0 type:kotlin.Int
|
||||
BLOCK_BODY
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: block>#' type=IrErrorType
|
||||
CALL 'public abstract fun invoke (): T of <root>.testArray declared in kotlin.Function0' type=T of <root>.testArray origin=null
|
||||
$this: GET_VAR 'block: kotlin.Function0<T of <root>.testArray> [crossinline] declared in <root>.testArray' type=kotlin.Function0<T of <root>.testArray> origin=null
|
||||
FUNCTION_REFERENCE 'local final fun <anonymous> (it: kotlin.Int): T of kotlin.Array declared in <root>.testArray' type=kotlin.Function1<kotlin.Int, T of kotlin.Array> origin=LAMBDA
|
||||
CLASS CLASS name:Box modality:FINAL visibility:public superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Box
|
||||
|
||||
@@ -64,6 +64,6 @@ FILE fqName:<root> fileName:/implicitCastToNonNull.kt
|
||||
$this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ
|
||||
arg0: GET_VAR 'x: T of <root>.test5 declared in <root>.test5' type=T of <root>.test5 origin=null
|
||||
arg1: CONST Null type=kotlin.Nothing? value=null
|
||||
then: ERROR_CALL 'Unresolved reference: <Unresolved name: fn>#' type=IrErrorType
|
||||
GET_VAR 'x: T of <root>.test5 declared in <root>.test5' type=T of <root>.test5 origin=null
|
||||
|
||||
then: CALL 'public abstract fun invoke (p1: S of <root>.test5): kotlin.Unit declared in kotlin.Function1' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'fn: kotlin.Function1<S of <root>.test5, kotlin.Unit> declared in <root>.test5' type=kotlin.Function1<S of <root>.test5, kotlin.Unit> origin=null
|
||||
p1: GET_VAR 'x: T of <root>.test5 declared in <root>.test5' type=T of <root>.test5 origin=null
|
||||
|
||||
+2
-3
@@ -76,9 +76,8 @@ FILE fqName:<root> fileName:/samConversionsWithSmartCasts.kt
|
||||
FUN name:test8 visibility:public modality:FINAL <> (a:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:a index:0 type:kotlin.Function0<kotlin.Unit>
|
||||
BLOCK_BODY
|
||||
CALL 'public open fun run1 (r: java.lang.Runnable?): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=null
|
||||
$this: CONSTRUCTOR_CALL 'public constructor <init> () declared in <root>.J' type=<root>.J origin=null
|
||||
r: CALL 'public open fun id (x: T of <uninitialized parent>?): T of <uninitialized parent>? declared in <root>.J' type=IrErrorType origin=null
|
||||
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/J.run1]>#' type=IrErrorType
|
||||
CALL 'public open fun id (x: T of <uninitialized parent>?): T of <uninitialized parent>? declared in <root>.J' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
x: GET_VAR 'a: kotlin.Function0<kotlin.Unit> declared in <root>.test8' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
FUN name:test9 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
|
||||
@@ -7,11 +7,12 @@ FILE fqName:<root> fileName:/variableAsFunctionCall.kt
|
||||
BLOCK_BODY
|
||||
ERROR_CALL 'Unresolved reference: this#' type=kotlin.String
|
||||
FUNCTION_REFERENCE 'local final fun <anonymous> (): kotlin.Function0<kotlin.String> declared in <root>.k' type=kotlin.Function1<kotlin.Function0<kotlin.String>, kotlin.Function0<kotlin.String>> origin=LAMBDA
|
||||
FUN name:test1 visibility:public modality:FINAL <> (f:kotlin.Function0<kotlin.Unit>) returnType:IrErrorType
|
||||
FUN name:test1 visibility:public modality:FINAL <> (f:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:f index:0 type:kotlin.Function0<kotlin.Unit>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test1 (f: kotlin.Function0<kotlin.Unit>): IrErrorType declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: f>#' type=IrErrorType
|
||||
RETURN type=kotlin.Nothing from='public final fun test1 (f: kotlin.Function0<kotlin.Unit>): kotlin.Unit declared in <root>'
|
||||
CALL 'public abstract fun invoke (): kotlin.Unit declared in kotlin.Function0' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'f: kotlin.Function0<kotlin.Unit> declared in <root>.test1' type=kotlin.Function0<kotlin.Unit> origin=null
|
||||
FUN name:test2 visibility:public modality:FINAL <> (f:kotlin.Function1<kotlin.String, kotlin.Unit>) returnType:IrErrorType
|
||||
VALUE_PARAMETER name:f index:0 type:kotlin.Function1<kotlin.String, kotlin.Unit>
|
||||
BLOCK_BODY
|
||||
@@ -22,9 +23,9 @@ FILE fqName:<root> fileName:/variableAsFunctionCall.kt
|
||||
RETURN type=kotlin.Nothing from='public final fun test3 (): IrErrorType declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: invoke>#' type=IrErrorType
|
||||
CALL 'public final fun k (): kotlin.Function0<kotlin.String> declared in <root>' type=kotlin.Function0<kotlin.String> origin=null
|
||||
FUN name:test4 visibility:public modality:FINAL <> (ns:kotlin.String?) returnType:IrErrorType
|
||||
FUN name:test4 visibility:public modality:FINAL <> (ns:kotlin.String?) returnType:kotlin.String
|
||||
VALUE_PARAMETER name:ns index:0 type:kotlin.String?
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun test4 (ns: kotlin.String?): IrErrorType declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: invoke>#' type=IrErrorType
|
||||
|
||||
RETURN type=kotlin.Nothing from='public final fun test4 (ns: kotlin.String?): kotlin.String declared in <root>'
|
||||
CALL 'public abstract fun invoke (): kotlin.String declared in kotlin.Function0' type=kotlin.String origin=null
|
||||
$this: CALL 'public final fun k (): kotlin.Function0<kotlin.String> declared in <root>' type=kotlin.Function0<kotlin.String> origin=null
|
||||
|
||||
+8
-7
@@ -9,11 +9,12 @@ FILE fqName:<root> fileName:/variableAsFunctionCallWithGenerics.kt
|
||||
BLOCK_BODY
|
||||
ERROR_CALL 'Unresolved reference: this#' type=IrErrorType
|
||||
FUNCTION_REFERENCE 'local final fun <anonymous> (): kotlin.Function0<T of <uninitialized parent>> declared in <root>.<get-gk>' type=kotlin.Function1<kotlin.Function0<T of <uninitialized parent>>, kotlin.Function0<T of <uninitialized parent>>> origin=LAMBDA
|
||||
FUN name:testGeneric1 visibility:public modality:FINAL <> (x:kotlin.String) returnType:IrErrorType
|
||||
FUN name:testGeneric1 visibility:public modality:FINAL <> (x:kotlin.String) returnType:T of <uninitialized parent>
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun testGeneric1 (x: kotlin.String): IrErrorType declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: gk>#' type=IrErrorType
|
||||
RETURN type=kotlin.Nothing from='public final fun testGeneric1 (x: kotlin.String): T of <uninitialized parent> declared in <root>'
|
||||
CALL 'public abstract fun invoke (): T of <uninitialized parent> declared in kotlin.Function0' type=T of <uninitialized parent> origin=null
|
||||
$this: CALL 'public final fun <get-gk> (): kotlin.Function0<T of <uninitialized parent>> declared in <root>' type=kotlin.Function0<T of <uninitialized parent>> origin=null
|
||||
PROPERTY name:kt26531Val visibility:public modality:FINAL [val]
|
||||
FUN name:<get-kt26531Val> visibility:public modality:FINAL <> () returnType:kotlin.Function0<T of <uninitialized parent>>
|
||||
correspondingProperty: PROPERTY name:kt26531Val visibility:public modality:FINAL [val]
|
||||
@@ -25,8 +26,8 @@ FILE fqName:<root> fileName:/variableAsFunctionCallWithGenerics.kt
|
||||
RETURN type=kotlin.Nothing from='local final fun <no name provided> (): kotlin.Function0<T of <uninitialized parent>> declared in <root>.<get-kt26531Val>'
|
||||
ERROR_CALL 'Unresolved reference: this#' type=IrErrorType
|
||||
FUNCTION_REFERENCE 'local final fun <no name provided> (): kotlin.Function0<T of <uninitialized parent>> declared in <root>.<get-kt26531Val>' type=kotlin.Function0<kotlin.Function0<T of <uninitialized parent>>> origin=ANONYMOUS_FUNCTION
|
||||
FUN name:kt26531 visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FUN name:kt26531 visibility:public modality:FINAL <> () returnType:T of <uninitialized parent>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun kt26531 (): IrErrorType declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: kt26531Val>#' type=IrErrorType
|
||||
|
||||
RETURN type=kotlin.Nothing from='public final fun kt26531 (): T of <uninitialized parent> declared in <root>'
|
||||
CALL 'public abstract fun invoke (): T of <uninitialized parent> declared in kotlin.Function0' type=T of <uninitialized parent> origin=null
|
||||
$this: CALL 'public final fun <get-kt26531Val> (): kotlin.Function0<T of <uninitialized parent>> declared in <root>' type=kotlin.Function0<T of <uninitialized parent>> origin=null
|
||||
|
||||
@@ -83,25 +83,26 @@ FILE fqName:<root> fileName:/multipleImplicitReceivers.kt
|
||||
VALUE_PARAMETER name:fooImpl index:0 type:<root>.IFoo
|
||||
VALUE_PARAMETER name:invokeImpl index:1 type:<root>.IInvoke
|
||||
BLOCK_BODY
|
||||
CALL 'public final fun with (receiver: T of <uninitialized parent>, block: kotlin.Function1<T of <uninitialized parent>, R of <uninitialized parent>>): R of <uninitialized parent> [inline] declared in kotlin' type=kotlin.Unit origin=null
|
||||
CALL 'public final fun with (receiver: T of <uninitialized parent>, block: kotlin.Function1<T of <uninitialized parent>, R of <uninitialized parent>>): R of <uninitialized parent> [inline] declared in kotlin' type=kotlin.Int origin=null
|
||||
receiver: GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.A
|
||||
block: BLOCK type=kotlin.Function2<<root>.A, <root>.A, kotlin.Unit> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:<root>.A) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:it index:0 type:<root>.A
|
||||
BLOCK_BODY
|
||||
CALL 'public final fun with (receiver: T of <uninitialized parent>, block: kotlin.Function1<T of <uninitialized parent>, R of <uninitialized parent>>): R of <uninitialized parent> [inline] declared in kotlin' type=kotlin.Unit origin=null
|
||||
CALL 'public final fun with (receiver: T of <uninitialized parent>, block: kotlin.Function1<T of <uninitialized parent>, R of <uninitialized parent>>): R of <uninitialized parent> [inline] declared in kotlin' type=kotlin.Int origin=null
|
||||
receiver: GET_VAR 'fooImpl: <root>.IFoo declared in <root>.test' type=<root>.IFoo origin=null
|
||||
block: BLOCK type=kotlin.Function2<<root>.IFoo, <root>.IFoo, kotlin.Unit> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:<root>.IFoo) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:it index:0 type:<root>.IFoo
|
||||
BLOCK_BODY
|
||||
CALL 'public final fun with (receiver: T of <uninitialized parent>, block: kotlin.Function1<T of <uninitialized parent>, R of <uninitialized parent>>): R of <uninitialized parent> [inline] declared in kotlin' type=kotlin.Unit origin=null
|
||||
CALL 'public final fun with (receiver: T of <uninitialized parent>, block: kotlin.Function1<T of <uninitialized parent>, R of <uninitialized parent>>): R of <uninitialized parent> [inline] declared in kotlin' type=kotlin.Int origin=null
|
||||
receiver: GET_VAR 'invokeImpl: <root>.IInvoke declared in <root>.test' type=<root>.IInvoke origin=null
|
||||
block: BLOCK type=kotlin.Function2<<root>.IInvoke, <root>.IInvoke, kotlin.Unit> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:<root>.IInvoke) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:it index:0 type:<root>.IInvoke
|
||||
BLOCK_BODY
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: foo>#' type=IrErrorType
|
||||
CALL 'public open fun invoke (): kotlin.Int declared in <root>.IInvoke' type=kotlin.Int origin=null
|
||||
$this: CALL 'public open fun <get-foo> (): <root>.B declared in <root>.IFoo' type=<root>.B origin=null
|
||||
FUNCTION_REFERENCE 'local final fun <anonymous> (it: <root>.IInvoke): kotlin.Unit declared in <root>.test.<anonymous>.<anonymous>' type=kotlin.Function2<<root>.IInvoke, <root>.IInvoke, kotlin.Unit> origin=LAMBDA
|
||||
FUNCTION_REFERENCE 'local final fun <anonymous> (it: <root>.IFoo): kotlin.Unit declared in <root>.test.<anonymous>' type=kotlin.Function2<<root>.IFoo, <root>.IFoo, kotlin.Unit> origin=LAMBDA
|
||||
FUNCTION_REFERENCE 'local final fun <anonymous> (it: <root>.A): kotlin.Unit declared in <root>.test' type=kotlin.Function2<<root>.A, <root>.A, kotlin.Unit> origin=LAMBDA
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ FILE fqName:<root> fileName:/fixationOrder1.kt
|
||||
<R>: <none>
|
||||
x: CONST String type=kotlin.String value=""
|
||||
y: CONST Int type=kotlin.Int value=1
|
||||
f: CALL 'public final fun foo <X, Y> (): kotlin.Function1<X of <root>.foo, Y of <root>.foo> declared in <root>' type=kotlin.Function1<kotlin.Any?, kotlin.Any?> origin=null
|
||||
f: CALL 'public final fun foo <X, Y> (): kotlin.Function1<X of <root>.foo, Y of <root>.foo> declared in <root>' type=kotlin.Function1<kotlin.String, kotlin.Int> origin=null
|
||||
<X>: <none>
|
||||
<Y>: <none>
|
||||
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
|
||||
+21
-21
@@ -68,32 +68,32 @@ FILE fqName:<root> fileName:/intersectionType2_NI.kt
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN name:run visibility:public modality:FINAL <T> (fn:kotlin.Function0<T of <root>.run>) returnType:IrErrorType
|
||||
FUN name:run visibility:public modality:FINAL <T> (fn:kotlin.Function0<T of <root>.run>) returnType:T of <root>.run
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[]
|
||||
VALUE_PARAMETER name:fn index:0 type:kotlin.Function0<T of <root>.run>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun run <T> (fn: kotlin.Function0<T of <root>.run>): IrErrorType declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: fn>#' type=IrErrorType
|
||||
FUN name:foo visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
RETURN type=kotlin.Nothing from='public final fun run <T> (fn: kotlin.Function0<T of <root>.run>): T of <root>.run declared in <root>'
|
||||
CALL 'public abstract fun invoke (): T of <root>.run declared in kotlin.Function0' type=T of <root>.run origin=null
|
||||
$this: GET_VAR 'fn: kotlin.Function0<T of <root>.run> declared in <root>.run' type=kotlin.Function0<T of <root>.run> origin=null
|
||||
FUN name:foo visibility:public modality:FINAL <> () returnType:<root>.B
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun foo (): IrErrorType declared in <root>'
|
||||
CALL 'public final fun run <T> (fn: kotlin.Function0<T of <root>.run>): IrErrorType declared in <root>' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun foo (): <root>.B declared in <root>'
|
||||
CALL 'public final fun run <T> (fn: kotlin.Function0<T of <root>.run>): T of <root>.run declared in <root>' type=<root>.B origin=null
|
||||
<T>: <none>
|
||||
fn: BLOCK type=IrErrorType origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:IrErrorType
|
||||
fn: BLOCK type=kotlin.Function0<<root>.B> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:<root>.B
|
||||
BLOCK_BODY
|
||||
VAR name:mm type:IrErrorType [val]
|
||||
ERROR_CALL 'Unresolved reference: B#' type=IrErrorType
|
||||
VAR name:nn type:IrErrorType [val]
|
||||
ERROR_CALL 'Unresolved reference: C#' type=IrErrorType
|
||||
VAR name:c type:IrErrorType [val]
|
||||
WHEN type=IrErrorType origin=IF
|
||||
BRANCH
|
||||
if: CONST Boolean type=IrErrorType value=true
|
||||
then: ERROR_CALL 'Unresolved reference: mm#' type=IrErrorType
|
||||
VAR name:mm type:<root>.B [val]
|
||||
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.B' type=<root>.B origin=null
|
||||
VAR name:nn type:<root>.C [val]
|
||||
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.C' type=<root>.C origin=null
|
||||
VAR name:c type:<root>.B [val]
|
||||
WHEN type=<root>.B origin=IF
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: ERROR_CALL 'Unresolved reference: nn#' type=IrErrorType
|
||||
ERROR_CALL 'Unresolved reference: c#' type=IrErrorType
|
||||
FUNCTION_REFERENCE 'local final fun <anonymous> (): IrErrorType declared in <root>.foo' type=IrErrorType origin=LAMBDA
|
||||
|
||||
then: GET_VAR 'val mm: <root>.B [val] declared in <root>.foo.<anonymous>' type=<root>.B origin=null
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: GET_VAR 'val nn: <root>.C [val] declared in <root>.foo.<anonymous>' type=<root>.C origin=null
|
||||
GET_VAR 'val c: <root>.B [val] declared in <root>.foo.<anonymous>' type=<root>.B origin=null
|
||||
FUNCTION_REFERENCE 'local final fun <anonymous> (): <root>.B declared in <root>.foo' type=kotlin.Function0<<root>.B> origin=LAMBDA
|
||||
|
||||
+21
-20
@@ -68,31 +68,32 @@ FILE fqName:<root> fileName:/intersectionType2_OI.kt
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN name:run visibility:public modality:FINAL <T> (fn:kotlin.Function0<T of <root>.run>) returnType:IrErrorType
|
||||
FUN name:run visibility:public modality:FINAL <T> (fn:kotlin.Function0<T of <root>.run>) returnType:T of <root>.run
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[]
|
||||
VALUE_PARAMETER name:fn index:0 type:kotlin.Function0<T of <root>.run>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun run <T> (fn: kotlin.Function0<T of <root>.run>): IrErrorType declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Unresolved name: fn>#' type=IrErrorType
|
||||
FUN name:foo visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
RETURN type=kotlin.Nothing from='public final fun run <T> (fn: kotlin.Function0<T of <root>.run>): T of <root>.run declared in <root>'
|
||||
CALL 'public abstract fun invoke (): T of <root>.run declared in kotlin.Function0' type=T of <root>.run origin=null
|
||||
$this: GET_VAR 'fn: kotlin.Function0<T of <root>.run> declared in <root>.run' type=kotlin.Function0<T of <root>.run> origin=null
|
||||
FUN name:foo visibility:public modality:FINAL <> () returnType:<root>.B
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun foo (): IrErrorType declared in <root>'
|
||||
CALL 'public final fun run <T> (fn: kotlin.Function0<T of <root>.run>): IrErrorType declared in <root>' type=IrErrorType origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun foo (): <root>.B declared in <root>'
|
||||
CALL 'public final fun run <T> (fn: kotlin.Function0<T of <root>.run>): T of <root>.run declared in <root>' type=<root>.B origin=null
|
||||
<T>: <none>
|
||||
fn: BLOCK type=IrErrorType origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:IrErrorType
|
||||
fn: BLOCK type=kotlin.Function0<<root>.B> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:<root>.B
|
||||
BLOCK_BODY
|
||||
VAR name:mm type:IrErrorType [val]
|
||||
ERROR_CALL 'Unresolved reference: B#' type=IrErrorType
|
||||
VAR name:nn type:IrErrorType [val]
|
||||
ERROR_CALL 'Unresolved reference: C#' type=IrErrorType
|
||||
VAR name:c type:IrErrorType [val]
|
||||
WHEN type=IrErrorType origin=IF
|
||||
BRANCH
|
||||
if: CONST Boolean type=IrErrorType value=true
|
||||
then: ERROR_CALL 'Unresolved reference: mm#' type=IrErrorType
|
||||
VAR name:mm type:<root>.B [val]
|
||||
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.B' type=<root>.B origin=null
|
||||
VAR name:nn type:<root>.C [val]
|
||||
CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.C' type=<root>.C origin=null
|
||||
VAR name:c type:<root>.B [val]
|
||||
WHEN type=<root>.B origin=IF
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: ERROR_CALL 'Unresolved reference: nn#' type=IrErrorType
|
||||
ERROR_CALL 'Unresolved reference: c#' type=IrErrorType
|
||||
FUNCTION_REFERENCE 'local final fun <anonymous> (): IrErrorType declared in <root>.foo' type=IrErrorType origin=LAMBDA
|
||||
then: GET_VAR 'val mm: <root>.B [val] declared in <root>.foo.<anonymous>' type=<root>.B origin=null
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: GET_VAR 'val nn: <root>.C [val] declared in <root>.foo.<anonymous>' type=<root>.C origin=null
|
||||
GET_VAR 'val c: <root>.B [val] declared in <root>.foo.<anonymous>' type=<root>.B origin=null
|
||||
FUNCTION_REFERENCE 'local final fun <anonymous> (): <root>.B declared in <root>.foo' type=kotlin.Function0<<root>.B> origin=LAMBDA
|
||||
|
||||
Reference in New Issue
Block a user