Add extensionReceiver to ScopeTowerLevel & use it in ImportingScopeBasedTowerLevel
This commit is contained in:
@@ -141,7 +141,7 @@ private fun ScopeTower.getExtensionInvokeCandidateDescriptor(
|
||||
): CandidateWithBoundDispatchReceiver<FunctionDescriptor>? {
|
||||
if (!KotlinBuiltIns.isExactExtensionFunctionType(extensionFunctionReceiver.type)) return null
|
||||
|
||||
return ReceiverScopeTowerLevel(this, extensionFunctionReceiver).getFunctions(OperatorNameConventions.INVOKE).single().let {
|
||||
return ReceiverScopeTowerLevel(this, extensionFunctionReceiver).getFunctions(OperatorNameConventions.INVOKE, null).single().let {
|
||||
assert(it.diagnostics.isEmpty())
|
||||
val synthesizedInvoke = createSynthesizedInvokes(listOf(it.descriptor)).single()
|
||||
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ class NewResolveOldInference(
|
||||
val explicitReceiver = context.call.explicitReceiver.check { it.exists() }
|
||||
|
||||
val dynamicScope = dynamicCallableDescriptors.createDynamicDescriptorScope(context.call, context.scope.ownerDescriptor)
|
||||
val scopeTower = ScopeTowerImpl(context, dynamicScope, explicitReceiver, context.call.createLookupLocation())
|
||||
val scopeTower = ScopeTowerImpl(context, dynamicScope, context.call.createLookupLocation())
|
||||
|
||||
val baseContext = Context(scopeTower, name, context, tracing)
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ interface ScopeTower {
|
||||
val dataFlowInfo: DataFlowDecorator
|
||||
|
||||
// The closest (the most local) levels goes first
|
||||
val levels: Sequence<ScopeTowerLevel>
|
||||
val levels: List<ScopeTowerLevel>
|
||||
}
|
||||
|
||||
interface DataFlowDecorator {
|
||||
@@ -54,9 +54,9 @@ interface DataFlowDecorator {
|
||||
}
|
||||
|
||||
interface ScopeTowerLevel {
|
||||
fun getVariables(name: Name): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
|
||||
fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
|
||||
|
||||
fun getFunctions(name: Name): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>
|
||||
fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>
|
||||
}
|
||||
|
||||
interface CandidateWithBoundDispatchReceiver<out D : CallableDescriptor> {
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.tower
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
|
||||
@@ -25,8 +24,6 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
|
||||
@@ -45,7 +42,6 @@ internal class CandidateWithBoundDispatchReceiverImpl<D : CallableDescriptor>(
|
||||
internal class ScopeTowerImpl(
|
||||
resolutionContext: ResolutionContext<*>,
|
||||
override val dynamicScope: MemberScope,
|
||||
private val explicitReceiver: Receiver?,
|
||||
override val location: LookupLocation
|
||||
): ScopeTower {
|
||||
override val dataFlowInfo: DataFlowDecorator = DataFlowDecoratorImpl(resolutionContext)
|
||||
@@ -54,62 +50,25 @@ internal class ScopeTowerImpl(
|
||||
override val implicitReceivers = resolutionContext.scope.getImplicitReceiversHierarchy().
|
||||
mapNotNull { it.value.check { !it.type.containsError() } }
|
||||
|
||||
override val levels: Sequence<ScopeTowerLevel> = createPrototypeLevels().asSequence().map { it.asTowerLevel(this) }
|
||||
override val levels: List<ScopeTowerLevel> = createLevels()
|
||||
|
||||
// we shouldn't calculate this before we entrance to some importing scope
|
||||
private val receiversForSyntheticExtensions: Collection<KotlinType> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
if (explicitReceiver != null) {
|
||||
if (explicitReceiver is ReceiverValue) {
|
||||
return@lazy dataFlowInfo.getAllPossibleTypes(explicitReceiver)
|
||||
}
|
||||
|
||||
if (explicitReceiver is ClassQualifier) {
|
||||
explicitReceiver.classValueReceiver?.let {
|
||||
return@lazy dataFlowInfo.getAllPossibleTypes(it)
|
||||
}
|
||||
}
|
||||
|
||||
// explicit receiver is package or class without companion object
|
||||
emptyList()
|
||||
}
|
||||
else {
|
||||
implicitReceivers.flatMap { dataFlowInfo.getAllPossibleTypes(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class LevelFactory {
|
||||
abstract fun asTowerLevel(resolveTower: ScopeTower): ScopeTowerLevel
|
||||
|
||||
class Scope(val lexicalScope: LexicalScope): LevelFactory() {
|
||||
override fun asTowerLevel(resolveTower: ScopeTower) = ScopeBasedTowerLevel(resolveTower, lexicalScope)
|
||||
}
|
||||
|
||||
class Receiver(val implicitReceiver: ReceiverParameterDescriptor): LevelFactory() {
|
||||
override fun asTowerLevel(resolveTower: ScopeTower) = ReceiverScopeTowerLevel(resolveTower, implicitReceiver.value)
|
||||
}
|
||||
|
||||
class ImportingScopeFactory(val importingScope: ImportingScope, val lazyReceiversForSyntheticExtensions: () -> Collection<KotlinType>): LevelFactory() {
|
||||
override fun asTowerLevel(resolveTower: ScopeTower) = ImportingScopeBasedTowerLevel(resolveTower, importingScope, lazyReceiversForSyntheticExtensions())
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPrototypeLevels(): List<LevelFactory> {
|
||||
val result = ArrayList<LevelFactory>()
|
||||
private fun createLevels(): List<ScopeTowerLevel> {
|
||||
val result = ArrayList<ScopeTowerLevel>()
|
||||
|
||||
// locals win
|
||||
lexicalScope.parentsWithSelf.
|
||||
filterIsInstance<LexicalScope>().
|
||||
filter { it.kind.withLocalDescriptors }.
|
||||
mapTo(result) { LevelFactory.Scope(it) }
|
||||
mapTo(result) { ScopeBasedTowerLevel(this, it) }
|
||||
|
||||
lexicalScope.parentsWithSelf.forEach { scope ->
|
||||
if (scope is LexicalScope) {
|
||||
if (!scope.kind.withLocalDescriptors) result.add(LevelFactory.Scope(scope))
|
||||
if (!scope.kind.withLocalDescriptors) result.add(ScopeBasedTowerLevel(this, scope))
|
||||
|
||||
scope.implicitReceiver?.let { result.add(LevelFactory.Receiver(it)) }
|
||||
scope.implicitReceiver?.let { result.add(ReceiverScopeTowerLevel(this, it.value)) }
|
||||
}
|
||||
else {
|
||||
result.add(LevelFactory.ImportingScopeFactory(scope as ImportingScope, { receiversForSyntheticExtensions }))
|
||||
result.add(ImportingScopeBasedTowerLevel(this, scope as ImportingScope))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-9
@@ -51,7 +51,7 @@ internal abstract class AbstractSimpleScopeTowerProcessor<C>(
|
||||
internal class ExplicitReceiverScopeTowerProcessor<C>(
|
||||
context: TowerContext<C>,
|
||||
val explicitReceiver: ReceiverValue,
|
||||
val collectCandidates: ScopeTowerLevel.(Name) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
): AbstractSimpleScopeTowerProcessor<C>(context) {
|
||||
override fun simpleProcess(data: TowerData): Collection<C> {
|
||||
return when (data) {
|
||||
@@ -63,12 +63,12 @@ internal class ExplicitReceiverScopeTowerProcessor<C>(
|
||||
|
||||
private fun resolveAsMember(): Collection<C> {
|
||||
val members = ReceiverScopeTowerLevel(context.scopeTower, explicitReceiver)
|
||||
.collectCandidates(name).filter { !it.requiresExtensionReceiver }
|
||||
.collectCandidates(name, null).filter { !it.requiresExtensionReceiver }
|
||||
return members.map { context.createCandidate(it, ExplicitReceiverKind.DISPATCH_RECEIVER, extensionReceiver = null) }
|
||||
}
|
||||
|
||||
private fun resolveAsExtension(level: ScopeTowerLevel): Collection<C> {
|
||||
val extensions = level.collectCandidates(name).filter { it.requiresExtensionReceiver }
|
||||
val extensions = level.collectCandidates(name, explicitReceiver).filter { it.requiresExtensionReceiver }
|
||||
return extensions.map { context.createCandidate(it, ExplicitReceiverKind.EXTENSION_RECEIVER, extensionReceiver = explicitReceiver) }
|
||||
}
|
||||
}
|
||||
@@ -76,12 +76,12 @@ internal class ExplicitReceiverScopeTowerProcessor<C>(
|
||||
private class QualifierScopeTowerProcessor<C>(
|
||||
context: TowerContext<C>,
|
||||
val qualifier: QualifierReceiver,
|
||||
val collectCandidates: ScopeTowerLevel.(Name) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
): AbstractSimpleScopeTowerProcessor<C>(context) {
|
||||
override fun simpleProcess(data: TowerData): Collection<C> {
|
||||
if (data != TowerData.Empty) return emptyList()
|
||||
|
||||
val staticMembers = QualifierScopeTowerLevel(context.scopeTower, qualifier).collectCandidates(name)
|
||||
val staticMembers = QualifierScopeTowerLevel(context.scopeTower, qualifier).collectCandidates(name, null)
|
||||
.filter { !it.requiresExtensionReceiver }
|
||||
.map { context.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null) }
|
||||
return staticMembers
|
||||
@@ -90,17 +90,17 @@ private class QualifierScopeTowerProcessor<C>(
|
||||
|
||||
private class NoExplicitReceiverScopeTowerProcessor<C>(
|
||||
context: TowerContext<C>,
|
||||
val collectCandidates: ScopeTowerLevel.(Name) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
) : AbstractSimpleScopeTowerProcessor<C>(context) {
|
||||
override fun simpleProcess(data: TowerData): Collection<C>
|
||||
= when(data) {
|
||||
is TowerData.TowerLevel -> {
|
||||
data.level.collectCandidates(name).filter { !it.requiresExtensionReceiver }.map {
|
||||
data.level.collectCandidates(name, null).filter { !it.requiresExtensionReceiver }.map {
|
||||
context.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null)
|
||||
}
|
||||
}
|
||||
is TowerData.BothTowerLevelAndImplicitReceiver -> {
|
||||
data.level.collectCandidates(name).filter { it.requiresExtensionReceiver }.map {
|
||||
data.level.collectCandidates(name, data.implicitReceiver).filter { it.requiresExtensionReceiver }.map {
|
||||
context.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = data.implicitReceiver)
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ private class NoExplicitReceiverScopeTowerProcessor<C>(
|
||||
private fun <C> createSimpleProcessor(
|
||||
context: TowerContext<C>,
|
||||
explicitReceiver: Receiver?,
|
||||
collectCandidates: ScopeTowerLevel.(Name) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<*>>
|
||||
) : ScopeTowerProcessor<C> {
|
||||
if (explicitReceiver is ReceiverValue) {
|
||||
return ExplicitReceiverScopeTowerProcessor(context, explicitReceiver, collectCandidates)
|
||||
|
||||
@@ -98,11 +98,11 @@ internal class ReceiverScopeTowerLevel(
|
||||
return result
|
||||
}
|
||||
|
||||
override fun getVariables(name: Name): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
|
||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
|
||||
return collectMembers { getContributedVariables(name, location) }
|
||||
}
|
||||
|
||||
override fun getFunctions(name: Name): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
||||
return collectMembers {
|
||||
getContributedFunctions(name, location) + it.getInnerConstructors(name, location)
|
||||
}
|
||||
@@ -110,12 +110,12 @@ internal class ReceiverScopeTowerLevel(
|
||||
}
|
||||
|
||||
internal class QualifierScopeTowerLevel(scopeTower: ScopeTower, val qualifier: QualifierReceiver) : AbstractScopeTowerLevel(scopeTower) {
|
||||
override fun getVariables(name: Name) = qualifier.getNestedClassesAndPackageMembersScope()
|
||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?) = qualifier.getNestedClassesAndPackageMembersScope()
|
||||
.getContributedVariablesAndObjects(name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
|
||||
override fun getFunctions(name: Name) = qualifier.getNestedClassesAndPackageMembersScope()
|
||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?) = qualifier.getNestedClassesAndPackageMembersScope()
|
||||
.getContributedFunctionsAndConstructors(name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
@@ -129,12 +129,12 @@ internal open class ScopeBasedTowerLevel protected constructor(
|
||||
|
||||
internal constructor(scopeTower: ScopeTower, lexicalScope: LexicalScope): this(scopeTower, lexicalScope as ResolutionScope)
|
||||
|
||||
override fun getVariables(name: Name): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
|
||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
|
||||
= resolutionScope.getContributedVariablesAndObjects(name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
|
||||
override fun getFunctions(name: Name): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>
|
||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>
|
||||
= resolutionScope.getContributedFunctionsAndConstructors(name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
@@ -142,22 +142,27 @@ internal open class ScopeBasedTowerLevel protected constructor(
|
||||
|
||||
internal class ImportingScopeBasedTowerLevel(
|
||||
scopeTower: ScopeTower,
|
||||
private val importingScope: ImportingScope,
|
||||
private val receiversForSyntheticExtensions: Collection<KotlinType>
|
||||
private val importingScope: ImportingScope
|
||||
): ScopeBasedTowerLevel(scopeTower, importingScope) {
|
||||
|
||||
override fun getVariables(name: Name): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
|
||||
val synthetic = importingScope.getContributedSyntheticExtensionProperties(receiversForSyntheticExtensions, name, location).map {
|
||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
|
||||
if (extensionReceiver == null) return super.getVariables(name, null)
|
||||
|
||||
val extensionReceiverTypes = scopeTower.dataFlowInfo.getAllPossibleTypes(extensionReceiver)
|
||||
val synthetic = importingScope.getContributedSyntheticExtensionProperties(extensionReceiverTypes, name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
return super.getVariables(name) + synthetic
|
||||
return super.getVariables(name, null) + synthetic
|
||||
}
|
||||
|
||||
override fun getFunctions(name: Name): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
||||
val synthetic = importingScope.getContributedSyntheticExtensionFunctions(receiversForSyntheticExtensions, name, location).map {
|
||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
|
||||
if (extensionReceiver == null) return super.getFunctions(name, null)
|
||||
|
||||
val extensionReceiverTypes = scopeTower.dataFlowInfo.getAllPossibleTypes(extensionReceiver)
|
||||
val synthetic = importingScope.getContributedSyntheticExtensionFunctions(extensionReceiverTypes, name, location).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
return super.getFunctions(name) + synthetic
|
||||
return super.getFunctions(name, null) + synthetic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user