Refactoring: replace ReceiverValue to ReceiverValueWithSmartCastInfo, Receiver to DetailedReceiver

This commit is contained in:
Stanislav Erokhin
2016-08-26 13:57:51 +03:00
parent d4a2cad35c
commit 0c60cda22a
8 changed files with 133 additions and 133 deletions
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tasks.createSynthesizedInvokes
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.DetailedReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.util.OperatorNameConventions
import java.util.*
@@ -87,7 +87,7 @@ abstract class AbstractInvokeTowerProcessor<F : Candidate<FunctionDescriptor>, V
// todo KT-9522 Allow invoke convention for synthetic property
class InvokeTowerProcessor<F : Candidate<FunctionDescriptor>, V : Candidate<VariableDescriptor>>(
invokeContext: InvokeTowerContext<F, V>,
explicitReceiver: Receiver?
explicitReceiver: DetailedReceiver?
) : AbstractInvokeTowerProcessor<F, V>(
invokeContext,
createVariableAndObjectProcessor(invokeContext.contextForVariable(stripExplicitReceiver = false), explicitReceiver)
@@ -103,7 +103,7 @@ class InvokeTowerProcessor<F : Candidate<FunctionDescriptor>, V : Candidate<Vari
class InvokeExtensionTowerProcessor<F : Candidate<FunctionDescriptor>, V : Candidate<VariableDescriptor>>(
invokeContext: InvokeTowerContext<F, V>,
private val explicitReceiver: ReceiverValue?
private val explicitReceiver: ReceiverValueWithSmartCastInfo?
) : AbstractInvokeTowerProcessor<F, V>(
invokeContext,
createVariableAndObjectProcessor(invokeContext.contextForVariable(stripExplicitReceiver = true), explicitReceiver = null)
@@ -121,7 +121,7 @@ class InvokeExtensionTowerProcessor<F : Candidate<FunctionDescriptor>, V : Candi
private class InvokeExtensionScopeTowerProcessor<C : Candidate<FunctionDescriptor>>(
context: TowerContext<FunctionDescriptor, C>,
private val invokeCandidateDescriptor: CandidateWithBoundDispatchReceiver<FunctionDescriptor>,
private val explicitReceiver: ReceiverValue?
private val explicitReceiver: ReceiverValueWithSmartCastInfo?
) : AbstractSimpleScopeTowerProcessor<FunctionDescriptor, C>(context) {
override fun simpleProcess(data: TowerData): Collection<C> {
@@ -139,11 +139,12 @@ private class InvokeExtensionScopeTowerProcessor<C : Candidate<FunctionDescripto
// todo debug info
private fun ScopeTower.getExtensionInvokeCandidateDescriptor(
extensionFunctionReceiver: ReceiverValue
extensionFunctionReceiver: ReceiverValueWithSmartCastInfo
): CandidateWithBoundDispatchReceiver<FunctionDescriptor>? {
if (!extensionFunctionReceiver.type.isExtensionFunctionType) return null
val type = extensionFunctionReceiver.receiverValue.type
if (!type.isExtensionFunctionType) return null // todo: missing smart cast?
val invokeDescriptor = extensionFunctionReceiver.type.memberScope.getContributedFunctions(OperatorNameConventions.INVOKE, location).single()
val invokeDescriptor = type.memberScope.getContributedFunctions(OperatorNameConventions.INVOKE, location).single()
val synthesizedInvoke = createSynthesizedInvokes(listOf(invokeDescriptor)).single()
// here we don't add SynthesizedDescriptor diagnostic because it should has priority as member
@@ -153,8 +154,8 @@ private fun ScopeTower.getExtensionInvokeCandidateDescriptor(
// case 1.(foo())() or (foo())()
fun <F : Candidate<FunctionDescriptor>> createCallTowerProcessorForExplicitInvoke(
functionContext: TowerContext<FunctionDescriptor, F>,
expressionForInvoke: ReceiverValue,
explicitReceiver: ReceiverValue?
expressionForInvoke: ReceiverValueWithSmartCastInfo,
explicitReceiver: ReceiverValueWithSmartCastInfo?
): ScopeTowerProcessor<F> {
val invokeExtensionDescriptor = functionContext.scopeTower.getExtensionInvokeCandidateDescriptor(expressionForInvoke)
if (explicitReceiver != null) {
@@ -22,52 +22,29 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
interface ScopeTower {
/**
* Adds receivers to the list in order of locality, so that the closest (the most local) receiver goes first
* Doesn't include receivers with error types
*/
val implicitReceivers: List<ReceiverValue>
val lexicalScope: LexicalScope
fun getImplicitReceiver(scope: LexicalScope): ReceiverValueWithSmartCastInfo?
val dynamicScope: MemberScope
val syntheticScopes: SyntheticScopes
val location: LookupLocation
val dataFlowInfo: DataFlowDecorator
val isDebuggerContext: Boolean
}
abstract class DataFlowDecorator() {
private val cache = HashMap<ReceiverValue, SmartCastInfo>()
fun isStableReceiver(receiver: ReceiverValue): Boolean = getSmartCastInfo(receiver).isStable
// doesn't include receiver.type
fun getSmartCastTypes(receiver: ReceiverValue): Set<KotlinType> = getSmartCastInfo(receiver).possibleTypes
private fun getSmartCastInfo(receiver: ReceiverValue): SmartCastInfo
= cache.getOrPut(receiver) { calculateSmartCastInfo(receiver) }
protected data class SmartCastInfo(val isStable: Boolean, val possibleTypes: Set<KotlinType>)
protected abstract fun calculateSmartCastInfo(receiver: ReceiverValue): SmartCastInfo
}
interface ScopeTowerLevel {
fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
fun getObjects(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>
fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>
}
interface CandidateWithBoundDispatchReceiver<out D : CallableDescriptor> {
@@ -75,7 +52,7 @@ interface CandidateWithBoundDispatchReceiver<out D : CallableDescriptor> {
val diagnostics: List<ResolutionDiagnostic>
val dispatchReceiver: ReceiverValue?
val dispatchReceiver: ReceiverValueWithSmartCastInfo?
fun copy(newDescriptor: @UnsafeVariance D): CandidateWithBoundDispatchReceiver<D>
}
@@ -23,9 +23,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.coroutine.CoroutineReceiverValue
import org.jetbrains.kotlin.resolve.coroutine.createCoroutineSuspensionFunctionView
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.*
import org.jetbrains.kotlin.utils.addToStdlib.check
@@ -54,8 +52,8 @@ internal abstract class AbstractSimpleScopeTowerProcessor<D : CallableDescriptor
internal class ExplicitReceiverScopeTowerProcessor<D : CallableDescriptor, C: Candidate<D>>(
context: TowerContext<D, C>,
val explicitReceiver: ReceiverValue,
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<D>>
val explicitReceiver: ReceiverValueWithSmartCastInfo,
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection<CandidateWithBoundDispatchReceiver<D>>
): AbstractSimpleScopeTowerProcessor<D, C>(context) {
override fun simpleProcess(data: TowerData): Collection<C> {
return when (data) {
@@ -80,7 +78,7 @@ internal class ExplicitReceiverScopeTowerProcessor<D : CallableDescriptor, C: Ca
private class QualifierScopeTowerProcessor<D : CallableDescriptor, C: Candidate<D>>(
context: TowerContext<D, C>,
val qualifier: QualifierReceiver,
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<D>>
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection<CandidateWithBoundDispatchReceiver<D>>
): AbstractSimpleScopeTowerProcessor<D, C>(context) {
override fun simpleProcess(data: TowerData): Collection<C> {
if (data != TowerData.Empty) return emptyList()
@@ -94,7 +92,7 @@ private class QualifierScopeTowerProcessor<D : CallableDescriptor, C: Candidate<
private class NoExplicitReceiverScopeTowerProcessor<D : CallableDescriptor, C: Candidate<D>>(
context: TowerContext<D, C>,
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<D>>
val collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection<CandidateWithBoundDispatchReceiver<D>>
) : AbstractSimpleScopeTowerProcessor<D, C>(context) {
override fun simpleProcess(data: TowerData): Collection<C>
= when(data) {
@@ -111,7 +109,7 @@ private class NoExplicitReceiverScopeTowerProcessor<D : CallableDescriptor, C: C
context.createCandidate(
it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = data.implicitReceiver))
if (data.implicitReceiver is CoroutineReceiverValue) {
if (data.implicitReceiver.receiverValue is CoroutineReceiverValue) {
val newDescriptor = it.descriptor.createCoroutineSuspensionFunctionView() ?: return@forEach
result.add(
context.createCandidate(
@@ -128,11 +126,11 @@ private class NoExplicitReceiverScopeTowerProcessor<D : CallableDescriptor, C: C
private fun <D : CallableDescriptor, C: Candidate<D>> createSimpleProcessor(
context: TowerContext<D, C>,
explicitReceiver: Receiver?,
explicitReceiver: DetailedReceiver?,
classValueReceiver: Boolean,
collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValue?) -> Collection<CandidateWithBoundDispatchReceiver<D>>
collectCandidates: ScopeTowerLevel.(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection<CandidateWithBoundDispatchReceiver<D>>
) : ScopeTowerProcessor<C> {
if (explicitReceiver is ReceiverValue) {
if (explicitReceiver is ReceiverValueWithSmartCastInfo) {
return ExplicitReceiverScopeTowerProcessor(context, explicitReceiver, collectCandidates)
}
else if (explicitReceiver is QualifierReceiver) {
@@ -140,7 +138,7 @@ private fun <D : CallableDescriptor, C: Candidate<D>> createSimpleProcessor(
if (!classValueReceiver) return qualifierProcessor
// todo enum entry, object.
val classValue = explicitReceiver.classValueReceiver ?: return qualifierProcessor
val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return qualifierProcessor
return CompositeScopeTowerProcessor(
qualifierProcessor,
ExplicitReceiverScopeTowerProcessor(context, classValue, collectCandidates)
@@ -155,25 +153,25 @@ private fun <D : CallableDescriptor, C: Candidate<D>> createSimpleProcessor(
}
fun <C : Candidate<VariableDescriptor>> createVariableProcessor(
context: TowerContext<VariableDescriptor, C>, explicitReceiver: Receiver?, classValueReceiver: Boolean = true
context: TowerContext<VariableDescriptor, C>, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
) = createSimpleProcessor(context, explicitReceiver, classValueReceiver, ScopeTowerLevel::getVariables)
fun <C : Candidate<VariableDescriptor>> createVariableAndObjectProcessor(
context: TowerContext<VariableDescriptor, C>, explicitReceiver: Receiver?, classValueReceiver: Boolean = true
context: TowerContext<VariableDescriptor, C>, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
) = CompositeScopeTowerProcessor(
createVariableProcessor(context, explicitReceiver),
createSimpleProcessor(context, explicitReceiver, classValueReceiver, ScopeTowerLevel::getObjects)
)
fun <C : Candidate<FunctionDescriptor>> createSimpleFunctionProcessor(
context: TowerContext<FunctionDescriptor, C>, explicitReceiver: Receiver?, classValueReceiver: Boolean = true
context: TowerContext<FunctionDescriptor, C>, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
) = createSimpleProcessor(context, explicitReceiver, classValueReceiver, ScopeTowerLevel::getFunctions)
fun <F: Candidate<FunctionDescriptor>, V: Candidate<VariableDescriptor>> createFunctionProcessor(
simpleContext: TowerContext<FunctionDescriptor, F>,
invokeContext: InvokeTowerContext<F, V>,
explicitReceiver: Receiver?
explicitReceiver: DetailedReceiver?
): CompositeScopeTowerProcessor<F> {
// a.foo() -- simple function call
@@ -190,14 +188,14 @@ fun <F: Candidate<FunctionDescriptor>, V: Candidate<VariableDescriptor>> createF
fun <D : CallableDescriptor, C: Candidate<D>> createProcessorWithReceiverValueOrEmpty(
explicitReceiver: Receiver?,
create: (ReceiverValue?) -> ScopeTowerProcessor<C>
explicitReceiver: DetailedReceiver?,
create: (ReceiverValueWithSmartCastInfo?) -> ScopeTowerProcessor<C>
): ScopeTowerProcessor<C> {
return if (explicitReceiver is QualifierReceiver) {
explicitReceiver.classValueReceiver?.let(create)
explicitReceiver.classValueReceiverWithSmartCastInfo?.let(create)
?: KnownResultProcessor<C>(listOf())
}
else {
create(explicitReceiver as ReceiverValue?)
create(explicitReceiver as ReceiverValueWithSmartCastInfo?)
}
}
@@ -29,10 +29,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassValueDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.hasHidesMembersAnnotation
import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution
import org.jetbrains.kotlin.resolve.scopes.*
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.*
import org.jetbrains.kotlin.resolve.scopes.utils.collectFunctions
import org.jetbrains.kotlin.resolve.scopes.utils.collectVariables
import org.jetbrains.kotlin.resolve.selectMostSpecificInEachOverridableGroup
@@ -49,7 +46,7 @@ internal abstract class AbstractScopeTowerLevel(
protected fun <D : CallableDescriptor> createCandidateDescriptor(
descriptor: D,
dispatchReceiver: ReceiverValue?,
dispatchReceiver: ReceiverValueWithSmartCastInfo?,
specialError: ResolutionDiagnostic? = null,
dispatchReceiverSmartCastType: KotlinType? = null
): CandidateWithBoundDispatchReceiver<D> {
@@ -67,7 +64,7 @@ internal abstract class AbstractScopeTowerLevel(
val shouldSkipVisibilityCheck = scopeTower.isDebuggerContext
if (!shouldSkipVisibilityCheck) {
Visibilities.findInvisibleMember(
getReceiverValueWithSmartCast(dispatchReceiver, dispatchReceiverSmartCastType),
getReceiverValueWithSmartCast(dispatchReceiver?.receiverValue, dispatchReceiverSmartCastType),
descriptor,
scopeTower.lexicalScope.ownerDescriptor
)?.let { diagnostics.add(VisibilityError(it)) }
@@ -82,28 +79,28 @@ internal abstract class AbstractScopeTowerLevel(
// todo add static methods & fields with error
internal class ReceiverScopeTowerLevel(
scopeTower: ScopeTower,
val dispatchReceiver: ReceiverValue
val dispatchReceiver: ReceiverValueWithSmartCastInfo
): AbstractScopeTowerLevel(scopeTower) {
private fun <D : CallableDescriptor> collectMembers(
getMembers: ResolutionScope.(KotlinType?) -> Collection<D>
): Collection<CandidateWithBoundDispatchReceiver<D>> {
val result = ArrayList<CandidateWithBoundDispatchReceiver<D>>(0)
dispatchReceiver.type.memberScope.getMembers(dispatchReceiver.type).mapTo(result) {
val receiverValue = dispatchReceiver.receiverValue
receiverValue.type.memberScope.getMembers(receiverValue.type).mapTo(result) {
createCandidateDescriptor(it, dispatchReceiver)
}
val smartCastPossibleTypes = scopeTower.dataFlowInfo.getSmartCastTypes(dispatchReceiver)
val unstableError = if (scopeTower.dataFlowInfo.isStableReceiver(dispatchReceiver)) null else UnstableSmartCastDiagnostic
val unstableError = if (dispatchReceiver.isStable) null else UnstableSmartCastDiagnostic
val unstableCandidates = if (unstableError != null) ArrayList<CandidateWithBoundDispatchReceiver<D>>(0) else null
for (possibleType in smartCastPossibleTypes) {
for (possibleType in dispatchReceiver.possibleTypes) {
possibleType.memberScope.getMembers(possibleType).mapTo(unstableCandidates ?: result) {
createCandidateDescriptor(it, dispatchReceiver.smartCastReceiver(possibleType), unstableError, dispatchReceiverSmartCastType = possibleType)
}
}
if (smartCastPossibleTypes.isNotEmpty()) {
if (dispatchReceiver.possibleTypes.isNotEmpty()) {
if (unstableCandidates == null) {
result.retainAll(result.selectMostSpecificInEachOverridableGroup { descriptor })
}
@@ -112,13 +109,13 @@ internal class ReceiverScopeTowerLevel(
}
}
if (dispatchReceiver.type.isDynamic()) {
if (receiverValue.type.isDynamic()) {
scopeTower.dynamicScope.getMembers(null).mapTo(result) {
createCandidateDescriptor(it, dispatchReceiver, DynamicDescriptorDiagnostic)
}
}
if (dispatchReceiver is CoroutineReceiverValue) {
if (receiverValue is CoroutineReceiverValue) {
result.addAll(result.mapNotNull {
val suspensionFunctionView = it.descriptor.createCoroutineSuspensionFunctionView() ?: return@mapNotNull null
createCandidateDescriptor(suspensionFunctionView, dispatchReceiver)
@@ -128,18 +125,22 @@ internal class ReceiverScopeTowerLevel(
return result
}
private fun ReceiverValue.smartCastReceiver(targetType: KotlinType)
= if (this is ImplicitClassReceiver) CastImplicitClassReceiver(this.classDescriptor, targetType) else this
private fun ReceiverValueWithSmartCastInfo.smartCastReceiver(targetType: KotlinType): ReceiverValueWithSmartCastInfo {
if (receiverValue !is ImplicitClassReceiver) return this
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
val newReceiverValue = CastImplicitClassReceiver(receiverValue.classDescriptor, targetType)
return ReceiverValueWithSmartCastInfo(newReceiverValue, possibleTypes, isStable)
}
override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
return collectMembers { getContributedVariables(name, location) }
}
override fun getObjects(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
return emptyList()
}
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
return collectMembers {
getContributedFunctions(name, location) + it.getInnerConstructors(name, location)
}
@@ -147,17 +148,17 @@ internal class ReceiverScopeTowerLevel(
}
internal class QualifierScopeTowerLevel(scopeTower: ScopeTower, val qualifier: QualifierReceiver) : AbstractScopeTowerLevel(scopeTower) {
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?) = qualifier.staticScope
override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = qualifier.staticScope
.getContributedVariables(name, location).map {
createCandidateDescriptor(it, dispatchReceiver = null)
}
override fun getObjects(name: Name, extensionReceiver: ReceiverValue?) = qualifier.staticScope
override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = qualifier.staticScope
.getContributedObjectVariables(name, location).map {
createCandidateDescriptor(it, dispatchReceiver = null)
}
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?) = qualifier.staticScope
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = qualifier.staticScope
.getContributedFunctionsAndConstructors(name, location).map {
createCandidateDescriptor(it, dispatchReceiver = null)
}
@@ -171,17 +172,17 @@ internal open class ScopeBasedTowerLevel protected constructor(
internal constructor(scopeTower: ScopeTower, lexicalScope: LexicalScope): this(scopeTower, lexicalScope as ResolutionScope)
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
= resolutionScope.getContributedVariables(name, location).map {
createCandidateDescriptor(it, dispatchReceiver = null)
}
override fun getObjects(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
= resolutionScope.getContributedObjectVariables(name, location).map {
createCandidateDescriptor(it, dispatchReceiver = null)
}
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>>
= resolutionScope.getContributedFunctionsAndConstructors(name, location).map {
createCandidateDescriptor(it, dispatchReceiver = null)
}
@@ -195,41 +196,42 @@ internal class SyntheticScopeBasedTowerLevel(
scopeTower: ScopeTower,
private val syntheticScopes: SyntheticScopes
): AbstractScopeTowerLevel(scopeTower) {
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
private val ReceiverValueWithSmartCastInfo.allTypes: Set<KotlinType>
get() = possibleTypes + receiverValue.type
override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>> {
if (extensionReceiver == null) return emptyList()
val extensionReceiverTypes = scopeTower.dataFlowInfo.getAllPossibleTypes(extensionReceiver)
return syntheticScopes.collectSyntheticExtensionProperties(extensionReceiverTypes, name, location).map {
return syntheticScopes.collectSyntheticExtensionProperties(extensionReceiver.allTypes, name, location).map {
createCandidateDescriptor(it, dispatchReceiver = null)
}
}
override fun getObjects(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<VariableDescriptor>>
= emptyList()
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver<FunctionDescriptor>> {
if (extensionReceiver == null) return emptyList()
val extensionReceiverTypes = scopeTower.dataFlowInfo.getAllPossibleTypes(extensionReceiver)
return syntheticScopes.collectSyntheticExtensionFunctions(extensionReceiverTypes, name, location).map {
return syntheticScopes.collectSyntheticExtensionFunctions(extensionReceiver.allTypes, name, location).map {
createCandidateDescriptor(it, dispatchReceiver = null)
}
}
}
internal class HidesMembersTowerLevel(scopeTower: ScopeTower): AbstractScopeTowerLevel(scopeTower) {
override fun getVariables(name: Name, extensionReceiver: ReceiverValue?)
override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?)
= getCandidates(name, extensionReceiver, LexicalScope::collectVariables)
override fun getObjects(name: Name, extensionReceiver: ReceiverValue?)
override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?)
= emptyList<CandidateWithBoundDispatchReceiver<VariableDescriptor>>()
override fun getFunctions(name: Name, extensionReceiver: ReceiverValue?)
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?)
= getCandidates(name, extensionReceiver, LexicalScope::collectFunctions)
private fun <T: CallableDescriptor> getCandidates(
name: Name,
extensionReceiver: ReceiverValue?,
extensionReceiver: ReceiverValueWithSmartCastInfo?,
collectCandidates: LexicalScope.(Name, LookupLocation) -> Collection<T>
): Collection<CandidateWithBoundDispatchReceiver<T>> {
if (extensionReceiver == null || name !in HIDES_MEMBERS_NAME_LIST) return emptyList()
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStat
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
import org.jetbrains.kotlin.utils.addToStdlib.check
import java.util.*
@@ -45,7 +45,7 @@ interface TowerContext<D : CallableDescriptor, out C: Candidate<D>> {
fun createCandidate(
towerCandidate: CandidateWithBoundDispatchReceiver<D>,
explicitReceiverKind: ExplicitReceiverKind,
extensionReceiver: ReceiverValue?
extensionReceiver: ReceiverValueWithSmartCastInfo?
): C
}
@@ -57,14 +57,14 @@ interface InvokeTowerContext<F : Candidate<FunctionDescriptor>, V : Candidate<Va
// foo() -> ReceiverValue(foo), context for invoke
// null means that there is no invoke on variable
fun contextForInvoke(variable: V, useExplicitReceiver: Boolean): Pair<ReceiverValue, TowerContext<FunctionDescriptor, F>>?
fun contextForInvoke(variable: V, useExplicitReceiver: Boolean): Pair<ReceiverValueWithSmartCastInfo, TowerContext<FunctionDescriptor, F>>?
}
sealed class TowerData {
object Empty : TowerData()
class OnlyImplicitReceiver(val implicitReceiver: ReceiverValue): TowerData()
class OnlyImplicitReceiver(val implicitReceiver: ReceiverValueWithSmartCastInfo): TowerData()
class TowerLevel(val level: ScopeTowerLevel) : TowerData()
class BothTowerLevelAndImplicitReceiver(val level: ScopeTowerLevel, val implicitReceiver: ReceiverValue) : TowerData()
class BothTowerLevelAndImplicitReceiver(val level: ScopeTowerLevel, val implicitReceiver: ReceiverValueWithSmartCastInfo) : TowerData()
}
interface ScopeTowerProcessor<out C> {
@@ -93,7 +93,7 @@ class TowerResolver {
if (scope is LexicalScope) {
if (!scope.kind.withLocalDescriptors) result.add(ScopeBasedTowerLevel(this, scope))
scope.implicitReceiver?.let { result.add(ReceiverScopeTowerLevel(this, it.value)) }
getImplicitReceiver(scope)?.let { result.add(ReceiverScopeTowerLevel(this, it)) }
}
else {
result.add(ImportingScopeBasedTowerLevel(this, scope as ImportingScope))
@@ -138,7 +138,7 @@ class TowerResolver {
TowerData.TowerLevel(ScopeBasedTowerLevel(this, scope)).process()?.let { return it }
}
val implicitReceiver = scope.implicitReceiver?.value
val implicitReceiver = getImplicitReceiver(scope)
if (implicitReceiver != null) {
// hides members extensions
TowerData.BothTowerLevelAndImplicitReceiver(hidesMembersLevel, implicitReceiver).process()?.let { return it }
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.resolve.calls.tower
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
val ResolutionCandidateApplicability.isSuccess: Boolean
get() = this <= ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY
@@ -29,10 +29,8 @@ val CallableDescriptor.isSynthesized: Boolean
val CandidateWithBoundDispatchReceiver<*>.requiresExtensionReceiver: Boolean
get() = descriptor.extensionReceiverParameter != null
fun DataFlowDecorator.getAllPossibleTypes(receiver: ReceiverValue) = getSmartCastTypes(receiver) + receiver.type
internal class CandidateWithBoundDispatchReceiverImpl<out D : CallableDescriptor>(
override val dispatchReceiver: ReceiverValue?,
override val dispatchReceiver: ReceiverValueWithSmartCastInfo?,
override val descriptor: D,
override val diagnostics: List<ResolutionDiagnostic>
) : CandidateWithBoundDispatchReceiver<D> {
@@ -18,11 +18,26 @@ package org.jetbrains.kotlin.resolve.scopes.receivers
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.KotlinType
interface QualifierReceiver : Receiver {
// this receiver used only for resolution. see subtypes
interface DetailedReceiver
class ReceiverValueWithSmartCastInfo(
val receiverValue: ReceiverValue,
val possibleTypes: Set<KotlinType>, // doesn't include receiver.type
val isStable: Boolean
): DetailedReceiver
interface QualifierReceiver : Receiver, DetailedReceiver {
val descriptor: DeclarationDescriptor
val staticScope: MemberScope
val classValueReceiver: ReceiverValue?
// for qualifiers smart cast is impossible
val classValueReceiverWithSmartCastInfo: ReceiverValueWithSmartCastInfo?
get() = classValueReceiver?.let { ReceiverValueWithSmartCastInfo(it, emptySet(), true) }
}