scripting ucache: update synchronously in unit test mode
This commit is contained in:
+1
-1
@@ -96,7 +96,7 @@ class CompositeScriptConfigurationManager(val project: Project) : ScriptConfigur
|
|||||||
default.updateScriptDefinitionsReferences()
|
default.updateScriptDefinitionsReferences()
|
||||||
|
|
||||||
if (classpathRoots.customDefinitionsUsed) {
|
if (classpathRoots.customDefinitionsUsed) {
|
||||||
updater.ensureUpdateScheduled()
|
updater.invalidateAndCommit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-5
@@ -34,12 +34,22 @@ import java.util.concurrent.locks.ReentrantLock
|
|||||||
import kotlin.concurrent.withLock
|
import kotlin.concurrent.withLock
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility for postponing indexing of new roots to the end of some bulk operation.
|
* Holder for [ScriptClassRootsCache].
|
||||||
|
*
|
||||||
|
* Updates of [classpathRoots] performed asynchronously using the copy-on-write strategy.
|
||||||
|
* [gatherRoots] called when updating is required. Cache will built from the scratch.
|
||||||
|
*
|
||||||
|
* Updates can be coalesced by using `update { invalidate() }` transaction.
|
||||||
|
* As an alternative you can just call [invalidateAndCommit].
|
||||||
|
*
|
||||||
|
* After update roots changed event will be triggered if there are new root.
|
||||||
|
* This will start indexing.
|
||||||
|
* Also analysis cache will be cleared and changed opened script files will be reanalyzed.
|
||||||
*/
|
*/
|
||||||
class ScriptClassRootsUpdater(
|
class ScriptClassRootsUpdater(
|
||||||
val project: Project,
|
val project: Project,
|
||||||
val manager: CompositeScriptConfigurationManager,
|
val manager: CompositeScriptConfigurationManager,
|
||||||
private val buildNewRoots: (ScriptClassRootsBuilder) -> Unit
|
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
|
||||||
@@ -48,10 +58,11 @@ class ScriptClassRootsUpdater(
|
|||||||
|
|
||||||
private fun recreateRootsCache(): ScriptClassRootsCache {
|
private fun recreateRootsCache(): ScriptClassRootsCache {
|
||||||
val builder = ScriptClassRootsBuilder(project)
|
val builder = ScriptClassRootsBuilder(project)
|
||||||
buildNewRoots(builder)
|
gatherRoots(builder)
|
||||||
return builder.build()
|
return builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Volatile
|
||||||
var classpathRoots: ScriptClassRootsCache = recreateRootsCache()
|
var classpathRoots: ScriptClassRootsCache = recreateRootsCache()
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@@ -77,6 +88,10 @@ class ScriptClassRootsUpdater(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun invalidateAndCommit() {
|
||||||
|
update { invalidate() }
|
||||||
|
}
|
||||||
|
|
||||||
fun checkInTransaction() {
|
fun checkInTransaction() {
|
||||||
check(concurrentUpdates.get() > 0)
|
check(concurrentUpdates.get() > 0)
|
||||||
}
|
}
|
||||||
@@ -119,7 +134,7 @@ class ScriptClassRootsUpdater(
|
|||||||
private var scheduledUpdate: ProgressIndicator? = null
|
private var scheduledUpdate: ProgressIndicator? = null
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun ensureUpdateScheduled() {
|
private fun ensureUpdateScheduled() {
|
||||||
scheduledUpdate?.cancel()
|
scheduledUpdate?.cancel()
|
||||||
runReadAction {
|
runReadAction {
|
||||||
if (project.isDisposed && !Disposer.isDisposing(project)) {
|
if (project.isDisposed && !Disposer.isDisposing(project)) {
|
||||||
@@ -136,12 +151,14 @@ class ScriptClassRootsUpdater(
|
|||||||
doUpdate(false)
|
doUpdate(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkInvalidSdks(remove: Sdk? = null) {
|
internal fun checkInvalidSdks(remove: Sdk? = null) {
|
||||||
// sdks should be updated synchronously to avoid disposed roots usage
|
// sdks should be updated synchronously to avoid disposed roots usage
|
||||||
syncLock.withLock {
|
syncLock.withLock {
|
||||||
val current = classpathRoots
|
val current = classpathRoots
|
||||||
val actualSdks = current.sdks.rebuild(remove = remove)
|
val actualSdks = current.sdks.rebuild(remove = remove)
|
||||||
if (actualSdks != current.sdks) {
|
if (actualSdks != current.sdks) {
|
||||||
|
// don't call invalidateAndCommit as it may be synchronous
|
||||||
|
// let's update sdks immediately and schedule cache rebuilding
|
||||||
classpathRoots = current.withUpdatedSdks(actualSdks)
|
classpathRoots = current.withUpdatedSdks(actualSdks)
|
||||||
ensureUpdateScheduled()
|
ensureUpdateScheduled()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -342,7 +342,7 @@ class GradleBuildRootsManager(val project: Project) : ScriptingSupport() {
|
|||||||
val old = roots.add(newRoot)
|
val old = roots.add(newRoot)
|
||||||
if (old is GradleBuildRoot.Imported) removeData(old.pathPrefix)
|
if (old is GradleBuildRoot.Imported) removeData(old.pathPrefix)
|
||||||
if (old is GradleBuildRoot.Imported || newRoot is GradleBuildRoot.Imported) {
|
if (old is GradleBuildRoot.Imported || newRoot is GradleBuildRoot.Imported) {
|
||||||
updater.ensureUpdateScheduled()
|
updater.invalidateAndCommit()
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNotifications(newRoot.pathPrefix)
|
updateNotifications(newRoot.pathPrefix)
|
||||||
@@ -352,7 +352,7 @@ class GradleBuildRootsManager(val project: Project) : ScriptingSupport() {
|
|||||||
val removed = roots.remove(rootPath)
|
val removed = roots.remove(rootPath)
|
||||||
if (removed is GradleBuildRoot.Imported) {
|
if (removed is GradleBuildRoot.Imported) {
|
||||||
removeData(rootPath)
|
removeData(rootPath)
|
||||||
updater.ensureUpdateScheduled()
|
updater.invalidateAndCommit()
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNotifications(rootPath)
|
updateNotifications(rootPath)
|
||||||
|
|||||||
Reference in New Issue
Block a user