@@ -82,7 +82,7 @@ import Control.Concurrent.STM.Stats (atomicallyNamed)
82
82
import Control.Concurrent.Strict
83
83
import Control.DeepSeq
84
84
import Control.Exception.Extra hiding (bracket_ )
85
- import Control.Lens ((&) , (?~) , (%~) )
85
+ import Control.Lens ((&) , (?~) , (%~) , over )
86
86
import Control.Monad.Extra
87
87
import Control.Monad.IO.Class
88
88
import Control.Monad.Reader
@@ -120,6 +120,8 @@ import Data.Vector (Vector)
120
120
import qualified Data.Vector as Vector
121
121
import Development.IDE.Core.Debouncer
122
122
import Development.IDE.Core.FileUtils (getModTime )
123
+ import Development.IDE.Core.HaskellErrorIndex hiding (Log )
124
+ import qualified Development.IDE.Core.HaskellErrorIndex as HaskellErrorIndex
123
125
import Development.IDE.Core.PositionMapping
124
126
import Development.IDE.Core.ProgressReporting
125
127
import Development.IDE.Core.RuleTypes
@@ -151,6 +153,7 @@ import Development.IDE.Types.Shake
151
153
import qualified Focus
152
154
import GHC.Fingerprint
153
155
import GHC.Stack (HasCallStack )
156
+ import GHC.Types.Error (diagnosticCode , errMsgDiagnostic )
154
157
import HieDb.Types
155
158
import Ide.Logger hiding (Priority )
156
159
import qualified Ide.Logger as Logger
@@ -194,6 +197,7 @@ data Log
194
197
| LogShakeGarbageCollection ! T. Text ! Int ! Seconds
195
198
-- * OfInterest Log messages
196
199
| LogSetFilesOfInterest ! [(NormalizedFilePath , FileOfInterestStatus )]
200
+ | LogInitializeHaskellErrorIndex ! HaskellErrorIndex. Log
197
201
deriving Show
198
202
199
203
instance Pretty Log where
@@ -237,6 +241,8 @@ instance Pretty Log where
237
241
LogSetFilesOfInterest ofInterest ->
238
242
" Set files of interst to" <> Pretty. line
239
243
<> indent 4 (pretty $ fmap (first fromNormalizedFilePath) ofInterest)
244
+ LogInitializeHaskellErrorIndex hei ->
245
+ " Haskell Error Index:" <+> pretty hei
240
246
241
247
-- | We need to serialize writes to the database, so we send any function that
242
248
-- needs to write to the database over the channel, where it will be picked up by
@@ -332,6 +338,8 @@ data ShakeExtras = ShakeExtras
332
338
-- ^ Queue of restart actions to be run.
333
339
, loaderQueue :: TQueue (IO () )
334
340
-- ^ Queue of loader actions to be run.
341
+ , haskellErrorIndex :: Maybe HaskellErrorIndex
342
+ -- ^ List of errors in the Haskell Error Index (errors.haskell.org)
335
343
}
336
344
337
345
type WithProgressFunc = forall a .
@@ -702,6 +710,7 @@ shakeOpen recorder lspEnv defaultConfig idePlugins debouncer
702
710
dirtyKeys <- newTVarIO mempty
703
711
-- Take one VFS snapshot at the start
704
712
vfsVar <- newTVarIO =<< vfsSnapshot lspEnv
713
+ haskellErrorIndex <- initHaskellErrorIndex (cmapWithPrio LogInitializeHaskellErrorIndex recorder)
705
714
pure ShakeExtras {shakeRecorder = recorder, .. }
706
715
shakeDb <-
707
716
shakeNewDatabase
@@ -1321,24 +1330,25 @@ traceA (A Failed{}) = "Failed"
1321
1330
traceA (A Stale {}) = " Stale"
1322
1331
traceA (A Succeeded {}) = " Success"
1323
1332
1324
- updateFileDiagnostics :: MonadIO m
1325
- => Recorder (WithPriority Log )
1333
+ updateFileDiagnostics
1334
+ :: Recorder (WithPriority Log )
1326
1335
-> NormalizedFilePath
1327
1336
-> Maybe Int32
1328
1337
-> Key
1329
1338
-> ShakeExtras
1330
1339
-> [FileDiagnostic ] -- ^ current results
1331
- -> m ()
1340
+ -> Action ()
1332
1341
updateFileDiagnostics recorder fp ver k ShakeExtras {diagnostics, hiddenDiagnostics, publishedDiagnostics, debouncer, lspEnv, ideTesting} current0 = do
1342
+ hei <- haskellErrorIndex <$> getShakeExtras
1333
1343
liftIO $ withTrace (" update diagnostics " <> fromString(fromNormalizedFilePath fp)) $ \ addTag -> do
1334
1344
addTag " key" (show k)
1345
+ current <- traverse (attachHEI hei) $ map (over fdLspDiagnosticL diagsFromRule) current0
1335
1346
let (currentShown, currentHidden) = partition ((== ShowDiag ) . fdShouldShowDiagnostic) current
1336
1347
uri = filePathToUri' fp
1337
1348
addTagUnsafe :: String -> String -> String -> a -> a
1338
1349
addTagUnsafe msg t x v = unsafePerformIO(addTag (msg <> t) x) `seq` v
1339
1350
update :: (forall a . String -> String -> a -> a ) -> [FileDiagnostic ] -> STMDiagnosticStore -> STM [FileDiagnostic ]
1340
1351
update addTagUnsafeMethod new store = addTagUnsafeMethod " count" (show $ Prelude. length new) $ setStageDiagnostics addTagUnsafeMethod uri ver (renderKey k) new store
1341
- current = map (fdLspDiagnosticL %~ diagsFromRule) current0
1342
1352
addTag " version" (show ver)
1343
1353
mask_ $ do
1344
1354
-- Mask async exceptions to ensure that updated diagnostics are always
@@ -1362,6 +1372,18 @@ updateFileDiagnostics recorder fp ver k ShakeExtras{diagnostics, hiddenDiagnosti
1362
1372
LSP. PublishDiagnosticsParams (fromNormalizedUri uri') (fmap fromIntegral ver) (map fdLspDiagnostic newDiags)
1363
1373
return action
1364
1374
where
1375
+ attachHEI :: Maybe HaskellErrorIndex -> FileDiagnostic -> IO FileDiagnostic
1376
+ attachHEI mbHei diag
1377
+ | Just hei <- mbHei
1378
+ , SomeStructuredMessage msg <- fdStructuredMessage diag
1379
+ , Just code <- diagnosticCode (errMsgDiagnostic msg)
1380
+ , Just heiError <- hei `heiGetError` code
1381
+ = pure $ diag & fdLspDiagnosticL %~ attachHeiErrorCodeDescription heiError
1382
+ | otherwise
1383
+ = do
1384
+ writeFile " /home/dylan/attachHEI" (show mbHei <> " \n " <> show diag)
1385
+ pure diag
1386
+
1365
1387
diagsFromRule :: Diagnostic -> Diagnostic
1366
1388
diagsFromRule c@ Diagnostic {_range}
1367
1389
| coerce ideTesting = c & L. relatedInformation ?~
0 commit comments