@@ -3,6 +3,7 @@ package project
3
3
import (
4
4
"context"
5
5
"fmt"
6
+ "maps"
6
7
"slices"
7
8
"sync"
8
9
@@ -14,7 +15,7 @@ import (
14
15
)
15
16
16
17
type ConfigFileEntry struct {
17
- mu sync.Mutex
18
+ mu sync.RWMutex
18
19
commandLine * tsoptions.ParsedCommandLine
19
20
projects collections.Set [* Project ]
20
21
infos collections.Set [* ScriptInfo ]
@@ -114,6 +115,8 @@ func (c *ConfigFileRegistry) acquireConfig(fileName string, path tspath.Path, pr
114
115
func (c * ConfigFileRegistry ) getConfig (path tspath.Path ) * tsoptions.ParsedCommandLine {
115
116
entry , ok := c .ConfigFiles .Load (path )
116
117
if ok {
118
+ entry .mu .RLock ()
119
+ defer entry .mu .RUnlock ()
117
120
return entry .commandLine
118
121
}
119
122
return nil
@@ -199,48 +202,58 @@ func (c *ConfigFileRegistry) onConfigChange(path tspath.Path, changeKind lsproto
199
202
return false
200
203
}
201
204
entry .mu .Lock ()
202
- defer entry .mu .Unlock ()
203
- if entry .SetPendingReload (PendingReloadFull ) {
204
- for info := range entry .infos .Keys () {
205
- delete (c .defaultProjectFinder .configFileForOpenFiles , info .Path ())
206
- delete (c .defaultProjectFinder .configFilesAncestorForOpenFiles , info .Path ())
207
- }
208
- for project := range entry .projects .Keys () {
209
- if project .configFilePath == path {
210
- switch changeKind {
211
- case lsproto .FileChangeTypeCreated :
212
- fallthrough
213
- case lsproto .FileChangeTypeChanged :
214
- project .deferredClose = false
215
- project .SetPendingReload (PendingReloadFull )
216
- case lsproto .FileChangeTypeDeleted :
217
- project .deferredClose = true
218
- }
219
- } else {
220
- project .markAsDirty ()
205
+ hasSet := entry .SetPendingReload (PendingReloadFull )
206
+ var infos map [* ScriptInfo ]struct {}
207
+ var projects map [* Project ]struct {}
208
+ if hasSet {
209
+ infos = maps .Clone (entry .infos .Keys ())
210
+ projects = maps .Clone (entry .projects .Keys ())
211
+ }
212
+ entry .mu .Unlock ()
213
+ if ! hasSet {
214
+ return false
215
+ }
216
+ for info := range infos {
217
+ delete (c .defaultProjectFinder .configFileForOpenFiles , info .Path ())
218
+ delete (c .defaultProjectFinder .configFilesAncestorForOpenFiles , info .Path ())
219
+ }
220
+ for project := range projects {
221
+ if project .configFilePath == path {
222
+ switch changeKind {
223
+ case lsproto .FileChangeTypeCreated :
224
+ fallthrough
225
+ case lsproto .FileChangeTypeChanged :
226
+ project .deferredClose = false
227
+ project .SetPendingReload (PendingReloadFull )
228
+ case lsproto .FileChangeTypeDeleted :
229
+ project .deferredClose = true
221
230
}
231
+ } else {
232
+ project .markAsDirty ()
222
233
}
223
- return true
224
234
}
225
- return false
235
+ return true
226
236
}
227
237
228
238
func (c * ConfigFileRegistry ) tryInvokeWildCardDirectories (fileName string , path tspath.Path ) {
229
239
configFiles := c .ConfigFiles .ToMap ()
230
240
for configPath , entry := range configFiles {
231
241
entry .mu .Lock ()
232
- if entry .commandLine != nil && entry .commandLine .MatchesFileName (fileName ) {
233
- if entry .SetPendingReload (PendingReloadFileNames ) {
234
- for project := range entry .projects .Keys () {
235
- if project .configFilePath == configPath {
236
- project .SetPendingReload (PendingReloadFileNames )
237
- } else {
238
- project .markAsDirty ()
239
- }
242
+ hasSet := entry .commandLine != nil && entry .commandLine .MatchesFileName (fileName ) && entry .SetPendingReload (PendingReloadFileNames )
243
+ var projects map [* Project ]struct {}
244
+ if hasSet {
245
+ projects = maps .Clone (entry .projects .Keys ())
246
+ }
247
+ entry .mu .Unlock ()
248
+ if hasSet {
249
+ for project := range projects {
250
+ if project .configFilePath == configPath {
251
+ project .SetPendingReload (PendingReloadFileNames )
252
+ } else {
253
+ project .markAsDirty ()
240
254
}
241
255
}
242
256
}
243
- entry .mu .Unlock ()
244
257
}
245
258
}
246
259
0 commit comments