1
- {-# LANGUAGE DeriveAnyClass #-}
2
- {-# LANGUAGE DeriveGeneric #-}
3
- {-# LANGUAGE OverloadedStrings #-}
1
+ {-# LANGUAGE ViewPatterns #-}
2
+ {-# LANGUAGE DeriveAnyClass #-}
3
+ {-# LANGUAGE DeriveGeneric #-}
4
4
{-# LANGUAGE DuplicateRecordFields #-}
5
+ {-# LANGUAGE OverloadedStrings #-}
5
6
6
7
-- | Provides code actions to add missing pragmas (whenever GHC suggests to)
7
8
module Ide.Plugin.Pragmas
@@ -10,20 +11,22 @@ module Ide.Plugin.Pragmas
10
11
-- , commands -- TODO: get rid of this
11
12
) where
12
13
13
- import Control.Lens hiding (List )
14
+ import Control.Lens hiding (List )
14
15
import Data.Aeson
15
16
import qualified Data.HashMap.Strict as H
16
17
import qualified Data.Text as T
18
+ import Development.IDE as D
19
+ import qualified GHC.Generics as Generics
17
20
import Ide.Plugin
18
21
import Ide.Types
19
- import qualified GHC.Generics as Generics
22
+ import Language.Haskell.LSP.Types
20
23
import qualified Language.Haskell.LSP.Types as J
21
24
import qualified Language.Haskell.LSP.Types.Lens as J
22
- import Development.IDE as D
23
- import Language.Haskell.LSP.Types
24
25
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
27
30
28
31
-- ---------------------------------------------------------------------
29
32
@@ -67,28 +70,37 @@ addPragmaCmd _lf _ide (AddPragmaParams uri pragmaName) = do
67
70
return (Right Null , Just (WorkspaceApplyEdit , ApplyWorkspaceEditParams res))
68
71
69
72
-- ---------------------------------------------------------------------
70
-
71
73
-- | Offer to add a missing Language Pragma to the top of a file.
72
74
-- Pragmas are defined by a curated list of known pragmas, see 'possiblePragmas'.
73
75
codeActionProvider :: 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
79
80
-- 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
81
82
-- 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
+
92
104
93
105
-- ---------------------------------------------------------------------
94
106
@@ -101,68 +113,9 @@ findPragma str = concatMap check possiblePragmas
101
113
-- ---------------------------------------------------------------------
102
114
103
115
-- | Possible Pragma names.
104
- -- Is non-exhaustive, and may be extended.
116
+ -- See discussion at https://github.com/haskell/ghcide/pull/638
105
117
possiblePragmas :: [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]
166
119
167
120
-- ---------------------------------------------------------------------
168
121
0 commit comments