Added utility functions for functions and variables in scope
This commit is contained in:
@@ -97,6 +97,26 @@ public fun LexicalScope.findClassifier(name: Name, location: LookupLocation): Cl
|
||||
public fun LexicalScope.findPackage(name: Name): PackageViewDescriptor?
|
||||
= findFirstFromImportingScopes { it.getContributedPackage(name) }
|
||||
|
||||
public fun LexicalScope.collectVariables(name: Name, location: LookupLocation): Collection<VariableDescriptor>
|
||||
= collectAllFromMeAndParent { it.getContributedVariables(name, location) }
|
||||
|
||||
public fun LexicalScope.collectFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor>
|
||||
= collectAllFromMeAndParent { it.getContributedFunctions(name, location) }
|
||||
|
||||
public fun LexicalScope.findVariable(name: Name, location: LookupLocation, predicate: (VariableDescriptor) -> Boolean = { true }): VariableDescriptor? {
|
||||
processForMeAndParent {
|
||||
it.getContributedVariables(name, location).firstOrNull(predicate)?.let { return it }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
public fun LexicalScope.findFunction(name: Name, location: LookupLocation, predicate: (FunctionDescriptor) -> Boolean = { true }): FunctionDescriptor? {
|
||||
processForMeAndParent {
|
||||
it.getContributedFunctions(name, location).firstOrNull(predicate)?.let { return it }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
public fun LexicalScope.takeSnapshot(): LexicalScope = if (this is LexicalWritableScope) takeSnapshot() else this
|
||||
|
||||
public fun LexicalScope.asKtScope(): KtScope {
|
||||
@@ -128,9 +148,8 @@ private class LexicalToKtScopeAdapter(lexicalScope: LexicalScope): KtScope {
|
||||
return lexicalScope.collectAllFromImportingScopes { it.getContributedVariables(name, location) }
|
||||
}
|
||||
|
||||
override fun getFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
return lexicalScope.collectAllFromMeAndParent { it.getContributedFunctions(name, location) }
|
||||
}
|
||||
override fun getFunctions(name: Name, location: LookupLocation)
|
||||
= lexicalScope.collectFunctions(name, location)
|
||||
|
||||
override fun getLocalVariable(name: Name) = lexicalScope.findLocalVariable(name)
|
||||
|
||||
|
||||
@@ -23,16 +23,17 @@ 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.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectFunctions
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectVariables
|
||||
|
||||
|
||||
public fun LexicalScope.getAllAccessibleVariables(name: Name): Collection<VariableDescriptor> {
|
||||
return getVariablesFromImplicitReceivers(name) + collectAllFromMeAndParent { it.getContributedVariables(name, NoLookupLocation.FROM_IDE) }
|
||||
return getVariablesFromImplicitReceivers(name) + collectVariables(name, NoLookupLocation.FROM_IDE)
|
||||
}
|
||||
|
||||
public fun LexicalScope.getAllAccessibleFunctions(name: Name): Collection<FunctionDescriptor> {
|
||||
return getImplicitReceiversWithInstance().flatMap { it.type.memberScope.getFunctions(name, NoLookupLocation.FROM_IDE) } +
|
||||
collectAllFromMeAndParent { it.getContributedFunctions(name, NoLookupLocation.FROM_IDE) }
|
||||
collectFunctions(name, NoLookupLocation.FROM_IDE)
|
||||
}
|
||||
|
||||
public fun LexicalScope.getVariablesFromImplicitReceivers(name: Name): Collection<VariableDescriptor> = getImplicitReceiversWithInstance().flatMap {
|
||||
|
||||
+3
-4
@@ -36,9 +36,9 @@ 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.descriptorUtil.isExtension
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findLocalVariable
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import java.util.*
|
||||
|
||||
@@ -106,8 +106,7 @@ class MultipleArgumentsItemProvider(
|
||||
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.findLocalVariable(name)
|
||||
?: scope.collectAllFromMeAndParent { it.getContributedVariables(name, NoLookupLocation.FROM_IDE) }.singleOrNull()
|
||||
val variable = scope.findVariable(name, NoLookupLocation.FROM_IDE) { !it.isExtension }
|
||||
?: scope.getVariableFromImplicitReceivers(name) ?: return null
|
||||
return if (smartCastCalculator.types(variable).any { KotlinTypeChecker.DEFAULT.isSubtypeOf(it, parameter.getType()) })
|
||||
variable
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.idea.util.nullability
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectFunctions
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.TypeNullability
|
||||
@@ -43,7 +43,7 @@ class TypesWithContainsDetector(
|
||||
private val heuristicSignatures = resolutionFacade.ideService<HeuristicSignatures>()
|
||||
|
||||
private val typesWithExtensionContains: Collection<KotlinType> = scope
|
||||
.collectAllFromMeAndParent { it.getContributedFunctions(containsName, NoLookupLocation.FROM_IDE) }
|
||||
.collectFunctions(containsName, NoLookupLocation.FROM_IDE)
|
||||
.filter { it.getExtensionReceiverParameter() != null && isGoodContainsFunction(it, listOf()) }
|
||||
.map { it.getExtensionReceiverParameter()!!.getType() }
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectFunctions
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
|
||||
@@ -47,7 +47,7 @@ public class IterableTypesDetection(
|
||||
private val cache = HashMap<FuzzyType, FuzzyType?>()
|
||||
|
||||
private val typesWithExtensionIterator: Collection<KotlinType> = scope
|
||||
.collectAllFromMeAndParent { it.getContributedFunctions(iteratorName, NoLookupLocation.FROM_IDE) }
|
||||
.collectFunctions(iteratorName, NoLookupLocation.FROM_IDE)
|
||||
.map { it.extensionReceiverParameter }
|
||||
.filterNotNull()
|
||||
.map { it.type }
|
||||
|
||||
@@ -53,7 +53,8 @@ import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
@@ -230,14 +231,14 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Kotlin
|
||||
val name = originalFqName.shortName()
|
||||
|
||||
if (refData.kind == KotlinReferenceData.Kind.EXTENSION_FUNCTION) {
|
||||
if (fileResolutionScope.parentsWithSelf.any { scope ->
|
||||
scope.getContributedFunctions(name, NoLookupLocation.FROM_IDE).any { it.importableFqName == originalFqName }
|
||||
}) return null // already imported
|
||||
if (fileResolutionScope.findFunction(name, NoLookupLocation.FROM_IDE) { it.importableFqName == originalFqName } != null) {
|
||||
return null // already imported
|
||||
}
|
||||
}
|
||||
else if (refData.kind == KotlinReferenceData.Kind.EXTENSION_PROPERTY) {
|
||||
if (fileResolutionScope.parentsWithSelf.any { scope ->
|
||||
scope.getContributedVariables(name, NoLookupLocation.FROM_IDE).any { it.importableFqName == originalFqName }
|
||||
}) return null // already imported
|
||||
if (fileResolutionScope.findVariable(name, NoLookupLocation.FROM_IDE) { it.importableFqName == originalFqName } != null) {
|
||||
return null // already imported
|
||||
}
|
||||
}
|
||||
|
||||
val referencedDescriptors = try {
|
||||
|
||||
@@ -119,19 +119,17 @@ public class KotlinImportOptimizer() : ImportOptimizer {
|
||||
if (target.containingDeclaration !is ClassDescriptor) return false
|
||||
|
||||
fun isInScope(scope: LexicalScope): Boolean {
|
||||
return scope.parentsWithSelf.any {
|
||||
when (target) {
|
||||
is FunctionDescriptor ->
|
||||
it.getContributedFunctions(target.name, NoLookupLocation.FROM_IDE).contains(target)
|
||||
return when (target) {
|
||||
is FunctionDescriptor ->
|
||||
scope.findFunction(target.name, NoLookupLocation.FROM_IDE) { it == target } != null
|
||||
|
||||
is PropertyDescriptor ->
|
||||
it.getContributedVariables(target.name, NoLookupLocation.FROM_IDE).contains(target)
|
||||
is PropertyDescriptor ->
|
||||
scope.findVariable(target.name, NoLookupLocation.FROM_IDE) { it == target } != null
|
||||
|
||||
is ClassDescriptor ->
|
||||
it.getContributedClassifier(target.name, NoLookupLocation.FROM_IDE) == target
|
||||
is ClassDescriptor ->
|
||||
scope.findClassifier(target.name, NoLookupLocation.FROM_IDE) == target
|
||||
|
||||
else -> false
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
||||
@@ -124,8 +124,7 @@ public class ConvertFunctionToPropertyIntention : JetSelfTargetingIntention<KtNa
|
||||
}
|
||||
|
||||
callableDescriptor.getContainingScope()
|
||||
?.collectAllFromMeAndParent { it.getContributedVariables(callableDescriptor.name, NoLookupLocation.FROM_IDE) }
|
||||
?.firstOrNull()
|
||||
?.findVariable(callableDescriptor.name, NoLookupLocation.FROM_IDE)
|
||||
?.let { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) }
|
||||
?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } }
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
|
||||
import java.util.*
|
||||
|
||||
public class ConvertPropertyToFunctionIntention : JetSelfTargetingIntention<KtProperty>(javaClass(), "Convert property to function"), LowPriorityAction {
|
||||
@@ -103,8 +103,7 @@ public class ConvertPropertyToFunctionIntention : JetSelfTargetingIntention<KtPr
|
||||
|
||||
if (callable is KtProperty) {
|
||||
callableDescriptor.getContainingScope()
|
||||
?.collectAllFromMeAndParent { it.getContributedFunctions(callableDescriptor.name, NoLookupLocation.FROM_IDE) }
|
||||
?.firstOrNull { it.getValueParameters().isEmpty() }
|
||||
?.findFunction(callableDescriptor.name, NoLookupLocation.FROM_IDE) { it.valueParameters.isEmpty() }
|
||||
?.let { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) }
|
||||
?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } }
|
||||
}
|
||||
|
||||
+3
-4
@@ -41,7 +41,7 @@ import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
|
||||
import java.util.*
|
||||
|
||||
public class JetChangeSignatureData(
|
||||
@@ -80,9 +80,8 @@ public class JetChangeSignatureData(
|
||||
val bodyScope = (callable as? KtFunction)?.bodyExpression?.let { it.getResolutionScope(it.analyze(), it.getResolutionFacade()) }
|
||||
val paramNames = baseDescriptor.valueParameters.map { it.name.asString() }
|
||||
val validator = bodyScope?.let { bodyScope ->
|
||||
CollectingNameValidator(paramNames) { name ->
|
||||
val identifier = Name.identifier(name)
|
||||
bodyScope.collectAllFromMeAndParent { it.getContributedVariables(identifier, NoLookupLocation.FROM_IDE) }.isEmpty()
|
||||
CollectingNameValidator(paramNames) {
|
||||
bodyScope.findVariable(Name.identifier(it), NoLookupLocation.FROM_IDE) == null
|
||||
}
|
||||
} ?: CollectingNameValidator(paramNames)
|
||||
val receiverType = baseDescriptor.getExtensionReceiverParameter()?.getType() ?: return null
|
||||
|
||||
@@ -43,8 +43,9 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findPackage
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.processForMeAndParent
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
|
||||
@@ -108,29 +109,20 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert
|
||||
|
||||
private fun isAlreadyImported(target: DeclarationDescriptor, topLevelScope: LexicalScope, targetFqName: FqName): Boolean {
|
||||
val name = target.name
|
||||
when (target) {
|
||||
return when (target) {
|
||||
is ClassDescriptor -> {
|
||||
val classifier = topLevelScope.findClassifier(name, NoLookupLocation.FROM_IDE)
|
||||
if (classifier?.importableFqName == targetFqName) return true
|
||||
classifier?.importableFqName == targetFqName
|
||||
}
|
||||
|
||||
is FunctionDescriptor -> {
|
||||
topLevelScope.processForMeAndParent {
|
||||
if (it.getContributedFunctions(name, NoLookupLocation.FROM_IDE).any { it.importableFqName == targetFqName }) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
is FunctionDescriptor ->
|
||||
topLevelScope.findFunction(name, NoLookupLocation.FROM_IDE) { it.importableFqName == targetFqName } != null
|
||||
|
||||
is PropertyDescriptor -> {
|
||||
topLevelScope.processForMeAndParent {
|
||||
if (it.getContributedVariables(name, NoLookupLocation.FROM_IDE).any { it.importableFqName == targetFqName }) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
is PropertyDescriptor ->
|
||||
topLevelScope.findVariable(name, NoLookupLocation.FROM_IDE) { it.importableFqName == targetFqName } != null
|
||||
|
||||
else -> false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun importDescriptor(descriptor: DeclarationDescriptor): ImportDescriptorResult {
|
||||
|
||||
Reference in New Issue
Block a user