Less use of KtScope
This commit is contained in:
@@ -42,7 +42,6 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.asKtScope
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.TypeNullability
|
||||
import org.jetbrains.kotlin.types.typeUtil.nullability
|
||||
@@ -194,7 +193,7 @@ fun thisExpressionItems(bindingContext: BindingContext, position: KtExpression,
|
||||
val psiFactory = KtPsiFactory(position)
|
||||
|
||||
val result = ArrayList<ThisItemLookupObject>()
|
||||
for ((receiver, expressionFactory) in scope.asKtScope().getImplicitReceiversWithInstanceToExpression()) {
|
||||
for ((receiver, expressionFactory) in scope.getImplicitReceiversWithInstanceToExpression()) {
|
||||
if (expressionFactory == null) continue
|
||||
// if prefix does not start with "this@" do not include immediate this in the form with label
|
||||
val expression = expressionFactory.createExpression(psiFactory, shortThis = !prefix.startsWith("this@")) as? KtThisExpression ?: continue
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.completion.smart.TypesWithContainsDetector
|
||||
import org.jetbrains.kotlin.idea.core.IterableTypesDetection
|
||||
import org.jetbrains.kotlin.idea.core.getResolutionScope
|
||||
import org.jetbrains.kotlin.idea.core.mapArgumentsToParameters
|
||||
import org.jetbrains.kotlin.idea.core.resolveCandidates
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
@@ -555,7 +556,7 @@ class ExpectedInfos(
|
||||
else
|
||||
null
|
||||
|
||||
val scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, expressionWithType)!!
|
||||
val scope = expressionWithType.getResolutionScope(bindingContext, resolutionFacade)
|
||||
val iterableDetector = resolutionFacade.ideService<IterableTypesDetection>().createDetector(scope)
|
||||
|
||||
val byTypeFilter = object : ByTypeFilter {
|
||||
|
||||
+12
-7
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.idea.core.getResolutionScope
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
@@ -31,23 +33,26 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.Nullability
|
||||
import org.jetbrains.kotlin.resolve.scopes.KtScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import java.util.HashMap
|
||||
import java.util.*
|
||||
|
||||
class SmartCastCalculator(
|
||||
val bindingContext: BindingContext,
|
||||
val containingDeclarationOrModule: DeclarationDescriptor,
|
||||
expression: KtExpression
|
||||
expression: KtExpression,
|
||||
resolutionFacade: ResolutionFacade
|
||||
) {
|
||||
private val receiver = if (expression is KtSimpleNameExpression) expression.getReceiverExpression() else null
|
||||
|
||||
// keys are VariableDescriptor's and ThisReceiver's
|
||||
private val entityToSmartCastInfo: Map<Any, SmartCastInfo>
|
||||
= processDataFlowInfo(bindingContext.getDataFlowInfo(expression), bindingContext[BindingContext.RESOLUTION_SCOPE, expression], receiver)
|
||||
private val entityToSmartCastInfo: Map<Any, SmartCastInfo> = processDataFlowInfo(
|
||||
bindingContext.getDataFlowInfo(expression),
|
||||
expression.getResolutionScope(bindingContext, resolutionFacade),
|
||||
receiver)
|
||||
|
||||
fun types(descriptor: VariableDescriptor): Collection<KotlinType> {
|
||||
val type = descriptor.returnType ?: return emptyList()
|
||||
@@ -76,7 +81,7 @@ class SmartCastCalculator(
|
||||
constructor() : this(emptyList(), false)
|
||||
}
|
||||
|
||||
private fun processDataFlowInfo(dataFlowInfo: DataFlowInfo, resolutionScope: KtScope?, receiver: KtExpression?): Map<Any, SmartCastInfo> {
|
||||
private fun processDataFlowInfo(dataFlowInfo: DataFlowInfo, resolutionScope: LexicalScope?, receiver: KtExpression?): Map<Any, SmartCastInfo> {
|
||||
if (dataFlowInfo == DataFlowInfo.EMPTY) return emptyMap()
|
||||
|
||||
val dataFlowValueToEntity: (DataFlowValue) -> Any?
|
||||
@@ -126,7 +131,7 @@ class SmartCastCalculator(
|
||||
return entityToInfo
|
||||
}
|
||||
|
||||
private fun KtScope.findNearestReceiverForVariable(variableDescriptor: VariableDescriptor): ReceiverParameterDescriptor? {
|
||||
private fun LexicalScope.findNearestReceiverForVariable(variableDescriptor: VariableDescriptor): ReceiverParameterDescriptor? {
|
||||
val classifier = variableDescriptor.containingDeclaration as? ClassifierDescriptor ?: return null
|
||||
val type = classifier.defaultType
|
||||
return getImplicitReceiversWithInstance().firstOrNull { it.type.isSubtypeOf(type) }
|
||||
|
||||
+15
-7
@@ -27,6 +27,8 @@ import org.jetbrains.kotlin.idea.completion.ArgumentPositionData
|
||||
import org.jetbrains.kotlin.idea.completion.ExpectedInfo
|
||||
import org.jetbrains.kotlin.idea.completion.SmartCastCalculator
|
||||
import org.jetbrains.kotlin.idea.completion.Tail
|
||||
import org.jetbrains.kotlin.idea.core.getResolutionScope
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.getVariableFromImplicitReceivers
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.psi.Call
|
||||
@@ -34,17 +36,22 @@ import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.KtScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.getLocalVariable
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import java.util.*
|
||||
|
||||
class MultipleArgumentsItemProvider(val bindingContext: BindingContext,
|
||||
val smartCastCalculator: SmartCastCalculator) {
|
||||
class MultipleArgumentsItemProvider(
|
||||
private val bindingContext: BindingContext,
|
||||
private val smartCastCalculator: SmartCastCalculator,
|
||||
private val resolutionFacade: ResolutionFacade
|
||||
) {
|
||||
|
||||
public fun addToCollection(collection: MutableCollection<LookupElement>,
|
||||
expectedInfos: Collection<ExpectedInfo>,
|
||||
context: KtExpression) {
|
||||
val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, context] ?: return
|
||||
val resolutionScope = context.getResolutionScope(bindingContext, resolutionFacade)
|
||||
|
||||
val added = HashSet<String>()
|
||||
for (expectedInfo in expectedInfos) {
|
||||
@@ -96,11 +103,12 @@ class MultipleArgumentsItemProvider(val bindingContext: BindingContext,
|
||||
.assignSmartCompletionPriority(SmartCompletionItemPriority.MULTIPLE_ARGUMENTS_ITEM)
|
||||
}
|
||||
|
||||
private fun variableInScope(parameter: ValueParameterDescriptor, scope: KtScope): VariableDescriptor? {
|
||||
private fun variableInScope(parameter: ValueParameterDescriptor, scope: LexicalScope): VariableDescriptor? {
|
||||
val name = parameter.getName()
|
||||
//TODO: there can be more than one property with such name in scope and we should be able to select one (but we need API for this)
|
||||
val variable = scope.getLocalVariable(name) ?: scope.getProperties(name, NoLookupLocation.FROM_IDE).singleOrNull() ?:
|
||||
scope.getVariableFromImplicitReceivers(name) ?: return null
|
||||
val variable = scope.getLocalVariable(name)
|
||||
?: scope.collectAllFromMeAndParent { it.getDeclaredVariables(name, NoLookupLocation.FROM_IDE) }.singleOrNull()
|
||||
?: scope.getVariableFromImplicitReceivers(name) ?: return null
|
||||
return if (smartCastCalculator.types(variable).any { KotlinTypeChecker.DEFAULT.isSubtypeOf(it, parameter.getType()) })
|
||||
variable
|
||||
else
|
||||
|
||||
+3
-2
@@ -80,7 +80,7 @@ class SmartCompletion(
|
||||
private val callableTypeExpectedInfo = expectedInfos.filterCallableExpected()
|
||||
|
||||
public val smartCastCalculator: SmartCastCalculator by lazy(LazyThreadSafetyMode.NONE) {
|
||||
SmartCastCalculator(bindingContext, resolutionFacade.moduleDescriptor, expression)
|
||||
SmartCastCalculator(bindingContext, resolutionFacade.moduleDescriptor, expression, resolutionFacade)
|
||||
}
|
||||
|
||||
public val descriptorFilter: ((DeclarationDescriptor) -> Collection<LookupElement>)?
|
||||
@@ -228,7 +228,8 @@ class SmartCompletion(
|
||||
}
|
||||
}
|
||||
|
||||
MultipleArgumentsItemProvider(bindingContext, smartCastCalculator).addToCollection(items, expectedInfos, expression)
|
||||
MultipleArgumentsItemProvider(bindingContext, smartCastCalculator, resolutionFacade)
|
||||
.addToCollection(items, expectedInfos, expression)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user