[kotlin] KTIJ-25280 Scripts: reduce the use of Workspace Model to the platform interaction only

^KTIJ-25280 fixed

GitOrigin-RevId: 5153283afaa8b272ce13ac8fdeb39bf264811d97
This commit is contained in:
Andrei Klunnyi
2023-04-14 18:35:46 +02:00
committed by intellij-monorepo-bot
parent d7995a972b
commit 4eb8e29c5c
22 changed files with 112 additions and 590 deletions

View File

@@ -12,8 +12,6 @@ import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.idea.base.projectStructure.RootKindFilter
import org.jetbrains.kotlin.idea.base.projectStructure.RootKindMatcher
import org.jetbrains.kotlin.idea.base.projectStructure.isKotlinBinary
import org.jetbrains.kotlin.idea.core.script.ucache.getAllScriptDependenciesSourcesScope
import org.jetbrains.kotlin.idea.core.script.ucache.getAllScriptsDependenciesClassFilesScope
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.util.isKotlinFileType
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
@@ -88,10 +86,11 @@ internal class RootKindMatcherImpl(private val project: Project) : RootKindMatch
return true
}
val classFileScope = when {
correctedFilter.includeScriptDependencies -> getAllScriptsDependenciesClassFilesScope(project)
else -> null
}
val classFileScope = when {
correctedFilter.includeScriptDependencies -> ScriptConfigurationManager.getInstance(
project).getAllScriptsDependenciesClassFilesScope()
else -> null
}
if (classFileScope != null && classFileScope.contains(virtualFile)) {
return true
@@ -104,7 +103,9 @@ internal class RootKindMatcherImpl(private val project: Project) : RootKindMatch
}
val sourceFileScope = when {
correctedFilter.includeScriptDependencies -> getAllScriptDependenciesSourcesScope(project)
correctedFilter.includeScriptDependencies -> ScriptConfigurationManager.getInstance(project)
.getAllScriptDependenciesSourcesScope()
else -> null
}

View File

