1
- {-# LANGUAGE DeriveAnyClass #-}
2
- {-# LANGUAGE DeriveGeneric #-}
3
- {-# LANGUAGE GADTs #-}
4
- {-# LANGUAGE LambdaCase #-}
5
- {-# LANGUAGE NumDecimals #-}
6
- {-# LANGUAGE OverloadedStrings #-}
7
- {-# LANGUAGE ScopedTypeVariables #-}
8
- {-# LANGUAGE TupleSections #-}
9
- {-# LANGUAGE TypeApplications #-}
10
- {-# LANGUAGE ViewPatterns #-}
1
+ {-# LANGUAGE GADTs #-}
2
+ {-# LANGUAGE LambdaCase #-}
3
+ {-# LANGUAGE NumDecimals #-}
4
+ {-# LANGUAGE OverloadedStrings #-}
5
+ {-# LANGUAGE TypeApplications #-}
11
6
12
7
-- | A plugin that uses tactics to synthesize code
13
8
module Ide.Plugin.Tactic
@@ -19,7 +14,6 @@ module Ide.Plugin.Tactic
19
14
import Bag (listToBag , bagToList )
20
15
import Control.Arrow
21
16
import Control.Monad
22
- import Control.Monad.Error.Class (MonadError (throwError ))
23
17
import Control.Monad.Trans
24
18
import Control.Monad.Trans.Maybe
25
19
import Data.Aeson
@@ -46,9 +40,6 @@ import Development.IDE.GHC.ExactPrint
46
40
import Development.IDE.Spans.LocalBindings (getDefiningBindings )
47
41
import Development.Shake (Action )
48
42
import qualified FastString
49
- import GHC.Generics (Generic )
50
- import GHC.LanguageExtensions.Type (Extension (LambdaCase ))
51
- import Ide.Plugin.Tactic.Auto
52
43
import Ide.Plugin.Tactic.CaseSplit
53
44
import Ide.Plugin.Tactic.Context
54
45
import Ide.Plugin.Tactic.GHC
@@ -57,16 +48,15 @@ import Ide.Plugin.Tactic.Range
57
48
import Ide.Plugin.Tactic.Tactics
58
49
import Ide.Plugin.Tactic.TestTypes
59
50
import Ide.Plugin.Tactic.Types
60
- import Ide.PluginUtils
61
51
import Ide.Types
62
52
import Language.LSP.Server
63
53
import Language.LSP.Types
64
54
import OccName
65
55
import Prelude hiding (span )
66
- import Refinery.Tactic (goal )
67
56
import SrcLoc (containsSpan )
68
57
import System.Timeout
69
58
import TcRnTypes (tcg_binds )
59
+ import Ide.Plugin.Tactic.LanguageServer.TacticProviders
70
60
71
61
72
62
descriptor :: PluginId -> PluginDescriptor IdeState
@@ -84,85 +74,13 @@ descriptor plId = (defaultPluginDescriptor plId)
84
74
tacticDesc :: T. Text -> T. Text
85
75
tacticDesc name = " fill the hole using the " <> name <> " tactic"
86
76
87
- ------------------------------------------------------------------------------
88
- -- | A 'TacticProvider' is a way of giving context-sensitive actions to the LS
89
- -- UI.
90
- type TacticProvider = DynFlags -> PluginId -> Uri -> Range -> Judgement -> IO [Command |? CodeAction ]
91
-
92
-
93
- ------------------------------------------------------------------------------
94
- -- | Construct a 'CommandId'
95
- tcCommandId :: TacticCommand -> CommandId
96
- tcCommandId c = coerce $ T. pack $ " tactics" <> show c <> " Command"
97
77
98
78
99
79
------------------------------------------------------------------------------
100
80
-- | The name of the command for the LS.
101
81
tcCommandName :: TacticCommand -> T. Text
102
82
tcCommandName = T. pack . show
103
83
104
- ------------------------------------------------------------------------------
105
- -- | Mapping from tactic commands to their contextual providers. See 'provide',
106
- -- 'filterGoalType' and 'filterBindingType' for the nitty gritty.
107
- commandProvider :: TacticCommand -> TacticProvider
108
- commandProvider Auto = provide Auto " "
109
- commandProvider Intros =
110
- filterGoalType isFunction $
111
- provide Intros " "
112
- commandProvider Destruct =
113
- filterBindingType destructFilter $ \ occ _ ->
114
- provide Destruct $ T. pack $ occNameString occ
115
- commandProvider Homomorphism =
116
- filterBindingType homoFilter $ \ occ _ ->
117
- provide Homomorphism $ T. pack $ occNameString occ
118
- commandProvider DestructLambdaCase =
119
- requireExtension LambdaCase $
120
- filterGoalType (isJust . lambdaCaseable) $
121
- provide DestructLambdaCase " "
122
- commandProvider HomomorphismLambdaCase =
123
- requireExtension LambdaCase $
124
- filterGoalType ((== Just True ) . lambdaCaseable) $
125
- provide HomomorphismLambdaCase " "
126
-
127
-
128
- ------------------------------------------------------------------------------
129
- -- | A mapping from tactic commands to actual tactics for refinery.
130
- commandTactic :: TacticCommand -> OccName -> TacticsM ()
131
- commandTactic Auto = const auto
132
- commandTactic Intros = const intros
133
- commandTactic Destruct = useNameFromHypothesis destruct
134
- commandTactic Homomorphism = useNameFromHypothesis homo
135
- commandTactic DestructLambdaCase = const destructLambdaCase
136
- commandTactic HomomorphismLambdaCase = const homoLambdaCase
137
-
138
-
139
- ------------------------------------------------------------------------------
140
- -- | Lift a function over 'HyInfo's to one that takes an 'OccName' and tries to
141
- -- look it up in the hypothesis.
142
- useNameFromHypothesis :: (HyInfo CType -> TacticsM a ) -> OccName -> TacticsM a
143
- useNameFromHypothesis f name = do
144
- hy <- jHypothesis <$> goal
145
- case M. lookup name $ hyByName hy of
146
- Just hi -> f hi
147
- Nothing -> throwError $ NotInScope name
148
-
149
-
150
-
151
- ------------------------------------------------------------------------------
152
- -- | We should show homos only when the goal type is the same as the binding
153
- -- type, and that both are usual algebraic types.
154
- homoFilter :: Type -> Type -> Bool
155
- homoFilter (algebraicTyCon -> Just t1) (algebraicTyCon -> Just t2) = t1 == t2
156
- homoFilter _ _ = False
157
-
158
-
159
- ------------------------------------------------------------------------------
160
- -- | We should show destruct for bindings only when those bindings have usual
161
- -- algebraic types.
162
- destructFilter :: Type -> Type -> Bool
163
- destructFilter _ (algebraicTyCon -> Just _) = True
164
- destructFilter _ _ = False
165
-
166
84
167
85
runIde :: IdeState -> Action a -> IO a
168
86
runIde state = runAction " tactic" state
@@ -182,71 +100,8 @@ codeActionProvider state plId (CodeActionParams _ _ (TextDocumentIdentifier uri)
182
100
range
183
101
jdg
184
102
pure $ Right $ List actions
185
- codeActionProvider _ _ _ = pure $ Right $ codeActions []
186
-
187
-
188
- codeActions :: [CodeAction ] -> List (Command |? CodeAction )
189
- codeActions = List . fmap InR
190
-
191
-
192
- ------------------------------------------------------------------------------
193
- -- | Terminal constructor for providing context-sensitive tactics. Tactics
194
- -- given by 'provide' are always available.
195
- provide :: TacticCommand -> T. Text -> TacticProvider
196
- provide tc name _ plId uri range _ = do
197
- let title = tacticTitle tc name
198
- params = TacticParams { tp_file = uri , tp_range = range , tp_var_name = name }
199
- cmd = mkLspCommand plId (tcCommandId tc) title (Just [toJSON params])
200
- pure
201
- $ pure
202
- $ InR
203
- $ CodeAction title (Just CodeActionQuickFix ) Nothing Nothing Nothing Nothing
204
- $ Just cmd
205
-
103
+ codeActionProvider _ _ _ = pure $ Right $ List []
206
104
207
- ------------------------------------------------------------------------------
208
- -- | Restrict a 'TacticProvider', making sure it appears only when the given
209
- -- predicate holds for the goal.
210
- requireExtension :: Extension -> TacticProvider -> TacticProvider
211
- requireExtension ext tp dflags plId uri range jdg =
212
- case xopt ext dflags of
213
- True -> tp dflags plId uri range jdg
214
- False -> pure []
215
-
216
-
217
- ------------------------------------------------------------------------------
218
- -- | Restrict a 'TacticProvider', making sure it appears only when the given
219
- -- predicate holds for the goal.
220
- filterGoalType :: (Type -> Bool ) -> TacticProvider -> TacticProvider
221
- filterGoalType p tp dflags plId uri range jdg =
222
- case p $ unCType $ jGoal jdg of
223
- True -> tp dflags plId uri range jdg
224
- False -> pure []
225
-
226
-
227
- ------------------------------------------------------------------------------
228
- -- | Multiply a 'TacticProvider' for each binding, making sure it appears only
229
- -- when the given predicate holds over the goal and binding types.
230
- filterBindingType
231
- :: (Type -> Type -> Bool ) -- ^ Goal and then binding types.
232
- -> (OccName -> Type -> TacticProvider )
233
- -> TacticProvider
234
- filterBindingType p tp dflags plId uri range jdg =
235
- let hy = jHypothesis jdg
236
- g = jGoal jdg
237
- in fmap join $ for (unHypothesis hy) $ \ hi ->
238
- let ty = unCType $ hi_type hi
239
- in case p (unCType g) ty of
240
- True -> tp (hi_name hi) ty dflags plId uri range jdg
241
- False -> pure []
242
-
243
-
244
- data TacticParams = TacticParams
245
- { tp_file :: Uri -- ^ Uri of the file to fill the hole in
246
- , tp_range :: Range -- ^ The range of the hole
247
- , tp_var_name :: T. Text
248
- }
249
- deriving (Show , Eq , Generic , ToJSON , FromJSON )
250
105
251
106
252
107
------------------------------------------------------------------------------
0 commit comments