Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support structured diagnostics 2 #4433

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
44cf722
Change FileDiagnostic type synonym to a datatype
dylan-thinnes Jun 8, 2024
789977d
Make `ideErrorWithSource` produce FileDiagnostic by adding filepath arg
dylan-thinnes Jun 8, 2024
e9d1c68
Supply structured error wherever we easily can - TODOs for hard parts
dylan-thinnes Jun 9, 2024
176e626
Fix UnitTests for new FileDiagnostic struct
dylan-thinnes Jun 9, 2024
2e03927
Remove explicit uses of FileDiagnostic, add codes to LSP diagnostics
dylan-thinnes Jun 9, 2024
3ce7019
Add field for expected error codes in ghcide tests
dylan-thinnes Jun 10, 2024
11fdd87
Expect GHC-83865 for "type error" test - basic test
dylan-thinnes Jun 10, 2024
ac17800
Return structured warnings in TcModuleResult by copying from Driver
dylan-thinnes Jun 10, 2024
59abf29
Store FileDiagnostic instead of LSP Diagnostic in Shake store
dylan-thinnes Jun 16, 2024
861170a
Add expected error codes for diagnostics that have them
dylan-thinnes Jun 16, 2024
441a323
Dispatch TODOs, amend remaining TODOs as future work
dylan-thinnes Jun 16, 2024
34618b8
Add scary comments all over copied code in Compat.Driver
dylan-thinnes Jun 16, 2024
a1769a8
Update all remaining diagnostics that could use an expected error code
dylan-thinnes Jun 16, 2024
ac5b8bb
Add _code to pretty printing for FileDiagnostic
dylan-thinnes Jun 16, 2024
7b8f271
Use case instead of `maybe` for StructuredMessage match
dylan-thinnes Jun 16, 2024
037ca0a
Use CPP to prevent setting _code before structured errors
dylan-thinnes Jun 16, 2024
8662431
Swap modifier for lenses, document StructuredMessage type
dylan-thinnes Jun 16, 2024
676ef8f
Add link to Issue & MR to Compat.Driver
dylan-thinnes Jun 16, 2024
6b5b043
Drop attachReason logic from withWarnings, technically incorrect
dylan-thinnes Jun 16, 2024
36fd84e
Revert "Drop attachReason logic", needed by pragmas-plugin
dylan-thinnes Jun 16, 2024
2868e83
Fix plugins where necessary for new diagnostic structure
dylan-thinnes Jun 16, 2024
7d4cf38
Fix build issues with other tests from `expectDiagnostics`
dylan-thinnes Jun 16, 2024
dafb559
Improve comment on metadata fdStructuredMessage in FileDiagnostic
dylan-thinnes Jun 17, 2024
d904b98
Add note to withWarnings explaining the current state of things
dylan-thinnes Jun 20, 2024
27c36cf
Attach reasons into data field of LSP Diagnostic instead of code field
dylan-thinnes Jun 20, 2024
3961148
Fix up mistakes from merge, TODO fix merge issues for 9.3.0
dylan-thinnes Jun 20, 2024
0aa6aaa
Set CodeDescription from HaskellErrorIndex when available
dylan-thinnes Jun 24, 2024
c14cee6
Remove debugging print, fix expectation for preprocessor tests
dylan-thinnes Jun 27, 2024
7a6e00e
Fix CPP for using Show instance on DiagnosticCode
dylan-thinnes Jun 27, 2024
a8a7a64
Remove diagFromErrMsgs for GHC version < 9.6.1 using CPP
dylan-thinnes Jun 28, 2024
14fbd7c
CPP fix
dylan-thinnes Jun 28, 2024
61164ea
More stylish-haskell, more CPP fix
dylan-thinnes Jun 28, 2024
53221ff
Fix all stylish-haskell errors triggering
dylan-thinnes Jun 28, 2024
4d1742e
Fix more CPP
dylan-thinnes Jun 29, 2024
8b229fc
Only override the LSP diagnostic code when not already set
dylan-thinnes Jun 29, 2024
296b847
Fixes for stylish-haskell
dylan-thinnes Jun 29, 2024
dd3da46
Qualify s, t for FuzzySearch
dylan-thinnes Jun 29, 2024
4fd35fd
Ignore use of unsafePerformIO in FuzzySearch
dylan-thinnes Jun 29, 2024
6a66ad2
Properly split GHC.Types.Error import in Diagnostics for stylish-haskell
dylan-thinnes Jun 30, 2024
679bc6b
Force type signature of annotation on FuzzySearch.dictionary
dylan-thinnes Jun 30, 2024
de8bfaa
DRY up definition of closure_errs
dylan-thinnes Jul 2, 2024
5177e65
Remove unused imports
noughtmare Oct 17, 2024
e651d41
Post-rebase fixes
noughtmare Oct 17, 2024
b627909
stylish-haskell formatting
noughtmare Oct 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ghcide-bench/src/Experiments.hs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ experiments =
flip allM docs $ \DocumentPositions{..} -> do
bottom <- pred . length . T.lines <$> documentContents doc
diags <- getCurrentDiagnostics doc
case requireDiagnostic diags (DiagnosticSeverity_Error, (fromIntegral bottom, 8), "Found hole", Nothing) of
case requireDiagnostic diags (DiagnosticSeverity_Error, (fromIntegral bottom, 8), "Found hole", Just "88464", Nothing) of
Nothing -> pure True
Just _err -> pure False
),
Expand Down
4 changes: 4 additions & 0 deletions ghcide/ghcide.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,10 @@ library
, hiedb ^>= 0.6.0.0
, hls-graph == 2.9.0.1
, hls-plugin-api == 2.9.0.1
, http-conduit
, implicit-hie >= 0.1.4.0 && < 0.1.5
, lens
, lens-aeson
, list-t
, lsp ^>=2.7
, lsp-types ^>=2.3
Expand Down Expand Up @@ -134,6 +136,7 @@ library
Development.IDE.Core.Debouncer
Development.IDE.Core.FileStore
Development.IDE.Core.FileUtils
Development.IDE.Core.HaskellErrorIndex
Development.IDE.Core.IdeConfiguration
Development.IDE.Core.OfInterest
Development.IDE.Core.PluginUtils
Expand All @@ -150,6 +153,7 @@ library
Development.IDE.GHC.Compat
Development.IDE.GHC.Compat.Core
Development.IDE.GHC.Compat.CmdLine
Development.IDE.GHC.Compat.Driver
Development.IDE.GHC.Compat.Env
Development.IDE.GHC.Compat.Iface
Development.IDE.GHC.Compat.Logger
Expand Down
34 changes: 22 additions & 12 deletions ghcide/session-loader/Development/IDE/Session.hs
Original file line number Diff line number Diff line change
Expand Up @@ -573,10 +573,11 @@
this_flags = (this_error_env, this_dep_info)
this_error_env = ([this_error], Nothing)
this_error = ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) _cfp
$ T.unlines
[ "No cradle target found. Is this file listed in the targets of your cradle?"
, "If you are using a .cabal file, please ensure that this module is listed in either the exposed-modules or other-modules section"
]
(T.unlines
[ "No cradle target found. Is this file listed in the targets of your cradle?"
, "If you are using a .cabal file, please ensure that this module is listed in either the exposed-modules or other-modules section"
])
Nothing