@@ -18,8 +18,7 @@ import org.jetbrains.kotlin.idea.base.scripting.projectStructure.ScriptModuleInf
import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.IdeaModuleInfo
import org.jetbrains.kotlin.idea.core.script.ScriptRelatedModuleNameFile
import org.jetbrains.kotlin.idea.base.projectStructure.isKotlinBinary
import org.jetbrains.kotlin.idea.core.script.ucache.getAllScriptDependenciesSourcesScope
import org.jetbrains.kotlin.idea.core.script.ucache.getAllScriptsDependenciesClassFilesScope
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
import org.jetbrains.kotlin.utils.yieldIfNotNull
@@ -48,7 +47,7 @@ internal class ScriptingModuleInfoProviderExtension : ModuleInfoProviderExtensio
) {
val isBinary = virtualFile.fileType.isKotlinBinary
if (isBinary && virtualFile in getAllScriptsDependenciesClassFilesScope(project)) {
if (isBinary && virtualFile in ScriptConfigurationManager.getInstance(project).getAllScriptsDependenciesClassFilesScope()) {
if (isLibrarySource) {
register(ScriptDependenciesSourceInfo.ForProject(project))
} else {
@@ -56,7 +55,7 @@ internal class ScriptingModuleInfoProviderExtension : ModuleInfoProviderExtensio
}
}
if (!isBinary && virtualFile in getAllScriptDependenciesSourcesScope(project)) {
if (!isBinary && virtualFile in ScriptConfigurationManager.getInstance(project).getAllScriptDependenciesSourcesScope()) {
register(ScriptDependenciesSourceInfo.ForProject(project))
}
}

View File

@@ -14,8 +14,6 @@ import org.jetbrains.kotlin.idea.base.scripting.KotlinBaseScriptingBundle
import org.jetbrains.kotlin.idea.base.scripting.ScriptingTargetPlatformDetector
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.script.dependencies.KotlinScriptSearchScope
import org.jetbrains.kotlin.idea.core.script.ucache.getAllScriptsDependenciesClassFilesScope
import org.jetbrains.kotlin.idea.core.script.ucache.getScriptDependenciesClassFilesScope
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.TargetPlatformVersion
@@ -75,9 +73,10 @@ sealed class ScriptDependenciesInfo(override val project: Project) : IdeaModuleI
get() {
// TODO: this is not very efficient because KotlinSourceFilterScope already checks if the files are in scripts classpath
val scriptKtFile = PsiManager.getInstance(project).findFile(scriptFile) as KtFile
val scriptVFile = scriptKtFile.virtualFile ?: scriptKtFile.viewProvider.virtualFile
return KotlinSourceFilterScope.libraryClasses(
getScriptDependenciesClassFilesScope(project, scriptKtFile), project
)
ScriptConfigurationManager.getInstance(project).getScriptDependenciesClassFilesScope(scriptVFile), project
)
}
}
@@ -90,7 +89,8 @@ sealed class ScriptDependenciesInfo(override val project: Project) : IdeaModuleI
override val contentScope: GlobalSearchScope
get() {
return KotlinSourceFilterScope.libraryClasses(getAllScriptsDependenciesClassFilesScope(project), project)
return KotlinSourceFilterScope.libraryClasses(
ScriptConfigurationManager.getInstance(project).getAllScriptsDependenciesClassFilesScope(), project)
}
companion object {

View File

@@ -7,7 +7,7 @@ import org.jetbrains.kotlin.idea.base.scripting.KotlinBaseScriptingBundle
import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.IdeaModuleInfo
import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.SourceForBinaryModuleInfo
import org.jetbrains.kotlin.idea.base.projectStructure.scope.KotlinSourceFilterScope
import org.jetbrains.kotlin.idea.core.script.ucache.getAllScriptDependenciesSourcesScope
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
@@ -26,7 +26,7 @@ sealed class ScriptDependenciesSourceInfo(override val project: Project) : IdeaM
// include project sources because script dependencies sources may contain roots from project
// the main example is buildSrc for *.gradle.kts files
override fun sourceScope(): GlobalSearchScope = KotlinSourceFilterScope.projectAndLibrarySources(
getAllScriptDependenciesSourcesScope(project), project
ScriptConfigurationManager.getInstance(project).getAllScriptDependenciesSourcesScope(), project
)
override fun hashCode() = project.hashCode()

View File

@@ -5,7 +5,6 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.workspaceModel.ide.WorkspaceModel
import org.jetbrains.kotlin.analysis.project.structure.*
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.config.LanguageVersionSettings
@@ -13,10 +12,6 @@ import org.jetbrains.kotlin.idea.base.projectStructure.KtModuleByModuleInfoBase
import org.jetbrains.kotlin.idea.base.projectStructure.KtModuleFactory
import org.jetbrains.kotlin.idea.base.projectStructure.toKtModuleOfType
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.script.ucache.KotlinScriptId
import org.jetbrains.kotlin.idea.core.script.ucache.KotlinScriptLibraryRootTypeId
import org.jetbrains.kotlin.idea.core.script.ucache.listDependencies
import org.jetbrains.kotlin.idea.core.script.ucache.scriptsAsEntities
import org.jetbrains.kotlin.psi.KtFile
import java.nio.file.Path
@@ -79,15 +74,6 @@ private class KtScriptDependencyModuleByModuleInfo(
.map { it.toNioPath() }
}
is ScriptDependenciesInfo.ForFile -> {
if (scriptsAsEntities) {
val entityStorage = WorkspaceModel.getInstance(project).currentSnapshot
val scriptEntity = entityStorage.resolve(KotlinScriptId(moduleInfo.scriptFile.path))
if (scriptEntity != null) {
return scriptEntity.listDependencies(project, KotlinScriptLibraryRootTypeId.COMPILED)
.map { it.toNioPath() }
}
}
return ScriptConfigurationManager.getInstance(project)
.getScriptDependenciesClassFiles(moduleInfo.scriptFile)
.map { it.toNioPath() }

View File

@@ -1,130 +0,0 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.core.script
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.openapi.roots.ProjectRootModificationTracker
import com.intellij.openapi.util.Condition
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.psi.*
import com.intellij.psi.impl.java.stubs.index.JavaFullClassNameIndex
import com.intellij.psi.search.EverythingGlobalScope
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.StubIndex
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.CommonProcessors
import com.intellij.util.Processor
import com.intellij.util.containers.ConcurrentFactoryMap
import org.jetbrains.kotlin.idea.core.script.dependencies.KotlinScriptMarkerFileSystem
import org.jetbrains.kotlin.idea.core.script.ucache.computeClassRoots
import org.jetbrains.kotlin.idea.core.script.ucache.scriptsAsEntities
import org.jetbrains.kotlin.resolve.jvm.KotlinSafeClassFinder
internal class KotlinScriptDependenciesClassFinder(private val project: Project) : NonClasspathClassFinder(project), KotlinSafeClassFinder {
private val useOnlyForScripts = Registry.`is`("kotlin.resolve.scripting.limit.dependency.element.finder", true)
/*
PsiElementFinder's are global and can be called for any context.
As 'KotlinScriptDependenciesClassFinder' is meant to provide additional dependencies only for scripts,
we need to know if the caller came from a script resolution context.
We are doing so by checking if the given scope contains a synthetic 'KotlinScriptMarkerFileSystem.rootFile'.
Normally, only global scopes and 'KotlinScriptScope' contains such a file.
*/
private fun isApplicable(scope: GlobalSearchScope): Boolean =
!scriptsAsEntities && (!useOnlyForScripts || scope.contains(KotlinScriptMarkerFileSystem.rootFile))
override fun getClassRoots(scope: GlobalSearchScope?): List<VirtualFile> {
if (scriptsAsEntities) return super.getClassRoots(scope)
var result = super.getClassRoots(scope)
if (scope is EverythingGlobalScope) {
result = result + KotlinScriptMarkerFileSystem.rootFile
}
return result
}
override fun calcClassRoots(): List<VirtualFile> = if (scriptsAsEntities) emptyList() else computeClassRoots(project)
private val everywhereCache = CachedValuesManager.getManager(project).createCachedValue {
CachedValueProvider.Result.create(
ConcurrentFactoryMap.createMap { qualifiedName: String ->
findClassNotCached(qualifiedName, GlobalSearchScope.everythingScope(project))
},
ScriptDependenciesModificationTracker.getInstance(project),
PsiModificationTracker.MODIFICATION_COUNT,
ProjectRootModificationTracker.getInstance(project),
VirtualFileManager.getInstance()
)
}
override fun findClass(qualifiedName: String, scope: GlobalSearchScope): PsiClass? {
return if (isApplicable(scope)) everywhereCache.value[qualifiedName]?.takeIf { isInScope(it, scope) } else null
}
private fun findClassNotCached(qualifiedName: String, scope: GlobalSearchScope): PsiClass? {
val topLevelClass = super.findClass(qualifiedName, scope)
if (topLevelClass != null && isInScope(topLevelClass, scope)) {
return topLevelClass
}
// The following code is needed because NonClasspathClassFinder cannot find inner classes
// JavaFullClassNameIndex cannot be used directly, because it filters only classes in source roots
val processor = QualifiedClassNameProcessor(qualifiedName)
StubIndex.getInstance().processElements(
JavaFullClassNameIndex.getInstance().key,
qualifiedName,
project,
scope.takeUnless { it is EverythingGlobalScope },
PsiClass::class.java,
processor
)
return processor.foundValue?.takeIf { isInScope(it, scope) }
}
private fun isInScope(clazz: PsiClass, scope: GlobalSearchScope): Boolean {
if (scope is EverythingGlobalScope) {
return true
}
val file = clazz.containingFile?.virtualFile ?: return false
val index = ProjectFileIndex.getInstance(myProject)
return !index.isInContent(file) && !index.isInLibrary(file) && scope.contains(file)
}
override fun findClasses(qualifiedName: String, scope: GlobalSearchScope): Array<PsiClass> =
if (isApplicable(scope)) super.findClasses(qualifiedName, scope) else emptyArray()
override fun getSubPackages(psiPackage: PsiPackage, scope: GlobalSearchScope): Array<PsiPackage> =
if (isApplicable(scope)) super.getSubPackages(psiPackage, scope) else emptyArray()
override fun getClasses(psiPackage: PsiPackage, scope: GlobalSearchScope): Array<PsiClass> =
if (isApplicable(scope)) super.getClasses(psiPackage, scope) else emptyArray()
override fun getPackageFiles(psiPackage: PsiPackage, scope: GlobalSearchScope): Array<PsiFile> =
if (isApplicable(scope)) super.getPackageFiles(psiPackage, scope) else emptyArray()
override fun getPackageFilesFilter(psiPackage: PsiPackage, scope: GlobalSearchScope): Condition<PsiFile>? =
if (isApplicable(scope)) super.getPackageFilesFilter(psiPackage, scope) else null
override fun getClassNames(psiPackage: PsiPackage, scope: GlobalSearchScope): Set<String> =
if (isApplicable(scope)) super.getClassNames(psiPackage, scope) else emptySet()
override fun processPackageDirectories(
psiPackage: PsiPackage, scope: GlobalSearchScope,
consumer: Processor<in PsiDirectory>, includeLibrarySources: Boolean
): Boolean = if (isApplicable(scope)) super.processPackageDirectories(psiPackage, scope, consumer, includeLibrarySources) else true
private class QualifiedClassNameProcessor(private val qualifiedName: String): CommonProcessors.FindFirstProcessor<PsiClass>() {
override fun accept(t: PsiClass?): Boolean {
return t?.qualifiedName == qualifiedName
}
}
}

View File

@@ -22,8 +22,6 @@ class KotlinScriptExternalLibrariesNodesProvider: ExternalLibrariesWorkspaceMode
override fun getWorkspaceClass(): Class<KotlinScriptEntity> = KotlinScriptEntity::class.java
override fun createNode(entity: KotlinScriptEntity, project: Project, settings: ViewSettings?): AbstractTreeNode<*>? {
if (!scriptsAsEntities) return null
val dependencies = entity.listDependencies(project)
val path = entity.path
val scriptFile = VirtualFileManager.getInstance().findFileByNioPath(Path.of(path))

View File

@@ -55,9 +55,6 @@ internal class IdeScriptDependenciesProvider(project: Project) : ScriptDependenc
}
/**
* **Please, note** that [ScriptConfigurationManager] should not be used directly.
* Instead, consider using [org.jetbrains.kotlin.idea.core.script.ucache.KotlinScriptImplementationSwitcher].
*
* Facade for loading and caching Kotlin script files configuration.
*
* This service also starts indexing of new dependency roots and runs highlighting
@@ -126,12 +123,6 @@ interface ScriptConfigurationManager {
@JvmStatic
fun getInstance(project: Project): ScriptConfigurationManager = project.service()
@JvmStatic
fun allExtraRoots(project: Project): Collection<VirtualFile> {
val manager = getInstance(project)
return manager.getAllScriptsDependenciesClassFiles() + manager.getAllScriptDependenciesSources()
}
@JvmStatic
fun compositeScriptConfigurationManager(project: Project) =
getInstance(project).cast<CompositeScriptConfigurationManager>()

View File

@@ -11,14 +11,14 @@ import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.PsiShortNamesCache
import com.intellij.psi.stubs.StubIndex
import com.intellij.util.Processor
import org.jetbrains.kotlin.idea.core.script.ucache.getAllScriptsDependenciesClassFilesScope
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
// Allow searching java classes in jars in script dependencies, this is needed for stuff like completion and autoimport
class JavaClassesInScriptDependenciesShortNameCache(private val project: Project) : PsiShortNamesCache() {
override fun getAllClassNames() = emptyArray<String>()
override fun getClassesByName(name: String, scope: GlobalSearchScope): Array<out PsiClass> {
val classpathScope = getAllScriptsDependenciesClassFilesScope(project)
val classpathScope = ScriptConfigurationManager.getInstance(project).getAllScriptsDependenciesClassFilesScope()
val classes = StubIndex.getElements(
JavaShortClassNameIndex.getInstance().key, name, project, classpathScope.intersectWith(scope), PsiClass::class.java
)

View File

@@ -2,28 +2,17 @@
package org.jetbrains.kotlin.idea.core.script.dependencies
import com.intellij.java.workspaceModel.fileIndex.JvmPackageRootData
import com.intellij.navigation.ItemPresentation
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.AdditionalLibraryRootsProvider
import com.intellij.openapi.roots.SyntheticLibrary
import com.intellij.openapi.roots.impl.CustomEntityProjectModelInfoProvider
import com.intellij.openapi.roots.impl.CustomEntityProjectModelInfoProvider.LibraryRoots
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.workspaceModel.core.fileIndex.WorkspaceFileIndexContributor
import com.intellij.workspaceModel.core.fileIndex.WorkspaceFileKind
import com.intellij.workspaceModel.core.fileIndex.WorkspaceFileSetRegistrar
import com.intellij.workspaceModel.core.fileIndex.impl.ModuleOrLibrarySourceRootData
import com.intellij.workspaceModel.ide.virtualFile
import com.intellij.workspaceModel.storage.EntityStorage
import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.idea.base.scripting.KotlinBaseScriptingBundle
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.script.ucache.KotlinScriptLibraryEntity
import org.jetbrains.kotlin.idea.core.script.ucache.KotlinScriptLibraryRootTypeId
import org.jetbrains.kotlin.idea.core.script.ucache.scriptsAsEntities
import javax.swing.Icon
/**
* See recommendations for custom entities indexing
@@ -39,7 +28,7 @@ class KotlinScriptProjectModelInfoProvider : CustomEntityProjectModelInfoProvide
entities: Sequence<KotlinScriptLibraryEntity>,
entityStorage: EntityStorage
): Sequence<LibraryRoots<KotlinScriptLibraryEntity>> =
if (!scriptsAsEntities || useWorkspaceFileContributor()) { // see KotlinScriptDependenciesLibraryRootProvider
if (useWorkspaceFileContributor()) { // see KotlinScriptDependenciesLibraryRootProvider
emptySequence()
} else {
entities.map { libEntity ->
@@ -59,7 +48,7 @@ class KotlinScriptWorkspaceFileIndexContributor : WorkspaceFileIndexContributor<
get() = KotlinScriptLibraryEntity::class.java
override fun registerFileSets(entity: KotlinScriptLibraryEntity, registrar: WorkspaceFileSetRegistrar, storage: EntityStorage) {
if (!scriptsAsEntities || !useWorkspaceFileContributor()) return // see KotlinScriptDependenciesLibraryRootProvider
if (!useWorkspaceFileContributor()) return // see KotlinScriptDependenciesLibraryRootProvider
val (classes, sources) = entity.roots.partition { it.type == KotlinScriptLibraryRootTypeId.COMPILED }
classes.forEach {
registrar.registerFileSet(it.url, WorkspaceFileKind.EXTERNAL, entity, RootData)
@@ -76,95 +65,3 @@ class KotlinScriptWorkspaceFileIndexContributor : WorkspaceFileIndexContributor<
private object RootSourceData : JvmPackageRootData, ModuleOrLibrarySourceRootData
}
class KotlinScriptDependenciesLibraryRootProvider : AdditionalLibraryRootsProvider() {
override fun getAdditionalProjectLibraries(project: Project): Collection<SyntheticLibrary> { // RootIndex & FileBasedIndexEx need it
if (scriptsAsEntities) return emptyList() // see KotlinScriptProjectModelInfoProvider
val manager = ScriptConfigurationManager.getInstance(project)
val classes = manager.getAllScriptsDependenciesClassFiles().filterValid()
val sources = manager.getAllScriptDependenciesSources().filterValid()
val sdkClasses = manager.getAllScriptsSdkDependenciesClassFiles().filterValid()
val sdkSources = manager.getAllScriptSdkDependenciesSources().filterValid()
return if (classes.isEmpty() && sources.isEmpty() && sdkClasses.isEmpty() && sdkSources.isEmpty()) {
emptyList()
} else {
val library = KotlinScriptDependenciesLibrary(classes = classes, sources = sources)
if (sdkClasses.isEmpty() && sdkSources.isEmpty()) {
listOf(library)
} else {
listOf(ScriptSdk(manager.getFirstScriptsSdk(), sdkClasses, sdkSources), library)
}
}
}
private fun Collection<VirtualFile>.filterValid() = this.filterTo(LinkedHashSet(), VirtualFile::isValid)
override fun getRootsToWatch(project: Project): Collection<VirtualFile> = if (scriptsAsEntities) {
emptyList()
} else {
ScriptConfigurationManager.allExtraRoots(project).filterValid()
}
abstract class AbstractDependenciesLibrary(
private val id: String,
val classes: Collection<VirtualFile>,
val sources: Collection<VirtualFile>
) :
SyntheticLibrary(id, null), ItemPresentation {
protected val gradle: Boolean by lazy { classes.hasGradleDependency() }
override fun getBinaryRoots(): Collection<VirtualFile> = classes
override fun getSourceRoots(): Collection<VirtualFile> = sources
override fun getIcon(unused: Boolean): Icon = if (gradle) {
KotlinIcons.GRADLE_SCRIPT
} else {
KotlinIcons.SCRIPT
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as AbstractDependenciesLibrary
return id == other.id && classes == other.classes && sources == other.sources
}
override fun hashCode(): Int {
return 31 * classes.hashCode() + sources.hashCode()
}
}
private class KotlinScriptDependenciesLibrary(classes: Collection<VirtualFile>, sources: Collection<VirtualFile>) :
AbstractDependenciesLibrary("KotlinScriptDependenciesLibrary", classes, sources) {
override fun getPresentableText(): String =
if (gradle) {
KotlinBaseScriptingBundle.message("script.name.gradle.script.dependencies")
} else {
KotlinBaseScriptingBundle.message("script.name.kotlin.script.dependencies")
}
}
private class ScriptSdk(val sdk: Sdk?, classes: Collection<VirtualFile>, sources: Collection<VirtualFile>) :
AbstractDependenciesLibrary("ScriptSdk", classes, sources) {
override fun getPresentableText(): String =
if (gradle) {
sdk?.let { KotlinBaseScriptingBundle.message("script.name.gradle.script.sdk.dependencies.0", it.name) }
?: KotlinBaseScriptingBundle.message("script.name.gradle.script.sdk.dependencies")
} else {
sdk?.let { KotlinBaseScriptingBundle.message("script.name.kotlin.script.sdk.dependencies.0", it.name) }
?: KotlinBaseScriptingBundle.message("script.name.kotlin.script.sdk.dependencies")
}
}
}
fun Collection<VirtualFile>.hasGradleDependency() = any { it.name.contains("gradle") }

View File

@@ -13,7 +13,7 @@ import com.intellij.psi.search.DelegatingGlobalSearchScope
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfoOrNull
import org.jetbrains.kotlin.idea.base.scripting.projectStructure.ScriptModuleInfo
import org.jetbrains.kotlin.idea.core.script.ucache.getScriptDependenciesClassFilesScope
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.util.isKotlinFileType
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
@@ -82,8 +82,9 @@ class KotlinScriptResolveScopeProvider : ResolveScopeProvider() {
if (scriptDefinition is ScriptDefinition.FromConfigurationsBase ||
scriptDefinition.asLegacyOrNull<KotlinScriptDefinitionFromAnnotatedTemplate>() != null
) {
val dependenciesScope = getScriptDependenciesClassFilesScope(project, ktFile)
return KotlinScriptSearchScope(project, GlobalSearchScope.fileScope(project, file).uniteWith(dependenciesScope))
val vFile = ktFile.virtualFile ?: ktFile.viewProvider.virtualFile
val dependenciesScope = ScriptConfigurationManager.getInstance(project).getScriptDependenciesClassFilesScope(vFile)
return KotlinScriptSearchScope(project, GlobalSearchScope.fileScope(project, file).uniteWith(dependenciesScope))
}
return null

View File

@@ -6,12 +6,8 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.ResolveScopeProvider
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.NonClasspathDirectoriesScope
import org.jetbrains.kotlin.idea.base.projectStructure.moduleInfo.SdkInfo
import org.jetbrains.kotlin.idea.base.projectStructure.scope.KotlinSourceFilterScope
import org.jetbrains.kotlin.idea.base.scripting.projectStructure.ScriptDependenciesInfo
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.script.ucache.*
/**
* @see KotlinScriptResolveScopeProvider
@@ -29,32 +25,14 @@ class ScriptDependenciesResolveScopeProvider : ResolveScopeProvider() {
- multiple editors can be opened (selected is only one of them)
*/
if (getAllScriptsDependenciesClassFiles(project).isEmpty()) return null
if (ScriptConfigurationManager.getInstance(project).getAllScriptsDependenciesClassFiles().isEmpty()) return null
if (file !in getAllScriptsDependenciesClassFilesScope(project)
&& file !in getAllScriptDependenciesSourcesScope(project)
if (file !in ScriptConfigurationManager.getInstance(project).getAllScriptsDependenciesClassFilesScope()
&& file !in ScriptConfigurationManager.getInstance(project).getAllScriptDependenciesSourcesScope()
) {
return null
}
if (scriptsAsEntities) {
val scripts = file.findDependentScripts(project) ?: return null
val dependencies = scripts.flatMap { it.listDependencies(project, KotlinScriptLibraryRootTypeId.COMPILED) }.distinct()
var searchScope = GlobalSearchScope.union(
arrayOf(
GlobalSearchScope.fileScope(project, file),
KotlinSourceFilterScope.libraryClasses(NonClasspathDirectoriesScope.compose(dependencies), project)
)
)
ScriptConfigurationManager.getInstance(project).getFirstScriptsSdk()?.let {
searchScope = searchScope.uniteWith(SdkInfo(project, it).contentScope)
}
return searchScope
}
val scope = GlobalSearchScope.union(
arrayOf(
GlobalSearchScope.fileScope(project, file),

View File

@@ -7,8 +7,7 @@ import com.intellij.psi.PsiClassOwner
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.compiled.*
import com.intellij.psi.util.MethodSignatureUtil
import org.jetbrains.kotlin.idea.core.script.ucache.getAllScriptDependenciesSources
import org.jetbrains.kotlin.idea.core.script.ucache.getAllScriptsDependenciesClassFilesScope
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class ScriptDependencySourceNavigationPolicyForJavaClasses : ClsCustomNavigationPolicy {
@@ -38,12 +37,12 @@ class ScriptDependencySourceNavigationPolicyForJavaClasses : ClsCustomNavigation
val project = file.project
val sourceFileName = file.classes.firstOrNull()?.safeAs<ClsClassImpl>()?.sourceFileName ?: return null
if (virtualFile !in getAllScriptsDependenciesClassFilesScope(project)) return null
if (virtualFile !in ScriptConfigurationManager.getInstance(project).getAllScriptsDependenciesClassFilesScope()) return null
val packageName = file.packageName
val relativePath = if (packageName.isEmpty()) sourceFileName else packageName.replace('.', '/') + '/' + sourceFileName
for (root in getAllScriptDependenciesSources(project).filter { it.isValid }) {
for (root in ScriptConfigurationManager.getInstance(project).getAllScriptDependenciesSources().filter { it.isValid }) {
val sourceFile = root.findFileByRelativePath(relativePath)
if (sourceFile != null && sourceFile.isValid) {
val sourcePsi = file.manager.findFile(sourceFile)

View File

@@ -101,7 +101,7 @@ class ScriptClassRootsCache(
return HeavyScriptInfo(configuration, roots, compose(roots), sdk)
}
return if (sdk == null || scriptsAsEntities) {
return if (sdk == null) {
heavyInfoForRoots(vfsRoots)
} else {
val sdkClasses = sdk.rootProvider.getFiles(OrderRootType.CLASSES).toList()

View File

@@ -12,10 +12,8 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.project.ProjectManagerListener
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.AdditionalLibraryRootsListener
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.PsiManager
import com.intellij.testFramework.LightVirtualFile
import com.intellij.util.applyIf
@@ -23,14 +21,10 @@ import com.intellij.util.ui.EDT.isCurrentThreadEdt
import com.intellij.workspaceModel.ide.WorkspaceModel
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.jetbrains.kotlin.idea.base.scripting.KotlinBaseScriptingBundle
import org.jetbrains.kotlin.idea.base.util.CheckCanceledLock
import org.jetbrains.kotlin.idea.core.KotlinPluginDisposable
import org.jetbrains.kotlin.idea.core.script.KotlinScriptDependenciesClassFinder
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesModificationTracker
import org.jetbrains.kotlin.idea.core.script.configuration.CompositeScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.script.dependencies.hasGradleDependency
import org.jetbrains.kotlin.idea.core.script.scriptingDebugLog
import org.jetbrains.kotlin.idea.core.util.EDT
import org.jetbrains.kotlin.idea.util.FirPluginOracleService
import org.jetbrains.kotlin.idea.util.application.isUnitTestMode
@@ -208,71 +202,36 @@ abstract class ScriptClassRootsUpdater(
if (disposable.disposed) return
if (scriptsAsEntities) { // (updates.changed && !updates.hasNewRoots)
val manager = VirtualFileManager.getInstance()
val updatedScriptPaths = when (updates) {
is ScriptClassRootsCache.IncrementalUpdates -> updates.updatedScripts
else -> updates.cache.scriptsPaths()
}
updatedScriptPaths.takeUnless { it.isEmpty() }?.asSequence()
?.map {
val byNioPath = manager.findFileByNioPath(Paths.get(it))
if (byNioPath == null) { // e.g. jupyter notebooks have their .kts in memory only
val path = it.applyIf(it.startsWith("/")) { it.replaceFirst("/", "") }
LightVirtualFile(path)
} else {
byNioPath
}
}
?.let { updatedScriptFiles ->
val actualScriptPaths = updates.cache.scriptsPaths()
val (filesToAddOrUpdate, filesToRemove) = updatedScriptFiles.partition { actualScriptPaths.contains(it.path) }
// Here we're sometimes under read-lock.
// There is no way to acquire write-lock (on EDT) without releasing this thread.
applyDiffToModelAsync(filesToAddOrUpdate, filesToRemove)
}
val manager = VirtualFileManager.getInstance()
val updatedScriptPaths = when (updates) {
is ScriptClassRootsCache.IncrementalUpdates -> updates.updatedScripts
else -> updates.cache.scriptsPaths()
}
updatedScriptPaths.takeUnless { it.isEmpty() }?.asSequence()
?.map {
val byNioPath = manager.findFileByNioPath(Paths.get(it))
if (byNioPath == null) { // e.g. jupyter notebooks have their .kts in memory only
val path = it.applyIf(it.startsWith("/")) { it.replaceFirst("/", "") }
LightVirtualFile(path)
} else {
byNioPath
}
}
?.let { updatedScriptFiles ->
val actualScriptPaths = updates.cache.scriptsPaths()
val (filesToAddOrUpdate, filesToRemove) = updatedScriptFiles.partition { actualScriptPaths.contains(it.path) }
// Here we're sometimes under read-lock.
// There is no way to acquire write-lock (on EDT) without releasing this thread.
applyDiffToModelAsync(filesToAddOrUpdate, filesToRemove)
}
if (updates.hasNewRoots) {
runInEdt(ModalityState.NON_MODAL) {
runWriteAction {
if (project.isDisposed) return@runWriteAction
if (!scriptsAsEntities) {
scriptingDebugLog { "kotlin.script.dependencies from ${updates.oldRoots} to ${updates.newRoots}" }
val hasGradleDependency = updates.newSdkRoots.hasGradleDependency() || updates.newRoots.hasGradleDependency()
val dependencySdkLibraryName = if (hasGradleDependency) {
KotlinBaseScriptingBundle.message("script.name.gradle.script.sdk.dependencies")
} else {
KotlinBaseScriptingBundle.message("script.name.kotlin.script.sdk.dependencies")
}
AdditionalLibraryRootsListener.fireAdditionalLibraryChanged(
project,
dependencySdkLibraryName,
updates.oldSdkRoots,
updates.newSdkRoots,
dependencySdkLibraryName
)
val dependencyLibraryName = if (hasGradleDependency) {
KotlinBaseScriptingBundle.message("script.name.gradle.script.dependencies")
} else {
KotlinBaseScriptingBundle.message("script.name.kotlin.script.dependencies")
}
AdditionalLibraryRootsListener.fireAdditionalLibraryChanged(
project,
dependencyLibraryName,
updates.oldRoots,
updates.newRoots,
dependencyLibraryName
)
}
ScriptDependenciesModificationTracker.getInstance(project).incModificationCount()
}
}
@@ -281,11 +240,6 @@ abstract class ScriptClassRootsUpdater(
runReadAction {
if (project.isDisposed) return@runReadAction
if (!scriptsAsEntities) {
PsiElementFinder.EP.findExtensionOrFail(KotlinScriptDependenciesClassFinder::class.java, project).clearCache()
ScriptDependenciesModificationTracker.getInstance(project).incModificationCount()
}
if (updates.hasUpdatedScripts) {
updateHighlighting(project) { file -> updates.isScriptChanged(file.path) }
}

View File

@@ -4,7 +4,6 @@ package org.jetbrains.kotlin.idea.core.script.ucache
import com.intellij.ide.scratch.ScratchUtil
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.LightVirtualFile
import com.intellij.util.applyIf
@@ -126,6 +125,58 @@ private fun KotlinScriptEntity.debugInfo(storage: EntityStorage): String {
}
}
@Suppress("unused") // exists for debug purposes
private fun managerScriptsDebugInfo(project: Project, scriptFiles: Sequence<VirtualFile>? = null): String = buildString {
val configurationManager = ScriptConfigurationManager.getInstance(project)
val allSourcesSize = configurationManager.getAllScriptDependenciesSources().size
val allSdkSourcesSize = configurationManager.getAllScriptSdkDependenciesSources().size
val allClassesSize = configurationManager.getAllScriptsDependenciesClassFiles().size
val allSdkClassesSize = configurationManager.getAllScriptsSdkDependenciesClassFiles().size
scriptFiles?.forEach {
val classDepSize = configurationManager.getScriptDependenciesClassFiles(it).size
val sourceDepSize = configurationManager.getScriptDependenciesSourceFiles(it).size
append("[${it.path}]: classes: ${classDepSize}, sources: ${sourceDepSize}\n")
}
insert(
0,
"==> ScriptConfigurationManager (classes: $allClassesSize, sdkClasses: $allSdkClassesSize, sources: $allSourcesSize, sdkSources: $allSdkSourcesSize)\n"
)
}
@Suppress("unused") // exists for debug purposes
private fun scriptEntitiesDebugInfo(project: Project, listRoots: Boolean = false): String {
fun List<KotlinScriptLibraryRoot>.print(indent: CharSequence = " ") = asSequence()
.mapIndexed { i, root -> "$indent${i + 1}: ${root.url.presentableUrl}" }
.joinToString("\n", indent)
return buildString {
val entityStorage = WorkspaceModel.getInstance(project).currentSnapshot
val allClasses = HashSet<KotlinScriptLibraryRoot>()
val allSources = HashSet<KotlinScriptLibraryRoot>()
entityStorage.entities(KotlinScriptEntity::class.java).forEachIndexed { scriptIndex, scriptEntity ->
append("#${scriptIndex + 1}: [${scriptEntity.path}]\n")
scriptEntity.dependencies.forEachIndexed dependencies@{ libIndex, libId ->
val lib = entityStorage.resolve(libId) ?: return@dependencies
val (classes, sources) = lib.roots.partition { it.type == KotlinScriptLibraryRootTypeId.COMPILED }
allClasses.addAll(classes)
allSources.addAll(sources)
append(" Lib #${libIndex + 1}: \"${lib.name}\", classes: ${classes.size}, sources: ${sources.size} \n")
applyIf(listRoots) {
append(" Classes:\n ${classes.print()}\n")
append(" Sources:\n ${sources.print()}\n")
}
}
}
insert(0, "==> WorkspaceModel (unique classes: ${allClasses.size}, sources: ${allSources.size})\n")
}
}
private fun MutableEntityStorage.syncScriptEntities(
scriptFilesToAddOrUpdate: List<VirtualFile>,
@@ -244,7 +295,6 @@ private fun MutableEntityStorage.getActualScriptLibraries(scriptFile: VirtualFil
libraries.fillWithFiles(project, dependenciesClassFiles, dependenciesSourceFiles)
libraries.fillWithIdeSpecificDependencies(project, scriptFile)
libraries.fillWithSdkDependencies(project, scriptFile)
val mergedLibraries = libraries.mergeClassAndSourceRoots()
@@ -289,19 +339,6 @@ private fun MutableList<KotlinScriptLibraryEntity>.fillWithIdeSpecificDependenci
}
}
private fun MutableList<KotlinScriptLibraryEntity>.fillWithSdkDependencies(project: Project, scriptFile: VirtualFile) {
val configurationManager = ScriptConfigurationManager.getInstance(project)
val scriptSdk = configurationManager.getScriptSdk(scriptFile)
val projectSdk = ProjectRootManager.getInstance(project).projectSdk
if (scriptSdk?.homePath != projectSdk?.homePath) {
val sdkClassFiles = configurationManager.getScriptSdkDependenciesClassFiles(scriptFile)
val sdkSourceFiles = configurationManager.getScriptSdkDependenciesSourceFiles(scriptFile)
fillWithFiles(project, sdkClassFiles, sdkSourceFiles)
}
}
private fun KotlinScriptLibraryEntity.hasSameRootsAs(dependency: KotlinScriptLibraryEntity): Boolean =
this.roots.containsAll(dependency.roots) && dependency.roots.containsAll(this.roots)

View File

@@ -1,131 +0,0 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.core.script.ucache
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.NonClasspathDirectoriesScope
import com.intellij.util.applyIf
import com.intellij.workspaceModel.ide.WorkspaceModel
import com.intellij.workspaceModel.storage.EntityStorage
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.psi.KtFile
const val KOTLIN_SCRIPTS_AS_ENTITIES = "kotlin.scripts.as.entities"
val scriptsAsEntities: Boolean
get() = Registry.`is`(KOTLIN_SCRIPTS_AS_ENTITIES, true)
/**
* ScriptConfigurationManager or WorkspaceModel based on 'scriptsAsEntities'
*/
fun getScriptDependenciesClassFilesScope(project: Project, ktFile: KtFile): GlobalSearchScope {
val vFile = ktFile.virtualFile ?: ktFile.viewProvider.virtualFile
require(ktFile.isScript()) { "argument must be a script: ${vFile.path}" }
return if (scriptsAsEntities) {
val entityStorage = WorkspaceModel.getInstance(project).currentSnapshot
val scriptEntity = entityStorage.resolve(KotlinScriptId(vFile.path))
if (scriptEntity == null) {
// WorkspaceModel doesn't know about the file yet. But once the latest sync is over it will.
// We cannot synchronously call its syncScriptEntities() because it requires platform write-lock acquisition and this function
// is called under platform read-lock.
ScriptConfigurationManager.getInstance(project).getScriptDependenciesClassFilesScope(vFile)
} else {
NonClasspathDirectoriesScope.compose(scriptEntity.listDependencies(project, KotlinScriptLibraryRootTypeId.COMPILED))
}
} else {
ScriptConfigurationManager.getInstance(project).getScriptDependenciesClassFilesScope(vFile)
}
}
fun getAllScriptsDependenciesClassFilesScope(project: Project): GlobalSearchScope =
// calculation based on WS model is inefficient and leads to freezes
ScriptConfigurationManager.getInstance(project).getAllScriptsDependenciesClassFilesScope()
fun getAllScriptDependenciesSourcesScope(project: Project): GlobalSearchScope =
// calculation based on WS model is inefficient and leads to freezes
ScriptConfigurationManager.getInstance(project).getAllScriptDependenciesSourcesScope()
fun getAllScriptsDependenciesClassFiles(project: Project): Collection<VirtualFile> =
// calculation based on WS model is inefficient and leads to delays
ScriptConfigurationManager.getInstance(project).getAllScriptsDependenciesClassFiles()
fun getAllScriptDependenciesSources(project: Project): Collection<VirtualFile> =
// calculation based on WS model is inefficient and leads to freezes
ScriptConfigurationManager.getInstance(project).getAllScriptDependenciesSources()
fun computeClassRoots(project: Project): List<VirtualFile> {
return if (scriptsAsEntities) {
val entityStorage = WorkspaceModel.getInstance(project).currentSnapshot
entityStorage.listDependenciesOfAllScriptEntities(project, KotlinScriptLibraryRootTypeId.COMPILED).toList()
} else {
val manager = ScriptConfigurationManager.getInstance(project)
(manager.getAllScriptsDependenciesClassFiles() + manager.getAllScriptsSdkDependenciesClassFiles()).filter { it.isValid }
}
}
private fun EntityStorage.listDependenciesOfAllScriptEntities(
project: Project,
rootTypeId: KotlinScriptLibraryRootTypeId
): Collection<VirtualFile> =
entities(KotlinScriptEntity::class.java)
.flatMap { it.listDependencies(project, rootTypeId) }
.toSet()
@Suppress("unused") // exists for debug purposes
internal fun scriptEntitiesDebugInfo(project: Project, listRoots: Boolean = false): String {
fun List<KotlinScriptLibraryRoot>.print(indent: CharSequence = " ") = asSequence()
.mapIndexed { i, root -> "$indent${i + 1}: ${root.url.presentableUrl}" }
.joinToString("\n", indent)
return buildString {
val entityStorage = WorkspaceModel.getInstance(project).currentSnapshot
val allClasses = HashSet<KotlinScriptLibraryRoot>()
val allSources = HashSet<KotlinScriptLibraryRoot>()
entityStorage.entities(KotlinScriptEntity::class.java).forEachIndexed { scriptIndex, scriptEntity ->
append("#${scriptIndex + 1}: [${scriptEntity.path}]\n")
scriptEntity.dependencies.forEachIndexed { libIndex, libId ->
val lib = entityStorage.resolve(libId) ?: return@forEachIndexed
val (classes, sources) = lib.roots.partition { it.type == KotlinScriptLibraryRootTypeId.COMPILED }
allClasses.addAll(classes)
allSources.addAll(sources)
append(" Lib #${libIndex + 1}: \"${lib.name}\", classes: ${classes.size}, sources: ${sources.size} \n")
applyIf(listRoots) {
append(" Classes:\n ${classes.print()}\n")
append(" Sources:\n ${sources.print()}\n")
}
}
}
insert(0, "==> WorkspaceModel (unique classes: ${allClasses.size}, sources: ${allSources.size})\n")
}
}
@Suppress("unused") // exists for debug purposes
internal fun managerScriptsDebugInfo(project: Project, scriptFiles: Sequence<VirtualFile>? = null): String = buildString {
val configurationManager = ScriptConfigurationManager.getInstance(project)
val allSourcesSize = configurationManager.getAllScriptDependenciesSources().size
val allSdkSourcesSize = configurationManager.getAllScriptSdkDependenciesSources().size
val allClassesSize = configurationManager.getAllScriptsDependenciesClassFiles().size
val allSdkClassesSize = configurationManager.getAllScriptsSdkDependenciesClassFiles().size
scriptFiles?.forEach {
val classDepSize = configurationManager.getScriptDependenciesClassFiles(it).size
val sourceDepSize = configurationManager.getScriptDependenciesSourceFiles(it).size
append("[${it.path}]: classes: ${classDepSize}, sources: ${sourceDepSize}\n")
}
insert(
0,
"==> ScriptConfigurationManager (classes: $allClassesSize, sdkClasses: $allSdkClassesSize, sources: $allSourcesSize, sdkSources: $allSdkSourcesSize)\n"
)
}

View File

@@ -5,7 +5,6 @@ package org.jetbrains.kotlin.idea.codeInsight.gradle
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import com.intellij.testFramework.runInEdtAndWait
@@ -13,7 +12,6 @@ import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.script.ucache.KOTLIN_SCRIPTS_AS_ENTITIES
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.plugins.gradle.extensions.cloneWithCorruptedRoots
import org.jetbrains.plugins.gradle.extensions.rootsFiles
@@ -21,44 +19,10 @@ import org.jetbrains.plugins.gradle.extensions.rootsUrls
import org.jetbrains.plugins.gradle.tooling.annotation.TargetVersions
import org.jetbrains.plugins.gradle.util.GradleConstants
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExternalResource
import org.junit.runners.Parameterized
abstract class GradleBuildFileHighlightingTest : KotlinGradleImportingTestCase() {
companion object {
private val GRADLE_VERSION_AND_SCRIPT_FLAG = SUPPORTED_GRADLE_VERSIONS
.map { listOf(arrayOf(it, false), arrayOf(it, true)) }
.flatten()
@JvmStatic
@Suppress("ACCIDENTAL_OVERRIDE")
@Parameterized.Parameters(name = "{index}: with Gradle-{0}, scriptsAsEntities-{1}")
fun testInputData(): List<Array<out Any>> = GRADLE_VERSION_AND_SCRIPT_FLAG
}
@JvmField
@Parameterized.Parameter(1)
var scriptsAsEntities: Boolean? = null
@JvmField
@Rule
val setRegistryFlag = RegistryFlagRule()
inner class RegistryFlagRule : ExternalResource() {
override fun before() {
Registry.get(KOTLIN_SCRIPTS_AS_ENTITIES).setValue(scriptsAsEntities!!)
}
override fun after() {
Registry.get(KOTLIN_SCRIPTS_AS_ENTITIES).resetToDefault()
}
}
class KtsInJsProject2114 : GradleBuildFileHighlightingTest() {
@TargetVersions("4.8 <=> 6.0")
@Test

View File

@@ -6,7 +6,6 @@ import com.intellij.build.SyncViewManager
import com.intellij.build.events.BuildEvent
import com.intellij.build.events.MessageEvent
import com.intellij.build.events.impl.MessageEventImpl
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.replaceService
@@ -58,8 +57,6 @@ abstract class GradleKtsImportTest : KotlinGradleImportingTestCase() {
@Test
@TargetVersions("6.0.1+")
fun testWorkspaceModelInSyncAfterImport() {
Registry.get("kotlin.scripts.as.entities").setValue(true)
configureByFiles()
importProject()
@@ -71,7 +68,6 @@ abstract class GradleKtsImportTest : KotlinGradleImportingTestCase() {
val ktsFile = KtsFixture(fileName).virtualFile
val (managerClassFiles, managerSourceFiles) = getDependenciesFromManager(ktsFile)
val (sdkClasses, sdkSources) = getSdkDependencies(ktsFile)
val entityStorage = WorkspaceModel.getInstance(myProject).currentSnapshot
val scriptEntity = entityStorage.entities(KotlinScriptEntity::class.java).find { it.path.contains(fileName) }
@@ -80,8 +76,8 @@ abstract class GradleKtsImportTest : KotlinGradleImportingTestCase() {
val entityClassFiles = scriptEntity.listDependencies(myProject, KotlinScriptLibraryRootTypeId.COMPILED)
val entitySourceFiles = scriptEntity.listDependencies(myProject, KotlinScriptLibraryRootTypeId.SOURCES)
assertEquals("Class dependencies for $fileName are not equivalent", entityClassFiles, managerClassFiles + sdkClasses)
assertEquals("Source dependencies for $fileName are not equivalent", entitySourceFiles, managerSourceFiles + sdkSources)
assertEquals("Class dependencies for $fileName are not equivalent", entityClassFiles, managerClassFiles)
assertEquals("Source dependencies for $fileName are not equivalent", entitySourceFiles, managerSourceFiles)
}
// classes, sources
@@ -90,13 +86,6 @@ abstract class GradleKtsImportTest : KotlinGradleImportingTestCase() {
val managerSourceFiles = scriptConfigurationManager.getScriptDependenciesSourceFiles(file)
return Pair(managerClassFiles, managerSourceFiles)
}
// classes, sources
private fun getSdkDependencies(file: VirtualFile): Pair<Collection<VirtualFile>, Collection<VirtualFile>> {
val managerClassFiles = scriptConfigurationManager.getScriptSdkDependenciesClassFiles(file)
val managerSourceFiles = scriptConfigurationManager.getScriptSdkDependenciesSourceFiles(file)
return Pair(managerClassFiles, managerSourceFiles)
}
}

View File

@@ -18,8 +18,7 @@ class RegisteredFindersTest : KotlinLightCodeInsightFixtureTestCase() {
fun testKnownNonClasspathFinder() {
val expectedFindersNames = setOf(
"GantClassFinder",
"KotlinScriptDependenciesClassFinder"
"GantClassFinder"
).toMutableSet()
val optionalFindersNames = setOf(

View File

@@ -414,7 +414,6 @@ fun checkExtract(files: ExtractTestFiles, checkAdditionalAfterdata: Boolean = fa
try {
runInEdtAndWait {
runReadAction {
// To make extraction work in `kotlin.scripts.as.entities=true` mode it's crucial to load dependencies in advance
ScriptConfigurationManager.updateScriptDependenciesSynchronously(files.mainFile)
}
}

View File

@@ -57,11 +57,8 @@
<postStartupActivity implementation="org.jetbrains.kotlin.idea.core.script.LoadScriptDefinitionsStartupActivity" order="last"/>
<java.elementFinder implementation="org.jetbrains.kotlin.idea.core.script.KotlinScriptDependenciesClassFinder" order="last"/>
<java.shortNamesCache implementation="org.jetbrains.kotlin.idea.core.script.dependencies.JavaClassesInScriptDependenciesShortNameCache"/>
<additionalLibraryRootsProvider implementation="org.jetbrains.kotlin.idea.core.script.dependencies.KotlinScriptDependenciesLibraryRootProvider"/>
<psi.clsCustomNavigationPolicy implementation="org.jetbrains.kotlin.idea.core.script.dependencies.ScriptDependencySourceNavigationPolicyForJavaClasses"/>
@@ -82,12 +79,6 @@
<!--suppress PluginXmlValidity -->
<indexableEntityProvider implementation="org.jetbrains.kotlin.idea.core.script.ucache.KotlinScriptDependencyIndexableEntityProvider"/>
<registryKey
key="kotlin.scripts.as.entities"
description="Enables explicit script dependencies support"
defaultValue="true"
restartRequired="true"/>
<registryKey
key="kotlin.scripting.support.warning"
description="Show Kotlin scripting support warning"