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