@@ -14,6 +14,8 @@ import ConLike
1414import Control.Applicative
1515import Control.Lens hiding (List , use )
1616import Control.Monad
17+ import Control.Monad.Trans.Class
18+ import Control.Monad.Trans.Maybe
1719import Data.Aeson
1820import Data.Char
1921import qualified Data.HashMap.Strict as H
@@ -60,29 +62,31 @@ data AddMinimalMethodsParams = AddMinimalMethodsParams
6062 deriving (Show , Eq , Generics.Generic , ToJSON , FromJSON )
6163
6264addMethodPlaceholders :: 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
6568 let
6669 ps = pm_parsed_source pm
6770 anns = relativiseApiAnns ps (pm_annotations pm)
6871 old = T. pack $ exactPrint ps anns
6972
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
7175 let
72- Right (List (unzip -> (mAnns, mDecls))) = traverse (makeMethodDecl df) methodGroup
7376 (ps', (anns', _), _) = runTransform (mergeAnns (mergeAnnList mAnns) anns) (addMethodDecls ps mDecls)
7477 new = T. pack $ exactPrint ps' anns'
7578
7679 pure (Right Null , Just (WorkspaceApplyEdit , ApplyWorkspaceEditParams (workspaceEdit caps old new)))
7780 where
78- caps = clientCapabilities lf
79- Just docPath = uriToNormalizedFilePath $ toNormalizedUri uri
81+ errorResult = (Right Null , Nothing )
8082
83+ caps = clientCapabilities lf
8184 indent = 2
8285
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
8690
8791 addMethodDecls :: ParsedSource -> [LHsDecl GhcPs ] -> Transform (Located (HsModule GhcPs ))
8892 addMethodDecls ps mDecls = do
@@ -125,19 +129,22 @@ addMethodPlaceholders lf state AddMinimalMethodsParams{..} = do
125129-- 1. sensitive to the format of diagnostic messages from GHC
126130-- 2. pattern matches are not exhaustive
127131codeAction :: 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
130135 pure . Right . List $ actions
131136 where
132- Just docPath = uriToNormalizedFilePath $ toNormalizedUri uri
137+ errorResult = Right (List [] )
138+ uri = docId ^. J. uri
139+ List diags = context ^. J. diagnostics
133140
134141 ghcDiags = filter (\ d -> d ^. J. source == Just " typecheck" ) diags
135142 methodDiags = filter (\ d -> isClassMethodWarning (d ^. J. message)) ghcDiags
136143
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
141148 where
142149 range = diag ^. J. range
143150
@@ -159,28 +166,25 @@ codeAction _ state plId (TextDocumentIdentifier uri) _ CodeActionContext{ _diagn
159166 . CodeAction title (Just CodeActionQuickFix ) (Just (List [] )) Nothing
160167 . Just
161168
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
165171 pure
166172 $ head . head
167173 $ pointCommand hf (fromJust (fromCurrentRange pmap range) ^. J. start & J. character -~ 1 )
168174 ( (Map. keys . Map. filter isClassNodeIdentifier . nodeIdentifiers . nodeInfo)
169175 <=< nodeChildren
170176 )
171177
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
177182 tcthing <- tcLookup name
178183 case tcthing of
179184 AGlobal (AConLike (RealDataCon con))
180185 | Just cls <- tyConClass_maybe (dataConOrigTyCon con) -> pure cls
181186 _ -> panic " Ide.Plugin.Class.findClassFromIdentifier"
182- pure cls
183- findClassFromIdentifier (Left _) = panic " Ide.Plugin.Class.findClassIdentifier"
187+ findClassFromIdentifier _ (Left _) = panic " Ide.Plugin.Class.findClassIdentifier"
184188
185189ghostSpan :: RealSrcSpan
186190ghostSpan = realSrcLocSpan $ mkRealSrcLoc (fsLit " <haskell-language-sever>" ) 1 1
0 commit comments