Less use of KtScope

This commit is contained in:
Valentin Kipyatkov
2015-10-24 12:49:15 +03:00
parent c93de93332
commit 3eb1cff36a
27 changed files with 156 additions and 149 deletions
@@ -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 {
@@ -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) }
@@ -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
@@ -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)
}
}