Load script definitions in IDE on project opening

This will speed up first script opening,
will avoid unexpected indexing because of new definitions
Script definitions are also needed for Kotlin scripting settings
This commit is contained in:
Natalia Selezneva
2020-04-02 16:02:24 +03:00
parent 942c8aaafc
commit 1513429613
2 changed files with 30 additions and 4 deletions
@@ -16,10 +16,12 @@ import com.intellij.openapi.diagnostic.ControlFlowException
import com.intellij.openapi.extensions.ExtensionPointName import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.extensions.Extensions import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.fileTypes.FileTypeManager import com.intellij.openapi.fileTypes.FileTypeManager
import com.intellij.openapi.progress.runBackgroundableTask
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.JavaSdk import com.intellij.openapi.projectRoots.JavaSdk
import com.intellij.openapi.projectRoots.ex.PathUtilEx import com.intellij.openapi.projectRoots.ex.PathUtilEx
import com.intellij.openapi.roots.ProjectRootManager import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.startup.StartupActivity
import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.openapi.vfs.VirtualFileManager
@@ -28,7 +30,9 @@ import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.caches.project.SdkInfo import org.jetbrains.kotlin.idea.caches.project.SdkInfo
import org.jetbrains.kotlin.idea.caches.project.getScriptRelatedModuleInfo import org.jetbrains.kotlin.idea.caches.project.getScriptRelatedModuleInfo
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
import org.jetbrains.kotlin.idea.util.application.executeOnPooledThread
import org.jetbrains.kotlin.idea.util.application.getServiceSafe import org.jetbrains.kotlin.idea.util.application.getServiceSafe
import org.jetbrains.kotlin.idea.util.application.isUnitTestMode
import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe
import org.jetbrains.kotlin.script.ScriptTemplatesProvider import org.jetbrains.kotlin.script.ScriptTemplatesProvider
import org.jetbrains.kotlin.scripting.definitions.* import org.jetbrains.kotlin.scripting.definitions.*
@@ -55,6 +59,20 @@ import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
import kotlin.script.experimental.jvm.util.scriptCompilationClasspathFromContextOrStdlib import kotlin.script.experimental.jvm.util.scriptCompilationClasspathFromContextOrStdlib
import kotlin.script.templates.standard.ScriptTemplateWithArgs import kotlin.script.templates.standard.ScriptTemplateWithArgs
class LoadScriptDefinitionsStartupActivity : StartupActivity {
override fun runActivity(project: Project) {
if (isUnitTestMode()) {
// In tests definitions are loaded synchronously because they are needed to analyze script
// In IDE script won't be highlighted before all definitions are loaded, then the highlighting will be restarted
ScriptDefinitionsManager.getInstance(project).reloadScriptDefinitionsIfNeeded()
} else {
executeOnPooledThread {
ScriptDefinitionsManager.getInstance(project).reloadScriptDefinitionsIfNeeded()
}
}
}
}
class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinitionProvider() { class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinitionProvider() {
private var definitionsBySource = mutableMapOf<ScriptDefinitionsSource, List<ScriptDefinition>>() private var definitionsBySource = mutableMapOf<ScriptDefinitionsSource, List<ScriptDefinition>>()
private var definitions: List<ScriptDefinition>? = null private var definitions: List<ScriptDefinition>? = null
@@ -124,7 +142,17 @@ class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinit
return fromNewEp.dropLast(1) + fromDeprecatedEP + fromNewEp.last() return fromNewEp.dropLast(1) + fromDeprecatedEP + fromNewEp.last()
} }
fun reloadScriptDefinitionsIfNeeded() = lock.write {
if (definitions == null) {
loadScriptDefinitions()
}
}
fun reloadScriptDefinitions() = lock.write { fun reloadScriptDefinitions() = lock.write {
loadScriptDefinitions()
}
private fun loadScriptDefinitions() {
for (source in getSources()) { for (source in getSources()) {
val definitions = source.safeGetDefinitions() val definitions = source.safeGetDefinitions()
definitionsBySource[source] = definitions definitionsBySource[source] = definitions
@@ -147,9 +175,6 @@ class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinit
} }
fun isReady(): Boolean { fun isReady(): Boolean {
if (definitions == null) {
reloadScriptDefinitions()
}
return definitions != null && definitionsBySource.keys.all { source -> return definitions != null && definitionsBySource.keys.all { source ->
// TODO: implement another API for readiness checking // TODO: implement another API for readiness checking
(source as? ScriptDefinitionContributor)?.isReady() != false (source as? ScriptDefinitionContributor)?.isReady() != false
@@ -319,7 +344,7 @@ fun ScriptDefinitionContributor.asSource(): ScriptDefinitionsSource =
if (this is ScriptDefinitionsSource) this if (this is ScriptDefinitionsSource) this
else ScriptDefinitionSourceFromContributor(this) else ScriptDefinitionSourceFromContributor(this)
class StandardScriptDefinitionContributor(project: Project) : ScriptDefinitionContributor { class StandardScriptDefinitionContributor(val project: Project) : ScriptDefinitionContributor {
private val standardIdeScriptDefinition = StandardIdeScriptDefinition(project) private val standardIdeScriptDefinition = StandardIdeScriptDefinition(project)
override fun getDefinitions() = listOf(standardIdeScriptDefinition) override fun getDefinitions() = listOf(standardIdeScriptDefinition)
@@ -10,5 +10,6 @@
<trafficLightRendererContributor implementation="org.jetbrains.kotlin.idea.core.script.ScriptTrafficLightRendererContributor"/> <trafficLightRendererContributor implementation="org.jetbrains.kotlin.idea.core.script.ScriptTrafficLightRendererContributor"/>
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.script.ScriptTemplatesClassRootsIndex"/> <fileBasedIndex implementation="org.jetbrains.kotlin.idea.script.ScriptTemplatesClassRootsIndex"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.core.script.LoadScriptDefinitionsStartupActivity"/>
</extensions> </extensions>
</idea-plugin> </idea-plugin>