Prepare infrastruct for fixing customized script resolving
Move ConfigManager and ClassFinder to the idea-analysis Add (back) IndexableSetContributor Add a method in ConfigManager to generate all dependencies scope Add and use delegating scope with possibility to get base scope from it (used in the class finder)
This commit is contained in:
@@ -61,9 +61,20 @@ public class JavaClassFinderImpl implements JavaClassFinder {
|
|||||||
// Only activate post create
|
// Only activate post create
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class DelegatingGlobalSearchScopeWithBaseAccess extends DelegatingGlobalSearchScope {
|
||||||
|
|
||||||
|
public DelegatingGlobalSearchScopeWithBaseAccess(@NotNull GlobalSearchScope baseScope) {
|
||||||
|
super(baseScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalSearchScope getBase() {
|
||||||
|
return myBaseScope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
javaSearchScope = new DelegatingGlobalSearchScope(baseScope) {
|
javaSearchScope = new DelegatingGlobalSearchScopeWithBaseAccess(baseScope) {
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(@NotNull VirtualFile file) {
|
public boolean contains(@NotNull VirtualFile file) {
|
||||||
return myBaseScope.contains(file) && (file.isDirectory() || file.getFileType() != KotlinFileType.INSTANCE);
|
return myBaseScope.contains(file) && (file.isDirectory() || file.getFileType() != KotlinFileType.INSTANCE);
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ internal data class CustomizedScriptModuleInfo(val project: Project, val module:
|
|||||||
}) ?: emptyList())
|
}) ?: emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FileLibraryScope(project: Project, private val libraryRoot: VirtualFile) : GlobalSearchScope(project) {
|
class FileLibraryScope(project: Project, private val libraryRoot: VirtualFile) : GlobalSearchScope(project) {
|
||||||
val cachedEntries : MutableSet<VirtualFile> = hashSetOf()
|
val cachedEntries : MutableSet<VirtualFile> = hashSetOf()
|
||||||
|
|
||||||
override fun contains(file: VirtualFile): Boolean =
|
override fun contains(file: VirtualFile): Boolean =
|
||||||
|
|||||||
+31
-1
@@ -17,14 +17,20 @@
|
|||||||
package org.jetbrains.kotlin.idea.script
|
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.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.vfs.StandardFileSystems
|
import com.intellij.openapi.vfs.StandardFileSystems
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
import com.intellij.openapi.vfs.VirtualFileManager
|
||||||
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.util.indexing.IndexableSetContributor
|
||||||
|
import com.intellij.util.io.URLUtil
|
||||||
|
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
|
||||||
|
|
||||||
@Suppress("unused") // project component
|
@Suppress("unused") // project component
|
||||||
class KotlinScriptConfigurationManager(private val project: Project,
|
class KotlinScriptConfigurationManager(private val project: Project,
|
||||||
@@ -75,10 +81,19 @@ class KotlinScriptConfigurationManager(private val project: Project,
|
|||||||
} }
|
} }
|
||||||
}
|
}
|
||||||
return project.baseDir.vfsWalkFiles { getScriptClasspathRaw(it) }
|
return project.baseDir.vfsWalkFiles { getScriptClasspathRaw(it) }
|
||||||
.mapNotNull { StandardFileSystems.local()?.findFileByPath(it) }
|
|
||||||
.distinct()
|
.distinct()
|
||||||
|
.mapNotNull {
|
||||||
|
if (File(it).isDirectory)
|
||||||
|
StandardFileSystems.local()?.findFileByPath(it) ?: throw FileNotFoundException("Classpath entry points to a non-existent location: $it")
|
||||||
|
else
|
||||||
|
StandardFileSystems.jar()?.findFileByPath(it + URLUtil.JAR_SEPARATOR) ?: throw FileNotFoundException("Classpath entry points to a file that is not a JAR archive: $it")
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getAllScriptsClasspathScope(): GlobalSearchScope =
|
||||||
|
GlobalSearchScope.union(getAllScriptsClasspath().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 {
|
||||||
it + (scriptExtraImportsProvider?.getExtraImports(file)?.flatMap { it.classpath } ?: emptyList())
|
it + (scriptExtraImportsProvider?.getExtraImports(file)?.flatMap { it.classpath } ?: emptyList())
|
||||||
@@ -92,6 +107,21 @@ class KotlinScriptConfigurationManager(private val project: Project,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun getInstance(project: Project): KotlinScriptConfigurationManager =
|
||||||
|
project.getComponent(KotlinScriptConfigurationManager::class.java)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class KotlinScriptDependenciesIndexableSetContributor : IndexableSetContributor() {
|
||||||
|
|
||||||
|
override fun getAdditionalProjectRootsToIndex(project: Project): Set<VirtualFile> =
|
||||||
|
super.getAdditionalProjectRootsToIndex(project) +
|
||||||
|
KotlinScriptConfigurationManager.getInstance(project).getAllScriptsClasspath()
|
||||||
|
|
||||||
|
override fun getAdditionalRootsToIndex(): Set<VirtualFile> = emptySet()
|
||||||
|
}
|
||||||
|
|
||||||
+13
-2
@@ -26,6 +26,7 @@ import com.intellij.psi.search.EverythingGlobalScope
|
|||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.util.containers.ConcurrentFactoryMap
|
import com.intellij.util.containers.ConcurrentFactoryMap
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.CustomizedScriptModuleSearchScope
|
import org.jetbrains.kotlin.idea.caches.resolve.CustomizedScriptModuleSearchScope
|
||||||
|
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl
|
||||||
|
|
||||||
@Suppress("unused") // project extension
|
@Suppress("unused") // project extension
|
||||||
class KotlinScriptDependenciesClassFinder(project: Project,
|
class KotlinScriptDependenciesClassFinder(project: Project,
|
||||||
@@ -33,13 +34,22 @@ class KotlinScriptDependenciesClassFinder(project: Project,
|
|||||||
) : NonClasspathClassFinder(project) {
|
) : NonClasspathClassFinder(project) {
|
||||||
|
|
||||||
private val myCaches = object : ConcurrentFactoryMap<VirtualFile, PackageDirectoryCache>() {
|
private val myCaches = object : ConcurrentFactoryMap<VirtualFile, PackageDirectoryCache>() {
|
||||||
override fun create(file: VirtualFile): PackageDirectoryCache? = NonClasspathClassFinder.createCache( kotlinScriptConfigurationManager.getScriptClasspath(file))
|
override fun create(file: VirtualFile): PackageDirectoryCache? {
|
||||||
|
|
||||||
|
val scriptClasspath = kotlinScriptConfigurationManager.getScriptClasspath(file)
|
||||||
|
val v = NonClasspathClassFinder.createCache(scriptClasspath)
|
||||||
|
return v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun calcClassRoots(): List<VirtualFile> = kotlinScriptConfigurationManager.getAllScriptsClasspath()
|
override fun calcClassRoots(): List<VirtualFile> = kotlinScriptConfigurationManager.getAllScriptsClasspath()
|
||||||
|
|
||||||
override fun getCache(scope: GlobalSearchScope?): PackageDirectoryCache =
|
override fun getCache(scope: GlobalSearchScope?): PackageDirectoryCache =
|
||||||
(scope as? CustomizedScriptModuleSearchScope)?.let { myCaches.get(it.scriptFile) } ?: super.getCache(scope)
|
(scope as? CustomizedScriptModuleSearchScope ?:
|
||||||
|
(scope as? JavaClassFinderImpl.DelegatingGlobalSearchScopeWithBaseAccess)?.base as? CustomizedScriptModuleSearchScope
|
||||||
|
)?.let {
|
||||||
|
myCaches.get(it.scriptFile)
|
||||||
|
} ?: super.getCache(scope)
|
||||||
|
|
||||||
override fun clearCache() {
|
override fun clearCache() {
|
||||||
super.clearCache()
|
super.clearCache()
|
||||||
@@ -50,6 +60,7 @@ class KotlinScriptDependenciesClassFinder(project: Project,
|
|||||||
super.findClass(qualifiedName, scope)?.let { aClass ->
|
super.findClass(qualifiedName, scope)?.let { aClass ->
|
||||||
when {
|
when {
|
||||||
scope is CustomizedScriptModuleSearchScope ||
|
scope is CustomizedScriptModuleSearchScope ||
|
||||||
|
(scope as? JavaClassFinderImpl.DelegatingGlobalSearchScopeWithBaseAccess)?.base is CustomizedScriptModuleSearchScope ||
|
||||||
scope is EverythingGlobalScope ||
|
scope is EverythingGlobalScope ||
|
||||||
aClass.containingFile?.virtualFile.let { file ->
|
aClass.containingFile?.virtualFile.let { file ->
|
||||||
file != null &&
|
file != null &&
|
||||||
@@ -291,6 +291,8 @@
|
|||||||
<projectService serviceInterface="org.jetbrains.kotlin.console.KotlinConsoleKeeper"
|
<projectService serviceInterface="org.jetbrains.kotlin.console.KotlinConsoleKeeper"
|
||||||
serviceImplementation="org.jetbrains.kotlin.console.KotlinConsoleKeeper"/>
|
serviceImplementation="org.jetbrains.kotlin.console.KotlinConsoleKeeper"/>
|
||||||
|
|
||||||
|
<indexedRootsProvider implementation="org.jetbrains.kotlin.idea.script.KotlinScriptDependenciesIndexableSetContributor"/>
|
||||||
|
|
||||||
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
|
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
|
||||||
|
|
||||||
<internalFileTemplate name="Kotlin File"/>
|
<internalFileTemplate name="Kotlin File"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user