diff --git a/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/KotlinCacheService.kt b/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/KotlinCacheService.kt index 645b4173871..e38c48848cd 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/KotlinCacheService.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/caches/resolve/KotlinCacheService.kt @@ -18,8 +18,10 @@ package org.jetbrains.kotlin.caches.resolve import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.project.Project +import com.intellij.psi.PsiFile import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.diagnostics.KotlinSuppressCache interface KotlinCacheService { @@ -28,6 +30,7 @@ interface KotlinCacheService { } fun getResolutionFacade(elements: List): ResolutionFacade + fun getResolutionFacadeByFile(file: PsiFile, platform: TargetPlatform): ResolutionFacade fun getSuppressionCache(): KotlinSuppressCache } \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt index 93e64fc9e61..7bf099d60bf 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt @@ -21,6 +21,8 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.projectRoots.Sdk import com.intellij.openapi.roots.ProjectRootModificationTracker import com.intellij.openapi.util.ModificationTracker +import com.intellij.psi.PsiCodeFragment +import com.intellij.psi.PsiFile import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager @@ -48,8 +50,9 @@ import org.jetbrains.kotlin.resolve.diagnostics.KotlinSuppressCache import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull -import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList import org.jetbrains.kotlin.utils.addToStdlib.sumByLong +import java.lang.AssertionError +import java.lang.IllegalStateException internal val LOG = Logger.getInstance(KotlinCacheService::class.java) @@ -309,12 +312,25 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService { val syntheticFiles = findSyntheticFiles(files) val file = files.first() val moduleInfo = file.getModuleInfo() - val projectFacade = if (syntheticFiles.isNotEmpty()) { - getFacadeForSyntheticFiles(syntheticFiles) + if (syntheticFiles.isNotEmpty()) { + val projectFacade = getFacadeForSyntheticFiles(syntheticFiles) + return ResolutionFacadeImpl(projectFacade, moduleInfo) } else { - globalFacade(TargetPlatformDetector.getPlatform(file), moduleInfo.sdk) + val platform = TargetPlatformDetector.getPlatform(file) + return getResolutionFacadeByModuleInfo(moduleInfo, platform) } + } + + override fun getResolutionFacadeByFile(file: PsiFile, platform: TargetPlatform): ResolutionFacade { + assert(file !is PsiCodeFragment) + assert(ProjectRootsUtil.isInProjectSource(file)) + val moduleInfo = file.getModuleInfo() + return getResolutionFacadeByModuleInfo(moduleInfo, platform) + } + + private fun getResolutionFacadeByModuleInfo(moduleInfo: IdeaModuleInfo, platform: TargetPlatform): ResolutionFacade { + val projectFacade = globalFacade(platform, moduleInfo.sdk) return ResolutionFacadeImpl(projectFacade, moduleInfo) } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReferencesSearcher.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReferencesSearcher.kt index 11d3735b813..ff58aa60197 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReferencesSearcher.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReferencesSearcher.kt @@ -120,9 +120,8 @@ class KotlinReferencesSearcher : QueryExecutorBase, searchScope: SearchScope, consumer: Processor, diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/ContainsOperatorReferenceSearcher.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/ContainsOperatorReferenceSearcher.kt index 09ae28bc2e2..677dc19f545 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/ContainsOperatorReferenceSearcher.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/ContainsOperatorReferenceSearcher.kt @@ -23,11 +23,14 @@ import com.intellij.psi.search.SearchScope import com.intellij.util.Processor import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtOperationReferenceExpression +import org.jetbrains.kotlin.psi.KtWhenConditionInRange import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance class ContainsOperatorReferenceSearcher( - targetFunction: KtFunction, + targetFunction: PsiElement, searchScope: SearchScope, consumer: Processor, optimizer: SearchRequestCollector diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/DestructuringDeclarationReferenceSearcher.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/DestructuringDeclarationReferenceSearcher.kt index a6d6e7aa96d..1dcfaa79739 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/DestructuringDeclarationReferenceSearcher.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/DestructuringDeclarationReferenceSearcher.kt @@ -22,18 +22,20 @@ import com.intellij.psi.search.SearchRequestCollector import com.intellij.psi.search.SearchScope import com.intellij.util.Processor import org.jetbrains.kotlin.KtNodeTypes +import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.dataClassUtils.getComponentIndex import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance class DestructuringDeclarationReferenceSearcher( - targetDeclaration: KtDeclaration, + targetDeclaration: PsiElement, searchScope: SearchScope, consumer: Processor, optimizer: SearchRequestCollector ) : OperatorReferenceSearcher(targetDeclaration, searchScope, consumer, optimizer, wordsToSearch = listOf("(")) { + //TODO private val componentIndex = when (targetDeclaration) { is KtParameter -> targetDeclaration.dataClassComponentFunction()?.name?.asString()?.let { getComponentIndex(it) } is KtFunction -> targetDeclaration.name?.let { getComponentIndex(it) } @@ -41,6 +43,15 @@ class DestructuringDeclarationReferenceSearcher( else -> null } + override fun resolveTargetToDescriptor(): FunctionDescriptor? { + if (targetDeclaration is KtParameter) { + return targetDeclaration.dataClassComponentFunction() + } + else { + return super.resolveTargetToDescriptor() + } + } + override fun run() { if (componentIndex == null) return super.run() diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/ExpressionsOfTypeProcessor.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/ExpressionsOfTypeProcessor.kt index d3bb9b46f20..0d01e9d7583 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/ExpressionsOfTypeProcessor.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/ExpressionsOfTypeProcessor.kt @@ -20,6 +20,8 @@ import com.intellij.ide.highlighter.JavaFileType import com.intellij.lang.java.JavaLanguage import com.intellij.lang.xml.XMLLanguage import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ProjectRootManager import com.intellij.psi.* import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.LocalSearchScope @@ -30,6 +32,7 @@ import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.toLightClass +import org.jetbrains.kotlin.caches.resolve.KotlinCacheService import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticUtils @@ -39,7 +42,6 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference -import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters import org.jetbrains.kotlin.idea.search.restrictToKotlinSources @@ -51,6 +53,7 @@ import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* +import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.types.KotlinType import java.util.* @@ -59,9 +62,9 @@ import java.util.* class ExpressionsOfTypeProcessor( private val typeToSearch: FuzzyType, private val searchScope: SearchScope, + private val project: Project, private val suspiciousExpressionHandler: (KtExpression) -> Unit, - private val suspiciousScopeHandler: (SearchScope) -> Unit, - private val resolutionFacade: ResolutionFacade + private val suspiciousScopeHandler: (SearchScope) -> Unit ) { enum class Mode { ALWAYS_SMART, @@ -89,9 +92,20 @@ class ExpressionsOfTypeProcessor( else -> fqName } } - } - private val project = resolutionFacade.project + private fun SearchScope.isEmpty(): Boolean { + when (this) { + GlobalSearchScope.EMPTY_SCOPE -> return true + + is GlobalSearchScope -> { + val rootManager = ProjectRootManager.getInstance(project!!) + return rootManager.fileIndex.iterateContent { it.isDirectory || it !in this } + } + + else -> return (this as LocalSearchScope).scope.isEmpty() + } + } + } // note: a Task must define equals & hashCode! private interface Task { @@ -104,6 +118,8 @@ class ExpressionsOfTypeProcessor( private val scopesToUsePlainSearch = LinkedHashMap>() fun run() { + if (searchScope.restrictToKotlinSources().isEmpty()) return // optimization + val classDescriptor = typeToSearch.type.constructor.declarationDescriptor ?: return val classDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, classDescriptor) val psiClass = when (classDeclaration) { @@ -123,7 +139,9 @@ class ExpressionsOfTypeProcessor( processTasks() val scopeElements = scopesToUsePlainSearch.values.flatMap { it }.toTypedArray() - suspiciousScopeHandler(LocalSearchScope(scopeElements)) + if (scopeElements.isNotEmpty()) { + suspiciousScopeHandler(LocalSearchScope(scopeElements)) + } } private fun addTask(task: Task) { @@ -439,6 +457,7 @@ class ExpressionsOfTypeProcessor( if (psiClass != null) { testLog?.add("Resolved java class to descriptor: ${psiClass.qualifiedName}") + val resolutionFacade = KotlinCacheService.getInstance(project).getResolutionFacadeByFile(psiClass.containingFile, JvmPlatform) val classDescriptor = psiClass.resolveToDescriptor(resolutionFacade) if (classDescriptor != null && SingleAbstractMethodUtils.getSingleAbstractMethodOrNull(classDescriptor) != null) { addSamInterfaceToProcess(psiClass) @@ -541,18 +560,23 @@ class ExpressionsOfTypeProcessor( private fun usePlainSearch(scope: KtElement) { val file = scope.getContainingKtFile() - val restricted = LocalSearchScope(scope).intersectWith(searchScope) as LocalSearchScope - ScopeLoop@ - for (element in restricted.scope) { - val prevElements = scopesToUsePlainSearch.getOrPut(file) { ArrayList() } - for ((index, prevElement) in prevElements.withIndex()) { - if (prevElement.isAncestor(element, strict = false)) continue@ScopeLoop - if (element.isAncestor(prevElement)) { - prevElements[index] = element - continue@ScopeLoop + val restricted = LocalSearchScope(scope).intersectWith(searchScope) + if (restricted is LocalSearchScope) { + ScopeLoop@ + for (element in restricted.scope) { + val prevElements = scopesToUsePlainSearch.getOrPut(file) { ArrayList() } + for ((index, prevElement) in prevElements.withIndex()) { + if (prevElement.isAncestor(element, strict = false)) continue@ScopeLoop + if (element.isAncestor(prevElement)) { + prevElements[index] = element + continue@ScopeLoop + } } + prevElements.add(element) } - prevElements.add(element) + } + else { + assert(restricted == GlobalSearchScope.EMPTY_SCOPE) } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/IndexingOperatorReferenceSearcher.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/IndexingOperatorReferenceSearcher.kt index e9c1651f0db..47dfd6fa33f 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/IndexingOperatorReferenceSearcher.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/IndexingOperatorReferenceSearcher.kt @@ -29,7 +29,7 @@ import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance class IndexingOperatorReferenceSearcher( - targetFunction: KtFunction, + targetFunction: PsiElement, searchScope: SearchScope, consumer: Processor, optimizer: SearchRequestCollector, diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/InvokeOperatorReferenceSearcher.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/InvokeOperatorReferenceSearcher.kt index c2a763c0796..3ad0f72a42d 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/InvokeOperatorReferenceSearcher.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/InvokeOperatorReferenceSearcher.kt @@ -17,38 +17,22 @@ package org.jetbrains.kotlin.idea.search.usagesSearch import com.intellij.psi.PsiElement -import com.intellij.psi.PsiMethod import com.intellij.psi.PsiReference import com.intellij.psi.search.SearchRequestCollector import com.intellij.psi.search.SearchScope import com.intellij.util.Processor -import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtExpression -import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance class InvokeOperatorReferenceSearcher( - targetFunction: KtFunction, + targetFunction: PsiElement, searchScope: SearchScope, consumer: Processor, optimizer: SearchRequestCollector ) : OperatorReferenceSearcher(targetFunction, searchScope, consumer, optimizer, wordsToSearch = emptyList()) { - companion object { - fun runForPsiMethod( - invokeFunction: PsiMethod, - scope: SearchScope, - consumer: Processor, - optimizer: SearchRequestCollector - ) { - if (invokeFunction !is KtLightMethod) return //TODO - val ktFunction = invokeFunction.kotlinOrigin as? KtFunction ?: return //TODO? - InvokeOperatorReferenceSearcher(ktFunction, scope, consumer, optimizer).run() - } - } - override fun processSuspiciousExpression(expression: KtExpression) { val callExpression = expression.parent as? KtCallExpression ?: return processReferenceElement(callExpression) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/OperatorReferenceSearch.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/OperatorReferenceSearch.kt index 748c415a6e5..011c3f55f92 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/OperatorReferenceSearch.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/OperatorReferenceSearch.kt @@ -22,10 +22,9 @@ import com.intellij.psi.search.* import com.intellij.util.Processor import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.namedUnwrappedElement -import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade +import org.jetbrains.kotlin.idea.caches.resolve.getJavaOrKotlinMemberDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinRequestResultProcessor @@ -44,7 +43,7 @@ import org.jetbrains.kotlin.util.isValidOperator import java.util.* abstract class OperatorReferenceSearcher( - private val targetDeclaration: KtDeclaration, + protected val targetDeclaration: PsiElement, private val searchScope: SearchScope, private val consumer: Processor, private val optimizer: SearchRequestCollector, @@ -70,47 +69,46 @@ abstract class OperatorReferenceSearcher( } companion object { - fun createForKtFunction( - function: KtFunction, + fun create( + declaration: PsiElement, searchScope: SearchScope, consumer: Processor, optimizer: SearchRequestCollector, options: KotlinReferencesSearchOptions ): OperatorReferenceSearcher<*>? { - val name = function.name ?: return null - return create(function, name, searchScope, consumer, optimizer, options) - } + val functionName = when (declaration) { + is KtNamedFunction -> declaration.name + is PsiMethod -> declaration.name + else -> null + } ?: return null - fun createForPsiMethod( - psiMethod: PsiMethod, - searchScope: SearchScope, - consumer: Processor, - optimizer: SearchRequestCollector, - options: KotlinReferencesSearchOptions - ): OperatorReferenceSearcher<*>? { - if (psiMethod !is KtLightMethod) return null //TODO? - val ktDeclaration = psiMethod.kotlinOrigin as? KtDeclaration ?: return null //TODO? - return create(ktDeclaration, psiMethod.name, searchScope, consumer, optimizer, options) - } - - private fun create( - declaration: KtDeclaration, - functionName: String, - searchScope: SearchScope, - consumer: Processor, - optimizer: SearchRequestCollector, - options: KotlinReferencesSearchOptions - ): OperatorReferenceSearcher<*>? { if (!Name.isValidIdentifier(functionName)) return null val name = Name.identifier(functionName) + val declarationToUse = if (declaration is KtLightMethod) { + declaration.kotlinOrigin ?: return null + } + else { + declaration + } + + return create(declarationToUse, name, consumer, optimizer, options, searchScope) + } + + private fun create( + declaration: PsiElement, + name: Name, + consumer: Processor, + optimizer: SearchRequestCollector, + options: KotlinReferencesSearchOptions, + searchScope: SearchScope + ): OperatorReferenceSearcher<*>? { if (isComponentLike(name)) { if (!options.searchForComponentConventions) return null return DestructuringDeclarationReferenceSearcher(declaration, searchScope, consumer, optimizer) } if (!options.searchForOperatorConventions) return null - if (declaration !is KtFunction) return null if (name == OperatorNameConventions.INVOKE) { return InvokeOperatorReferenceSearcher(declaration, searchScope, consumer, optimizer) @@ -148,16 +146,28 @@ abstract class OperatorReferenceSearcher( return null } - private object SearchesInProgress : ThreadLocal>() { - override fun initialValue() = HashSet() + //TODO: check no light elements here + private object SearchesInProgress : ThreadLocal>() { + override fun initialValue() = HashSet() } } + open protected fun resolveTargetToDescriptor(): FunctionDescriptor? { + return when (targetDeclaration) { + is KtDeclaration -> targetDeclaration.resolveToDescriptor() + is PsiMember -> targetDeclaration.getJavaOrKotlinMemberDescriptor() + else -> null + } as? FunctionDescriptor + } + open fun run() { val inProgress = SearchesInProgress.get() if (!inProgress.add(targetDeclaration)) return //TODO: it's not quite correct try { + val descriptor = resolveTargetToDescriptor() ?: return + if (!descriptor.isValidOperator()) return + val usePlainSearch = when (ExpressionsOfTypeProcessor.mode) { ExpressionsOfTypeProcessor.Mode.ALWAYS_SMART -> false ExpressionsOfTypeProcessor.Mode.ALWAYS_PLAIN -> true @@ -168,9 +178,6 @@ abstract class OperatorReferenceSearcher( return } - val descriptor = targetDeclaration.resolveToDescriptor() as? CallableDescriptor ?: return - if (descriptor is FunctionDescriptor && !descriptor.isValidOperator()) return - val dataType = if (descriptor.isExtension) { descriptor.fuzzyExtensionReceiverType()!! } @@ -182,9 +189,9 @@ abstract class OperatorReferenceSearcher( ExpressionsOfTypeProcessor( dataType, searchScope, + project, suspiciousExpressionHandler = { expression -> processSuspiciousExpression(expression) }, - suspiciousScopeHandler = { searchScope -> doPlainSearch(searchScope) }, - resolutionFacade = targetDeclaration.getResolutionFacade() + suspiciousScopeHandler = { searchScope -> doPlainSearch(searchScope) } ).run() } finally { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/UnaryOperatorReferenceSearcher.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/UnaryOperatorReferenceSearcher.kt index 3b2defa00b7..77c547d07e4 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/UnaryOperatorReferenceSearcher.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/UnaryOperatorReferenceSearcher.kt @@ -29,7 +29,7 @@ import org.jetbrains.kotlin.psi.KtUnaryExpression import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance class UnaryOperatorReferenceSearcher( - targetFunction: KtFunction, + targetFunction: PsiElement, private val operationToken: KtSingleValueToken, searchScope: SearchScope, consumer: Processor, diff --git a/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.kt b/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.kt index 25bd492e936..d649d00cb8f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.kt @@ -22,8 +22,11 @@ import com.intellij.find.findUsages.AbstractFindUsagesDialog import com.intellij.find.findUsages.FindUsagesOptions import com.intellij.find.impl.FindManagerImpl import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.fileTypes.FileTypeManager import com.intellij.psi.PsiElement import com.intellij.psi.PsiReference +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.psi.search.LocalSearchScope import com.intellij.psi.search.SearchScope import com.intellij.psi.search.searches.MethodReferencesSearch import com.intellij.psi.search.searches.ReferencesSearch @@ -32,6 +35,7 @@ import com.intellij.util.* import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ParameterDescriptor +import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.findUsages.KotlinCallableFindUsagesOptions import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory @@ -44,11 +48,10 @@ import org.jetbrains.kotlin.idea.search.declarationsSearch.searchOverriders import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDetector import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters +import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage import org.jetbrains.kotlin.idea.util.application.runReadAction -import org.jetbrains.kotlin.psi.KtCallableDeclaration -import org.jetbrains.kotlin.psi.KtFunction -import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors import org.jetbrains.kotlin.resolve.source.getPsi @@ -131,9 +134,7 @@ abstract class KotlinFindMemberUsagesHandler val uniqueProcessor = CommonProcessors.UniqueProcessor(processor) if (options.isUsages) { - // we disable searchForComponentConventions and searchForOperatorConventions for ReferencesSearch because they will be searched by MethodReferencesSearch val kotlinSearchOptions = createKotlinReferencesSearchOptions(options) - .copy(searchForComponentConventions = false, searchForOperatorConventions = false) val searchParameters = KotlinReferencesSearchParameters(element, options.searchScope, kotlinOptions = kotlinSearchOptions) with(applyQueryFilters(element, options, ReferencesSearch.search(searchParameters))) { @@ -141,7 +142,12 @@ abstract class KotlinFindMemberUsagesHandler } for (psiMethod in runReadAction { element.toLightMethods() }) { - with(applyQueryFilters(element, options, MethodReferencesSearch.search(psiMethod, options.searchScope, true))) { + var searchScope = options.searchScope + // TODO: very bad code!! ReferencesSearch does not work correctly for constructors and annotation parameters + if (element is KtNamedFunction || (element is KtParameter && element.dataClassComponentFunction() != null)) { + searchScope = searchScope.excludeKotlinSources() + } + with(applyQueryFilters(element, options, MethodReferencesSearch.search(psiMethod, searchScope, true))) { if (!forEach(referenceProcessor)) return false } } @@ -156,6 +162,21 @@ abstract class KotlinFindMemberUsagesHandler return true } + private fun SearchScope.excludeKotlinSources(): SearchScope { + if (this is GlobalSearchScope) { + val fileTypes = FileTypeManager.getInstance().registeredFileTypes.filter { it != KotlinFileType.INSTANCE }.toTypedArray() + return GlobalSearchScope.getScopeRestrictedByFileTypes(this, *fileTypes) + } + else { + this as LocalSearchScope + val filteredElements = scope.filter { it.containingFile !is KtFile } + return if (filteredElements.isNotEmpty()) + LocalSearchScope(filteredElements.toTypedArray()) + else + GlobalSearchScope.EMPTY_SCOPE + } + } + protected abstract fun createKotlinReferencesSearchOptions(options: FindUsagesOptions): KotlinReferencesSearchOptions protected abstract fun applyQueryFilters(element: PsiElement, diff --git a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinConventionMethodReferencesSearcher.kt b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinConventionMethodReferencesSearcher.kt index f82b30931aa..16f8e360f47 100644 --- a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinConventionMethodReferencesSearcher.kt +++ b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinConventionMethodReferencesSearcher.kt @@ -35,7 +35,7 @@ class KotlinConventionMethodReferencesSearcher() : QueryExecutorBase