@@ -25,7 +25,6 @@ import Data.List.NonEmpty (NonEmpty ((:|)),
25
25
import qualified Data.Map as M
26
26
import Data.Maybe
27
27
import Data.Mod.Word
28
- import qualified Data.Set as S
29
28
import qualified Data.Text as T
30
29
import Development.IDE (Recorder , WithPriority ,
31
30
usePropertyAction )
@@ -42,7 +41,9 @@ import qualified Development.IDE.GHC.ExactPrint as E
42
41
import Development.IDE.Plugin.CodeAction
43
42
import Development.IDE.Spans.AtPoint
44
43
import Development.IDE.Types.Location
44
+ import HieDb ((:.) (.. ))
45
45
import HieDb.Query
46
+ import HieDb.Types (RefRow (refIsGenerated ))
46
47
import Ide.Plugin.Error
47
48
import Ide.Plugin.Properties
48
49
import Ide.PluginUtils
@@ -196,6 +197,8 @@ refsAtName state nfp name = do
196
197
dbRefs <- case nameModule_maybe name of
197
198
Nothing -> pure []
198
199
Just mod -> liftIO $ mapMaybe rowToLoc <$> withHieDb (\ hieDb ->
200
+ -- See Note [Generated references]
201
+ filter (\ (refRow HieDb. :. _) -> refIsGenerated refRow) <$>
199
202
findReferences
200
203
hieDb
201
204
True
@@ -230,15 +233,29 @@ handleGetHieAst state nfp =
230
233
-- which is bad (see https://github.com/haskell/haskell-language-server/issues/3799)
231
234
fmap removeGenerated $ runActionE " Rename.GetHieAst" state $ useE GetHieAst nfp
232
235
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
+ -}
235
243
removeGenerated :: HieAstResult -> HieAstResult
236
- removeGenerated HAR {.. } = HAR {hieAst = go hieAst,.. }
244
+ removeGenerated HAR {.. } =
245
+ HAR {hieAst = sourceOnlyAsts, refMap = sourceOnlyRefMap, .. }
237
246
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
242
259
243
260
collectWith :: (Hashable a , Eq b ) => (a -> b ) -> HashSet a -> [(b , HashSet a )]
244
261
collectWith f = map (\ (a :| as) -> (f a, HS. fromList (a: as))) . groupWith f . HS. toList
0 commit comments