@@ -25,7 +25,6 @@ import Data.List.NonEmpty (NonEmpty ((:|)),
2525import qualified Data.Map as M
2626import Data.Maybe
2727import Data.Mod.Word
28- import qualified Data.Set as S
2928import qualified Data.Text as T
3029import Development.IDE (Recorder , WithPriority ,
3130 usePropertyAction )
@@ -42,7 +41,9 @@ import qualified Development.IDE.GHC.ExactPrint as E
4241import Development.IDE.Plugin.CodeAction
4342import Development.IDE.Spans.AtPoint
4443import Development.IDE.Types.Location
44+ import HieDb ((:.) (.. ))
4545import HieDb.Query
46+ import HieDb.Types (RefRow (refIsGenerated ))
4647import Ide.Plugin.Error
4748import Ide.Plugin.Properties
4849import Ide.PluginUtils
@@ -196,6 +197,8 @@ refsAtName state nfp name = do
196197 dbRefs <- case nameModule_maybe name of
197198 Nothing -> pure []
198199 Just mod -> liftIO $ mapMaybe rowToLoc <$> withHieDb (\ hieDb ->
200+ -- See Note [Generated references]
201+ filter (\ (refRow HieDb. :. _) -> refIsGenerated refRow) <$>
199202 findReferences
200203 hieDb
201204 True
@@ -230,15 +233,29 @@ handleGetHieAst state nfp =
230233 -- which is bad (see https://github.com/haskell/haskell-language-server/issues/3799)
231234 fmap removeGenerated $ runActionE " Rename.GetHieAst" state $ useE GetHieAst nfp
232235
233- -- | We don't want to rename in code generated by GHC as this gives false positives.
234- -- So we restrict the HIE file to remove all the generated code.
236+ {- Note [Generated references]
237+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
238+ GHC inserts `Use`s of record constructor everywhere where its record selectors are used,
239+ which leads to record fields being renamed whenever corresponding constructor is renamed.
240+ see https://github.com/haskell/haskell-language-server/issues/2915
241+ To work around this, we filter out compiler-generated references.
242+ -}
235243removeGenerated :: HieAstResult -> HieAstResult
236- removeGenerated HAR {.. } = HAR {hieAst = go hieAst,.. }
244+ removeGenerated HAR {.. } =
245+ HAR {hieAst = sourceOnlyAsts, refMap = sourceOnlyRefMap, .. }
237246 where
238- go :: HieASTs a -> HieASTs a
239- go hf =
240- HieASTs (fmap goAst (getAsts hf))
241- goAst (Node nsi sp xs) = Node (SourcedNodeInfo $ M. restrictKeys (getSourcedNodeInfo nsi) (S. singleton SourceInfo )) sp (map goAst xs)
247+ goAsts :: HieASTs a -> HieASTs a
248+ goAsts (HieASTs asts) = HieASTs (fmap goAst asts)
249+
250+ goAst :: HieAST a -> HieAST a
251+ goAst (Node (SourcedNodeInfo sniMap) sp children) =
252+ let sourceOnlyNodeInfos = SourcedNodeInfo $ M. delete GeneratedInfo sniMap
253+ in Node sourceOnlyNodeInfos sp $ map goAst children
254+
255+ sourceOnlyAsts = goAsts hieAst
256+ -- Also need to regenerate the RefMap, because the one in HAR
257+ -- is generated from HieASTs containing GeneratedInfo
258+ sourceOnlyRefMap = generateReferencesMap $ getAsts sourceOnlyAsts
242259
243260collectWith :: (Hashable a , Eq b ) => (a -> b ) -> HashSet a -> [(b , HashSet a )]
244261collectWith f = map (\ (a :| as) -> (f a, HS. fromList (a: as))) . groupWith f . HS. toList
0 commit comments