Skip to content

Commit 1209674

Browse files
committed
Migrate hls-class-plugin to use StructuredMessage
1 parent 4c335b2 commit 1209674

File tree

1 file changed

+26
-12
lines changed

1 file changed

+26
-12
lines changed

plugins/hls-class-plugin/src/Ide/Plugin/Class/CodeAction.hs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
{-# LANGUAGE GADTs #-}
2+
{-# LANGUAGE LambdaCase #-}
23
{-# LANGUAGE OverloadedLists #-}
34
{-# LANGUAGE RecordWildCards #-}
45
{-# LANGUAGE ViewPatterns #-}
56

67
module Ide.Plugin.Class.CodeAction where
78

9+
import Control.Arrow ((>>>))
810
import Control.Lens hiding (List, use)
911
import Control.Monad.Error.Class (MonadError (throwError))
1012
import Control.Monad.Extra
@@ -23,11 +25,14 @@ import Data.Maybe (isNothing, listToMaybe,
2325
import qualified Data.Set as Set
2426
import qualified Data.Text as T
2527
import Development.IDE
26-
import Development.IDE.Core.Compile (sourceTypecheck)
2728
import Development.IDE.Core.FileStore (getVersionedTextDoc)
2829
import Development.IDE.Core.PluginUtils
2930
import Development.IDE.Core.PositionMapping (fromCurrentRange)
3031
import Development.IDE.GHC.Compat
32+
import Development.IDE.GHC.Compat.Error (TcRnMessage (..),
33+
_TcRnMessage,
34+
flatTcRnMessage,
35+
msgEnvelopeErrorL)
3136
import Development.IDE.GHC.Compat.Util
3237
import Development.IDE.Spans.AtPoint (pointCommand)
3338
import Ide.Plugin.Class.ExactPrint
@@ -80,21 +85,23 @@ addMethodPlaceholders _ state _ param@AddMinimalMethodsParams{..} = do
8085
-- This implementation is ad-hoc in a sense that the diagnostic detection mechanism is
8186
-- sensitive to the format of diagnostic messages from GHC.
8287
codeAction :: Recorder (WithPriority Log) -> PluginMethodHandler IdeState Method_TextDocumentCodeAction
83-
codeAction recorder state plId (CodeActionParams _ _ docId _ context) = do
88+
codeAction recorder state plId (CodeActionParams _ _ docId caRange _) = do
8489
verTxtDocId <- liftIO $ runAction "classplugin.codeAction.getVersionedTextDoc" state $ getVersionedTextDoc docId
8590
nfp <- getNormalizedFilePathE (verTxtDocId ^. L.uri)
86-
actions <- join <$> mapM (mkActions nfp verTxtDocId) methodDiags
87-
pure $ InL actions
91+
activeDiagnosticsInRange (shakeExtras state) nfp caRange
92+
>>= \case
93+
Nothing -> pure $ InL []
94+
Just fileDiags -> do
95+
actions <- join <$> mapM (mkActions nfp verTxtDocId) (methodDiags fileDiags)
96+
pure $ InL actions
8897
where
89-
diags = context ^. L.diagnostics
90-
91-
ghcDiags = filter (\d -> d ^. L.source == Just sourceTypecheck) diags
92-
methodDiags = filter (\d -> isClassMethodWarning (d ^. L.message)) ghcDiags
98+
methodDiags fileDiags =
99+
filter (\d -> isClassMethodWarning (d ^. fdStructuredMessageL)) fileDiags
93100

94101
mkActions
95102
:: NormalizedFilePath
96103
-> VersionedTextDocumentIdentifier
97-
-> Diagnostic
104+
-> FileDiagnostic
98105
-> ExceptT PluginError (HandlerM Ide.Plugin.Config.Config) [Command |? CodeAction]
99106
mkActions docPath verTxtDocId diag = do
100107
(HAR {hieAst = ast}, pmap) <- runActionE "classplugin.findClassIdentifier.GetHieAst" state
@@ -117,7 +124,7 @@ codeAction recorder state plId (CodeActionParams _ _ docId _ context) = do
117124
$ fmap (second (filter (\(bind, _) -> bind `notElem` implemented)))
118125
$ mkMethodGroups hsc gblEnv range sigs cls
119126
where
120-
range = diag ^. L.range
127+
range = diag ^. fdLspDiagnosticL . L.range
121128

122129
mkMethodGroups :: HscEnv -> TcGblEnv -> Range -> [InstanceBindTypeSig] -> Class -> [MethodGroup]
123130
mkMethodGroups hsc gblEnv range sigs cls = minimalDef <> [allClassMethods]
@@ -203,8 +210,15 @@ isClassNodeIdentifier :: Identifier -> IdentifierDetails a -> Bool
203210
isClassNodeIdentifier (Right i) ident | 'C':':':_ <- unpackFS $ occNameFS $ occName i = (isNothing . identType) ident && Use `Set.member` identInfo ident
204211
isClassNodeIdentifier _ _ = False
205212

206-
isClassMethodWarning :: T.Text -> Bool
207-
isClassMethodWarning = T.isPrefixOf "• No explicit implementation for"
213+
isClassMethodWarning :: StructuredMessage -> Bool
214+
isClassMethodWarning message = case message ^? _SomeStructuredMessage . msgEnvelopeErrorL . _TcRnMessage of
215+
Nothing -> False
216+
Just tcRnMessage -> isGhcClassMethodWarning tcRnMessage
217+
218+
isGhcClassMethodWarning :: TcRnMessage -> Bool
219+
isGhcClassMethodWarning = flatTcRnMessage >>> \case
220+
TcRnUnsatisfiedMinimalDef{} -> True
221+
_ -> False
208222

209223
isInstanceValBind :: ContextInfo -> Bool
210224
isInstanceValBind (ValBind InstanceBind _ _) = True

0 commit comments

Comments
 (0)