gradle.kts: update notification only after caches updated
This commit is contained in:
+10
-3
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
|
|||||||
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesModificationTracker
|
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesModificationTracker
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptChangesNotifier
|
import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptChangesNotifier
|
||||||
import org.jetbrains.kotlin.idea.core.script.configuration.utils.getKtFile
|
import org.jetbrains.kotlin.idea.core.script.configuration.utils.getKtFile
|
||||||
|
import org.jetbrains.kotlin.idea.core.script.ucache.ScriptClassRootsBuilder
|
||||||
import org.jetbrains.kotlin.idea.core.script.ucache.ScriptClassRootsCache
|
import org.jetbrains.kotlin.idea.core.script.ucache.ScriptClassRootsCache
|
||||||
import org.jetbrains.kotlin.idea.core.script.ucache.ScriptClassRootsUpdater
|
import org.jetbrains.kotlin.idea.core.script.ucache.ScriptClassRootsUpdater
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
@@ -52,9 +53,15 @@ class CompositeScriptConfigurationManager(val project: Project) : ScriptConfigur
|
|||||||
|
|
||||||
val default = DefaultScriptingSupport(this)
|
val default = DefaultScriptingSupport(this)
|
||||||
|
|
||||||
val updater = ScriptClassRootsUpdater(project, this) { builder ->
|
val updater = object : ScriptClassRootsUpdater(project, this) {
|
||||||
default.collectConfigurations(builder)
|
override fun gatherRoots(builder: ScriptClassRootsBuilder) {
|
||||||
plugins.forEach { it.collectConfigurations(builder) }
|
default.collectConfigurations(builder)
|
||||||
|
plugins.forEach { it.collectConfigurations(builder) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun afterUpdate() {
|
||||||
|
plugins.forEach { it.afterUpdate() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tryGetScriptDefinitionFast(locationId: String): ScriptDefinition? {
|
fun tryGetScriptDefinitionFast(locationId: String): ScriptDefinition? {
|
||||||
|
|||||||
+1
@@ -35,6 +35,7 @@ interface ScriptingSupport {
|
|||||||
fun isApplicable(file: VirtualFile): Boolean
|
fun isApplicable(file: VirtualFile): Boolean
|
||||||
fun isConfigurationLoadingInProgress(file: KtFile): Boolean
|
fun isConfigurationLoadingInProgress(file: KtFile): Boolean
|
||||||
fun collectConfigurations(builder: ScriptClassRootsBuilder)
|
fun collectConfigurations(builder: ScriptClassRootsBuilder)
|
||||||
|
fun afterUpdate()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val EPN: ExtensionPointName<ScriptingSupport> =
|
val EPN: ExtensionPointName<ScriptingSupport> =
|
||||||
|
|||||||
+12
-3
@@ -47,16 +47,19 @@ import java.util.concurrent.atomic.AtomicReference
|
|||||||
* This will start indexing.
|
* This will start indexing.
|
||||||
* Also analysis cache will be cleared and changed opened script files will be reanalyzed.
|
* Also analysis cache will be cleared and changed opened script files will be reanalyzed.
|
||||||
*/
|
*/
|
||||||
class ScriptClassRootsUpdater(
|
abstract class ScriptClassRootsUpdater(
|
||||||
val project: Project,
|
val project: Project,
|
||||||
val manager: CompositeScriptConfigurationManager,
|
val manager: CompositeScriptConfigurationManager
|
||||||
private val gatherRoots: (ScriptClassRootsBuilder) -> Unit
|
|
||||||
) {
|
) {
|
||||||
private var lastSeen: ScriptClassRootsCache? = null
|
private var lastSeen: ScriptClassRootsCache? = null
|
||||||
private var invalidated: Boolean = false
|
private var invalidated: Boolean = false
|
||||||
private var syncUpdateRequired: Boolean = false
|
private var syncUpdateRequired: Boolean = false
|
||||||
private val concurrentUpdates = AtomicInteger()
|
private val concurrentUpdates = AtomicInteger()
|
||||||
|
|
||||||
|
abstract fun gatherRoots(builder: ScriptClassRootsBuilder)
|
||||||
|
|
||||||
|
abstract fun afterUpdate()
|
||||||
|
|
||||||
private fun recreateRootsCache(): ScriptClassRootsCache {
|
private fun recreateRootsCache(): ScriptClassRootsCache {
|
||||||
val builder = ScriptClassRootsBuilder(project)
|
val builder = ScriptClassRootsBuilder(project)
|
||||||
gatherRoots(builder)
|
gatherRoots(builder)
|
||||||
@@ -68,6 +71,11 @@ class ScriptClassRootsUpdater(
|
|||||||
*/
|
*/
|
||||||
private val cache: AtomicReference<ScriptClassRootsCache> = AtomicReference(recreateRootsCache())
|
private val cache: AtomicReference<ScriptClassRootsCache> = AtomicReference(recreateRootsCache())
|
||||||
|
|
||||||
|
init {
|
||||||
|
@Suppress("LeakingThis")
|
||||||
|
afterUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
val classpathRoots: ScriptClassRootsCache
|
val classpathRoots: ScriptClassRootsCache
|
||||||
get() = cache.get()
|
get() = cache.get()
|
||||||
|
|
||||||
@@ -196,6 +204,7 @@ class ScriptClassRootsUpdater(
|
|||||||
val old = cache.get()
|
val old = cache.get()
|
||||||
val new = recreateRootsCache()
|
val new = recreateRootsCache()
|
||||||
if (cache.compareAndSet(old, new)) {
|
if (cache.compareAndSet(old, new)) {
|
||||||
|
afterUpdate()
|
||||||
return new.diff(lastSeen)
|
return new.diff(lastSeen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
|||||||
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
||||||
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
|
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [GradleBuildRoot] is a linked gradle build (don't confuse with gradle project and included build).
|
* [GradleBuildRoot] is a linked gradle build (don't confuse with gradle project and included build).
|
||||||
@@ -28,8 +29,11 @@ import java.io.File
|
|||||||
sealed class GradleBuildRoot(
|
sealed class GradleBuildRoot(
|
||||||
private val lastModifiedFiles: LastModifiedFiles
|
private val lastModifiedFiles: LastModifiedFiles
|
||||||
) {
|
) {
|
||||||
@Volatile
|
enum class ImportingStatus {
|
||||||
var importing = false
|
importing, updatingCaches, updated
|
||||||
|
}
|
||||||
|
|
||||||
|
val importing = AtomicReference(ImportingStatus.updated)
|
||||||
|
|
||||||
abstract val pathPrefix: String
|
abstract val pathPrefix: String
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -86,7 +86,7 @@ abstract class GradleBuildRootsLocator {
|
|||||||
isImported -> NotificationKind.dontCare
|
isImported -> NotificationKind.dontCare
|
||||||
standalone -> NotificationKind.standalone
|
standalone -> NotificationKind.standalone
|
||||||
nearest == null -> NotificationKind.outsideAnything
|
nearest == null -> NotificationKind.outsideAnything
|
||||||
nearest.importing -> NotificationKind.dontCare
|
importing -> NotificationKind.dontCare
|
||||||
else -> when (nearest) {
|
else -> when (nearest) {
|
||||||
is Legacy -> NotificationKind.dontCare
|
is Legacy -> NotificationKind.dontCare
|
||||||
is New -> NotificationKind.wasNotImportedAfterCreation
|
is New -> NotificationKind.wasNotImportedAfterCreation
|
||||||
@@ -97,6 +97,10 @@ abstract class GradleBuildRootsLocator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val importing: Boolean
|
||||||
|
get() = nearest != null &&
|
||||||
|
nearest.importing.get() != GradleBuildRoot.ImportingStatus.updated
|
||||||
|
|
||||||
private val isImported: Boolean
|
private val isImported: Boolean
|
||||||
get() = script != null
|
get() = script != null
|
||||||
|
|
||||||
|
|||||||
+18
-8
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.core.script.ucache.ScriptClassRootsBuilder
|
|||||||
import org.jetbrains.kotlin.idea.core.util.EDT
|
import org.jetbrains.kotlin.idea.core.util.EDT
|
||||||
import org.jetbrains.kotlin.idea.scripting.gradle.*
|
import org.jetbrains.kotlin.idea.scripting.gradle.*
|
||||||
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslGradleBuildSync
|
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslGradleBuildSync
|
||||||
|
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRoot.ImportingStatus.*
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||||
@@ -88,8 +89,8 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun isConfigurationLoadingInProgress(file: KtFile): Boolean {
|
override fun isConfigurationLoadingInProgress(file: KtFile): Boolean {
|
||||||
return when (val root = findScriptBuildRoot(file.originalFile.virtualFile)?.root) {
|
return when (val root = findScriptBuildRoot(file.originalFile.virtualFile)?.nearest) {
|
||||||
is GradleBuildRoot -> root.importing
|
is GradleBuildRoot -> root.importing.get() != updated
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,6 +109,14 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun afterUpdate() {
|
||||||
|
roots.list.forEach { root ->
|
||||||
|
if (root.importing.compareAndSet(updatingCaches, updated)) {
|
||||||
|
updateNotifications { it.startsWith(root.pathPrefix) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
override fun getScriptInfo(localPath: String): GradleScriptInfo? =
|
override fun getScriptInfo(localPath: String): GradleScriptInfo? =
|
||||||
@@ -126,7 +135,7 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun markImportingInProgress(workingDir: String, inProgress: Boolean = true) {
|
fun markImportingInProgress(workingDir: String, inProgress: Boolean = true) {
|
||||||
actualizeBuildRoot(workingDir)?.importing = inProgress
|
actualizeBuildRoot(workingDir)?.importing?.set(if (inProgress) importing else updated)
|
||||||
updateNotifications { it.startsWith(workingDir) }
|
updateNotifications { it.startsWith(workingDir) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,10 +146,10 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
if (root is Imported && root.data.models.isEmpty()) return
|
if (root is Imported && root.data.models.isEmpty()) return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
val oldRoot = actualizeBuildRoot(sync.workingDir) ?: return
|
||||||
val oldRoot = actualizeBuildRoot(sync.workingDir) ?: return
|
oldRoot.importing.set(updatingCaches)
|
||||||
oldRoot.importing = false
|
|
||||||
|
|
||||||
|
try {
|
||||||
if (oldRoot is Legacy) return
|
if (oldRoot is Legacy) return
|
||||||
|
|
||||||
val templateClasspath = GradleScriptDefinitionsContributor.getDefinitionsTemplateClasspath(project)
|
val templateClasspath = GradleScriptDefinitionsContributor.getDefinitionsTemplateClasspath(project)
|
||||||
@@ -153,8 +162,9 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
|||||||
newRoot.saveLastModifiedFiles()
|
newRoot.saveLastModifiedFiles()
|
||||||
|
|
||||||
add(newRoot)
|
add(newRoot)
|
||||||
} finally {
|
} catch (e: Throwable) {
|
||||||
updateNotifications { it.startsWith(sync.workingDir) }
|
markImportingInProgress(sync.workingDir, false)
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user