1
1
package com.intellij.lang.jsgraphql.schema.library
2
2
3
3
import com.intellij.openapi.application.ApplicationManager
4
+ import com.intellij.openapi.application.readAction
4
5
import com.intellij.openapi.components.Service
5
6
import com.intellij.openapi.components.service
6
7
import com.intellij.openapi.components.serviceAsync
@@ -14,13 +15,11 @@ import com.intellij.platform.backend.workspace.toVirtualFileUrl
14
15
import com.intellij.platform.workspace.storage.MutableEntityStorage
15
16
import com.intellij.psi.search.GlobalSearchScope
16
17
import com.intellij.util.PathUtil
18
+ import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
19
+ import com.intellij.util.concurrency.annotations.RequiresReadLockAbsence
17
20
import com.intellij.util.io.URLUtil
18
- import kotlinx.coroutines.CoroutineScope
19
- import kotlinx.coroutines.future.asCompletableFuture
20
- import kotlinx.coroutines.launch
21
+ import org.jetbrains.annotations.ApiStatus
21
22
import org.jetbrains.annotations.TestOnly
22
- import org.jetbrains.annotations.VisibleForTesting
23
- import java.util.concurrent.CompletableFuture
24
23
import java.util.concurrent.ConcurrentHashMap
25
24
import kotlin.concurrent.Volatile
26
25
@@ -35,8 +34,9 @@ private val BUNDLED_RESOURCE_PATHS = mapOf(
35
34
36
35
private val BUNDLED_LIBRARIES_IDS = BUNDLED_RESOURCE_PATHS .keys.map { it.identifier }.toSet()
37
36
37
+ @ApiStatus.Experimental
38
38
@Service(Service .Level .PROJECT )
39
- class GraphQLLibraryManager (private val project : Project , @VisibleForTesting val cs : CoroutineScope ) {
39
+ class GraphQLLibraryManager (private val project : Project ) {
40
40
companion object {
41
41
private val LOG = logger<GraphQLLibraryManager >()
42
42
@@ -57,18 +57,17 @@ class GraphQLLibraryManager(private val project: Project, @VisibleForTesting val
57
57
shouldInitializeLibraries = enabled
58
58
}
59
59
60
- private val isEnabled: Boolean
61
- get() = ApplicationManager .getApplication().isUnitTestMode() && ! shouldInitializeLibraries
62
-
63
60
/* *
64
61
* Registers an external GraphQL library.
65
62
* If a library with the same identifier is already registered,
66
63
* it will be replaced with the new library.
67
64
*
68
65
* @param library The external GraphQL library to register, containing its descriptor and set of root URLs.
69
66
*/
67
+ @RequiresBackgroundThread
68
+ @RequiresReadLockAbsence
70
69
suspend fun registerExternalLibrary (library : GraphQLLibrary ) {
71
- if (isEnabled ) {
70
+ if (! shouldInitializeLibraries ) {
72
71
return
73
72
}
74
73
@@ -81,16 +80,16 @@ class GraphQLLibraryManager(private val project: Project, @VisibleForTesting val
81
80
attachLibrary(library)
82
81
}
83
82
84
- private fun isBundledLibrary (library : GraphQLLibrary ): Boolean = library.descriptor.identifier in BUNDLED_LIBRARIES_IDS
85
-
86
83
/* *
87
84
* If the specified library is not currently registered, a warning message is logged.
88
85
* Otherwise, the library is removed from the list of external libraries and detached.
89
86
*
90
87
* @param library The external GraphQL library to unregister, containing its descriptor and set of root URLs.
91
88
*/
89
+ @RequiresBackgroundThread
90
+ @RequiresReadLockAbsence
92
91
suspend fun unregisterExternalLibrary (library : GraphQLLibrary ) {
93
- if (isEnabled ) {
92
+ if (! shouldInitializeLibraries ) {
94
93
return
95
94
}
96
95
@@ -115,31 +114,19 @@ class GraphQLLibraryManager(private val project: Project, @VisibleForTesting val
115
114
* @see getOrCreateLibraries
116
115
* @see updateLibrariesWorkspaceModel
117
116
*/
117
+ @RequiresBackgroundThread
118
+ @RequiresReadLockAbsence
118
119
suspend fun syncLibraries () {
119
- if (isEnabled ) {
120
+ if (! shouldInitializeLibraries ) {
120
121
return
121
122
}
122
123
123
124
val libraries = getOrCreateLibraries().also { LOG .debug { " GraphQL libraries to sync:\n ${it.joinToString(" \n " )} " } }
124
- val availableLibraries = libraries.filter { it.descriptor.isEnabled(project) }
125
+ val availableLibraries = libraries.filter { readAction { it.descriptor.isEnabled(project) } }
125
126
updateLibrariesWorkspaceModel(availableLibraries)
126
127
}
127
128
128
- /* *
129
- * Schedules the synchronization of GraphQL libraries in the workspace.
130
- *
131
- * This method triggers the [syncLibraries] function to execute asynchronously,
132
- * ensuring that the libraries, both external and bundled, are synchronized and updated
133
- * in the workspace model.
134
- *
135
- * The synchronization is managed using a CompletableFuture, allowing the Java code
136
- * to monitor its completion or handle any exceptions.
137
- *
138
- * @return A [CompletableFuture] representing the asynchronous task of library synchronization.
139
- */
140
- fun scheduleLibrariesSynchronization (): CompletableFuture <Unit > {
141
- return cs.launch { syncLibraries() }.asCompletableFuture()
142
- }
129
+ private fun isBundledLibrary (library : GraphQLLibrary ): Boolean = library.descriptor.identifier in BUNDLED_LIBRARIES_IDS
143
130
144
131
val libraries: Collection <GraphQLLibrary >
145
132
get() = sequenceOf(bundledLibraries.values, externalLibraries.values)
0 commit comments