1- {-# LANGUAGE DeriveAnyClass #-}
2- {-# LANGUAGE DeriveGeneric #-}
3- {-# LANGUAGE OverloadedStrings #-}
1+ {-# LANGUAGE ViewPatterns #-}
2+ {-# LANGUAGE DeriveAnyClass #-}
3+ {-# LANGUAGE DeriveGeneric #-}
44{-# LANGUAGE DuplicateRecordFields #-}
5+ {-# LANGUAGE OverloadedStrings #-}
56
67-- | Provides code actions to add missing pragmas (whenever GHC suggests to)
78module Ide.Plugin.Pragmas
@@ -10,20 +11,22 @@ module Ide.Plugin.Pragmas
1011 -- , commands -- TODO: get rid of this
1112 ) where
1213
13- import Control.Lens hiding (List )
14+ import Control.Lens hiding (List )
1415import Data.Aeson
1516import qualified Data.HashMap.Strict as H
1617import qualified Data.Text as T
18+ import Development.IDE as D
19+ import qualified GHC.Generics as Generics
1720import Ide.Plugin
1821import Ide.Types
19- import qualified GHC.Generics as Generics
22+ import Language.Haskell.LSP.Types
2023import qualified Language.Haskell.LSP.Types as J
2124import qualified Language.Haskell.LSP.Types.Lens as J
22- import Development.IDE as D
23- import Language.Haskell.LSP.Types
2425
25- import qualified Language.Haskell.LSP.Core as LSP
26- import qualified Language.Haskell.LSP.VFS as VFS
26+ import Control.Monad (join )
27+ import Development.IDE.GHC.Compat
28+ import qualified Language.Haskell.LSP.Core as LSP
29+ import qualified Language.Haskell.LSP.VFS as VFS
2730
2831-- ---------------------------------------------------------------------
2932
@@ -67,28 +70,37 @@ addPragmaCmd _lf _ide (AddPragmaParams uri pragmaName) = do
6770 return (Right Null , Just (WorkspaceApplyEdit , ApplyWorkspaceEditParams res))
6871
6972-- ---------------------------------------------------------------------
70-
7173-- | Offer to add a missing Language Pragma to the top of a file.
7274-- Pragmas are defined by a curated list of known pragmas, see 'possiblePragmas'.
7375codeActionProvider :: CodeActionProvider
74- codeActionProvider _ _ plId docId _ (J. CodeActionContext (J. List diags) _monly) = do
75- cmds <- mapM mkCommand pragmas
76- -- cmds <- mapM mkCommand ("FooPragma":pragmas)
77- return $ Right $ List cmds
78- where
76+ codeActionProvider _ state plId docId _ (J. CodeActionContext (J. List diags) _monly) = do
77+ let mFile = docId ^. J. uri & uriToFilePath <&> toNormalizedFilePath'
78+ pm <- fmap join $ runAction " addPragma" state $ getParsedModule `traverse` mFile
79+ let dflags = ms_hspp_opts . pm_mod_summary <$> pm
7980 -- Filter diagnostics that are from ghcmod
80- ghcDiags = filter (\ d -> d ^. J. source == Just " typecheck" ) diags
81+ ghcDiags = filter (\ d -> d ^. J. source == Just " typecheck" ) diags
8182 -- Get all potential Pragmas for all diagnostics.
82- pragmas = concatMap (\ d -> findPragma (d ^. J. message)) ghcDiags
83- mkCommand pragmaName = do
84- let
85- -- | Code Action for the given command.
86- codeAction :: J. Command -> J. CAResult
87- codeAction cmd = J. CACodeAction $ J. CodeAction title (Just J. CodeActionQuickFix ) (Just (J. List [] )) Nothing (Just cmd)
88- title = " Add \" " <> pragmaName <> " \" "
89- cmdParams = [toJSON (AddPragmaParams (docId ^. J. uri) pragmaName )]
90- cmd <- mkLspCommand plId " addPragma" title (Just cmdParams)
91- return $ codeAction cmd
83+ pragmas = concatMap (\ d -> genPragma dflags (d ^. J. message)) ghcDiags
84+ -- cmds <- mapM mkCommand ("FooPragma":pragmas)
85+ cmds <- mapM mkCommand pragmas
86+ return $ Right $ List cmds
87+ where
88+ mkCommand pragmaName = do
89+ let
90+ -- | Code Action for the given command.
91+ codeAction :: J. Command -> J. CAResult
92+ codeAction cmd = J. CACodeAction $ J. CodeAction title (Just J. CodeActionQuickFix ) (Just (J. List [] )) Nothing (Just cmd)
93+ title = " Add \" " <> pragmaName <> " \" "
94+ cmdParams = [toJSON (AddPragmaParams (docId ^. J. uri) pragmaName)]
95+ cmd <- mkLspCommand plId " addPragma" title (Just cmdParams)
96+ return $ codeAction cmd
97+ genPragma mDynflags target
98+ | Just dynFlags <- mDynflags,
99+ -- GHC does not export 'OnOff', so we have to view it as string
100+ disabled <- [ e | Just e <- T. stripPrefix " Off " . T. pack . prettyPrint <$> extensions dynFlags]
101+ = [ r | r <- findPragma target, r `notElem` disabled]
102+ | otherwise = []
103+
92104
93105-- ---------------------------------------------------------------------
94106
@@ -101,68 +113,9 @@ findPragma str = concatMap check possiblePragmas
101113-- ---------------------------------------------------------------------
102114
103115-- | Possible Pragma names.
104- -- Is non-exhaustive, and may be extended.
116+ -- See discussion at https://github.com/haskell/ghcide/pull/638
105117possiblePragmas :: [T. Text ]
106- possiblePragmas =
107- [
108- " ConstraintKinds"
109- , " DefaultSignatures"
110- , " DeriveAnyClass"
111- , " DeriveDataTypeable"
112- , " DeriveFoldable"
113- , " DeriveFunctor"
114- , " DeriveGeneric"
115- , " DeriveLift"
116- , " DeriveTraversable"
117- , " DerivingStrategies"
118- , " DerivingVia"
119- , " EmptyCase"
120- , " EmptyDataDecls"
121- , " EmptyDataDeriving"
122- , " FlexibleContexts"
123- , " FlexibleInstances"
124- , " GADTs"
125- , " GHCForeignImportPrim"
126- , " GeneralizedNewtypeDeriving"
127- , " IncoherentInstances"
128- , " InstanceSigs"
129- , " KindSignatures"
130- , " MultiParamTypeClasses"
131- , " MultiWayIf"
132- , " NamedFieldPuns"
133- , " NamedWildCards"
134- , " OverloadedStrings"
135- , " ParallelListComp"
136- , " PartialTypeSignatures"
137- , " PatternGuards"
138- , " PatternSignatures"
139- , " PatternSynonyms"
140- , " QuasiQuotes"
141- , " Rank2Types"
142- , " RankNTypes"
143- , " RecordPuns"
144- , " RecordWildCards"
145- , " RecursiveDo"
146- , " RelaxedPolyRec"
147- , " RoleAnnotations"
148- , " ScopedTypeVariables"
149- , " StandaloneDeriving"
150- , " StaticPointers"
151- , " TemplateHaskell"
152- , " TemplateHaskellQuotes"
153- , " TransformListComp"
154- , " TupleSections"
155- , " TypeApplications"
156- , " TypeFamilies"
157- , " TypeFamilyDependencies"
158- , " TypeInType"
159- , " TypeOperators"
160- , " TypeSynonymInstances"
161- , " UnboxedSums"
162- , " UndecidableInstances"
163- , " UndecidableSuperClasses"
164- , " ViewPatterns"
165- ]
118+ possiblePragmas = [name | FlagSpec {flagSpecName = T. pack -> name} <- xFlags, " Strict" /= name]
166119
167120-- ---------------------------------------------------------------------
168121
0 commit comments