Skip to content

Commit c71b3f7

Browse files
committed
Split up judgementForHole
1 parent b16c730 commit c71b3f7

File tree

1 file changed

+72
-36
lines changed
  • plugins/hls-tactics-plugin/src/Ide/Plugin

1 file changed

+72
-36
lines changed

plugins/hls-tactics-plugin/src/Ide/Plugin/Tactic.hs

Lines changed: 72 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
{-# LANGUAGE GADTs #-}
2-
{-# LANGUAGE LambdaCase #-}
3-
{-# LANGUAGE NumDecimals #-}
4-
{-# LANGUAGE OverloadedStrings #-}
5-
{-# LANGUAGE TypeApplications #-}
1+
{-# LANGUAGE FlexibleContexts #-}
2+
{-# LANGUAGE GADTs #-}
3+
{-# LANGUAGE LambdaCase #-}
4+
{-# LANGUAGE NumDecimals #-}
5+
{-# LANGUAGE OverloadedStrings #-}
6+
{-# LANGUAGE ScopedTypeVariables #-}
7+
{-# LANGUAGE TypeApplications #-}
68

79
-- | A plugin that uses tactics to synthesize code
810
module Ide.Plugin.Tactic
@@ -37,8 +39,8 @@ import Development.IDE.Core.Shake (useWithStale, IdeState (..))
3739
import Development.IDE.GHC.Compat
3840
import Development.IDE.GHC.Error (realSrcSpanToRange)
3941
import Development.IDE.GHC.ExactPrint
40-
import Development.IDE.Spans.LocalBindings (getDefiningBindings)
41-
import Development.Shake (Action)
42+
import Development.IDE.Spans.LocalBindings (Bindings, getDefiningBindings)
43+
import Development.Shake (RuleResult, Action)
4244
import qualified FastString
4345
import Ide.Plugin.Tactic.CaseSplit
4446
import Ide.Plugin.Tactic.Context
@@ -58,6 +60,7 @@ import Prelude hiding (span)
5860
import SrcLoc (containsSpan)
5961
import System.Timeout
6062
import TcRnTypes (tcg_binds)
63+
import Development.Shake.Classes
6164

6265

6366
descriptor :: PluginId -> PluginDescriptor IdeState
@@ -86,6 +89,18 @@ tcCommandName = T.pack . show
8689
runIde :: IdeState -> Action a -> IO a
8790
runIde state = runAction "tactic" state
8891

92+
runStaleIde
93+
:: forall a r
94+
. ( r ~ RuleResult a
95+
, Eq a , Hashable a , Binary a , Show a , Typeable a , NFData a
96+
, Show r, Typeable r, NFData r
97+
)
98+
=> IdeState
99+
-> NormalizedFilePath
100+
-> a
101+
-> MaybeT IO (r, PositionMapping)
102+
runStaleIde state nfp a = MaybeT $ runIde state $ useWithStale a nfp
103+
89104

90105
codeActionProvider :: PluginMethodHandler IdeState TextDocumentCodeAction
91106
codeActionProvider state plId (CodeActionParams _ _ (TextDocumentIdentifier uri) range _ctx)
@@ -114,29 +129,54 @@ judgementForHole
114129
-> Range
115130
-> MaybeT IO (Range, Judgement, Context, DynFlags)
116131
judgementForHole state nfp range = do
117-
(asts, amapping) <- MaybeT $ runIde state $ useWithStale GetHieAst nfp
118-
range' <- liftMaybe $ fromCurrentRange amapping range
132+
(asts, amapping) <- runStaleIde state nfp GetHieAst
133+
case asts of
134+
HAR _ _ _ _ (HieFromDisk _) -> fail "Need a fresh hie file"
135+
HAR _ hf _ _ HieFresh -> do
136+
(binds, _) <- runStaleIde state nfp GetBindings
137+
(tcmod, _) <- runStaleIde state nfp TypeCheck
138+
(rss, g) <- liftMaybe $ getSpanAndTypeAtHole amapping range hf
139+
resulting_range <- liftMaybe $ toCurrentRange amapping $ realSrcSpanToRange rss
140+
let (jdg, ctx) = mkJudgementAndContext g binds rss tcmod
141+
dflags <- getIdeDynflags state nfp
142+
pure (resulting_range, jdg, ctx, dflags)
119143

120-
(binds, _) <- MaybeT $ runIde state $ useWithStale GetBindings nfp
121144

145+
getIdeDynflags
146+
:: IdeState
147+
-> NormalizedFilePath
148+
-> MaybeT IO DynFlags
149+
getIdeDynflags state nfp = do
122150
-- Ok to use the stale 'ModIface', since all we need is its 'DynFlags'
123151
-- which don't change very often.
124-
((modsum,_), _) <- MaybeT $ runIde state $ useWithStale GetModSummaryWithoutTimestamps nfp
125-
let dflags = ms_hspp_opts modsum
152+
((modsum,_), _) <- runStaleIde state nfp GetModSummaryWithoutTimestamps
153+
pure $ ms_hspp_opts modsum
126154

127-
case asts of
128-
(HAR _ hf _ _ kind) -> do
129-
(rss, g) <- liftMaybe $ join $ listToMaybe $ M.elems $ flip M.mapWithKey (getAsts hf) $ \fs ast ->
130-
case selectSmallestContaining (rangeToRealSrcSpan (FastString.unpackFS fs) range') ast of
131-
Nothing -> Nothing
132-
Just ast' -> do
133-
let info = nodeInfo ast'
134-
ty <- listToMaybe $ nodeType info
135-
guard $ ("HsUnboundVar","HsExpr") `S.member` nodeAnnotations info
136-
pure (nodeSpan ast', ty)
137155

138-
resulting_range <- liftMaybe $ toCurrentRange amapping $ realSrcSpanToRange rss
139-
(tcmod, _) <- MaybeT $ runIde state $ useWithStale TypeCheck nfp
156+
getSpanAndTypeAtHole
157+
:: PositionMapping
158+
-> Range
159+
-> HieASTs b
160+
-> Maybe (Span, b)
161+
getSpanAndTypeAtHole amapping range hf = do
162+
range' <- fromCurrentRange amapping range
163+
join $ listToMaybe $ M.elems $ flip M.mapWithKey (getAsts hf) $ \fs ast ->
164+
case selectSmallestContaining (rangeToRealSrcSpan (FastString.unpackFS fs) range') ast of
165+
Nothing -> Nothing
166+
Just ast' -> do
167+
let info = nodeInfo ast'
168+
ty <- listToMaybe $ nodeType info
169+
guard $ ("HsUnboundVar","HsExpr") `S.member` nodeAnnotations info
170+
pure (nodeSpan ast', ty)
171+
172+
173+
mkJudgementAndContext
174+
:: Type
175+
-> Bindings
176+
-> RealSrcSpan
177+
-> TcModuleResult
178+
-> (Judgement, Context)
179+
mkJudgementAndContext g binds rss tcmod = do
140180
let tcg = tmrTypechecked tcmod
141181
tcs = tcg_binds tcg
142182
ctx = mkContext
@@ -147,18 +187,12 @@ judgementForHole state nfp range = do
147187
local_hy = spliceProvenance top_provs
148188
$ hypothesisFromBindings rss binds
149189
cls_hy = contextMethodHypothesis ctx
150-
case kind of
151-
HieFromDisk _hf' ->
152-
fail "Need a fresh hie file"
153-
HieFresh ->
154-
pure ( resulting_range
155-
, mkFirstJudgement
156-
(local_hy <> cls_hy)
157-
(isRhsHole rss tcs)
158-
g
159-
, ctx
160-
, dflags
161-
)
190+
in ( mkFirstJudgement
191+
(local_hy <> cls_hy)
192+
(isRhsHole rss tcs)
193+
g
194+
, ctx
195+
)
162196

163197
spliceProvenance
164198
:: Map OccName Provenance
@@ -195,6 +229,7 @@ tacticCmd tac state (TacticParams uri range var_name)
195229
tacticCmd _ _ _ =
196230
pure $ Left $ mkErr InvalidRequest "Bad URI"
197231

232+
198233
mkErr :: ErrorCode -> T.Text -> ResponseError
199234
mkErr code err = ResponseError code err Nothing
200235

@@ -278,6 +313,7 @@ mergeFunBindMatches _ _ _ = Left "mergeFunBindMatches: called on something that
278313
noteT :: String -> TransformT (Either String) a
279314
noteT = lift . Left
280315

316+
281317
------------------------------------------------------------------------------
282318
-- | Helper function to route 'mergeFunBindMatches' into the right place in an
283319
-- AST --- correctly dealing with inserting into instance declarations.

0 commit comments

Comments
 (0)