@@ -31,11 +31,11 @@ import Development.IDE.Core.Service (runAction)
31
31
import Development.IDE.Core.Shake (useWithStale , IdeState (.. ))
32
32
import Development.IDE.GHC.Compat
33
33
import Development.IDE.GHC.Error (realSrcSpanToRange )
34
- import Development.IDE.GHC.Util (hscEnv )
35
34
import Development.Shake (Action )
35
+ import DynFlags (xopt )
36
36
import qualified FastString
37
37
import GHC.Generics (Generic )
38
- import HscTypes ( hsc_dflags )
38
+ import GHC.LanguageExtensions.Type ( Extension ( LambdaCase ) )
39
39
import Ide.Plugin (mkLspCommand )
40
40
import Ide.Plugin.Tactic.BindSites
41
41
import Ide.Plugin.Tactic.Context
@@ -59,22 +59,17 @@ descriptor plId = (defaultPluginDescriptor plId)
59
59
(tcCommandId tc)
60
60
(tacticDesc $ tcCommandName tc)
61
61
(tacticCmd $ commandTactic tc))
62
- enabledTactics
62
+ [ minBound .. maxBound ]
63
63
, pluginCodeActionProvider = Just codeActionProvider
64
64
}
65
65
66
66
tacticDesc :: T. Text -> T. Text
67
67
tacticDesc name = " fill the hole using the " <> name <> " tactic"
68
68
69
- ------------------------------------------------------------------------------
70
-
71
- enabledTactics :: [TacticCommand ]
72
- enabledTactics = [Intros , Destruct , Homomorphism , Auto ]
73
-
74
69
------------------------------------------------------------------------------
75
70
-- | A 'TacticProvider' is a way of giving context-sensitive actions to the LS
76
71
-- UI.
77
- type TacticProvider = PluginId -> Uri -> Range -> Judgement -> IO [CAResult ]
72
+ type TacticProvider = DynFlags -> PluginId -> Uri -> Range -> Judgement -> IO [CAResult ]
78
73
79
74
80
75
------------------------------------------------------------------------------
@@ -93,10 +88,6 @@ tcCommandName = T.pack . show
93
88
-- 'filterGoalType' and 'filterBindingType' for the nitty gritty.
94
89
commandProvider :: TacticCommand -> TacticProvider
95
90
commandProvider Auto = provide Auto " "
96
- commandProvider Split = provide Split " "
97
- commandProvider Intro =
98
- filterGoalType isFunction $
99
- provide Intro " "
100
91
commandProvider Intros =
101
92
filterGoalType isFunction $
102
93
provide Intros " "
@@ -106,17 +97,25 @@ commandProvider Destruct =
106
97
commandProvider Homomorphism =
107
98
filterBindingType homoFilter $ \ occ _ ->
108
99
provide Homomorphism $ T. pack $ occNameString occ
100
+ commandProvider DestructLambdaCase =
101
+ requireExtension LambdaCase $
102
+ filterGoalType (isJust . lambdaCaseable) $
103
+ provide DestructLambdaCase " "
104
+ commandProvider HomomorphismLambdaCase =
105
+ requireExtension LambdaCase $
106
+ filterGoalType ((== Just True ) . lambdaCaseable) $
107
+ provide HomomorphismLambdaCase " "
109
108
110
109
111
110
------------------------------------------------------------------------------
112
111
-- | A mapping from tactic commands to actual tactics for refinery.
113
112
commandTactic :: TacticCommand -> OccName -> TacticsM ()
114
113
commandTactic Auto = const auto
115
- commandTactic Split = const split
116
- commandTactic Intro = const intro
117
114
commandTactic Intros = const intros
118
115
commandTactic Destruct = destruct
119
116
commandTactic Homomorphism = homo
117
+ commandTactic DestructLambdaCase = const destructLambdaCase
118
+ commandTactic HomomorphismLambdaCase = const homoLambdaCase
120
119
121
120
122
121
------------------------------------------------------------------------------
@@ -143,10 +142,11 @@ codeActionProvider :: CodeActionProvider
143
142
codeActionProvider _conf state plId (TextDocumentIdentifier uri) range _ctx
144
143
| Just nfp <- uriToNormalizedFilePath $ toNormalizedUri uri =
145
144
fromMaybeT (Right $ List [] ) $ do
146
- (_, _, span , jdg) <- MaybeT $ judgementForHole state nfp range
145
+ (_, _, span , jdg, dflags ) <- MaybeT $ judgementForHole state nfp range
147
146
actions <- lift $
148
147
-- This foldMap is over the function monoid.
149
- foldMap commandProvider enabledTactics
148
+ foldMap commandProvider [minBound .. maxBound ]
149
+ dflags
150
150
plId
151
151
uri
152
152
span
@@ -163,7 +163,7 @@ codeActions = List . fmap CACodeAction
163
163
-- | Terminal constructor for providing context-sensitive tactics. Tactics
164
164
-- given by 'provide' are always available.
165
165
provide :: TacticCommand -> T. Text -> TacticProvider
166
- provide tc name plId uri range _ = do
166
+ provide tc name _ plId uri range _ = do
167
167
let title = tacticTitle tc name
168
168
params = TacticParams { file = uri , range = range , var_name = name }
169
169
cmd <- mkLspCommand plId (tcCommandId tc) title (Just [toJSON params])
@@ -174,13 +174,23 @@ provide tc name plId uri range _ = do
174
174
$ Just cmd
175
175
176
176
177
+ ------------------------------------------------------------------------------
178
+ -- | Restrict a 'TacticProvider', making sure it appears only when the given
179
+ -- predicate holds for the goal.
180
+ requireExtension :: Extension -> TacticProvider -> TacticProvider
181
+ requireExtension ext tp dflags plId uri range jdg =
182
+ case xopt ext dflags of
183
+ True -> tp dflags plId uri range jdg
184
+ False -> pure []
185
+
186
+
177
187
------------------------------------------------------------------------------
178
188
-- | Restrict a 'TacticProvider', making sure it appears only when the given
179
189
-- predicate holds for the goal.
180
190
filterGoalType :: (Type -> Bool ) -> TacticProvider -> TacticProvider
181
- filterGoalType p tp plId uri range jdg =
191
+ filterGoalType p tp dflags plId uri range jdg =
182
192
case p $ unCType $ jGoal jdg of
183
- True -> tp plId uri range jdg
193
+ True -> tp dflags plId uri range jdg
184
194
False -> pure []
185
195
186
196
@@ -191,12 +201,12 @@ filterBindingType
191
201
:: (Type -> Type -> Bool ) -- ^ Goal and then binding types.
192
202
-> (OccName -> Type -> TacticProvider )
193
203
-> TacticProvider
194
- filterBindingType p tp plId uri range jdg =
204
+ filterBindingType p tp dflags plId uri range jdg =
195
205
let hy = jHypothesis jdg
196
206
g = jGoal jdg
197
207
in fmap join $ for (M. toList hy) $ \ (occ, CType ty) ->
198
208
case p (unCType g) ty of
199
- True -> tp occ ty plId uri range jdg
209
+ True -> tp occ ty dflags plId uri range jdg
200
210
False -> pure []
201
211
202
212
@@ -215,14 +225,19 @@ judgementForHole
215
225
:: IdeState
216
226
-> NormalizedFilePath
217
227
-> Range
218
- -> IO (Maybe (PositionMapping , BindSites , Range , Judgement ))
228
+ -> IO (Maybe (PositionMapping , BindSites , Range , Judgement , DynFlags ))
219
229
judgementForHole state nfp range = runMaybeT $ do
220
230
(asts, amapping) <- MaybeT $ runIde state $ useWithStale GetHieAst nfp
221
231
range' <- liftMaybe $ fromCurrentRange amapping range
222
232
223
233
(binds, _) <- MaybeT $ runIde state $ useWithStale GetBindings nfp
224
234
let b2 = bindSites $ refMap asts
225
235
236
+ -- Ok to use the stale 'ModIface', since all we need is its 'DynFlags'
237
+ -- which don't change very often.
238
+ (modsum, _) <- MaybeT $ runIde state $ useWithStale GetModSummaryWithoutTimestamps nfp
239
+ let dflags = ms_hspp_opts modsum
240
+
226
241
(rss, goal) <- liftMaybe $ join $ listToMaybe $ M. elems $ flip M. mapWithKey (getAsts $ hieAst asts) $ \ fs ast ->
227
242
case selectSmallestContaining (rangeToRealSrcSpan (FastString. unpackFS fs) range') ast of
228
243
Nothing -> Nothing
@@ -235,24 +250,20 @@ judgementForHole state nfp range = runMaybeT $ do
235
250
resulting_range <- liftMaybe $ toCurrentRange amapping $ realSrcSpanToRange rss
236
251
237
252
let hyps = hypothesisFromBindings rss binds
238
- pure (amapping, b2, resulting_range, mkFirstJudgement hyps goal)
253
+ pure (amapping, b2, resulting_range, mkFirstJudgement hyps goal, dflags )
239
254
240
255
241
256
242
257
tacticCmd :: (OccName -> TacticsM () ) -> CommandFunction TacticParams
243
258
tacticCmd tac lf state (TacticParams uri range var_name)
244
259
| Just nfp <- uriToNormalizedFilePath $ toNormalizedUri uri =
245
260
fromMaybeT (Right Null , Nothing ) $ do
246
- (pos, b2, _, jdg) <- MaybeT $ judgementForHole state nfp range
247
- -- Ok to use the stale 'ModIface', since all we need is its 'DynFlags'
248
- -- which don't change very often.
249
- (hscenv, _) <- MaybeT $ runIde state $ useWithStale GhcSession nfp
261
+ (pos, b2, _, jdg, dflags) <- MaybeT $ judgementForHole state nfp range
250
262
range' <- liftMaybe $ toCurrentRange pos range
251
263
(tcmod, _) <- MaybeT $ runIde state $ useWithStale TypeCheck nfp
252
264
let span = rangeToRealSrcSpan (fromNormalizedFilePath nfp) range'
253
265
-- TODO(sandy): unclear if this span is correct; might be
254
266
-- pointing to the wrong version of the file
255
- dflags = hsc_dflags $ hscEnv hscenv
256
267
tcg = fst $ tm_internals_ $ tmrModule tcmod
257
268
ctx = mkContext
258
269
(mapMaybe (sequenceA . (occName *** coerce)) $ getDefiningBindings b2 span )
0 commit comments