Ide Scopes: Allow including script dependencies into search scope
This includes script dependencies into scopes for some of the IDE services Should be revisited later to decide if given service should work for scripts
This commit is contained in:
+1
-1
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.SourceNavigationHelper
|
||||
import org.jetbrains.kotlin.idea.project.ResolveElementCache
|
||||
import org.jetbrains.kotlin.idea.stubindex.*
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope.sourceAndClassFiles
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope.Companion.sourceAndClassFiles
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||
|
||||
+1
@@ -108,6 +108,7 @@ private fun PsiElement.getJavaDescriptorResolver(resolutionFacade: ResolutionFac
|
||||
return resolutionFacade.getFrontendService(this, JavaDescriptorResolver::class.java)
|
||||
}
|
||||
else {
|
||||
//TODO_R: should this work in scripts?
|
||||
if (!ProjectRootsUtil.isInProjectOrLibraryClassFile(this)) return null
|
||||
|
||||
val cacheService = KotlinCacheService.getInstance(project)
|
||||
|
||||
@@ -31,7 +31,7 @@ fun getResolveScope(file: KtFile): GlobalSearchScope {
|
||||
}
|
||||
|
||||
return when (file.getModuleInfo()) {
|
||||
is ModuleSourceInfo -> KotlinSourceFilterScope.sourceAndClassFiles(file.resolveScope, file.project)
|
||||
is ModuleSourceInfo -> KotlinSourceFilterScope.projectSourceAndClassFiles(file.resolveScope, file.project)
|
||||
is ScriptModuleInfo -> file.getModuleInfo().contentScope()
|
||||
else -> GlobalSearchScope.EMPTY_SCOPE
|
||||
}
|
||||
|
||||
+34
-32
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,67 +29,69 @@ class KotlinSourceFilterScope private constructor(
|
||||
private val includeProjectSourceFiles: Boolean,
|
||||
private val includeLibrarySourceFiles: Boolean,
|
||||
private val includeClassFiles: Boolean,
|
||||
private val project: Project) : DelegatingGlobalSearchScope(delegate) {
|
||||
private val includeScriptDependencies: Boolean,
|
||||
private val project: Project
|
||||
) : DelegatingGlobalSearchScope(delegate) {
|
||||
|
||||
private val index = ProjectRootManager.getInstance(project).fileIndex
|
||||
|
||||
//NOTE: avoid recomputing in potentially bottleneck 'contains' method
|
||||
private val isJsProjectRef = Ref<Boolean?>(null)
|
||||
|
||||
override fun getProject(): Project? {
|
||||
return project
|
||||
}
|
||||
override fun getProject() = project
|
||||
|
||||
override fun contains(file: VirtualFile): Boolean {
|
||||
if (!super.contains(file)) return false
|
||||
|
||||
return ProjectRootsUtil.isInContent(
|
||||
project, file, includeProjectSourceFiles, includeLibrarySourceFiles, includeClassFiles, index, isJsProjectRef)
|
||||
project, file, includeProjectSourceFiles, includeLibrarySourceFiles, includeClassFiles, includeScriptDependencies, index, isJsProjectRef
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun sourcesAndLibraries(delegate: GlobalSearchScope, project: Project): GlobalSearchScope {
|
||||
return create(delegate, true, true, true, project)
|
||||
}
|
||||
@JvmStatic
|
||||
fun sourcesAndLibraries(delegate: GlobalSearchScope, project: Project) = create(delegate, true, true, true, true, project)
|
||||
|
||||
fun sourceAndClassFiles(delegate: GlobalSearchScope, project: Project): GlobalSearchScope {
|
||||
return create(delegate, true, false, true, project)
|
||||
}
|
||||
@JvmStatic
|
||||
fun sourceAndClassFiles(delegate: GlobalSearchScope, project: Project) = create(delegate, true, false, true, true, project)
|
||||
|
||||
fun sources(delegate: GlobalSearchScope, project: Project): GlobalSearchScope {
|
||||
return create(delegate, true, false, false, project)
|
||||
}
|
||||
@JvmStatic
|
||||
fun projectSourceAndClassFiles(delegate: GlobalSearchScope, project: Project) = create(delegate, true, false, true, false, project)
|
||||
|
||||
fun librarySources(delegate: GlobalSearchScope, project: Project): GlobalSearchScope {
|
||||
return create(delegate, false, true, false, project)
|
||||
}
|
||||
@JvmStatic
|
||||
fun sources(delegate: GlobalSearchScope, project: Project) = create(delegate, true, false, false, true, project)
|
||||
|
||||
fun libraryClassFiles(delegate: GlobalSearchScope, project: Project): GlobalSearchScope {
|
||||
return create(delegate, false, false, true, project)
|
||||
}
|
||||
@JvmStatic
|
||||
fun projectSources(delegate: GlobalSearchScope, project: Project) = create(delegate, true, false, false, false, project)
|
||||
|
||||
@JvmStatic
|
||||
fun librarySources(delegate: GlobalSearchScope, project: Project) = create(delegate, false, true, false, true, project)
|
||||
|
||||
@JvmStatic
|
||||
fun libraryClassFiles(delegate: GlobalSearchScope, project: Project) = create(delegate, false, false, true, true, project)
|
||||
|
||||
private fun create(
|
||||
delegate: GlobalSearchScope,
|
||||
includeProjectSourceFiles: Boolean,
|
||||
includeLibrarySourceFiles: Boolean,
|
||||
includeClassFiles: Boolean,
|
||||
includeScriptDependencies: Boolean,
|
||||
project: Project
|
||||
): GlobalSearchScope {
|
||||
if (delegate === GlobalSearchScope.EMPTY_SCOPE) return delegate
|
||||
|
||||
if (delegate is KotlinSourceFilterScope) {
|
||||
|
||||
val doIncludeProjectSourceFiles = delegate.includeProjectSourceFiles && includeProjectSourceFiles
|
||||
val doIncludeLibrarySourceFiles = delegate.includeLibrarySourceFiles && includeLibrarySourceFiles
|
||||
val doIncludeClassFiles = delegate.includeClassFiles && includeClassFiles
|
||||
|
||||
return KotlinSourceFilterScope(delegate.myBaseScope,
|
||||
doIncludeProjectSourceFiles,
|
||||
doIncludeLibrarySourceFiles,
|
||||
doIncludeClassFiles,
|
||||
project)
|
||||
return KotlinSourceFilterScope(
|
||||
delegate.myBaseScope,
|
||||
includeProjectSourceFiles = delegate.includeProjectSourceFiles && includeProjectSourceFiles,
|
||||
includeLibrarySourceFiles = delegate.includeLibrarySourceFiles && includeLibrarySourceFiles,
|
||||
includeClassFiles = delegate.includeClassFiles && includeClassFiles,
|
||||
includeScriptDependencies = delegate.includeScriptDependencies && includeScriptDependencies,
|
||||
project = project
|
||||
)
|
||||
}
|
||||
|
||||
return KotlinSourceFilterScope(delegate, includeProjectSourceFiles, includeLibrarySourceFiles, includeClassFiles, project)
|
||||
return KotlinSourceFilterScope(delegate, includeProjectSourceFiles, includeLibrarySourceFiles, includeClassFiles, includeScriptDependencies, project)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,29 +24,38 @@ import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.KotlinModuleFileType
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.JsProjectDetector
|
||||
import org.jetbrains.kotlin.idea.core.script.KotlinScriptConfigurationManager
|
||||
import org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInFileType
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
|
||||
private val classFileLike = listOf(JavaClassFileType.INSTANCE, KotlinBuiltInFileType)
|
||||
private val classFileLike = listOf(JavaClassFileType.INSTANCE, KotlinBuiltInFileType, KotlinModuleFileType.INSTANCE)
|
||||
|
||||
object ProjectRootsUtil {
|
||||
@JvmStatic fun isInContent(project: Project, file: VirtualFile, includeProjectSource: Boolean,
|
||||
includeLibrarySource: Boolean, includeLibraryClasses: Boolean,
|
||||
includeScriptDependencies: Boolean,
|
||||
fileIndex: ProjectFileIndex = ProjectFileIndex.SERVICE.getInstance(project),
|
||||
isJsProjectRef: Ref<Boolean?>? = null): Boolean {
|
||||
if (includeProjectSource && fileIndex.isInSourceContent(file)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (includeProjectSource && fileIndex.isInSourceContent(file)) return true
|
||||
|
||||
if (!includeLibraryClasses && !includeLibrarySource) return false
|
||||
|
||||
// NOTE: the following is a workaround for cases when class files are under library source roots and source files are under class roots
|
||||
val canContainClassFiles = file.fileType == ArchiveFileType.INSTANCE || file.isDirectory
|
||||
val isClassFile = file.fileType in classFileLike
|
||||
|
||||
if ((includeLibraryClasses && (isClassFile || canContainClassFiles) && fileIndex.isInLibraryClasses(file)) ||
|
||||
(includeLibrarySource && !isClassFile && fileIndex.isInLibrarySource(file))) {
|
||||
val scriptConfigurationManager = if (includeScriptDependencies) KotlinScriptConfigurationManager.getInstance(project) else null
|
||||
|
||||
return true
|
||||
if (includeLibraryClasses && (isClassFile || canContainClassFiles)) {
|
||||
if (fileIndex.isInLibraryClasses(file)) return true
|
||||
if (scriptConfigurationManager?.getAllScriptsClasspathScope()?.contains(file) == true) return true
|
||||
}
|
||||
if (includeLibrarySource && !isClassFile) {
|
||||
if (fileIndex.isInLibrarySource(file)) return true
|
||||
if (scriptConfigurationManager?.getAllLibrarySourcesScope()?.contains(file) == true) return true
|
||||
}
|
||||
|
||||
if ((includeLibraryClasses && fileIndex.isInLibraryClasses(file)) ||
|
||||
@@ -65,7 +74,8 @@ object ProjectRootsUtil {
|
||||
element: PsiElement,
|
||||
includeProjectSource: Boolean,
|
||||
includeLibrarySource: Boolean,
|
||||
includeLibraryClasses: Boolean
|
||||
includeLibraryClasses: Boolean,
|
||||
includeScriptDependencies: Boolean
|
||||
): Boolean {
|
||||
return runReadAction {
|
||||
val virtualFile = when (element) {
|
||||
@@ -74,39 +84,39 @@ object ProjectRootsUtil {
|
||||
} ?: return@runReadAction false
|
||||
|
||||
val project = element.project
|
||||
return@runReadAction isInContent(project, virtualFile, includeProjectSource, includeLibrarySource, includeLibraryClasses)
|
||||
return@runReadAction isInContent(project, virtualFile, includeProjectSource, includeLibrarySource, includeLibraryClasses, includeScriptDependencies)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic fun isInProjectSource(element: PsiElement): Boolean {
|
||||
return isInContent(element, includeProjectSource = true, includeLibrarySource = false, includeLibraryClasses = false)
|
||||
return isInContent(element, includeProjectSource = true, includeLibrarySource = false, includeLibraryClasses = false, includeScriptDependencies = false)
|
||||
}
|
||||
|
||||
@JvmStatic fun isProjectSourceFile(project: Project, file: VirtualFile): Boolean {
|
||||
return isInContent(project, file, includeProjectSource = true, includeLibrarySource = false, includeLibraryClasses = false)
|
||||
return isInContent(project, file, includeProjectSource = true, includeLibrarySource = false, includeLibraryClasses = false, includeScriptDependencies = false)
|
||||
}
|
||||
|
||||
@JvmStatic fun isInProjectOrLibSource(element: PsiElement): Boolean {
|
||||
return isInContent(element, includeProjectSource = true, includeLibrarySource = true, includeLibraryClasses = false)
|
||||
return isInContent(element, includeProjectSource = true, includeLibrarySource = true, includeLibraryClasses = false, includeScriptDependencies = false)
|
||||
}
|
||||
|
||||
@JvmStatic fun isInProjectOrLibraryContent(element: PsiElement): Boolean {
|
||||
return isInContent(element, includeProjectSource = true, includeLibrarySource = true, includeLibraryClasses = true)
|
||||
return isInContent(element, includeProjectSource = true, includeLibrarySource = true, includeLibraryClasses = true, includeScriptDependencies = true)
|
||||
}
|
||||
|
||||
@JvmStatic fun isInProjectOrLibraryClassFile(element: PsiElement): Boolean {
|
||||
return isInContent(element, includeProjectSource = true, includeLibrarySource = false, includeLibraryClasses = true)
|
||||
return isInContent(element, includeProjectSource = true, includeLibrarySource = false, includeLibraryClasses = true, includeScriptDependencies = false)
|
||||
}
|
||||
|
||||
@JvmStatic fun isLibraryClassFile(project: Project, file: VirtualFile): Boolean {
|
||||
return isInContent(project, file, includeProjectSource = false, includeLibrarySource = false, includeLibraryClasses = true)
|
||||
return isInContent(project, file, includeProjectSource = false, includeLibrarySource = false, includeLibraryClasses = true, includeScriptDependencies = true)
|
||||
}
|
||||
|
||||
@JvmStatic fun isLibrarySourceFile(project: Project, file: VirtualFile): Boolean {
|
||||
return isInContent(project, file, includeProjectSource = false, includeLibrarySource = true, includeLibraryClasses = false)
|
||||
return isInContent(project, file, includeProjectSource = false, includeLibrarySource = true, includeLibraryClasses = false, includeScriptDependencies = true)
|
||||
}
|
||||
|
||||
@JvmStatic fun isLibraryFile(project: Project, file: VirtualFile): Boolean {
|
||||
return isInContent(project, file, includeProjectSource = false, includeLibrarySource = true, includeLibraryClasses = true)
|
||||
return isInContent(project, file, includeProjectSource = false, includeLibrarySource = true, includeLibraryClasses = true, includeScriptDependencies = true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class KotlinGotoClassContributor : GotoClassContributor {
|
||||
|
||||
override fun getItemsByName(name: String, pattern: String, project: Project, includeNonProjectItems: Boolean): Array<NavigationItem> {
|
||||
val scope = if (includeNonProjectItems) GlobalSearchScope.allScope(project) else GlobalSearchScope.projectScope(project)
|
||||
val classesOrObjects = KotlinClassShortNameIndex.getInstance().get(name, project, KotlinSourceFilterScope.sourceAndClassFiles(scope, project))
|
||||
val classesOrObjects = KotlinClassShortNameIndex.getInstance().get(name, project, KotlinSourceFilterScope.projectSourceAndClassFiles(scope, project))
|
||||
|
||||
if (classesOrObjects.isEmpty()) return NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY
|
||||
|
||||
@@ -73,7 +73,7 @@ class KotlinGotoSymbolContributor : ChooseByNameContributor {
|
||||
|
||||
override fun getItemsByName(name: String, pattern: String, project: Project, includeNonProjectItems: Boolean): Array<NavigationItem> {
|
||||
val baseScope = if (includeNonProjectItems) GlobalSearchScope.allScope(project) else GlobalSearchScope.projectScope(project)
|
||||
val noLibrarySourceScope = KotlinSourceFilterScope.sourceAndClassFiles(baseScope, project)
|
||||
val noLibrarySourceScope = KotlinSourceFilterScope.projectSourceAndClassFiles(baseScope, project)
|
||||
|
||||
val result = ArrayList<NavigationItem>()
|
||||
result += KotlinFunctionShortNameIndex.getInstance().get(name, project, noLibrarySourceScope)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -193,7 +193,7 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection(), Clean
|
||||
object : Task.Modal(project, "Searching for imports to delete", true) {
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
val importsToDelete = runReadAction {
|
||||
val searchScope = KotlinSourceFilterScope.sources(GlobalSearchScope.projectScope(project), project)
|
||||
val searchScope = KotlinSourceFilterScope.projectSources(GlobalSearchScope.projectScope(project), project)
|
||||
ReferencesSearch.search(declaration, searchScope)
|
||||
.filterIsInstance<KtSimpleNameReference>()
|
||||
.mapNotNull { ref -> ref.expression.getStrictParentOfType<KtImportDirective>() }
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ class DeprecatedSymbolUsageInWholeProjectFix(
|
||||
object : Task.Modal(project, "Applying '$text'", true) {
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
val usages = runReadAction {
|
||||
val searchScope = KotlinSourceFilterScope.sources(GlobalSearchScope.projectScope(project), project)
|
||||
val searchScope = KotlinSourceFilterScope.projectSources(GlobalSearchScope.projectScope(project), project)
|
||||
ReferencesSearch.search(psiElement, searchScope)
|
||||
.filterIsInstance<KtSimpleNameReference>()
|
||||
.map { ref -> ref.expression }
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +44,7 @@ open class KotlinDirectInheritorsSearcher() : QueryExecutorBase<PsiClass, Direct
|
||||
if (scope == null) return
|
||||
|
||||
runReadAction {
|
||||
val noLibrarySourceScope = KotlinSourceFilterScope.sourceAndClassFiles(scope, baseClass.project)
|
||||
val noLibrarySourceScope = KotlinSourceFilterScope.projectSourceAndClassFiles(scope, baseClass.project)
|
||||
KotlinSuperClassIndex.getInstance()
|
||||
.get(name, baseClass.project, noLibrarySourceScope).asSequence()
|
||||
.mapNotNull { candidate -> SourceNavigationHelper.getOriginalPsiClassOrCreateLightClass(candidate) }
|
||||
|
||||
Reference in New Issue
Block a user