Refactor the mechanism how script configurations are updated

Introduce file attributes cache, which is only applicable when no dependencies are cached in memory cache
Refactor ScriptDependenciesCache to memory cache that is able to get configuration from cache and checks if it is up to date
Move all public methods to ScriptDependenciesManager
Introduce ScriptClassRootsManager that checks if root change event should be called after script configuration update
This commit is contained in:
Natalia Selezneva
2019-08-22 11:59:32 +03:00
parent dc46f73ecf
commit 961e8c2c74
37 changed files with 1025 additions and 898 deletions
@@ -12,6 +12,7 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResult
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
import kotlin.script.experimental.api.valueOrNull
import kotlin.script.experimental.dependencies.ScriptDependencies
@@ -22,17 +23,19 @@ open class ScriptDependenciesProvider constructor(
@Deprecated("Migrating to configuration refinement", level = DeprecationLevel.ERROR)
fun getScriptDependencies(file: VirtualFile): ScriptDependencies? {
val ktFile = PsiManager.getInstance(project).findFile(file) as? KtFile ?: return null
return getScriptConfigurationResult(ktFile)?.valueOrNull()?.legacyDependencies
return getScriptConfiguration(ktFile)?.legacyDependencies
}
@Deprecated("Migrating to configuration refinement", level = DeprecationLevel.ERROR)
fun getScriptDependencies(file: PsiFile): ScriptDependencies? {
if (file !is KtFile) return null
return getScriptConfigurationResult(file)?.valueOrNull()?.legacyDependencies
return getScriptConfiguration(file)?.legacyDependencies
}
open fun getScriptConfigurationResult(file: KtFile): ScriptCompilationConfigurationResult? = null
open fun getScriptConfiguration(file: KtFile): ScriptCompilationConfigurationWrapper? = getScriptConfigurationResult(file)?.valueOrNull()
companion object {
fun getInstance(project: Project): ScriptDependenciesProvider? =
ServiceManager.getService(project, ScriptDependenciesProvider::class.java)
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResu
import kotlin.script.experimental.api.ScriptCompilationConfiguration
import kotlin.script.experimental.api.ScriptDiagnostic
import kotlin.script.experimental.api.valueOr
import kotlin.script.experimental.api.valueOrNull
fun PsiFile.findScriptCompilationConfiguration(): ScriptCompilationConfiguration? {
// Do not use psiFile.script, see comments in findScriptDefinition
@@ -21,7 +20,7 @@ fun PsiFile.findScriptCompilationConfiguration(): ScriptCompilationConfiguration
val provider = ScriptDependenciesProvider.getInstance(project)
// Ignoring the error here, assuming that it will be reported elsewhere anyway (this is important scenario in IDE)
return provider?.getScriptConfigurationResult(this)?.valueOrNull()?.configuration
return provider?.getScriptConfiguration(this)?.configuration
?: findScriptDefinition()?.compilationConfiguration
}
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.psi.KtImportInfo
import org.jetbrains.kotlin.resolve.ImportPath
import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider
import kotlin.script.experimental.api.valueOrNull
class ScriptExtraImportsProviderExtension : ExtraImportsProviderExtension {
@@ -30,8 +29,7 @@ class ScriptExtraImportsProviderExtension : ExtraImportsProviderExtension {
override fun getExtraImports(ktFile: KtFile): Collection<KtImportInfo> =
ktFile.takeIf { it.isScript() }?.let { file ->
val refinedConfiguration = ScriptDependenciesProvider.getInstance(file.project)
?.getScriptConfigurationResult(file.originalFile as KtFile)
?.valueOrNull()
?.getScriptConfiguration(file.originalFile as KtFile)
refinedConfiguration?.defaultImports?.map {
ScriptExtraImportImpl(
ImportPath.fromString(it)
@@ -205,7 +205,7 @@ class LazyScriptDescriptor(
val res = ArrayList<ClassDescriptor>()
val importedScriptsFiles = ScriptDependenciesProvider.getInstance(scriptInfo.script.project)
?.getScriptConfigurationResult(scriptInfo.script.containingKtFile)?.valueOrNull()?.importedScripts
?.getScriptConfiguration(scriptInfo.script.containingKtFile)?.importedScripts
if (importedScriptsFiles != null) {
val findImportedScriptDescriptor = ImportedScriptDescriptorsFinder()
importedScriptsFiles.mapNotNullTo(res) {