void $ modifyVar' fileToFlags $ Map.insert hieYaml this_flags_map
void $ modifyVar' filesMap $ flip HM.union (HM.fromList (map ((,hieYaml) . fst) $ concatMap toFlagsMap all_targets))
Expand Down Expand Up @@ -633,7 +634,7 @@
[] -> error $ "GHC version could not be parsed: " <> version
((runTime, _):_)
| compileTime == runTime -> do
atomicModifyIORef' cradle_files (\xs -> (cfp:xs,()))

Check warning on line 637 in ghcide/session-loader/Development/IDE/Session.hs

View workflow job for this annotation

GitHub Actions / Hlint check run

Warning in loadSessionWithOptions in module Development.IDE.Session: Use atomicModifyIORef'_ ▫︎ Found: "atomicModifyIORef' cradle_files (\\ xs -> (cfp : xs, ()))" ▫︎ Perhaps: "atomicModifyIORef'_ cradle_files ((:) cfp)"
session (hieYaml, toNormalizedFilePath' cfp, opts, libDir)
| otherwise -> return (([renderPackageSetupException cfp GhcVersionMismatch{..}], Nothing),[])
-- Failure case, either a cradle error or the none cradle
Expand Down Expand Up @@ -797,10 +798,10 @@
-- GHC had an implementation of this function, but it was horribly inefficient
-- We should move back to the GHC implementation on compilers where
-- https://gitlab.haskell.org/ghc/ghc/-/merge_requests/12162 is included
checkHomeUnitsClosed' :: UnitEnv -> OS.Set UnitId -> [DriverMessages]
checkHomeUnitsClosed' :: UnitEnv -> OS.Set UnitId -> Maybe (Compat.MsgEnvelope DriverMessage)
checkHomeUnitsClosed' ue home_id_set
| OS.null bad_unit_ids = []
| otherwise = [singleMessage $ GHC.mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (OS.toList bad_unit_ids)]
| OS.null bad_unit_ids = Nothing
| otherwise = Just (GHC.mkPlainErrorMsgEnvelope rootLoc $ DriverHomePackagesNotClosed (OS.toList bad_unit_ids))
where
bad_unit_ids = upwards_closure OS.\\ home_id_set
rootLoc = mkGeneralSrcSpan (Compat.fsLit "<command line>")
Expand Down Expand Up @@ -875,13 +876,22 @@
hscEnv' <- -- Set up a multi component session with the other units on GHC 9.4
Compat.initUnits dfs hsc_env

let closure_errs = checkHomeUnitsClosed' (hsc_unit_env hscEnv') (hsc_all_home_unit_ids hscEnv')
multi_errs = map (ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Warning) _cfp . T.pack . Compat.printWithoutUniques) closure_errs
let closure_errs = maybeToList $ checkHomeUnitsClosed' (hsc_unit_env hscEnv') (hsc_all_home_unit_ids hscEnv')
closure_err_to_multi_err err =
ideErrorWithSource
(Just "cradle") (Just DiagnosticSeverity_Warning) _cfp
(T.pack (Compat.printWithoutUniques (singleMessage err)))
#if MIN_VERSION_ghc(9,6,1)
(Just (fmap GhcDriverMessage err))
#else
Nothing
#endif
multi_errs = map closure_err_to_multi_err closure_errs
bad_units = OS.fromList $ concat $ do
x <- bagToList $ mapBag errMsgDiagnostic $ unionManyBags $ map Compat.getMessages closure_errs
x <- map errMsgDiagnostic closure_errs
DriverHomePackagesNotClosed us <- pure x
pure us
isBad ci = (homeUnitId_ (componentDynFlags ci)) `OS.member` bad_units

Check warning on line 894 in ghcide/session-loader/Development/IDE/Session.hs

View workflow job for this annotation

GitHub Actions / Hlint check run

Suggestion in newComponentCache in module Development.IDE.Session: Redundant bracket ▫︎ Found: "(homeUnitId_ (componentDynFlags ci)) `OS.member` bad_units" ▫︎ Perhaps: "homeUnitId_ (componentDynFlags ci) `OS.member` bad_units"
-- Whenever we spin up a session on Linux, dynamically load libm.so.6
-- in. We need this in case the binary is statically linked, in which
-- case the interactive session will fail when trying to load
Expand Down Expand Up @@ -1223,6 +1233,6 @@
, "failed to load packages:", message <> "."
, "\nPlease ensure that ghcide is compiled with the same GHC installation as the project."]

