Skip to content

Commit 689f6e4

Browse files
committed
Fix refs at name
Reverts to the old implementation of refs at name. also fixes the filter for generated references which was causing problems on cross module renames.
1 parent 5c7188c commit 689f6e4

1 file changed

Lines changed: 68 additions & 36 deletions

File tree

  • plugins/hls-rename-plugin/src/Ide/Plugin

plugins/hls-rename-plugin/src/Ide/Plugin/Rename.hs

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ import qualified Development.IDE.GHC.ExactPrint as E
4242
import Development.IDE.Plugin.CodeAction
4343
import Development.IDE.Spans.AtPoint
4444
import Development.IDE.Types.Location
45-
import GHC (isGoodSrcSpan)
4645
import GHC.Iface.Ext.Types (HieAST (..),
4746
HieASTs (..),
4847
NodeOrigin (..),
4948
SourcedNodeInfo (..))
5049
import GHC.Iface.Ext.Utils (generateReferencesMap)
50+
import HieDb ((:.) (..))
5151
import HieDb.Query
5252
import HieDb.Types (RefRow (refIsGenerated))
5353
import Ide.Logger (Pretty (..),
@@ -97,7 +97,9 @@ prepareRenameProvider state _pluginId (PrepareRenameParams (TextDocumentIdentifi
9797
let spansWithNamesUnderCursor =
9898
[ srcSpan
9999
| (names, srcSpan) <- getNamesSpansAtPoint' hieAst pos
100-
, not (null names)]
100+
, not (null names)
101+
, positionInSpan pos srcSpan -- cursor must be within the trimmed span
102+
]
101103
-- When this handler says that rename is invalid, VSCode shows "The element can't be renamed"
102104
-- and doesn't even allow you to create full rename request.
103105
-- This handler deliberately approximates "things that definitely can't be renamed"
@@ -110,6 +112,15 @@ prepareRenameProvider state _pluginId (PrepareRenameParams (TextDocumentIdentifi
110112
[] -> InR Null
111113
srcSpan : _ -> InL $ PrepareRenameResult $ InL (realSrcSpanToRange srcSpan)
112114

115+
positionInSpan :: Position -> RealSrcSpan -> Bool
116+
positionInSpan (Position l c) sp =
117+
let start = realSrcSpanStart sp
118+
end = realSrcSpanEnd sp
119+
line = fromIntegral l + 1 -- LSP is 0-based, GHC is 1-based
120+
col = fromIntegral c + 1
121+
in (line, col) >= (srcLocLine start, srcLocCol start)
122+
&& (line, col) <= (srcLocLine end, srcLocCol end)
123+
113124
renameProvider :: PluginMethodHandler IdeState Method_TextDocumentRename
114125
renameProvider state pluginId (RenameParams _prog (TextDocumentIdentifier uri) pos newNameText) = do
115126
nfp <- getNormalizedFilePathE uri
@@ -296,29 +307,28 @@ refsAtName ::
296307
NormalizedFilePath ->
297308
Name ->
298309
ExceptT PluginError m [Location]
299-
refsAtName state nfp targetName = do
300-
HAR{refMap} <- handleGetHieAst state nfp
301-
302-
let localRefs =
303-
case M.lookup (Right targetName) refMap of
304-
Nothing -> []
305-
Just spans -> [ realSrcSpanToLocation sp | (sp, _) <- spans]
306-
307-
let defLoc = nameSrcSpan targetName
308-
defLocations = case srcSpanToLocation defLoc of
309-
Just loc | isGoodSrcSpan defLoc -> [loc]
310-
_ -> []
311-
312-
-- Only query HieDb if it's a global name
313-
globalRefs <-
314-
case nameModule_maybe targetName of
315-
Nothing -> pure []
316-
Just mod -> do
317-
ShakeExtras{withHieDb} <- liftIO $ runAction "Rename.HieDb" state getShakeExtras
318-
liftIO $ withHieDb $ \hieDb ->
319-
fmap (mapMaybe rowToLoc) $ findReferences hieDb True (nameOccName targetName) (Just $ moduleName mod) (Just $ moduleUnit mod) []
320-
321-
pure (defLocations ++ localRefs ++ globalRefs)
310+
refsAtName state nfp name = do
311+
ShakeExtras{withHieDb} <- liftIO $ runAction "Rename.HieDb" state getShakeExtras
312+
ast <- handleGetHieAst state nfp
313+
dbRefs <- case nameModule_maybe name of
314+
Nothing -> pure []
315+
Just mod -> liftIO $ mapMaybe rowToLoc <$> withHieDb (\hieDb ->
316+
-- See Note [Generated references]
317+
filter (\(refRow HieDb.:. _) -> not (refIsGenerated refRow)) <$>
318+
findReferences
319+
hieDb
320+
True
321+
(nameOccName name)
322+
(Just $ moduleName mod)
323+
(Just $ moduleUnit mod)
324+
[fromNormalizedFilePath nfp]
325+
)
326+
pure $ nameLocs name ast ++ dbRefs
327+
328+
nameLocs :: Name -> HieAstResult -> [Location]
329+
nameLocs name (HAR _ _ rm _ _) =
330+
concatMap (map (realSrcSpanToLocation . fst))
331+
(M.lookup (Right name) rm)
322332
---------------------------------------------------------------------------------------------------
323333
-- Util
324334

@@ -370,11 +380,35 @@ getNamesAtPoint' :: HieASTs a -> Position -> [Name]
370380
getNamesAtPoint' hf pos =
371381
concat $ pointCommand hf pos (rights . M.keys . getNodeIds)
372382

373-
-- | A variant of `getNamesAtPoint'` that also returns source spans.
383+
-- | A variant of `getNamesAtPoint'` that also returns source spans,
384+
-- trimmed to just the unqualified identifier (excluding any "Module." prefix).
374385
getNamesSpansAtPoint' :: HieASTs a -> Position -> [([Name], RealSrcSpan)]
375386
getNamesSpansAtPoint' hf pos =
376387
pointCommand hf pos $
377-
\astNode -> (rights . M.keys . getNodeIds $ astNode, nodeSpan astNode)
388+
\astNode ->
389+
let names = rights . M.keys . getNodeIds $ astNode
390+
srcSpan = nodeSpan astNode
391+
trimmed = trimQualifierSpan names srcSpan
392+
in (names, trimmed)
393+
394+
-- | Advance the start column of a span past any "Qualifier." prefix,
395+
-- using the OccName length of the first Name to find where the
396+
-- identifier begins.
397+
trimQualifierSpan :: [Name] -> RealSrcSpan -> RealSrcSpan
398+
trimQualifierSpan (n:_) sp
399+
| qualLen > 0
400+
= mkRealSrcSpan
401+
(mkRealSrcLoc file startLine (startCol + qualLen))
402+
(realSrcSpanEnd sp)
403+
| otherwise = sp
404+
where
405+
spanLen = srcLocCol (realSrcSpanEnd sp) - srcLocCol (realSrcSpanStart sp)
406+
identLen = length (occNameString (nameOccName n))
407+
qualLen = spanLen - identLen
408+
file = srcSpanFile sp
409+
startLine = srcLocLine (realSrcSpanStart sp)
410+
startCol = srcLocCol (realSrcSpanStart sp)
411+
trimQualifierSpan [] sp = sp
378412

379413
locToUri :: Location -> Uri
380414
locToUri (Location uri _) = uri
@@ -407,16 +441,14 @@ exportNameLocs pm names = do
407441
#else
408442
IEVar _ ieWrapped -> matchWrapped (getLoc export) ieWrapped
409443
#endif
410-
IEThingAll{} -> unsupported
411-
IEThingWith{} -> unsupported
412-
IEModuleContents{} -> unsupported
413-
IEThingAbs{} -> unsupported
414-
IEGroup{} -> unsupported
415-
IEDoc{} -> unsupported
416-
IEDocNamed{} -> unsupported
444+
IEThingAll{} -> pure []
445+
IEThingWith{} -> pure []
446+
IEModuleContents{} -> pure []
447+
IEThingAbs{} -> pure []
448+
IEGroup{} -> pure []
449+
IEDoc{} -> pure []
450+
IEDocNamed{} -> pure []
417451
where
418-
unsupported = throwError $ PluginInternalError "Renaming is unsupported for complex export forms"
419-
420452
matchWrapped :: SrcSpan -> LIEWrappedName GhcPs -> ExceptT PluginError (HandlerM config) [Location]
421453
matchWrapped l ieWrapped =
422454
case unwrapIEWrappedName (unLoc ieWrapped) of

0 commit comments

Comments
 (0)