Skip to content

Commit 0e04108

Browse files
committed
Add single file rewrites and ignore unknown files
Retrie is very slow and memory hungry on modules with lots of CPP. For instance, it runs out of memory on Development.IDE.GHC.Compat. This creates problems when rewriting (particularly folding). As a low key workaround, this adds new code actions that rewrite only in the current file. Rewriting on files without a cradle is also very slowbecause it results in calls to hie-bios that fail after consulting with Cabal. Thus exclude them.
1 parent 755edaa commit 0e04108

File tree

1 file changed

+66
-31
lines changed

1 file changed

+66
-31
lines changed

Diff for: src/Ide/Plugin/Retrie.hs

+66-31
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import Development.IDE.Core.RuleTypes as Ghcide (GetModIface (..),
4545
HiFileResult (..),
4646
TypeCheck (..),
4747
tmrModule)
48-
import Development.IDE.Core.Shake (IdeRule,
48+
import Development.IDE.Core.Shake (ideLogger, knownFilesVar, IdeRule,
4949
IdeState (shakeExtras),
5050
runIdeAction, use,
5151
useWithStaleFast, use_)
@@ -97,6 +97,10 @@ import Retrie.SYB (listify)
9797
import Retrie.Util (Verbosity (Loud))
9898
import StringBuffer (stringToStringBuffer)
9999
import System.Directory (makeAbsolute)
100+
import Control.Concurrent.Extra (readVar)
101+
import Data.Hashable (unhashed)
102+
import qualified Data.HashSet as Set
103+
import Development.IDE.Types.Logger (Priority(..), Logger(logPriority))
100104

101105
descriptor :: PluginId -> PluginDescriptor
102106
descriptor plId =
@@ -118,7 +122,8 @@ data RunRetrieParams = RunRetrieParams
118122
-- | rewrites for Retrie
119123
rewrites :: [Either ImportSpec RewriteSpec],
120124
-- | Originating file
121-
originatingFile :: String -- NormalizedFilePath
125+
originatingFile :: String,
126+
restrictToOriginatingFile :: Bool
122127
}
123128
deriving (Eq, Show, Generic, FromJSON, ToJSON)
124129

