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
@@ -35,10 +35,12 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.isAnnotatedAsHidden
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromImportingScopes
import org.jetbrains.kotlin.resolve.scopes.utils.getDescriptorsFiltered
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
@@ -115,7 +117,7 @@ public class ReferenceVariantsHelper(
}
is CallTypeAndReceiver.CALLABLE_REFERENCE -> {
val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression.parent as KtExpression] ?: return emptyList()
val resolutionScope = context[BindingContext.LEXICAL_SCOPE, expression.parent as KtExpression] ?: return emptyList()
return getVariantsForCallableReference(callTypeAndReceiver.receiver, resolutionScope, kindFilter, nameFilter)
}
@@ -128,9 +130,9 @@ public class ReferenceVariantsHelper(
else -> throw RuntimeException() //TODO: see KT-9394
}
val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return emptyList()
val resolutionScope = context[BindingContext.LEXICAL_SCOPE, expression] ?: return emptyList()
val dataFlowInfo = context.getDataFlowInfo(expression)
val containingDeclaration = resolutionScope.getContainingDeclaration()
val containingDeclaration = resolutionScope.ownerDescriptor
val smartCastManager = resolutionFacade.frontendService<SmartCastManager>()
val implicitReceiverTypes = resolutionScope.getImplicitReceiversWithInstance().flatMap {
@@ -187,7 +189,7 @@ public class ReferenceVariantsHelper(
private fun getVariantsForCallableReference(
qualifierTypeRef: KtTypeReference?,
resolutionScope: KtScope,
resolutionScope: LexicalScope,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor> {
@@ -224,7 +226,7 @@ public class ReferenceVariantsHelper(
private fun MutableSet<DeclarationDescriptor>.processAll(
implicitReceiverTypes: Collection<KotlinType>,
receiverTypes: Collection<KotlinType>,
resolutionScope: KtScope,
resolutionScope: LexicalScope,
callType: CallType<*>,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
@@ -256,12 +258,12 @@ public class ReferenceVariantsHelper(
constructorFilter: (ClassDescriptor) -> Boolean
) {
for (receiverType in receiverTypes) {
addNonExtensionCallablesAndConstructors(receiverType.memberScope, kindFilter, nameFilter, constructorFilter)
addNonExtensionCallablesAndConstructors(receiverType.memberScope.memberScopeAsImportingScope(), kindFilter, nameFilter, constructorFilter)
}
}
private fun MutableSet<DeclarationDescriptor>.addNonExtensionCallablesAndConstructors(
scope: KtScope,
scope: LexicalScope,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean,
constructorFilter: (ClassDescriptor) -> Boolean
@@ -286,7 +288,7 @@ public class ReferenceVariantsHelper(
}
private fun MutableSet<DeclarationDescriptor>.addScopeAndSyntheticExtensions(
resolutionScope: KtScope,
resolutionScope: LexicalScope,
receiverTypes: Collection<KotlinType>,
callType: CallType<*>,
kindFilter: DescriptorKindFilter,
@@ -308,13 +310,13 @@ public class ReferenceVariantsHelper(
}
if (kindFilter.acceptsKinds(DescriptorKindFilter.VARIABLES_MASK)) {
for (extension in resolutionScope.getSyntheticExtensionProperties(receiverTypes)) {
for (extension in resolutionScope.collectAllFromImportingScopes { it.getSyntheticExtensionProperties(receiverTypes) }) {
process(extension)
}
}
if (kindFilter.acceptsKinds(DescriptorKindFilter.FUNCTIONS_MASK)) {
for (extension in resolutionScope.getSyntheticExtensionFunctions(receiverTypes)) {
for (extension in resolutionScope.collectAllFromImportingScopes { it.getSyntheticExtensionFunctions(receiverTypes) }) {
process(extension)
}
}
@@ -218,7 +218,7 @@ public fun CallTypeAndReceiver<*, *>.receiverTypes(
expressionType?.let { listOf(ExpressionReceiver(receiverExpression, expressionType)) } ?: return emptyList()
}
else {
val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, position] ?: return emptyList()
val resolutionScope = bindingContext[BindingContext.LEXICAL_SCOPE, position] ?: return emptyList()
resolutionScope.getImplicitReceiversWithInstance().map { it.value }
}
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.psi.KtThisExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
@@ -51,12 +51,12 @@ public fun CallableDescriptor.substituteExtensionIfCallable(
}
public fun CallableDescriptor.substituteExtensionIfCallableWithImplicitReceiver(
scope: KtScope,
scope: LexicalScope,
context: BindingContext,
dataFlowInfo: DataFlowInfo
): Collection<CallableDescriptor> {
val receiverValues = scope.getImplicitReceiversWithInstance().map { it.getValue() }
return substituteExtensionIfCallable(receiverValues, context, dataFlowInfo, CallType.DEFAULT, scope.getContainingDeclaration())
return substituteExtensionIfCallable(receiverValues, context, dataFlowInfo, CallType.DEFAULT, scope.ownerDescriptor)
}
public fun CallableDescriptor.substituteExtensionIfCallable(
@@ -27,23 +27,23 @@ import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.renderer.render
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.KtScope
import java.util.LinkedHashMap
import java.util.LinkedHashSet
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
import java.util.*
public fun KtScope.getImplicitReceiversWithInstance(): Collection<ReceiverParameterDescriptor>
= getImplicitReceiversWithInstanceToExpression().keySet()
public fun LexicalScope.getImplicitReceiversWithInstance(): Collection<ReceiverParameterDescriptor>
= getImplicitReceiversWithInstanceToExpression().keys
public interface ReceiverExpressionFactory {
public fun createExpression(psiFactory: KtPsiFactory, shortThis: Boolean = true): KtExpression
}
public fun KtScope.getImplicitReceiversWithInstanceToExpression(): Map<ReceiverParameterDescriptor, ReceiverExpressionFactory?> {
public fun LexicalScope.getImplicitReceiversWithInstanceToExpression(): Map<ReceiverParameterDescriptor, ReceiverExpressionFactory?> {
// we use a set to workaround a bug with receiver for companion object present twice in the result of getImplicitReceiversHierarchy()
val receivers = LinkedHashSet(getImplicitReceiversHierarchy())
val outerDeclarationsWithInstance = LinkedHashSet<DeclarationDescriptor>()
var current: DeclarationDescriptor? = getContainingDeclaration()
var current: DeclarationDescriptor? = ownerDescriptor
while (current != null) {
if (current is PropertyAccessorDescriptor) {
current = current.getCorrespondingProperty()
@@ -22,21 +22,24 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
public fun KtScope.getAllAccessibleVariables(name: Name): Collection<VariableDescriptor>
= getVariablesFromImplicitReceivers(name) + getProperties(name, NoLookupLocation.FROM_IDE) + listOfNotNull(getLocalVariable(name))
public fun LexicalScope.getAllAccessibleVariables(name: Name): Collection<VariableDescriptor> {
return getVariablesFromImplicitReceivers(name) + collectAllFromMeAndParent { it.getDeclaredVariables(name, NoLookupLocation.FROM_IDE) }
}
public fun KtScope.getAllAccessibleFunctions(name: Name): Collection<FunctionDescriptor>
= getImplicitReceiversWithInstance().flatMap { it.type.memberScope.getFunctions(name, NoLookupLocation.FROM_IDE) } +
getFunctions(name, NoLookupLocation.FROM_IDE)
public fun LexicalScope.getAllAccessibleFunctions(name: Name): Collection<FunctionDescriptor> {
return getImplicitReceiversWithInstance().flatMap { it.type.memberScope.getFunctions(name, NoLookupLocation.FROM_IDE) } +
collectAllFromMeAndParent { it.getDeclaredFunctions(name, NoLookupLocation.FROM_IDE) }
}
public fun KtScope.getVariablesFromImplicitReceivers(name: Name): Collection<VariableDescriptor> = getImplicitReceiversWithInstance().flatMap {
public fun LexicalScope.getVariablesFromImplicitReceivers(name: Name): Collection<VariableDescriptor> = getImplicitReceiversWithInstance().flatMap {
it.type.memberScope.getProperties(name, NoLookupLocation.FROM_IDE)
}
public fun KtScope.getVariableFromImplicitReceivers(name: Name): VariableDescriptor? {
public fun LexicalScope.getVariableFromImplicitReceivers(name: Name): VariableDescriptor? {
getImplicitReceiversWithInstance().forEach {
it.type.memberScope.getProperties(name, NoLookupLocation.FROM_IDE).singleOrNull()?.let { return it }
}
@@ -23,8 +23,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.resolve.scopes.utils.asLexicalScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
@@ -33,7 +32,7 @@ import org.jetbrains.kotlin.types.expressions.PreliminaryDeclarationVisitor
@JvmOverloads
public fun KtExpression.computeTypeInfoInContext(
scope: KtScope,
scope: LexicalScope,
contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(),
dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY,
@@ -42,12 +41,12 @@ public fun KtExpression.computeTypeInfoInContext(
): JetTypeInfo {
PreliminaryDeclarationVisitor.createForExpression(this, trace)
return contextExpression.getResolutionFacade().frontendService<ExpressionTypingServices>()
.getTypeInfo(scope.asLexicalScope(), this, expectedType, dataFlowInfo, trace, isStatement)
.getTypeInfo(scope, this, expectedType, dataFlowInfo, trace, isStatement)
}
@JvmOverloads
public fun KtExpression.analyzeInContext(
scope: KtScope,
scope: LexicalScope,
contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(),
dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY,
@@ -60,7 +59,7 @@ public fun KtExpression.analyzeInContext(
@JvmOverloads
public fun KtExpression.computeTypeInContext(
scope: KtScope,
scope: LexicalScope,
contextExpression: KtExpression = this,
trace: BindingTrace = BindingTraceContext(),
dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY,
@@ -344,7 +344,7 @@ public class ShortenReferences(val options: (KtElement) -> Options = { Options.D
val callee = selector.getCalleeExpressionIfAny() as? KtReferenceExpression ?: return false
val target = callee.targets(bindingContext).singleOrNull() ?: return false
val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, qualifiedExpression] ?: return false
val scope = bindingContext[BindingContext.LEXICAL_SCOPE, qualifiedExpression] ?: return false
val selectorCopy = selector.copy() as KtReferenceExpression
val newContext = selectorCopy.analyzeInContext(scope, selector)
val targetsWhenShort = (selectorCopy.getCalleeExpressionIfAny() as KtReferenceExpression).targets(newContext)
@@ -392,7 +392,7 @@ public class ShortenReferences(val options: (KtElement) -> Options = { Options.D
val bindingContext = analyze(thisExpression)
val targetBefore = thisExpression.getInstanceReference().targets(bindingContext).singleOrNull() ?: return
val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, thisExpression] ?: return
val scope = bindingContext[BindingContext.LEXICAL_SCOPE, thisExpression] ?: return
val newContext = simpleThis.analyzeInContext(scope, thisExpression)
val targetAfter = simpleThis.getInstanceReference().targets(newContext).singleOrNull()
if (targetBefore == targetAfter) {
@@ -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)
}
}
@@ -17,41 +17,40 @@
package org.jetbrains.kotlin.idea.core
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.util.FuzzyType
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.utils.asLexicalScope
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
import org.jetbrains.kotlin.types.expressions.ForLoopConventionsChecker
import java.util.HashMap
import java.util.*
public class IterableTypesDetection(
private val project: Project,
private val moduleDescriptor: ModuleDescriptor,
private val forLoopConventionsChecker: ForLoopConventionsChecker
) {
companion object {
private val iteratorName = Name.identifier("iterator")
}
public fun createDetector(scope: KtScope): IterableTypesDetector {
public fun createDetector(scope: LexicalScope): IterableTypesDetector {
return Detector(scope)
}
private inner class Detector(private val scope: KtScope): IterableTypesDetector {
private inner class Detector(private val scope: LexicalScope): IterableTypesDetector {
private val cache = HashMap<FuzzyType, FuzzyType?>()
private val typesWithExtensionIterator: Collection<KotlinType> = scope.getFunctions(iteratorName, NoLookupLocation.FROM_IDE)
.map { it.getExtensionReceiverParameter() }
private val typesWithExtensionIterator: Collection<KotlinType> = scope
.collectAllFromMeAndParent { it.getDeclaredFunctions(iteratorName, NoLookupLocation.FROM_IDE) }
.map { it.extensionReceiverParameter }
.filterNotNull()
.map { it.getType() }
.map { it.type }
override fun isIterable(type: FuzzyType, loopVarType: KotlinType?): Boolean {
val elementType = elementType(type) ?: return false
@@ -74,7 +73,7 @@ public class IterableTypesDetection(
val expression = KtPsiFactory(project).createExpression("fake")
val expressionReceiver = ExpressionReceiver(expression, type.type)
val context = ExpressionTypingContext.newContext(BindingTraceContext(), scope.asLexicalScope(), DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE)
val context = ExpressionTypingContext.newContext(BindingTraceContext(), scope, DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE)
val elementType = forLoopConventionsChecker.checkIterableConvention(expressionReceiver, context)
return elementType?.let { FuzzyType(it, type.freeParameters) }
}
@@ -32,11 +32,10 @@ import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi.psiUtil.siblings
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.resolve.scopes.utils.asKtScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.utils.getClassifier
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.util.Collections
import java.util.HashSet
import java.util.*
public class CollectingNameValidator @JvmOverloads constructor(
existingNames: Collection<String> = Collections.emptySet(),
@@ -80,7 +79,7 @@ public class NewDeclarationNameValidator(
if (visibleDeclarationsContext != null) {
val bindingContext = visibleDeclarationsContext.analyze(BodyResolveMode.PARTIAL_FOR_COMPLETION)
val resolutionScope = visibleDeclarationsContext.getResolutionScope(bindingContext, visibleDeclarationsContext.getResolutionFacade())
if (resolutionScope.asKtScope().hasConflict(identifier)) return false
if (resolutionScope.hasConflict(identifier)) return false
}
return checkDeclarationsIn.none {
@@ -88,12 +87,10 @@ public class NewDeclarationNameValidator(
}
}
private fun KtScope.hasConflict(name: Name): Boolean {
val inDeclaration = getContainingDeclaration()
private fun LexicalScope.hasConflict(name: Name): Boolean {
fun DeclarationDescriptor.isVisible(): Boolean {
return when (this) {
is DeclarationDescriptorWithVisibility -> isVisible(inDeclaration)
is DeclarationDescriptorWithVisibility -> isVisible(ownerDescriptor)
else -> true
}
}
@@ -41,10 +41,8 @@ import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
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.resolve.scopes.utils.asKtScope
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@@ -93,7 +91,7 @@ public fun Call.mapArgumentsToParameters(targetDescriptor: CallableDescriptor):
return map
}
public fun ThisReceiver.asExpression(resolutionScope: KtScope, psiFactory: KtPsiFactory): KtExpression? {
public fun ThisReceiver.asExpression(resolutionScope: LexicalScope, psiFactory: KtPsiFactory): KtExpression? {
val expressionFactory = resolutionScope.getImplicitReceiversWithInstanceToExpression()
.entrySet()
.firstOrNull { it.key.getContainingDeclaration() == this.getDeclarationDescriptor() }
@@ -178,7 +176,7 @@ private fun expectedType(call: Call, bindingContext: BindingContext): KotlinType
fun KtCallableDeclaration.canOmitDeclaredType(initializerOrBodyExpression: KtExpression, canChangeTypeToSubtype: Boolean): Boolean {
val declaredType = (resolveToDescriptor() as? CallableDescriptor)?.returnType ?: return false
val bindingContext = initializerOrBodyExpression.analyze()
val scope = initializerOrBodyExpression.getResolutionScope(bindingContext, initializerOrBodyExpression.getResolutionFacade()).asKtScope()
val scope = initializerOrBodyExpression.getResolutionScope(bindingContext, initializerOrBodyExpression.getResolutionFacade())
val expressionType = initializerOrBodyExpression.computeTypeInContext(scope) ?: return false
if (KotlinTypeChecker.DEFAULT.equalTypes(expressionType, declaredType)) return true
return canChangeTypeToSubtype && expressionType.isSubtypeOf(declaredType)
@@ -23,11 +23,12 @@ import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.idea.analysis.analyzeInContext
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.getResolutionScope
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
@@ -44,7 +45,7 @@ public class AddForLoopIndicesIntention : JetSelfTargetingRangeIntention<KtForEx
val resolvedCall = loopRange.getResolvedCall(bindingContext)
if (resolvedCall?.resultingDescriptor?.fqNameUnsafe?.asString() == WITH_INDEX_FQ_NAME) return null // already withIndex() call
val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, element] ?: return null
val resolutionScope = element.getResolutionScope(bindingContext, element.getResolutionFacade())
val potentialExpression = createWithIndexExpression(loopRange)
val newBindingContext = potentialExpression.analyzeInContext(resolutionScope, loopRange)
@@ -50,6 +50,7 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.types.typeUtil.supertypes
@@ -123,7 +124,7 @@ public class ConvertFunctionToPropertyIntention : JetSelfTargetingIntention<KtNa
}
callableDescriptor.getContainingScope()
?.getProperties(callableDescriptor.name, NoLookupLocation.FROM_IDE)
?.collectAllFromMeAndParent { it.getDeclaredVariables(callableDescriptor.name, NoLookupLocation.FROM_IDE) }
?.firstOrNull()
?.let { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) }
?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } }
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
import java.util.*
public class ConvertPropertyToFunctionIntention : JetSelfTargetingIntention<KtProperty>(javaClass(), "Convert property to function"), LowPriorityAction {
@@ -102,7 +103,7 @@ public class ConvertPropertyToFunctionIntention : JetSelfTargetingIntention<KtPr
if (callable is KtProperty) {
callableDescriptor.getContainingScope()
?.getFunctions(callableDescriptor.name, NoLookupLocation.FROM_IDE)
?.collectAllFromMeAndParent { it.getDeclaredFunctions(callableDescriptor.name, NoLookupLocation.FROM_IDE) }
?.firstOrNull { it.getValueParameters().isEmpty() }
?.let { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) }
?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } }
@@ -22,15 +22,11 @@ import com.intellij.codeInsight.template.impl.ConstantNode
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.IterableTypesDetection
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.core.*
import org.jetbrains.kotlin.idea.resolve.ideService
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.siblings
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.KotlinType
@@ -50,7 +46,7 @@ public class IterateExpressionIntention : JetSelfTargetingIntention<KtExpression
val resolutionFacade = expression.getResolutionFacade()
val bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.PARTIAL)
val type = bindingContext.getType(expression) ?: return null
val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, expression] ?: return null
val scope = expression.getResolutionScope(bindingContext, resolutionFacade)
val detector = resolutionFacade.ideService<IterableTypesDetection>().createDetector(scope)
val elementType = detector.elementType(type)?.type ?: return null
return Data(type, elementType)
@@ -22,6 +22,8 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.idea.analysis.analyzeInContext
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.getResolutionScope
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtQualifiedExpression
@@ -51,7 +53,7 @@ public class RemoveExplicitSuperQualifierIntention : JetSelfTargetingRangeIntent
val bindingContext = selector.analyze(BodyResolveMode.PARTIAL)
if (selector.getResolvedCall(bindingContext) == null) return null
val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, qualifiedExpression] ?: return null
val resolutionScope = qualifiedExpression.getResolutionScope(bindingContext, selector.getResolutionFacade())
val dataFlowInfo = bindingContext.getDataFlowInfo(element)
val expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, qualifiedExpression] ?: TypeUtils.NO_EXPECTED_TYPE
@@ -49,7 +49,6 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.utils.asKtScope
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
@@ -101,7 +100,7 @@ class UsePropertyAccessSyntaxIntention : JetSelfTargetingOffsetIndependentIntent
val newExpression = applyTo(callExpressionCopy, property.name)
val bindingTrace = DelegatingBindingTrace(bindingContext, "Temporary trace")
val newBindingContext = newExpression.analyzeInContext(
resolutionScope.asKtScope(),
resolutionScope,
contextExpression = callExpression,
trace = bindingTrace,
dataFlowInfo = dataFlowInfo,
@@ -33,11 +33,13 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor;
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
import org.jetbrains.kotlin.idea.core.UtilsKt;
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade;
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
import org.jetbrains.kotlin.idea.core.IterableTypesDetection;
import org.jetbrains.kotlin.idea.core.IterableTypesDetector;
import org.jetbrains.kotlin.idea.util.ExtensionUtils;
import org.jetbrains.kotlin.idea.util.ScopeUtils;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
@@ -46,6 +48,8 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
import org.jetbrains.kotlin.resolve.scopes.KtScope;
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
import java.util.*;
@@ -66,10 +70,7 @@ public abstract class BaseJetVariableMacro extends Macro {
ResolutionFacade resolutionFacade = ResolutionUtils.getResolutionFacade(contextExpression);
BindingContext bindingContext = resolutionFacade.analyze(contextExpression, BodyResolveMode.FULL);
KtScope scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, contextExpression);
if (scope == null) {
return null;
}
LexicalScope scope = UtilsKt.getResolutionScope(contextExpression, bindingContext, resolutionFacade);
IterableTypesDetector detector = resolutionFacade.getIdeService(IterableTypesDetection.class).createDetector(scope);
@@ -106,10 +107,10 @@ public abstract class BaseJetVariableMacro extends Macro {
return declarations.toArray(new KtNamedDeclaration[declarations.size()]);
}
private static Collection<DeclarationDescriptor> getAllVariables(KtScope scope) {
private static Collection<DeclarationDescriptor> getAllVariables(LexicalScope scope) {
Collection<DeclarationDescriptor> result = ContainerUtil.newArrayList();
result.addAll(scope.getDescriptors(DescriptorKindFilter.VARIABLES, KtScope.Companion.getALL_NAME_FILTER()));
for (ReceiverParameterDescriptor implicitReceiver : scope.getImplicitReceiversHierarchy()) {
for (ReceiverParameterDescriptor implicitReceiver : ScopeUtilsKt.getImplicitReceiversHierarchy(scope)) {
result.addAll(implicitReceiver.getType().getMemberScope().getDescriptors(DescriptorKindFilter.VARIABLES, KtScope.Companion.getALL_NAME_FILTER()));
}
return result;
@@ -47,7 +47,7 @@ import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
import org.jetbrains.kotlin.resolve.scopes.utils.asKtScope
import org.jetbrains.kotlin.resolve.scopes.utils.getLocalVariable
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addIfNotNull
@@ -104,7 +104,7 @@ private fun performCallReplacement(
if (receiver == null) {
val receiverValue = if (descriptor.isExtension) resolvedCall.extensionReceiver else resolvedCall.dispatchReceiver
val resolutionScope = elementToBeReplaced.getResolutionScope(bindingContext, elementToBeReplaced.getResolutionFacade()).asKtScope()
val resolutionScope = elementToBeReplaced.getResolutionScope(bindingContext, elementToBeReplaced.getResolutionFacade())
if (receiverValue is ThisReceiver) {
receiver = receiverValue.asExpression(resolutionScope, psiFactory)
receiverType = receiverValue.type
@@ -658,13 +658,13 @@ private class ConstructedExpressionWrapperWithIntroduceFeature(
if (!safeCall) {
val block = expressionToBeReplaced.parent as? KtBlockExpression
if (block != null) {
val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, expressionToBeReplaced]
val resolutionScope = expressionToBeReplaced.getResolutionScope(bindingContext, expressionToBeReplaced.getResolutionFacade())
if (usages.isNotEmpty()) {
var explicitType: KotlinType? = null
if (valueType != null && !ErrorUtils.containsErrorType(valueType)) {
val valueTypeWithoutExpectedType = value.computeTypeInContext(
resolutionScope!!,
resolutionScope,
expressionToBeReplaced,
dataFlowInfo = bindingContext.getDataFlowInfo(expressionToBeReplaced)
)
@@ -674,7 +674,7 @@ private class ConstructedExpressionWrapperWithIntroduceFeature(
}
val name = suggestName { name ->
resolutionScope!!.getLocalVariable(Name.identifier(name)) == null && !isNameUsed(name)
resolutionScope.getLocalVariable(Name.identifier(name)) == null && !isNameUsed(name)
}
var declaration = psiFactory.createDeclarationByPattern<KtVariableDeclaration>("val $0 = $1", name, value)
@@ -45,7 +45,6 @@ import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider
import org.jetbrains.kotlin.resolve.lazy.descriptors.ClassResolutionScopesSupport
import org.jetbrains.kotlin.resolve.scopes.*
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver
import org.jetbrains.kotlin.resolve.scopes.utils.asKtScope
import org.jetbrains.kotlin.resolve.scopes.utils.chainImportingScopes
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
import org.jetbrains.kotlin.storage.LockBasedStorageManager
@@ -142,7 +141,7 @@ object ReplaceWithAnnotationAnalyzer {
else
resolvedCall.dispatchReceiver
if (receiver is ThisReceiver) {
val receiverExpression = receiver.asExpression(scope.asKtScope(), psiFactory)
val receiverExpression = receiver.asExpression(scope, psiFactory)
if (receiverExpression != null) {
receiversToAdd.add(expression to receiverExpression)
}
@@ -28,13 +28,12 @@ import com.intellij.refactoring.RefactoringBundle
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.*
import org.jetbrains.kotlin.idea.JetBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.core.getResolutionScope
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
import org.jetbrains.kotlin.psi.KtBlockExpression
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
@@ -43,8 +42,8 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.OverrideResolver
import org.jetbrains.kotlin.resolve.scopes.KtScope
import org.jetbrains.kotlin.resolve.scopes.utils.asKtScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
import java.util.*
public abstract class CallableRefactoring<T: CallableDescriptor>(
@@ -183,24 +182,25 @@ fun getAffectedCallables(project: Project, descriptorsForChange: Collection<Call
}
}
fun DeclarationDescriptor.getContainingScope(): KtScope? {
fun DeclarationDescriptor.getContainingScope(): LexicalScope? {
val declaration = DescriptorToSourceUtils.descriptorToDeclaration(this)
val block = declaration?.getParent() as? KtBlockExpression
if (block != null) {
val lastStatement = block.statements.last()
return lastStatement.analyze()[BindingContext.RESOLUTION_SCOPE, lastStatement]
val bindingContext = lastStatement.analyze()
return lastStatement.getResolutionScope(bindingContext, lastStatement.getResolutionFacade())
}
else {
val containingDescriptor = getContainingDeclaration() ?: return null
return when (containingDescriptor) {
is ClassDescriptorWithResolutionScopes -> containingDescriptor.getScopeForInitializerResolution().asKtScope()
is PackageFragmentDescriptor -> containingDescriptor.getMemberScope()
is ClassDescriptorWithResolutionScopes -> containingDescriptor.getScopeForInitializerResolution()
is PackageFragmentDescriptor -> containingDescriptor.getMemberScope().memberScopeAsImportingScope()
else -> null
}
}
}
fun KtDeclarationWithBody.getBodyScope(bindingContext: BindingContext): KtScope? {
val expression = getBodyExpression()?.getChildren()?.firstOrNull { it is KtExpression } as KtExpression?
return expression?.let { bindingContext[BindingContext.RESOLUTION_SCOPE, it] }
fun KtDeclarationWithBody.getBodyScope(bindingContext: BindingContext): LexicalScope? {
val expression = getBodyExpression()?.getChildren()?.firstOrNull { it is KtExpression } ?: return null
return expression.getResolutionScope(bindingContext, getResolutionFacade())
}
@@ -78,7 +78,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
import org.jetbrains.kotlin.resolve.scopes.KtScope;
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisReceiver;
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
@@ -634,13 +634,13 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
CallableDescriptor oldDescriptor = JetChangeInfoKt.getOriginalBaseFunctionDescriptor(changeInfo);
DeclarationDescriptor containingDeclaration = oldDescriptor.getContainingDeclaration();
KtScope parametersScope = null;
LexicalScope parametersScope = null;
if (oldDescriptor instanceof ConstructorDescriptor && containingDeclaration instanceof ClassDescriptorWithResolutionScopes)
parametersScope = ScopeUtilsKt.asKtScope(((ClassDescriptorWithResolutionScopes) containingDeclaration).getScopeForInitializerResolution());
parametersScope = ((ClassDescriptorWithResolutionScopes) containingDeclaration).getScopeForInitializerResolution();
else if (function instanceof KtFunction)
parametersScope = CallableRefactoringKt.getBodyScope((KtFunction) function, bindingContext);
KtScope callableScope = CallableRefactoringKt.getContainingScope(oldDescriptor);
LexicalScope callableScope = CallableRefactoringKt.getContainingScope(oldDescriptor);
JetMethodDescriptor.Kind kind = JetChangeInfoKt.getKind(changeInfo);
if (!kind.isConstructor() && callableScope != null && !info.getNewName().isEmpty()) {
@@ -680,7 +680,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
}
}
else if (function instanceof KtFunction) {
VariableDescriptor variable = parametersScope.getLocalVariable(Name.identifier(parameterName));
VariableDescriptor variable = ScopeUtilsKt.getLocalVariable(parametersScope, Name.identifier(parameterName));
if (variable != null && !(variable instanceof ValueParameterDescriptor)) {
PsiElement conflictElement = DescriptorToSourceUtils.descriptorToDeclaration(variable);
@@ -755,9 +755,9 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
if (usageInfo.getElement() instanceof KDocName) continue; // TODO support converting parameter to receiver in KDoc
KtExpression originalExpr = (KtExpression) usageInfo.getElement();
KtScope scope = ResolutionUtils.analyze(originalExpr, BodyResolveMode.FULL)
.get(BindingContext.RESOLUTION_SCOPE, originalExpr);
if (scope == null) continue;
BindingContext bindingContext = ResolutionUtils.analyze(originalExpr, BodyResolveMode.FULL);
LexicalScope scope = org.jetbrains.kotlin.idea.core.UtilsKt.getResolutionScope(
originalExpr, bindingContext, ResolutionUtils.getResolutionFacade(originalExpr));
KtThisExpression newExpr = (KtThisExpression) psiFactory.createExpression(newExprText);
@@ -36,19 +36,21 @@ import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.analyzer.AnalysisResult;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.idea.analysis.AnalyzerUtilKt;
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils;
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester;
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator;
import org.jetbrains.kotlin.idea.core.PsiModificationUtilsKt;
import org.jetbrains.kotlin.idea.core.UtilsKt;
import org.jetbrains.kotlin.idea.intentions.ConvertToBlockBodyIntention;
import org.jetbrains.kotlin.idea.intentions.RemoveCurlyBracesFromTemplateIntention;
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle;
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringUtil;
import org.jetbrains.kotlin.idea.refactoring.introduce.IntroduceUtilKt;
import org.jetbrains.kotlin.idea.refactoring.introduce.KotlinIntroduceHandlerBase;
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade;
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers;
import org.jetbrains.kotlin.idea.util.ShortenReferences;
import org.jetbrains.kotlin.idea.util.psi.patternMatching.JetPsiRange;
@@ -63,7 +65,7 @@ import org.jetbrains.kotlin.resolve.ObservableBindingTrace;
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
import org.jetbrains.kotlin.resolve.scopes.KtScope;
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
@@ -135,36 +137,29 @@ public class KotlinIntroduceVariableHandler extends KotlinIntroduceHandlerBase {
return;
}
AnalysisResult analysisResult = ResolutionUtils.analyzeAndGetResult(expression);
final BindingContext bindingContext = analysisResult.getBindingContext();
ResolutionFacade resolutionFacade = ResolutionUtils.getResolutionFacade(expression);
final BindingContext bindingContext = resolutionFacade.analyze(expression, BodyResolveMode.FULL);
final KotlinType expressionType = bindingContext.getType(expression); //can be null or error type
KtScope scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, expression);
if (scope != null) {
DataFlowInfo dataFlowInfo = BindingContextUtilsKt.getDataFlowInfo(bindingContext, expression);
LexicalScope scope = UtilsKt.getResolutionScope(expression, bindingContext, resolutionFacade);
DataFlowInfo dataFlowInfo = BindingContextUtilsKt.getDataFlowInfo(bindingContext, expression);
ObservableBindingTrace bindingTrace = new ObservableBindingTrace(new BindingTraceContext());
KotlinType typeNoExpectedType = AnalyzerUtilKt.computeTypeInfoInContext(
expression, scope, expression, bindingTrace, dataFlowInfo
).getType();
if (expressionType != null && typeNoExpectedType != null && !KotlinTypeChecker.DEFAULT.equalTypes(expressionType,
typeNoExpectedType)) {
noTypeInference = true;
}
ObservableBindingTrace bindingTrace = new ObservableBindingTrace(new BindingTraceContext());
KotlinType typeNoExpectedType = AnalyzerUtilKt.computeTypeInfoInContext(
expression, scope, expression, bindingTrace, dataFlowInfo
).getType();
if (expressionType != null && typeNoExpectedType != null && !KotlinTypeChecker.DEFAULT.equalTypes(expressionType,
typeNoExpectedType)) {
noTypeInference = true;
}
if (expressionType == null && bindingContext.get(BindingContext.QUALIFIER, expression) != null) {
showErrorHint(project, editor, JetRefactoringBundle.message("cannot.refactor.package.expression"));
return;
}
if (expressionType != null &&
KotlinTypeChecker.DEFAULT.equalTypes(analysisResult.getModuleDescriptor().getBuiltIns().getUnitType(), expressionType)) {
if (expressionType != null && KotlinBuiltIns.isUnit(expressionType)) {
showErrorHint(project, editor, JetRefactoringBundle.message("cannot.refactor.expression.has.unit.type"));
return;
}
if (expressionType == null && noTypeInference) {
showErrorHint(project, editor, JetRefactoringBundle.message("cannot.refactor.expression.should.have.inferred.type"));
return;
}
final PsiElement container = getContainer(expression);
PsiElement occurrenceContainer = getOccurrenceContainer(expression);
if (container == null) {