diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/JavaClassFinderImpl.java b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/JavaClassFinderImpl.java index 4759acf924e..c55e0238aa8 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/JavaClassFinderImpl.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/JavaClassFinderImpl.java @@ -61,9 +61,20 @@ public class JavaClassFinderImpl implements JavaClassFinder { // Only activate post create } + public class DelegatingGlobalSearchScopeWithBaseAccess extends DelegatingGlobalSearchScope { + + public DelegatingGlobalSearchScopeWithBaseAccess(@NotNull GlobalSearchScope baseScope) { + super(baseScope); + } + + public GlobalSearchScope getBase() { + return myBaseScope; + } + } + @PostConstruct public void initialize() { - javaSearchScope = new DelegatingGlobalSearchScope(baseScope) { + javaSearchScope = new DelegatingGlobalSearchScopeWithBaseAccess(baseScope) { @Override public boolean contains(@NotNull VirtualFile file) { return myBaseScope.contains(file) && (file.isDirectory() || file.getFileType() != KotlinFileType.INSTANCE); diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfos.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfos.kt index 498ed6bcf0c..f6644343c21 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfos.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaModuleInfos.kt @@ -330,7 +330,7 @@ internal data class CustomizedScriptModuleInfo(val project: Project, val module: }) ?: 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 = hashSetOf() override fun contains(file: VirtualFile): Boolean = diff --git a/idea/src/org/jetbrains/kotlin/idea/script/KotlinScriptConfigurationManager.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/script/KotlinScriptConfigurationManager.kt similarity index 71% rename from idea/src/org/jetbrains/kotlin/idea/script/KotlinScriptConfigurationManager.kt rename to idea/idea-analysis/src/org/jetbrains/kotlin/idea/script/KotlinScriptConfigurationManager.kt index c002cbc5f25..b6951b21b9f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/script/KotlinScriptConfigurationManager.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/script/KotlinScriptConfigurationManager.kt @@ -17,14 +17,20 @@ package org.jetbrains.kotlin.idea.script import com.intellij.openapi.components.AbstractProjectComponent +import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.openapi.vfs.newvfs.BulkFileListener 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 java.io.File +import java.io.FileNotFoundException @Suppress("unused") // project component class KotlinScriptConfigurationManager(private val project: Project, @@ -75,10 +81,19 @@ class KotlinScriptConfigurationManager(private val project: Project, } } } return project.baseDir.vfsWalkFiles { getScriptClasspathRaw(it) } - .mapNotNull { StandardFileSystems.local()?.findFileByPath(it) } .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 = scriptDefinitionProvider.findScriptDefinition(file)?.getScriptDependenciesClasspath()?.let { 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 = + super.getAdditionalProjectRootsToIndex(project) + + KotlinScriptConfigurationManager.getInstance(project).getAllScriptsClasspath() + + override fun getAdditionalRootsToIndex(): Set = emptySet() +} + diff --git a/idea/src/org/jetbrains/kotlin/idea/script/KotlinScriptDependenciesClassFinder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/script/KotlinScriptDependenciesClassFinder.kt similarity index 78% rename from idea/src/org/jetbrains/kotlin/idea/script/KotlinScriptDependenciesClassFinder.kt rename to idea/idea-analysis/src/org/jetbrains/kotlin/idea/script/KotlinScriptDependenciesClassFinder.kt index bb03d97e2da..873668fae04 100644 --- a/idea/src/org/jetbrains/kotlin/idea/script/KotlinScriptDependenciesClassFinder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/script/KotlinScriptDependenciesClassFinder.kt @@ -26,6 +26,7 @@ import com.intellij.psi.search.EverythingGlobalScope import com.intellij.psi.search.GlobalSearchScope import com.intellij.util.containers.ConcurrentFactoryMap import org.jetbrains.kotlin.idea.caches.resolve.CustomizedScriptModuleSearchScope +import org.jetbrains.kotlin.load.java.JavaClassFinderImpl @Suppress("unused") // project extension class KotlinScriptDependenciesClassFinder(project: Project, @@ -33,13 +34,22 @@ class KotlinScriptDependenciesClassFinder(project: Project, ) : NonClasspathClassFinder(project) { private val myCaches = object : ConcurrentFactoryMap() { - 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 = kotlinScriptConfigurationManager.getAllScriptsClasspath() 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() { super.clearCache() @@ -50,6 +60,7 @@ class KotlinScriptDependenciesClassFinder(project: Project, super.findClass(qualifiedName, scope)?.let { aClass -> when { scope is CustomizedScriptModuleSearchScope || + (scope as? JavaClassFinderImpl.DelegatingGlobalSearchScopeWithBaseAccess)?.base is CustomizedScriptModuleSearchScope || scope is EverythingGlobalScope || aClass.containingFile?.virtualFile.let { file -> file != null && diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index be3a0dbb795..b917db85b91 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -291,6 +291,8 @@ + +