Update index on definition/import files changes
This commit is contained in:
+9
-7
@@ -77,16 +77,18 @@ private fun findCandidateDeclarationsInIndex(
|
|||||||
project: Project,
|
project: Project,
|
||||||
referencedDescriptor: DeclarationDescriptor
|
referencedDescriptor: DeclarationDescriptor
|
||||||
): Collection<KtDeclaration?> {
|
): Collection<KtDeclaration?> {
|
||||||
val scope = GlobalSearchScope.union(
|
val libraryClassFilesScope = KotlinSourceFilterScope.libraryClassFiles(GlobalSearchScope.allScope(project), project)
|
||||||
arrayOf<GlobalSearchScope>(
|
// NOTE: using this scope here and getNoScopeWrap below is hopefully temporary and will be removed after refactoring
|
||||||
KotlinSourceFilterScope.libraryClassFiles(GlobalSearchScope.allScope(project), project),
|
// of searching logic
|
||||||
// NOTE: using this scope here and getNoScopeWrap below is hopefully temporary and will be removed after refactoring
|
val scriptsScope = KotlinScriptConfigurationManager.getInstance(project).getAllScriptsClasspathScope()
|
||||||
// of searching logic
|
val scope = scriptsScope?.let { GlobalSearchScope.union( arrayOf(libraryClassFilesScope, it)) } ?: libraryClassFilesScope
|
||||||
KotlinScriptConfigurationManager.getInstance(project).getAllScriptsClasspathScope()))
|
|
||||||
|
|
||||||
val containingClass = DescriptorUtils.getParentOfType(referencedDescriptor, ClassDescriptor::class.java, false)
|
val containingClass = DescriptorUtils.getParentOfType(referencedDescriptor, ClassDescriptor::class.java, false)
|
||||||
if (containingClass != null) {
|
if (containingClass != null) {
|
||||||
return KotlinFullClassNameIndex.getInstance().getNoScopeWrap(containingClass.fqNameSafe.asString(), project, scope)
|
return if (scriptsScope != null)
|
||||||
|
KotlinFullClassNameIndex.getInstance().getNoScopeWrap(containingClass.fqNameSafe.asString(), project, scope)
|
||||||
|
else
|
||||||
|
KotlinFullClassNameIndex.getInstance().get(containingClass.fqNameSafe.asString(), project, scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
val topLevelDeclaration = DescriptorUtils.getParentOfType(referencedDescriptor, PropertyDescriptor::class.java, false)
|
val topLevelDeclaration = DescriptorUtils.getParentOfType(referencedDescriptor, PropertyDescriptor::class.java, false)
|
||||||
|
|||||||
+44
-23
@@ -19,9 +19,9 @@ package org.jetbrains.kotlin.idea.script
|
|||||||
import com.intellij.openapi.components.AbstractProjectComponent
|
import com.intellij.openapi.components.AbstractProjectComponent
|
||||||
import com.intellij.openapi.components.ServiceManager
|
import com.intellij.openapi.components.ServiceManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.vfs.StandardFileSystems
|
import com.intellij.openapi.roots.ex.ProjectRootManagerEx
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.util.EmptyRunnable
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
import com.intellij.openapi.vfs.*
|
||||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener
|
import com.intellij.openapi.vfs.newvfs.BulkFileListener
|
||||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
@@ -31,11 +31,14 @@ import org.jetbrains.kotlin.idea.caches.resolve.FileLibraryScope
|
|||||||
import org.jetbrains.kotlin.script.*
|
import org.jetbrains.kotlin.script.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.OutputStream
|
||||||
|
|
||||||
@Suppress("unused") // project component
|
@Suppress("unused") // project component
|
||||||
class KotlinScriptConfigurationManager(private val project: Project,
|
class KotlinScriptConfigurationManager(private val project: Project,
|
||||||
private val scriptDefinitionProvider: KotlinScriptDefinitionProvider,
|
private val scriptDefinitionProvider: KotlinScriptDefinitionProvider,
|
||||||
private val scriptExtraImportsProvider: KotlinScriptExtraImportsProvider?
|
private val scriptExtraImportsProvider: KotlinScriptExtraImportsProvider?,
|
||||||
|
private val kotlinScriptDependenciesIndexableSetContributor: KotlinScriptDependenciesIndexableSetContributor?
|
||||||
) : AbstractProjectComponent(project) {
|
) : AbstractProjectComponent(project) {
|
||||||
|
|
||||||
private val kotlinEnvVars: Map<String, List<String>> by lazy { generateKotlinScriptClasspathEnvVarsForIdea(myProject) }
|
private val kotlinEnvVars: Map<String, List<String>> by lazy { generateKotlinScriptClasspathEnvVarsForIdea(myProject) }
|
||||||
@@ -45,6 +48,7 @@ class KotlinScriptConfigurationManager(private val project: Project,
|
|||||||
val conn = myProject.messageBus.connect()
|
val conn = myProject.messageBus.connect()
|
||||||
conn.subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() {
|
conn.subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() {
|
||||||
override fun after(events: List<VFileEvent>) {
|
override fun after(events: List<VFileEvent>) {
|
||||||
|
var anyScriptExtraImportsChanged = false
|
||||||
var anyScriptDefinitionChanged = false
|
var anyScriptDefinitionChanged = false
|
||||||
events.filter { it is VFileEvent }.forEach {
|
events.filter { it is VFileEvent }.forEach {
|
||||||
it.file?.let {
|
it.file?.let {
|
||||||
@@ -54,6 +58,9 @@ class KotlinScriptConfigurationManager(private val project: Project,
|
|||||||
scriptExtraImportsProvider?.run {
|
scriptExtraImportsProvider?.run {
|
||||||
if (isExtraImportsConfig(it)) {
|
if (isExtraImportsConfig(it)) {
|
||||||
invalidateExtraImports(it)
|
invalidateExtraImports(it)
|
||||||
|
if (!anyScriptExtraImportsChanged) {
|
||||||
|
anyScriptExtraImportsChanged = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,17 +68,23 @@ class KotlinScriptConfigurationManager(private val project: Project,
|
|||||||
if (anyScriptDefinitionChanged) {
|
if (anyScriptDefinitionChanged) {
|
||||||
reloadScriptDefinitions()
|
reloadScriptDefinitions()
|
||||||
}
|
}
|
||||||
|
if (anyScriptExtraImportsChanged) {
|
||||||
|
ProjectRootManagerEx.getInstanceEx(project)?.makeRootsChange(EmptyRunnable.getInstance(), false, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: cache
|
private val scriptClasspathCache = hashMapOf<VirtualFile, List<VirtualFile>>()
|
||||||
fun getScriptClasspath(file: VirtualFile): List<VirtualFile> =
|
private var allScriptsClasspathCache: List<VirtualFile>? = null
|
||||||
getScriptClasspathRaw(file)
|
|
||||||
.mapNotNull { StandardFileSystems.local().findFileByPath(it) }
|
fun getScriptClasspath(file: VirtualFile): List<VirtualFile> =
|
||||||
.distinct()
|
scriptClasspathCache.getOrPut(file, {
|
||||||
|
getScriptClasspathRaw(file)
|
||||||
|
.mapNotNull { StandardFileSystems.local().findFileByPath(it) }
|
||||||
|
.distinct()
|
||||||
|
})
|
||||||
|
|
||||||
// TODO: cache
|
|
||||||
fun getAllScriptsClasspath(): List<VirtualFile> {
|
fun getAllScriptsClasspath(): List<VirtualFile> {
|
||||||
fun<R> VirtualFile.vfsWalkFiles(onFile: (VirtualFile) -> List<R>?): List<R> {
|
fun<R> VirtualFile.vfsWalkFiles(onFile: (VirtualFile) -> List<R>?): List<R> {
|
||||||
assert(isDirectory)
|
assert(isDirectory)
|
||||||
@@ -80,19 +93,26 @@ class KotlinScriptConfigurationManager(private val project: Project,
|
|||||||
else -> onFile(it) ?: emptyList()
|
else -> onFile(it) ?: emptyList()
|
||||||
} }
|
} }
|
||||||
}
|
}
|
||||||
return project.baseDir.vfsWalkFiles { getScriptClasspathRaw(it) }
|
if (allScriptsClasspathCache == null) {
|
||||||
.distinct()
|
allScriptsClasspathCache = project.baseDir.vfsWalkFiles { getScriptClasspathRaw(it) }
|
||||||
.mapNotNull {
|
.distinct()
|
||||||
if (File(it).isDirectory)
|
.mapNotNull {
|
||||||
StandardFileSystems.local()?.findFileByPath(it) ?: throw FileNotFoundException("Classpath entry points to a non-existent location: $it")
|
if (File(it).isDirectory)
|
||||||
else
|
StandardFileSystems.local()?.findFileByPath(it) ?: throw FileNotFoundException("Classpath entry points to a non-existent location: $it")
|
||||||
StandardFileSystems.jar()?.findFileByPath(it + URLUtil.JAR_SEPARATOR) ?: throw FileNotFoundException("Classpath entry points to a file that is not a JAR archive: $it")
|
else
|
||||||
|
StandardFileSystems.jar()?.findFileByPath(it + URLUtil.JAR_SEPARATOR) ?: throw FileNotFoundException("Classpath entry points to a file that is not a JAR archive: $it")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return allScriptsClasspathCache!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAllScriptsClasspathScope(): GlobalSearchScope =
|
fun getAllScriptsClasspathScope(): GlobalSearchScope? {
|
||||||
GlobalSearchScope.union(getAllScriptsClasspath().map { FileLibraryScope(project, it) }.toTypedArray())
|
return getAllScriptsClasspath().let { cp ->
|
||||||
|
if (cp.isEmpty()) null
|
||||||
|
else GlobalSearchScope.union(cp.map { FileLibraryScope(project, it) }.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getScriptClasspathRaw(file: VirtualFile): List<String> =
|
private fun getScriptClasspathRaw(file: VirtualFile): List<String> =
|
||||||
scriptDefinitionProvider.findScriptDefinition(file)?.getScriptDependenciesClasspath()?.let {
|
scriptDefinitionProvider.findScriptDefinition(file)?.getScriptDependenciesClasspath()?.let {
|
||||||
@@ -118,9 +138,10 @@ class KotlinScriptConfigurationManager(private val project: Project,
|
|||||||
|
|
||||||
class KotlinScriptDependenciesIndexableSetContributor : IndexableSetContributor() {
|
class KotlinScriptDependenciesIndexableSetContributor : IndexableSetContributor() {
|
||||||
|
|
||||||
override fun getAdditionalProjectRootsToIndex(project: Project): Set<VirtualFile> =
|
override fun getAdditionalProjectRootsToIndex(project: Project): Set<VirtualFile> {
|
||||||
super.getAdditionalProjectRootsToIndex(project) +
|
return super.getAdditionalProjectRootsToIndex(project) +
|
||||||
KotlinScriptConfigurationManager.getInstance(project).getAllScriptsClasspath()
|
KotlinScriptConfigurationManager.getInstance(project).getAllScriptsClasspath()
|
||||||
|
}
|
||||||
|
|
||||||
override fun getAdditionalRootsToIndex(): Set<VirtualFile> = emptySet()
|
override fun getAdditionalRootsToIndex(): Set<VirtualFile> = emptySet()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user