renderPackageSetupException :: FilePath -> PackageSetupException -> (NormalizedFilePath, ShowDiagnostic, Diagnostic)
renderPackageSetupException :: FilePath -> PackageSetupException -> FileDiagnostic
renderPackageSetupException fp e =
ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) (toNormalizedFilePath' fp) (T.pack $ showPackageSetupException e)
ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) (toNormalizedFilePath' fp) (T.pack $ showPackageSetupException e) Nothing
13 changes: 8 additions & 5 deletions ghcide/session-loader/Development/IDE/Session/Diagnostics.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{-# LANGUAGE DeriveAnyClass #-}

Check warning on line 1 in ghcide/session-loader/Development/IDE/Session/Diagnostics.hs

View workflow job for this annotation

GitHub Actions / Hlint check run

Warning in module Development.IDE.Session.Diagnostics: Use module export list ▫︎ Found: "module Development.IDE.Session.Diagnostics where" ▫︎ Perhaps: "module Development.IDE.Session.Diagnostics (\n module Development.IDE.Session.Diagnostics\n ) where" ▫︎ Note: an explicit list is usually better

module Development.IDE.Session.Diagnostics where
import Control.Applicative
import Control.Lens
import Control.Monad
import qualified Data.Aeson as Aeson
import Data.List
Expand All @@ -27,11 +28,13 @@
Depicts the cradle error in a user-friendly way.
-}
renderCradleError :: CradleError -> Cradle a -> NormalizedFilePath -> FileDiagnostic
renderCradleError (CradleError deps _ec ms) cradle nfp
| HieBios.isCabalCradle cradle =
let (fp, showDiag, diag) = ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) nfp $ T.unlines $ map T.pack userFriendlyMessage in
(fp, showDiag, diag{_data_ = Just $ Aeson.toJSON CradleErrorDetails{cabalProjectFiles=absDeps}})
| otherwise = ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) nfp $ T.unlines $ map T.pack userFriendlyMessage
renderCradleError (CradleError deps _ec ms) cradle nfp =
let noDetails =
ideErrorWithSource (Just "cradle") (Just DiagnosticSeverity_Error) nfp (T.unlines $ map T.pack userFriendlyMessage) Nothing
in
if HieBios.isCabalCradle cradle
then noDetails & fdLspDiagnosticL %~ \diag -> diag{_data_ = Just $ Aeson.toJSON CradleErrorDetails{cabalProjectFiles=absDeps}}
else noDetails
where
absDeps = fmap (cradleRootDir cradle </>) deps
userFriendlyMessage :: [String]
Expand Down Expand Up @@ -84,7 +87,7 @@
surround start s end = do
guard (listToMaybe s == Just start)
guard (listToMaybe (reverse s) == Just end)
pure $ drop 1 $ take (length s - 1) s

Check warning on line 90 in ghcide/session-loader/Development/IDE/Session/Diagnostics.hs

View workflow job for this annotation

GitHub Actions / Hlint check run

Warning in parseMultiCradleErr in module Development.IDE.Session.Diagnostics: Use drop1 ▫︎ Found: "drop 1" ▫︎ Perhaps: "drop1"

multiCradleErrMessage :: MultiCradleErr -> [String]
multiCradleErrMessage e =
Expand Down
Loading
Loading