Skip to content

Commit 2e78baa

Browse files
Suggest adding pragmas for parse errors too (#1165)
* Suggest adding pragmas for parse errors too Only errors produced by the type checker were checked for mentions of a pragma that could be enabled. Many parse errors suggest enabling a pragma: * `@` -> `TypeApplications` * `forall` -> `RankNTypes`. Although `ScopedTypeVariables` would be a better suggestion, IMO. * ... Generate suggestions for these too. * Find pragma suggestions for all diagnostics, not just for GHC Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent 9eb92e0 commit 2e78baa

File tree

6 files changed

+48
-13
lines changed

6 files changed

+48
-13
lines changed

plugins/default/src/Ide/Plugin/Pragmas.hs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,8 @@ codeActionProvider _ state _plId docId _ (J.CodeActionContext (J.List diags) _mo
6767
let mFile = docId ^. J.uri & uriToFilePath <&> toNormalizedFilePath'
6868
pm <- fmap join $ runAction "addPragma" state $ getParsedModule `traverse` mFile
6969
let dflags = ms_hspp_opts . pm_mod_summary <$> pm
70-
-- Filter diagnostics that are from ghcmod
71-
ghcDiags = filter (\d -> d ^. J.source == Just "typecheck") diags
72-
-- Get all potential Pragmas for all diagnostics.
73-
pragmas = concatMap (\d -> genPragma dflags (d ^. J.message)) ghcDiags
70+
-- Get all potential Pragmas for all diagnostics.
71+
pragmas = concatMap (\d -> genPragma dflags (d ^. J.message)) diags
7472
cmds <- mapM mkCodeAction pragmas
7573
return $ Right $ List cmds
7674
where
@@ -81,13 +79,17 @@ codeActionProvider _ state _plId docId _ (J.CodeActionContext (J.List diags) _mo
8179
edit = mkPragmaEdit (docId ^. J.uri) pragmaName
8280
return codeAction
8381

84-
genPragma mDynflags target
85-
| Just dynFlags <- mDynflags,
86-
-- GHC does not export 'OnOff', so we have to view it as string
87-
disabled <- [ e | Just e <- T.stripPrefix "Off " . T.pack . prettyPrint <$> extensions dynFlags]
88-
= [ r | r <- findPragma target, r `notElem` disabled]
89-
| otherwise = []
90-
82+
genPragma mDynflags target =
83+
[ r | r <- findPragma target, r `notElem` disabled]
84+
where
85+
disabled
86+
| Just dynFlags <- mDynflags
87+
-- GHC does not export 'OnOff', so we have to view it as string
88+
= [ e | Just e <- T.stripPrefix "Off " . T.pack . prettyPrint <$> extensions dynFlags]
89+
| otherwise
90+
-- When the module failed to parse, we don't have access to its
91+
-- dynFlags. In that case, simply don't disable any pragmas.
92+
= []
9193

9294
-- ---------------------------------------------------------------------
9395

test/functional/FunctionalCodeAction.hs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ missingPragmaTests = testGroup "missing pragma warning code actions" [
425425
contents <- documentContents doc
426426

427427
let expected = [ "{-# LANGUAGE TypeSynonymInstances #-}"
428+
, "module NeedsPragmas where"
428429
, ""
429430
, "import GHC.Generics"
430431
, ""
@@ -443,6 +444,30 @@ missingPragmaTests = testGroup "missing pragma warning code actions" [
443444
]
444445

445446
liftIO $ (T.lines contents) @?= expected
447+
448+
, testCase "Adds TypeApplications pragma" $ do
449+
runSession hlsCommand fullCaps "test/testdata/addPragmas" $ do
450+
doc <- openDoc "TypeApplications.hs" "haskell"
451+
452+
_ <- waitForDiagnosticsFrom doc
453+
cas <- map fromAction <$> getAllCodeActions doc
454+
455+
liftIO $ "Add \"TypeApplications\"" `elem` map (^. L.title) cas @? "Contains TypeApplications code action"
456+
457+
executeCodeAction $ head cas
458+
459+
contents <- documentContents doc
460+
461+
let expected =
462+
[ "{-# LANGUAGE TypeApplications #-}"
463+
, "{-# LANGUAGE ScopedTypeVariables #-}"
464+
, "module TypeApplications where"
465+
, ""
466+
, "foo :: forall a. a -> a"
467+
, "foo = id @a"
468+
]
469+
470+
liftIO $ (T.lines contents) @?= expected
446471
]
447472

448473
unusedTermTests :: TestTree

test/testdata/addPragmas/NeedsPragmas.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
module NeedsPragmas where
12

23
import GHC.Generics
34

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{-# LANGUAGE ScopedTypeVariables #-}
2+
module TypeApplications where
3+
4+
foo :: forall a. a -> a
5+
foo = id @a

test/testdata/addPragmas/hie.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ cradle:
22
direct:
33
arguments:
44
- "NeedsPragmas"
5+
- "TypeApplications"

test/testdata/addPragmas/test.cabal

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ category: Web
1010
build-type: Simple
1111
cabal-version: >=1.10
1212

13-
executable p
14-
main-is: NeedsPragmas.hs
13+
library
14+
exposed-modules: NeedsPragmas
15+
TypeApplications
1516
hs-source-dirs: .
1617
build-depends: base >= 4.7 && < 5
1718
default-language: Haskell2010

0 commit comments

Comments
 (0)