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

Suggest adding pragmas for parse errors too #1165

Merged
merged 4 commits into from
Jan 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 13 additions & 11 deletions plugins/default/src/Ide/Plugin/Pragmas.hs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,8 @@ codeActionProvider _ state _plId docId _ (J.CodeActionContext (J.List diags) _mo
let mFile = docId ^. J.uri & uriToFilePath <&> toNormalizedFilePath'
pm <- fmap join $ runAction "addPragma" state $ getParsedModule `traverse` mFile
let dflags = ms_hspp_opts . pm_mod_summary <$> pm
-- Filter diagnostics that are from ghcmod
ghcDiags = filter (\d -> d ^. J.source == Just "typecheck") diags
-- Get all potential Pragmas for all diagnostics.
pragmas = concatMap (\d -> genPragma dflags (d ^. J.message)) ghcDiags
-- Get all potential Pragmas for all diagnostics.
pragmas = concatMap (\d -> genPragma dflags (d ^. J.message)) diags
cmds <- mapM mkCodeAction pragmas
return $ Right $ List cmds
where
Expand All @@ -81,13 +79,17 @@ codeActionProvider _ state _plId docId _ (J.CodeActionContext (J.List diags) _mo
edit = mkPragmaEdit (docId ^. J.uri) pragmaName
return codeAction

genPragma mDynflags target
| Just dynFlags <- mDynflags,
-- GHC does not export 'OnOff', so we have to view it as string
disabled <- [ e | Just e <- T.stripPrefix "Off " . T.pack . prettyPrint <$> extensions dynFlags]
= [ r | r <- findPragma target, r `notElem` disabled]
| otherwise = []

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

-- ---------------------------------------------------------------------

Expand Down
25 changes: 25 additions & 0 deletions test/functional/FunctionalCodeAction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ missingPragmaTests = testGroup "missing pragma warning code actions" [
contents <- documentContents doc

let expected = [ "{-# LANGUAGE TypeSynonymInstances #-}"
, "module NeedsPragmas where"
, ""
, "import GHC.Generics"
, ""
Expand All @@ -443,6 +444,30 @@ missingPragmaTests = testGroup "missing pragma warning code actions" [
]

liftIO $ (T.lines contents) @?= expected

, testCase "Adds TypeApplications pragma" $ do
runSession hlsCommand fullCaps "test/testdata/addPragmas" $ do
doc <- openDoc "TypeApplications.hs" "haskell"

_ <- waitForDiagnosticsFrom doc
cas <- map fromAction <$> getAllCodeActions doc

liftIO $ "Add \"TypeApplications\"" `elem` map (^. L.title) cas @? "Contains TypeApplications code action"

executeCodeAction $ head cas

contents <- documentContents doc

let expected =
[ "{-# LANGUAGE TypeApplications #-}"
, "{-# LANGUAGE ScopedTypeVariables #-}"
, "module TypeApplications where"
, ""
, "foo :: forall a. a -> a"
, "foo = id @a"
]

liftIO $ (T.lines contents) @?= expected
]

unusedTermTests :: TestTree
Expand Down
1 change: 1 addition & 0 deletions test/testdata/addPragmas/NeedsPragmas.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module NeedsPragmas where

import GHC.Generics

Expand Down
5 changes: 5 additions & 0 deletions test/testdata/addPragmas/TypeApplications.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{-# LANGUAGE ScopedTypeVariables #-}
module TypeApplications where

foo :: forall a. a -> a
foo = id @a
1 change: 1 addition & 0 deletions test/testdata/addPragmas/hie.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ cradle:
direct:
arguments:
- "NeedsPragmas"
- "TypeApplications"
5 changes: 3 additions & 2 deletions test/testdata/addPragmas/test.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ category: Web
build-type: Simple
cabal-version: >=1.10

executable p
main-is: NeedsPragmas.hs
library
exposed-modules: NeedsPragmas
TypeApplications
hs-source-dirs: .
build-depends: base >= 4.7 && < 5
default-language: Haskell2010
Expand Down