@@ -139,6 +144,7 @@ runRetrieCmd lsp state RunRetrieParams {..} =
139144
(hscEnv session)
140145
rewrites
141146
(toNormalizedFilePath originatingFile)
147+
restrictToOriginatingFile
142148
unless (null errors) $
143149
sendFunc lsp $
144150
NotShowMessage $
@@ -228,17 +234,24 @@ suggestBindRewrites originatingFile pos ms_mod (FunBind {fun_id = L l' rdrName,
228234
let ideclAsString = moduleNameString . fst <$> isQual_maybe r,
229235
let ideclThing = Just (IEVar $ occNameString $ rdrNameOcc r)
230236
]
231-
in [ let rewrites =
232-
[Right $ Unfold (qualify ms_mod pprName)]
233-
++ map Left imports
234-
description = "Unfold " <> pprNameText
235-
in (description, CodeActionRefactorInline, RunRetrieParams {..}),
237+
unfoldRewrite restrictToOriginatingFile =
238+
let rewrites =
239+
[Right $ Unfold (qualify ms_mod pprName)]
240+
++ map Left imports
241+
description = "Unfold " <> pprNameText <> describeRestriction restrictToOriginatingFile
242+
in (description, CodeActionRefactorInline, RunRetrieParams {..})
243+
foldRewrite restrictToOriginatingFile =
236244
let rewrites = [Right $ Fold (qualify ms_mod pprName)]
237-
description = "Fold " <> pprNameText
245+
description = "Fold " <> pprNameText <> describeRestriction restrictToOriginatingFile
238246
in (description, CodeActionRefactorExtract, RunRetrieParams {..})
239-
]
247+
in [unfoldRewrite False, unfoldRewrite True, foldRewrite False, foldRewrite True]
248+
where
240249
suggestBindRewrites _ _ _ _ = []
241250

251+
describeRestriction :: IsString p => Bool -> p
252+
describeRestriction restrictToOriginatingFile =
253+
if restrictToOriginatingFile then " in current file" else ""
254+
242255
-- TODO add imports to the rewrite
243256
suggestTypeRewrites ::
244257
(Outputable (IdP pass)) =>
@@ -251,13 +264,15 @@ suggestTypeRewrites originatingFile pos ms_mod (SynDecl {tcdLName = L l rdrName}
251264
| pos `isInsideSrcSpan` l =
252265
let pprName = prettyPrint rdrName
253266
pprNameText = T.pack pprName
254-
in [ let rewrites = [Right $ TypeForward (qualify ms_mod pprName)]
255-
description = "Unfold " <> pprNameText
256-
in (description, CodeActionRefactorInline, RunRetrieParams {..}),
267+
unfoldRewrite restrictToOriginatingFile =
268+
let rewrites = [Right $ TypeForward (qualify ms_mod pprName)]
269+
description = "Unfold " <> pprNameText <> describeRestriction restrictToOriginatingFile
270+
in (description, CodeActionRefactorInline, RunRetrieParams {..})
271+
foldRewrite restrictToOriginatingFile =
257272
let rewrites = [Right $ TypeBackward (qualify ms_mod pprName)]
258-
description = "Fold " <> pprNameText
273+
description = "Fold " <> pprNameText <> describeRestriction restrictToOriginatingFile
259274
in (description, CodeActionRefactorExtract, RunRetrieParams {..})
260-
]
275+
in [unfoldRewrite False, unfoldRewrite True, foldRewrite False, foldRewrite True]
261276
suggestTypeRewrites _ _ _ _ = []
262277

263278
-- TODO add imports to the rewrite
@@ -269,21 +284,11 @@ suggestRuleRewrites ::
269284
[(T.Text, CodeActionKind, RunRetrieParams)]
270285
suggestRuleRewrites originatingFile pos ms_mod (L _ (HsRules {rds_rules})) =
271286
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-
]
287+
[ [ forwardRewrite ruleName True
288+
, forwardRewrite ruleName False
289+
, backwardsRewrite ruleName True
290+
, backwardsRewrite ruleName False
291+
]
287292
| L l r <- rds_rules,
288293
pos `isInsideSrcSpan` l,
289294
#if MIN_GHC_API_VERSION(8,8,0)
@@ -293,6 +298,26 @@ suggestRuleRewrites originatingFile pos ms_mod (L _ (HsRules {rds_rules})) =
293298
#endif
294299
let ruleName = unpackFS rn
295300
]
301+
where
302+
forwardRewrite ruleName restrictToOriginatingFile =
303+
let rewrites =
304+
[Right $ RuleForward (qualify ms_mod ruleName)]
305+
description = "Apply rule " <> T.pack ruleName <> " forward" <>
306+
describeRestriction restrictToOriginatingFile
307+
308+
in ( description,
309+
CodeActionRefactor,
310+
RunRetrieParams {..}
311+
)
312+
backwardsRewrite ruleName restrictToOriginatingFile =
313+
let rewrites =
314+
[Right $ RuleBackward (qualify ms_mod ruleName)]
315+
description = "Apply rule " <> T.pack ruleName <> " backwards"
316+
in ( description,
317+
CodeActionRefactor,
318+
RunRetrieParams {..}
319+
)
320+
296321
suggestRuleRewrites _ _ _ _ = []
297322

298323
qualify :: GHC.Module -> String -> String
@@ -321,8 +346,11 @@ callRetrie ::
321346
HscEnv ->
322347
[Either ImportSpec RewriteSpec] ->
323348
NormalizedFilePath ->
349+
Bool ->
324350
IO ([CallRetrieError], WorkspaceEdit)
325-
callRetrie state session rewrites origin = do
351+
callRetrie state session rewrites origin restrictToOriginatingFile = do
352+
knownFiles <- readVar $ knownFilesVar $ shakeExtras state
353+
print knownFiles
326354
let reuseParsedModule f = do
327355
pm <-
328356
useOrFail "GetParsedModule" NoParse GetParsedModule f
@@ -338,6 +366,7 @@ callRetrie state session rewrites origin = do
338366
{ ms_hspp_buf =
339367
Just (stringToStringBuffer contents)
340368
}
369+
logPriority (ideLogger state) Info $ T.pack $ "Parsing module: " <> t
341370
(_, parsed) <-
342371
runGhcEnv session (parseModule ms')
343372
`catch` \e -> throwIO (GHCParseError nt (show @SomeException e))
@@ -368,7 +397,13 @@ callRetrie state session rewrites origin = do
368397
target = "."
369398

370399
retrieOptions :: Retrie.Options
371-
retrieOptions = (defaultOptions target) {Retrie.verbosity = Loud}
400+
retrieOptions = (defaultOptions target)
401+
{Retrie.verbosity = Loud
402+
,Retrie.targetFiles = map fromNormalizedFilePath $
403+
if restrictToOriginatingFile
404+
then [origin]
405+
else Set.toList $ unhashed knownFiles
406+
}
372407

373408
(theImports, theRewrites) = partitionEithers rewrites
374409

0 commit comments

Comments
 (0)