@@ -14,6 +14,8 @@ import ConLike
14
14
import Control.Applicative
15
15
import Control.Lens hiding (List , use )
16
16
import Control.Monad
17
+ import Control.Monad.Trans.Class
18
+ import Control.Monad.Trans.Maybe
17
19
import Data.Aeson
18
20
import Data.Char
19
21
import qualified Data.HashMap.Strict as H
@@ -60,29 +62,31 @@ data AddMinimalMethodsParams = AddMinimalMethodsParams
60
62
deriving (Show , Eq , Generics.Generic , ToJSON , FromJSON )
61
63
62
64
addMethodPlaceholders :: CommandFunction AddMinimalMethodsParams
63
- addMethodPlaceholders lf state AddMinimalMethodsParams {.. } = do
64
- Just pm <- runAction " classplugin" state $ use GetParsedModule docPath
65
+ addMethodPlaceholders lf state AddMinimalMethodsParams {.. } = fmap (fromMaybe errorResult) . runMaybeT $ do
66
+ docPath <- MaybeT . pure . uriToNormalizedFilePath $ toNormalizedUri uri
67
+ pm <- MaybeT . runAction " classplugin" state $ use GetParsedModule docPath
65
68
let
66
69
ps = pm_parsed_source pm
67
70
anns = relativiseApiAnns ps (pm_annotations pm)
68
71
old = T. pack $ exactPrint ps anns
69
72
70
- Just (hsc_dflags . hscEnv -> df) <- runAction " classplugin" state $ use GhcSessionDeps docPath
73
+ (hsc_dflags . hscEnv -> df) <- MaybeT . runAction " classplugin" state $ use GhcSessionDeps docPath
74
+ List (unzip -> (mAnns, mDecls)) <- MaybeT . pure $ traverse (makeMethodDecl df) methodGroup
71
75
let
72
- Right (List (unzip -> (mAnns, mDecls))) = traverse (makeMethodDecl df) methodGroup
73
76
(ps', (anns', _), _) = runTransform (mergeAnns (mergeAnnList mAnns) anns) (addMethodDecls ps mDecls)
74
77
new = T. pack $ exactPrint ps' anns'
75
78
76
79
pure (Right Null , Just (WorkspaceApplyEdit , ApplyWorkspaceEditParams (workspaceEdit caps old new)))
77
80
where
78
- caps = clientCapabilities lf
79
- Just docPath = uriToNormalizedFilePath $ toNormalizedUri uri
81
+ errorResult = (Right Null , Nothing )
80
82
83
+ caps = clientCapabilities lf
81
84
indent = 2
82
85
83
- makeMethodDecl df mName = do
84
- (ann, d) <- parseDecl df (T. unpack mName) . T. unpack $ toMethodName mName <> " = _"
85
- pure (setPrecedingLines d 1 indent ann, d)
86
+ makeMethodDecl df mName =
87
+ case parseDecl df (T. unpack mName) . T. unpack $ toMethodName mName <> " = _" of
88
+ Right (ann, d) -> Just (setPrecedingLines d 1 indent ann, d)
89
+ Left _ -> Nothing
86
90
87
91
addMethodDecls :: ParsedSource -> [LHsDecl GhcPs ] -> Transform (Located (HsModule GhcPs ))
88
92
addMethodDecls ps mDecls = do
@@ -125,19 +129,22 @@ addMethodPlaceholders lf state AddMinimalMethodsParams{..} = do
125
129
-- 1. sensitive to the format of diagnostic messages from GHC
126
130
-- 2. pattern matches are not exhaustive
127
131
codeAction :: CodeActionProvider
128
- codeAction _ state plId (TextDocumentIdentifier uri) _ CodeActionContext { _diagnostics = List diags } = do
129
- actions <- join <$> mapM mkActions methodDiags
132
+ codeAction _ state plId docId _ context = fmap (fromMaybe errorResult) . runMaybeT $ do
133
+ docPath <- MaybeT . pure . uriToNormalizedFilePath $ toNormalizedUri uri
134
+ actions <- join <$> mapM (mkActions docPath) methodDiags
130
135
pure . Right . List $ actions
131
136
where
132
- Just docPath = uriToNormalizedFilePath $ toNormalizedUri uri
137
+ errorResult = Right (List [] )
138
+ uri = docId ^. J. uri
139
+ List diags = context ^. J. diagnostics
133
140
134
141
ghcDiags = filter (\ d -> d ^. J. source == Just " typecheck" ) diags
135
142
methodDiags = filter (\ d -> isClassMethodWarning (d ^. J. message)) ghcDiags
136
143
137
- mkActions diag = do
138
- ident <- findClassIdentifier range
139
- cls <- findClassFromIdentifier ident
140
- traverse mkAction . minDefToMethodGroups . classMinimalDef $ cls
144
+ mkActions docPath diag = do
145
+ ident <- findClassIdentifier docPath range
146
+ cls <- findClassFromIdentifier docPath ident
147
+ lift . traverse mkAction . minDefToMethodGroups . classMinimalDef $ cls
141
148
where
142
149
range = diag ^. J. range
143
150
@@ -159,28 +166,25 @@ codeAction _ state plId (TextDocumentIdentifier uri) _ CodeActionContext{ _diagn
159
166
. CodeAction title (Just CodeActionQuickFix ) (Just (List [] )) Nothing
160
167
. Just
161
168
162
- findClassIdentifier :: Range -> IO Identifier
163
- findClassIdentifier range = do
164
- Just (hieAst -> hf, pmap) <- runAction " classplugin" state $ useWithStale GetHieAst docPath
169
+ findClassIdentifier docPath range = do
170
+ (hieAst -> hf, pmap) <- MaybeT . runAction " classplugin" state $ useWithStale GetHieAst docPath
165
171
pure
166
172
$ head . head
167
173
$ pointCommand hf (fromJust (fromCurrentRange pmap range) ^. J. start & J. character -~ 1 )
168
174
( (Map. keys . Map. filter isClassNodeIdentifier . nodeIdentifiers . nodeInfo)
169
175
<=< nodeChildren
170
176
)
171
177
172
- findClassFromIdentifier :: Identifier -> IO Class
173
- findClassFromIdentifier (Right name) = do
174
- Just (hscEnv -> hscenv, _) <- runAction " classplugin" state $ useWithStale GhcSessionDeps docPath
175
- Just (tmrTypechecked -> thisMod, _) <- runAction " classplugin" state $ useWithStale TypeCheck docPath
176
- (_, Just cls) <- initTcWithGbl hscenv thisMod ghostSpan $ do
178
+ findClassFromIdentifier docPath (Right name) = do
179
+ (hscEnv -> hscenv, _) <- MaybeT . runAction " classplugin" state $ useWithStale GhcSessionDeps docPath
180
+ (tmrTypechecked -> thisMod, _) <- MaybeT . runAction " classplugin" state $ useWithStale TypeCheck docPath
181
+ MaybeT . fmap snd . initTcWithGbl hscenv thisMod ghostSpan $ do
177
182
tcthing <- tcLookup name
178
183
case tcthing of
179
184
AGlobal (AConLike (RealDataCon con))
180
185
| Just cls <- tyConClass_maybe (dataConOrigTyCon con) -> pure cls
181
186
_ -> panic " Ide.Plugin.Class.findClassFromIdentifier"
182
- pure cls
183
- findClassFromIdentifier (Left _) = panic " Ide.Plugin.Class.findClassIdentifier"
187
+ findClassFromIdentifier _ (Left _) = panic " Ide.Plugin.Class.findClassIdentifier"
184
188
185
189
ghostSpan :: RealSrcSpan
186
190
ghostSpan = realSrcLocSpan $ mkRealSrcLoc (fsLit " <haskell-language-sever>" ) 1 1
0 commit comments