diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt index 443df14fff5..681d218f127 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt @@ -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() 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 { @@ -224,7 +226,7 @@ public class ReferenceVariantsHelper( private fun MutableSet.processAll( implicitReceiverTypes: Collection, receiverTypes: Collection, - 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.addNonExtensionCallablesAndConstructors( - scope: KtScope, + scope: LexicalScope, kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, constructorFilter: (ClassDescriptor) -> Boolean @@ -286,7 +288,7 @@ public class ReferenceVariantsHelper( } private fun MutableSet.addScopeAndSyntheticExtensions( - resolutionScope: KtScope, + resolutionScope: LexicalScope, receiverTypes: Collection, 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) } } diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt index 3480d6c649e..e3a2a45d231 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt @@ -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 } } diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/extensionsUtils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/extensionsUtils.kt index f4229b7ee93..c32781282ad 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/extensionsUtils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/extensionsUtils.kt @@ -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 { 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( diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/implicitReceiversUtils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/implicitReceiversUtils.kt index 3554d14b433..a98818fb30c 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/implicitReceiversUtils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/implicitReceiversUtils.kt @@ -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 - = getImplicitReceiversWithInstanceToExpression().keySet() +public fun LexicalScope.getImplicitReceiversWithInstance(): Collection + = getImplicitReceiversWithInstanceToExpression().keys public interface ReceiverExpressionFactory { public fun createExpression(psiFactory: KtPsiFactory, shortThis: Boolean = true): KtExpression } -public fun KtScope.getImplicitReceiversWithInstanceToExpression(): Map { +public fun LexicalScope.getImplicitReceiversWithInstanceToExpression(): Map { // 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() - var current: DeclarationDescriptor? = getContainingDeclaration() + var current: DeclarationDescriptor? = ownerDescriptor while (current != null) { if (current is PropertyAccessorDescriptor) { current = current.getCorrespondingProperty() diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/scopeUtils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/scopeUtils.kt index ae83ba4fb0b..cf92b5d6a65 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/scopeUtils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/scopeUtils.kt @@ -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 - = getVariablesFromImplicitReceivers(name) + getProperties(name, NoLookupLocation.FROM_IDE) + listOfNotNull(getLocalVariable(name)) +public fun LexicalScope.getAllAccessibleVariables(name: Name): Collection { + return getVariablesFromImplicitReceivers(name) + collectAllFromMeAndParent { it.getDeclaredVariables(name, NoLookupLocation.FROM_IDE) } +} -public fun KtScope.getAllAccessibleFunctions(name: Name): Collection - = getImplicitReceiversWithInstance().flatMap { it.type.memberScope.getFunctions(name, NoLookupLocation.FROM_IDE) } + - getFunctions(name, NoLookupLocation.FROM_IDE) +public fun LexicalScope.getAllAccessibleFunctions(name: Name): Collection { + 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 = getImplicitReceiversWithInstance().flatMap { +public fun LexicalScope.getVariablesFromImplicitReceivers(name: Name): Collection = 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 } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/analysis/AnalyzerUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/analysis/AnalyzerUtil.kt index 7a0517ab5f7..8ab1c70097a 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/analysis/AnalyzerUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/analysis/AnalyzerUtil.kt @@ -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() - .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, diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt index 2b0b6a39cf4..fc5caeb541b 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt @@ -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) { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt index 3a078b34cce..8b42f6c0067 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt @@ -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() - 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 diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt index b7bea025912..7b54e9b049a 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt @@ -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().createDetector(scope) val byTypeFilter = object : ByTypeFilter { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/SmartCastCalculator.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/SmartCastCalculator.kt index 36dc5f41ca7..3c79d1fbb39 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/SmartCastCalculator.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/SmartCastCalculator.kt @@ -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 - = processDataFlowInfo(bindingContext.getDataFlowInfo(expression), bindingContext[BindingContext.RESOLUTION_SCOPE, expression], receiver) + private val entityToSmartCastInfo: Map = processDataFlowInfo( + bindingContext.getDataFlowInfo(expression), + expression.getResolutionScope(bindingContext, resolutionFacade), + receiver) fun types(descriptor: VariableDescriptor): Collection { 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 { + private fun processDataFlowInfo(dataFlowInfo: DataFlowInfo, resolutionScope: LexicalScope?, receiver: KtExpression?): Map { 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) } diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/MultipleArgumentsItemProvider.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/MultipleArgumentsItemProvider.kt index 145d60b6262..f11a1cfead2 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/MultipleArgumentsItemProvider.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/MultipleArgumentsItemProvider.kt @@ -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, expectedInfos: Collection, context: KtExpression) { - val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, context] ?: return + val resolutionScope = context.getResolutionScope(bindingContext, resolutionFacade) val added = HashSet() 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 diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt index 506ada5515c..6af61fb70ab 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt @@ -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)? @@ -228,7 +228,8 @@ class SmartCompletion( } } - MultipleArgumentsItemProvider(bindingContext, smartCastCalculator).addToCollection(items, expectedInfos, expression) + MultipleArgumentsItemProvider(bindingContext, smartCastCalculator, resolutionFacade) + .addToCollection(items, expectedInfos, expression) } } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/IterableTypesDetection.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/IterableTypesDetection.kt index 94daf647cdd..26773e6a22c 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/IterableTypesDetection.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/IterableTypesDetection.kt @@ -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() - private val typesWithExtensionIterator: Collection = scope.getFunctions(iteratorName, NoLookupLocation.FROM_IDE) - .map { it.getExtensionReceiverParameter() } + private val typesWithExtensionIterator: Collection = 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) } } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/NameValidators.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/NameValidators.kt index 527fb067d4e..d09f0021844 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/NameValidators.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/NameValidators.kt @@ -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 = 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 } } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/Utils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/Utils.kt index 2c6ea61004d..cf0bf8a6282 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/Utils.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/Utils.kt @@ -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) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/AddForLoopIndicesIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/AddForLoopIndicesIntention.kt index 02f24efab40..0648bed1719 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/AddForLoopIndicesIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/AddForLoopIndicesIntention.kt @@ -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(javaClass(), "Convert property to function"), LowPriorityAction { @@ -102,7 +103,7 @@ public class ConvertPropertyToFunctionIntention : JetSelfTargetingIntention().createDetector(scope) val elementType = detector.elementType(type)?.type ?: return null return Data(type, elementType) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitSuperQualifierIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitSuperQualifierIntention.kt index 94b06cb174b..b7cfdeea6b3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitSuperQualifierIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitSuperQualifierIntention.kt @@ -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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/UsePropertyAccessSyntaxIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/UsePropertyAccessSyntaxIntention.kt index b6122bcebf9..cb346c5e61b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/UsePropertyAccessSyntaxIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/UsePropertyAccessSyntaxIntention.kt @@ -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, diff --git a/idea/src/org/jetbrains/kotlin/idea/liveTemplates/macro/BaseJetVariableMacro.java b/idea/src/org/jetbrains/kotlin/idea/liveTemplates/macro/BaseJetVariableMacro.java index 690ca31887a..cd341e8e93b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/liveTemplates/macro/BaseJetVariableMacro.java +++ b/idea/src/org/jetbrains/kotlin/idea/liveTemplates/macro/BaseJetVariableMacro.java @@ -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 getAllVariables(KtScope scope) { + private static Collection getAllVariables(LexicalScope scope) { Collection 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; diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt index 043f32df45b..d1f610dfde8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/CallableUsageReplacementStrategy.kt @@ -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("val $0 = $1", name, value) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt index 8c37c1724e7..4d25ba81d05 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/ReplaceWithAnnotationAnalyzer.kt @@ -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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/CallableRefactoring.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/CallableRefactoring.kt index 3ffaa8fee40..1b3bd22d336 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/CallableRefactoring.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/CallableRefactoring.kt @@ -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( @@ -183,24 +182,25 @@ fun getAffectedCallables(project: Project, descriptorsForChange: Collection 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()) } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java index 5c4ea5f5e5e..e58fe8626a0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java @@ -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); diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.java index 92fc8a002cd..b992768951e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/introduceVariable/KotlinIntroduceVariableHandler.java @@ -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) {