Skip to content

Commit e5ea4ff

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 e5ea4ff

File tree

1 file changed

+70
-34
lines changed

1 file changed

+70
-34
lines changed

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

+70-34
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE BangPatterns #-}
12
{-# LANGUAGE CPP #-}
23
{-# LANGUAGE DeriveAnyClass #-}
34
{-# LANGUAGE DeriveGeneric #-}
@@ -45,7 +46,7 @@ import Development.IDE.Core.RuleTypes as Ghcide (GetModIface (..),
4546
HiFileResult (..),
4647
TypeCheck (..),
4748
tmrModule)
48-
import Development.IDE.Core.Shake (IdeRule,
49+
import Development.IDE.Core.Shake (ideLogger, knownFilesVar, IdeRule,
4950
IdeState (shakeExtras),
5051
runIdeAction, use,
5152
useWithStaleFast, use_)
@@ -97,6 +98,10 @@ import Retrie.SYB (listify)
9798
import Retrie.Util (Verbosity (Loud))
9899
import StringBuffer (stringToStringBuffer)
99100
import System.Directory (makeAbsolute)
101+
import Control.Concurrent.Extra (readVar)
102+
import Data.Hashable (unhashed)
103+
import qualified Data.HashSet as Set
104+
import Development.IDE.Types.Logger (Priority(..), Logger(logPriority))
100105

101106
descriptor :: PluginId -> PluginDescriptor
102107
descriptor plId =
@@ -118,7 +123,8 @@ data RunRetrieParams = RunRetrieParams
118123
-- | rewrites for Retrie
119124
rewrites :: [Either ImportSpec RewriteSpec],
120125
-- | Originating file
121-
originatingFile :: String -- NormalizedFilePath
126+
originatingFile :: String,
127+
restrictToOriginatingFile :: Bool
122128
}
123129
deriving (Eq, Show, Generic, FromJSON, ToJSON)
124130

@@ -139,6 +145,7 @@ runRetrieCmd lsp state RunRetrieParams {..} =
139145
(hscEnv session)
140146
rewrites
141147
(toNormalizedFilePath originatingFile)
148+
restrictToOriginatingFile
142149
unless (null errors) $
143150
sendFunc lsp $
144151
NotShowMessage $
@@ -228,17 +235,24 @@ suggestBindRewrites originatingFile pos ms_mod (FunBind {fun_id = L l' rdrName,
228235
let ideclAsString = moduleNameString . fst <$> isQual_maybe r,
229236
let ideclThing = Just (IEVar $ occNameString $ rdrNameOcc r)
230237
]
231-
in [ let rewrites =
232-
[Right $ Unfold (qualify ms_mod pprName)]
233-
++ map Left imports
234-
description = "Unfold " <> pprNameText
235-
in (description, CodeActionRefactorInline, RunRetrieParams {..}),
238+
unfoldRewrite restrictToOriginatingFile =
239+
let rewrites =
240+
[Right $ Unfold (qualify ms_mod pprName)]
241+
++ map Left imports
242+
description = "Unfold " <> pprNameText <> describeRestriction restrictToOriginatingFile
243+
in (description, CodeActionRefactorInline, RunRetrieParams {..})
244+
foldRewrite restrictToOriginatingFile =
236245
let rewrites = [Right $ Fold (qualify ms_mod pprName)]
237-
description = "Fold " <> pprNameText
246+
description = "Fold " <> pprNameText <> describeRestriction restrictToOriginatingFile
238247
in (description, CodeActionRefactorExtract, RunRetrieParams {..})
239-
]
248+
in [unfoldRewrite False, unfoldRewrite True, foldRewrite False, foldRewrite True]
249+
where
240250
suggestBindRewrites _ _ _ _ = []
241251

252+
describeRestriction :: IsString p => Bool -> p
253+
describeRestriction restrictToOriginatingFile =
254+
if restrictToOriginatingFile then " in current file" else ""
255+
242256
-- TODO add imports to the rewrite
243257
suggestTypeRewrites ::
244258
(Outputable (IdP pass)) =>
@@ -251,13 +265,15 @@ suggestTypeRewrites originatingFile pos ms_mod (SynDecl {tcdLName = L l rdrName}
251265
| pos `isInsideSrcSpan` l =
252266
let pprName = prettyPrint rdrName
253267
pprNameText = T.pack pprName
254-
in [ let rewrites = [Right $ TypeForward (qualify ms_mod pprName)]
255-
description = "Unfold " <> pprNameText
256-
in (description, CodeActionRefactorInline, RunRetrieParams {..}),
268+
unfoldRewrite restrictToOriginatingFile =
269+
let rewrites = [Right $ TypeForward (qualify ms_mod pprName)]
270+
description = "Unfold " <> pprNameText <> describeRestriction restrictToOriginatingFile
271+
in (description, CodeActionRefactorInline, RunRetrieParams {..})
272+
foldRewrite restrictToOriginatingFile =
257273
let rewrites = [Right $ TypeBackward (qualify ms_mod pprName)]
258-
description = "Fold " <> pprNameText
274+
description = "Fold " <> pprNameText <> describeRestriction restrictToOriginatingFile
259275
in (description, CodeActionRefactorExtract, RunRetrieParams {..})
260-
]
276+
in [unfoldRewrite False, unfoldRewrite True, foldRewrite False, foldRewrite True]
261277
suggestTypeRewrites _ _ _ _ = []
262278

263279
-- TODO add imports to the rewrite
@@ -269,21 +285,11 @@ suggestRuleRewrites ::
269285
[(T.Text, CodeActionKind, RunRetrieParams)]
270286
suggestRuleRewrites originatingFile pos ms_mod (L _ (HsRules {rds_rules})) =
271287
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-
]
288+
[ [ forwardRewrite ruleName True
289+
, forwardRewrite ruleName False
290+
, backwardsRewrite ruleName True
291+
, backwardsRewrite ruleName False
292+
]
287293
| L l r <- rds_rules,
288294
pos `isInsideSrcSpan` l,
289295
#if MIN_GHC_API_VERSION(8,8,0)
@@ -293,6 +299,26 @@ suggestRuleRewrites originatingFile pos ms_mod (L _ (HsRules {rds_rules})) =
293299
#endif
294300
let ruleName = unpackFS rn
295301
]
302+
where
303+
forwardRewrite ruleName restrictToOriginatingFile =
304+
let rewrites =
305+
[Right $ RuleForward (qualify ms_mod ruleName)]
306+
description = "Apply rule " <> T.pack ruleName <> " forward" <>
307+
describeRestriction restrictToOriginatingFile
308+
309+
in ( description,
310+
CodeActionRefactor,
311+
RunRetrieParams {..}
312+
)
313+
backwardsRewrite ruleName restrictToOriginatingFile =
314+
let rewrites =
315+
[Right $ RuleBackward (qualify ms_mod ruleName)]
316+
description = "Apply rule " <> T.pack ruleName <> " backwards"
317+
in ( description,
318+
CodeActionRefactor,
319+
RunRetrieParams {..}
320+
)
321+
296322
suggestRuleRewrites _ _ _ _ = []
297323

298324
qualify :: GHC.Module -> String -> String
@@ -321,8 +347,11 @@ callRetrie ::
321347
HscEnv ->
322348
[Either ImportSpec RewriteSpec] ->
323349
NormalizedFilePath ->
350+
Bool ->
324351
IO ([CallRetrieError], WorkspaceEdit)
325-
callRetrie state session rewrites origin = do
352+
callRetrie state session rewrites origin restrictToOriginatingFile = do
353+
knownFiles <- readVar $ knownFilesVar $ shakeExtras state
354+
print knownFiles
326355
let reuseParsedModule f = do
327356
pm <-
328357
useOrFail "GetParsedModule" NoParse GetParsedModule f
@@ -338,10 +367,11 @@ callRetrie state session rewrites origin = do
338367
{ ms_hspp_buf =
339368
Just (stringToStringBuffer contents)
340369
}
341-
(_, parsed) <-
370+
logPriority (ideLogger state) Info $ T.pack $ "Parsing module: " <> t
371+
(_, !parsed) <-
342372
runGhcEnv session (parseModule ms')
343373
`catch` \e -> throwIO (GHCParseError nt (show @SomeException e))
344-
(fixities, parsed) <- fixFixities f (fixAnns parsed)
374+
(!fixities, !parsed) <- fixFixities f (fixAnns parsed)
345375
return (fixities, parsed)
346376

347377
contents <- do
@@ -359,7 +389,7 @@ callRetrie state session rewrites origin = do
359389
return res
360390
res <- parseCPP parseModule contents
361391
fixities <- readIORef fixitiesRef
362-
return (fixities, res)
392+
return $! (fixities, res)
363393
else do
364394
(fixities, pm) <- reuseParsedModule nt
365395
return (fixities, NoCPP pm)
@@ -368,7 +398,13 @@ callRetrie state session rewrites origin = do
368398
target = "."
369399

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

373409
(theImports, theRewrites) = partitionEithers rewrites
374410

0 commit comments

Comments
 (0)