17
17
18
18
module Ide.Plugin.Retrie (descriptor ) where
19
19
20
+ import Control.Concurrent.Extra (readVar )
20
21
import Control.Exception.Safe (Exception (.. ), SomeException ,
21
22
catch , throwIO , try )
22
23
import Control.Monad (forM , unless )
@@ -29,7 +30,9 @@ import Data.Aeson.Types (FromJSON)
29
30
import Data.Bifunctor (Bifunctor (first ), second )
30
31
import Data.Coerce
31
32
import Data.Either (partitionEithers )
33
+ import Data.Hashable (unhashed )
32
34
import qualified Data.HashMap.Strict as HM
35
+ import qualified Data.HashSet as Set
33
36
import Data.IORef.Extra (atomicModifyIORef'_ , newIORef ,
34
37
readIORef )
35
38
import Data.List.Extra (nubOrdOn )
@@ -47,18 +50,21 @@ import Development.IDE.Core.RuleTypes as Ghcide (GetModIface (..),
47
50
tmrModule )
48
51
import Development.IDE.Core.Shake (IdeRule ,
49
52
IdeState (shakeExtras ),
53
+ ideLogger , knownFilesVar ,
50
54
runIdeAction , use ,
51
55
useWithStaleFast , use_ )
52
- import Development.IDE.GHC.Error (realSrcSpanToRange , isInsideSrcSpan )
56
+ import Development.IDE.GHC.Error (isInsideSrcSpan ,
57
+ realSrcSpanToRange )
53
58
import Development.IDE.GHC.Util (hscEnv , prettyPrint , runGhcEnv )
54
59
import Development.IDE.Types.Location
60
+ import Development.IDE.Types.Logger (Logger (logPriority ),
61
+ Priority (.. ))
55
62
import Development.Shake (RuleResult )
56
63
import GHC (GenLocated (L ), GhcRn ,
57
64
HsBindLR (FunBind ),
58
65
HsGroup (.. ),
59
66
HsValBindsLR (.. ), HscEnv , IdP ,
60
67
LRuleDecls ,
61
- mi_fixities ,
62
68
ModSummary (ModSummary , ms_hspp_buf , ms_mod ),
63
69
NHsValBindsLR (.. ),
64
70
ParsedModule (.. ),
@@ -68,8 +74,9 @@ import GHC (GenLocated (L), GhcRn,
68
74
TyClDecl (SynDecl ),
69
75
TyClGroup (.. ),
70
76
TypecheckedModule (.. ), fun_id ,
71
- moduleNameString , parseModule ,
72
- rds_rules , srcSpanFile )
77
+ mi_fixities , moduleNameString ,
78
+ parseModule , rds_rules ,
79
+ srcSpanFile )
73
80
import GHC.Generics (Generic )
74
81
import GhcPlugins (Outputable ,
75
82
SourceText (NoSourceText ),
@@ -114,11 +121,12 @@ retrieCommand =
114
121
115
122
-- | Parameters for the runRetrie PluginCommand.
116
123
data RunRetrieParams = RunRetrieParams
117
- { description :: T. Text ,
124
+ { description :: T. Text ,
118
125
-- | rewrites for Retrie
119
- rewrites :: [Either ImportSpec RewriteSpec ],
126
+ rewrites :: [Either ImportSpec RewriteSpec ],
120
127
-- | Originating file
121
- originatingFile :: String -- NormalizedFilePath
128
+ originatingFile :: String ,
129
+ restrictToOriginatingFile :: Bool
122
130
}
123
131
deriving (Eq , Show , Generic , FromJSON , ToJSON )
124
132
@@ -139,6 +147,7 @@ runRetrieCmd lsp state RunRetrieParams {..} =
139
147
(hscEnv session)
140
148
rewrites
141
149
(toNormalizedFilePath originatingFile)
150
+ restrictToOriginatingFile
142
151
unless (null errors) $
143
152
sendFunc lsp $
144
153
NotShowMessage $
@@ -228,17 +237,24 @@ suggestBindRewrites originatingFile pos ms_mod (FunBind {fun_id = L l' rdrName,
228
237
let ideclAsString = moduleNameString . fst <$> isQual_maybe r,
229
238
let ideclThing = Just (IEVar $ occNameString $ rdrNameOcc r)
230
239
]
231
- in [ let rewrites =
232
- [Right $ Unfold (qualify ms_mod pprName)]
233
- ++ map Left imports
234
- description = " Unfold " <> pprNameText
235
- in (description, CodeActionRefactorInline , RunRetrieParams {.. }),
240
+ unfoldRewrite restrictToOriginatingFile =
241
+ let rewrites =
242
+ [Right $ Unfold (qualify ms_mod pprName)]
243
+ ++ map Left imports
244
+ description = " Unfold " <> pprNameText <> describeRestriction restrictToOriginatingFile
245
+ in (description, CodeActionRefactorInline , RunRetrieParams {.. })
246
+ foldRewrite restrictToOriginatingFile =
236
247
let rewrites = [Right $ Fold (qualify ms_mod pprName)]
237
- description = " Fold " <> pprNameText
248
+ description = " Fold " <> pprNameText <> describeRestriction restrictToOriginatingFile
238
249
in (description, CodeActionRefactorExtract , RunRetrieParams {.. })
239
- ]
250
+ in [unfoldRewrite False , unfoldRewrite True , foldRewrite False , foldRewrite True ]
251
+ where
240
252
suggestBindRewrites _ _ _ _ = []
241
253
254
+ describeRestriction :: IsString p => Bool -> p
255
+ describeRestriction restrictToOriginatingFile =
256
+ if restrictToOriginatingFile then " in current file" else " "
257
+
242
258
-- TODO add imports to the rewrite
243
259
suggestTypeRewrites ::
244
260
(Outputable (IdP pass )) =>
@@ -251,13 +267,15 @@ suggestTypeRewrites originatingFile pos ms_mod (SynDecl {tcdLName = L l rdrName}
251
267
| pos `isInsideSrcSpan` l =
252
268
let pprName = prettyPrint rdrName
253
269
pprNameText = T. pack pprName
254
- in [ let rewrites = [Right $ TypeForward (qualify ms_mod pprName)]
255
- description = " Unfold " <> pprNameText
256
- in (description, CodeActionRefactorInline , RunRetrieParams {.. }),
270
+ unfoldRewrite restrictToOriginatingFile =
271
+ let rewrites = [Right $ TypeForward (qualify ms_mod pprName)]
272
+ description = " Unfold " <> pprNameText <> describeRestriction restrictToOriginatingFile
273
+ in (description, CodeActionRefactorInline , RunRetrieParams {.. })
274
+ foldRewrite restrictToOriginatingFile =
257
275
let rewrites = [Right $ TypeBackward (qualify ms_mod pprName)]
258
- description = " Fold " <> pprNameText
276
+ description = " Fold " <> pprNameText <> describeRestriction restrictToOriginatingFile
259
277
in (description, CodeActionRefactorExtract , RunRetrieParams {.. })
260
- ]
278
+ in [unfoldRewrite False , unfoldRewrite True , foldRewrite False , foldRewrite True ]
261
279
suggestTypeRewrites _ _ _ _ = []
262
280
263
281
-- TODO add imports to the rewrite
@@ -269,21 +287,11 @@ suggestRuleRewrites ::
269
287
[(T. Text , CodeActionKind , RunRetrieParams )]
270
288
suggestRuleRewrites originatingFile pos ms_mod (L _ (HsRules {rds_rules})) =
271
289
concat
272
- [ [ let rewrites =
273
- [Right $ RuleForward (qualify ms_mod ruleName)]
274
- description = " Apply rule " <> T. pack ruleName <> " forward"
275
- in ( description,
276
- CodeActionRefactor ,
277
- RunRetrieParams {.. }
278
- ),
279
- let rewrites =
280
- [Right $ RuleBackward (qualify ms_mod ruleName)]
281
- description = " Apply rule " <> T. pack ruleName <> " backwards"
282
- in ( description,
283
- CodeActionRefactor ,
284
- RunRetrieParams {.. }
285
- )
286
- ]
290
+ [ [ forwardRewrite ruleName True
291
+ , forwardRewrite ruleName False
292
+ , backwardsRewrite ruleName True
293
+ , backwardsRewrite ruleName False
294
+ ]
287
295
| L l r <- rds_rules,
288
296
pos `isInsideSrcSpan` l,
289
297
#if MIN_GHC_API_VERSION(8,8,0)
@@ -293,6 +301,26 @@ suggestRuleRewrites originatingFile pos ms_mod (L _ (HsRules {rds_rules})) =
293
301
#endif
294
302
let ruleName = unpackFS rn
295
303
]
304
+ where
305
+ forwardRewrite ruleName restrictToOriginatingFile =
306
+ let rewrites =
307
+ [Right $ RuleForward (qualify ms_mod ruleName)]
308
+ description = " Apply rule " <> T. pack ruleName <> " forward" <>
309
+ describeRestriction restrictToOriginatingFile
310
+
311
+ in ( description,
312
+ CodeActionRefactor ,
313
+ RunRetrieParams {.. }
314
+ )
315
+ backwardsRewrite ruleName restrictToOriginatingFile =
316
+ let rewrites =
317
+ [Right $ RuleBackward (qualify ms_mod ruleName)]
318
+ description = " Apply rule " <> T. pack ruleName <> " backwards"
319
+ in ( description,
320
+ CodeActionRefactor ,
321
+ RunRetrieParams {.. }
322
+ )
323
+
296
324
suggestRuleRewrites _ _ _ _ = []
297
325
298
326
qualify :: GHC. Module -> String -> String
@@ -321,8 +349,11 @@ callRetrie ::
321
349
HscEnv ->
322
350
[Either ImportSpec RewriteSpec ] ->
323
351
NormalizedFilePath ->
352
+ Bool ->
324
353
IO ([CallRetrieError ], WorkspaceEdit )
325
- callRetrie state session rewrites origin = do
354
+ callRetrie state session rewrites origin restrictToOriginatingFile = do
355
+ knownFiles <- readVar $ knownFilesVar $ shakeExtras state
356
+ print knownFiles
326
357
let reuseParsedModule f = do
327
358
pm <-
328
359
useOrFail " GetParsedModule" NoParse GetParsedModule f
@@ -338,6 +369,7 @@ callRetrie state session rewrites origin = do
338
369
{ ms_hspp_buf =
339
370
Just (stringToStringBuffer contents)
340
371
}
372
+ logPriority (ideLogger state) Info $ T. pack $ " Parsing module: " <> t
341
373
(_, parsed) <-
342
374
runGhcEnv session (parseModule ms')
343
375
`catch` \ e -> throwIO (GHCParseError nt (show @ SomeException e))
@@ -368,7 +400,13 @@ callRetrie state session rewrites origin = do
368
400
target = " ."
369
401
370
402
retrieOptions :: Retrie. Options
371
- retrieOptions = (defaultOptions target) {Retrie. verbosity = Loud }
403
+ retrieOptions = (defaultOptions target)
404
+ {Retrie. verbosity = Loud
405
+ ,Retrie. targetFiles = map fromNormalizedFilePath $
406
+ if restrictToOriginatingFile
407
+ then [origin]
408
+ else Set. toList $ unhashed knownFiles
409
+ }
372
410
373
411
(theImports, theRewrites) = partitionEithers rewrites
374
412
0 commit comments