@@ -191,9 +191,9 @@ data ShakeExtras = ShakeExtras
191
191
,logger :: Logger
192
192
,globals :: Var (HMap. HashMap TypeRep Dynamic )
193
193
,state :: Values
194
- ,diagnostics :: Var DiagnosticStore
195
- ,hiddenDiagnostics :: Var DiagnosticStore
196
- ,publishedDiagnostics :: Var ( HMap. HashMap NormalizedUri [Diagnostic ])
194
+ ,diagnostics :: STMDiagnosticStore
195
+ ,hiddenDiagnostics :: STMDiagnosticStore
196
+ ,publishedDiagnostics :: STM. Map NormalizedUri [Diagnostic ]
197
197
-- ^ This represents the set of diagnostics that we have published.
198
198
-- Due to debouncing not every change might get published.
199
199
,positionMapping :: Var (HMap. HashMap NormalizedUri (Map TextDocumentVersion (PositionDelta , PositionMapping )))
@@ -437,8 +437,8 @@ deleteValue
437
437
=> ShakeExtras
438
438
-> k
439
439
-> NormalizedFilePath
440
- -> IO ()
441
- deleteValue ShakeExtras {dirtyKeys, state} key file = atomically $ do
440
+ -> STM ()
441
+ deleteValue ShakeExtras {dirtyKeys, state} key file = do
442
442
STM. delete (toKey key file) state
443
443
modifyTVar' dirtyKeys $ HSet. insert (toKey key file)
444
444
@@ -447,10 +447,11 @@ recordDirtyKeys
447
447
=> ShakeExtras
448
448
-> k
449
449
-> [NormalizedFilePath ]
450
- -> IO ()
451
- recordDirtyKeys ShakeExtras {dirtyKeys} key file = withEventTrace " recordDirtyKeys" $ \ addEvent -> do
452
- atomically $ modifyTVar' dirtyKeys $ \ x -> foldl' (flip HSet. insert) x (toKey key <$> file)
453
- addEvent (fromString $ " dirty " <> show key) (fromString $ unlines $ map fromNormalizedFilePath file)
450
+ -> STM (IO () )
451
+ recordDirtyKeys ShakeExtras {dirtyKeys} key file = do
452
+ modifyTVar' dirtyKeys $ \ x -> foldl' (flip HSet. insert) x (toKey key <$> file)
453
+ return $ withEventTrace " recordDirtyKeys" $ \ addEvent -> do
454
+ addEvent (fromString $ " dirty " <> show key) (fromString $ unlines $ map fromNormalizedFilePath file)
454
455
455
456
456
457
-- | We return Nothing if the rule has not run and Just Failed if it has failed to produce a value.
@@ -509,9 +510,9 @@ shakeOpen lspEnv defaultConfig logger debouncer
509
510
shakeExtras <- do
510
511
globals <- newVar HMap. empty
511
512
state <- STM. newIO
512
- diagnostics <- newVar mempty
513
- hiddenDiagnostics <- newVar mempty
514
- publishedDiagnostics <- newVar mempty
513
+ diagnostics <- STM. newIO
514
+ hiddenDiagnostics <- STM. newIO
515
+ publishedDiagnostics <- STM. newIO
515
516
positionMapping <- newVar HMap. empty
516
517
knownTargetsVar <- newVar $ hashed HMap. empty
517
518
let restartShakeSession = shakeRestart ideState
@@ -756,15 +757,13 @@ instantiateDelayedAction (DelayedAction _ s p a) = do
756
757
d' = DelayedAction (Just u) s p a'
757
758
return (b, d')
758
759
759
- getDiagnostics :: IdeState -> IO [FileDiagnostic ]
760
+ getDiagnostics :: IdeState -> STM [FileDiagnostic ]
760
761
getDiagnostics IdeState {shakeExtras = ShakeExtras {diagnostics}} = do
761
- val <- readVar diagnostics
762
- return $ getAllDiagnostics val
762
+ getAllDiagnostics diagnostics
763
763
764
- getHiddenDiagnostics :: IdeState -> IO [FileDiagnostic ]
764
+ getHiddenDiagnostics :: IdeState -> STM [FileDiagnostic ]
765
765
getHiddenDiagnostics IdeState {shakeExtras = ShakeExtras {hiddenDiagnostics}} = do
766
- val <- readVar hiddenDiagnostics
767
- return $ getAllDiagnostics val
766
+ getAllDiagnostics hiddenDiagnostics
768
767
769
768
-- | Find and release old keys from the state Hashmap
770
769
-- For the record, there are other state sources that this process does not release:
@@ -1154,30 +1153,26 @@ updateFileDiagnostics fp k ShakeExtras{logger, diagnostics, hiddenDiagnostics, p
1154
1153
let (currentShown, currentHidden) = partition ((== ShowDiag ) . fst ) current
1155
1154
uri = filePathToUri' fp
1156
1155
ver = vfsVersion =<< modTime
1157
- update new store =
1158
- let store' = setStageDiagnostics uri ver (T. pack $ show k) new store
1159
- new' = getUriDiagnostics uri store'
1160
- in (store', new')
1156
+ update new store = setStageDiagnostics uri ver (T. pack $ show k) new store
1161
1157
mask_ $ do
1162
1158
-- Mask async exceptions to ensure that updated diagnostics are always
1163
1159
-- published. Otherwise, we might never publish certain diagnostics if
1164
1160
-- an exception strikes between modifyVar but before
1165
1161
-- publishDiagnosticsNotification.
1166
- newDiags <- modifyVar diagnostics $ pure . update (map snd currentShown)
1167
- _ <- modifyVar hiddenDiagnostics $ pure . update (map snd currentHidden)
1162
+ newDiags <- liftIO $ atomically $ update (map snd currentShown) diagnostics
1163
+ _ <- liftIO $ atomically $ update (map snd currentHidden) hiddenDiagnostics
1168
1164
let uri = filePathToUri' fp
1169
1165
let delay = if null newDiags then 0.1 else 0
1170
1166
registerEvent debouncer delay uri $ do
1171
- join $ mask_ $ modifyVar publishedDiagnostics $ \ published -> do
1172
- let lastPublish = HMap. lookupDefault [] uri published
1173
- ! published' = HMap. insert uri newDiags published
1174
- action = when (lastPublish /= newDiags) $ case lspEnv of
1167
+ join $ mask_ $ do
1168
+ lastPublish <- atomically $ STM. focus (Focus. lookupWithDefault [] <* Focus. insert newDiags) uri publishedDiagnostics
1169
+ let action = when (lastPublish /= newDiags) $ case lspEnv of
1175
1170
Nothing -> -- Print an LSP event.
1176
1171
logInfo logger $ showDiagnosticsColored $ map (fp,ShowDiag ,) newDiags
1177
1172
Just env -> LSP. runLspT env $
1178
1173
LSP. sendNotification LSP. STextDocumentPublishDiagnostics $
1179
1174
LSP. PublishDiagnosticsParams (fromNormalizedUri uri) ver (List newDiags)
1180
- return (published', action)
1175
+ return action
1181
1176
1182
1177
newtype Priority = Priority Double
1183
1178
@@ -1192,10 +1187,21 @@ actionLogger = do
1192
1187
ShakeExtras {logger} <- getShakeExtras
1193
1188
return logger
1194
1189
1190
+ --------------------------------------------------------------------------------
1191
+ type STMDiagnosticStore = STM. Map NormalizedUri StoreItem
1195
1192
1196
1193
getDiagnosticsFromStore :: StoreItem -> [Diagnostic ]
1197
1194
getDiagnosticsFromStore (StoreItem _ diags) = concatMap SL. fromSortedList $ Map. elems diags
1198
1195
1196
+ updateSTMDiagnostics :: STMDiagnosticStore
1197
+ -> NormalizedUri -> TextDocumentVersion -> DiagnosticsBySource
1198
+ -> STM [LSP. Diagnostic ]
1199
+ updateSTMDiagnostics store uri mv newDiagsBySource =
1200
+ getDiagnosticsFromStore . fromJust <$> STM. focus (Focus. alter update *> Focus. lookup ) uri store
1201
+ where
1202
+ update (Just (StoreItem mvs dbs))
1203
+ | mvs == mv = Just (StoreItem mv (newDiagsBySource <> dbs))
1204
+ update _ = Just (StoreItem mv newDiagsBySource)
1199
1205
1200
1206
-- | Sets the diagnostics for a file and compilation step
1201
1207
-- if you want to clear the diagnostics call this with an empty list
@@ -1204,25 +1210,17 @@ setStageDiagnostics
1204
1210
-> TextDocumentVersion -- ^ the time that the file these diagnostics originate from was last edited
1205
1211
-> T. Text
1206
1212
-> [LSP. Diagnostic ]
1207
- -> DiagnosticStore
1208
- -> DiagnosticStore
1209
- setStageDiagnostics uri ver stage diags ds = updateDiagnostics ds uri ver updatedDiags
1213
+ -> STMDiagnosticStore
1214
+ -> STM [ LSP. Diagnostic ]
1215
+ setStageDiagnostics uri ver stage diags ds = updateSTMDiagnostics ds uri ver updatedDiags
1210
1216
where
1211
1217
updatedDiags = Map. singleton (Just stage) (SL. toSortedList diags)
1212
1218
1213
1219
getAllDiagnostics ::
1214
- DiagnosticStore ->
1215
- [FileDiagnostic ]
1220
+ STMDiagnosticStore ->
1221
+ STM [FileDiagnostic ]
1216
1222
getAllDiagnostics =
1217
- concatMap (\ (k,v) -> map (fromUri k,ShowDiag ,) $ getDiagnosticsFromStore v) . HMap. toList
1218
-
1219
- getUriDiagnostics ::
1220
- NormalizedUri ->
1221
- DiagnosticStore ->
1222
- [LSP. Diagnostic ]
1223
- getUriDiagnostics uri ds =
1224
- maybe [] getDiagnosticsFromStore $
1225
- HMap. lookup uri ds
1223
+ fmap (concatMap (\ (k,v) -> map (fromUri k,ShowDiag ,) $ getDiagnosticsFromStore v)) . ListT. toList . STM. listT
1226
1224
1227
1225
updatePositionMapping :: IdeState -> VersionedTextDocumentIdentifier -> List TextDocumentContentChangeEvent -> IO ()
1228
1226
updatePositionMapping IdeState {shakeExtras = ShakeExtras {positionMapping}} VersionedTextDocumentIdentifier {.. } (List changes) = do
0 commit comments