@@ -26,6 +26,7 @@ import Data.List (find, intersperse)
26
26
import qualified Data.Map as Map
27
27
import Data.Maybe (fromMaybe , isJust ,
28
28
mapMaybe , maybeToList )
29
+ import Data.Monoid (First (.. ), getFirst )
29
30
import Data.Text (Text )
30
31
import qualified Data.Text as T
31
32
import Data.Unique (hashUnique , newUnique )
@@ -48,6 +49,7 @@ import Development.IDE.Core.PositionMapping (PositionMapping,
48
49
toCurrentRange )
49
50
import Development.IDE.Core.RuleTypes (TcModuleResult (.. ),
50
51
TypeCheck (.. ))
52
+ import Development.IDE.GHC.CoreFile (occNamePrefixes )
51
53
import qualified Development.IDE.Core.Shake as Shake
52
54
import Development.IDE.GHC.Compat (FieldLabel (flSelector ),
53
55
FieldOcc (FieldOcc ),
@@ -238,7 +240,7 @@ inlayHintDotdotProvider _ state pId InlayHintParams {_textDocument = TextDocumen
238
240
-- checks if 'a' is equal to 'Name' if the 'Either' is 'Right a', otherwise return 'False'
239
241
nameEq = either (const False ) ((==) name)
240
242
in fmap fst $ find (nameEq . snd ) filteredLocations
241
- valueWithLoc = [ (T. pack $ printName name, findLocation name defnLocs') | name <- names' ]
243
+ valueWithLoc = [ (stripPrefix $ T. pack $ printName name, findLocation name defnLocs') | name <- names' ]
242
244
-- use `, ` to separate labels with definition location
243
245
label = intersperse (mkInlayHintLabelPart (" , " , Nothing )) $ fmap mkInlayHintLabelPart valueWithLoc
244
246
pure $ InlayHint { _position = currentEnd -- at the end of dotdot
@@ -287,7 +289,7 @@ inlayHintPosRecProvider _ state _pId InlayHintParams {_textDocument = TextDocume
287
289
, _data_ = Nothing
288
290
}
289
291
290
- mkInlayHintLabelPart name loc = InlayHintLabelPart (printOutputable (pprNameUnqualified name) <> " =" ) Nothing loc Nothing
292
+ mkInlayHintLabelPart name loc = InlayHintLabelPart (printFieldName (pprNameUnqualified name) <> " =" ) Nothing loc Nothing
291
293
292
294
mkTitle :: [Extension ] -> Text
293
295
mkTitle exts = " Expand record wildcard"
@@ -410,10 +412,10 @@ data RecordInfo
410
412
deriving (Generic )
411
413
412
414
instance Pretty RecordInfo where
413
- pretty (RecordInfoPat ss p) = pretty (printOutputable ss) <> " :" <+> pretty (printOutputable p)
414
- pretty (RecordInfoCon ss e) = pretty (printOutputable ss) <> " :" <+> pretty (printOutputable e)
415
+ pretty (RecordInfoPat ss p) = pretty (printFieldName ss) <> " :" <+> pretty (printOutputable p)
416
+ pretty (RecordInfoCon ss e) = pretty (printFieldName ss) <> " :" <+> pretty (printOutputable e)
415
417
pretty (RecordInfoApp ss (RecordAppExpr _ _ fla))
416
- = pretty (printOutputable ss) <> " :" <+> hsep (map (pretty . printOutputable) fla)
418
+ = pretty (printFieldName ss) <> " :" <+> hsep (map (pretty . printOutputable) fla)
417
419
418
420
recordInfoToRange :: RecordInfo -> Range
419
421
recordInfoToRange (RecordInfoPat ss _) = realSrcSpanToRange ss
@@ -520,7 +522,7 @@ processRecordFlds flds = flds { rec_dotdot = Nothing , rec_flds = puns' }
520
522
521
523
522
524
showRecordPat :: Outputable (Pat GhcTc ) => UniqFM Name [Name ] -> Pat GhcTc -> Maybe Text
523
- showRecordPat names = fmap printOutputable . mapConPatDetail (\ case
525
+ showRecordPat names = fmap printFieldName . mapConPatDetail (\ case
524
526
RecCon flds -> Just $ RecCon (preprocessRecordPat names flds)
525
527
_ -> Nothing )
526
528
@@ -561,7 +563,7 @@ showRecordApp (RecordAppExpr _ recConstr fla)
561
563
= Just $ printOutputable recConstr <> " { "
562
564
<> T. intercalate " , " (showFieldWithArg <$> fla)
563
565
<> " }"
564
- where showFieldWithArg (field, arg) = printOutputable field <> " = " <> printOutputable arg
566
+ where showFieldWithArg (field, arg) = printFieldName field <> " = " <> printOutputable arg
565
567
566
568
collectRecords :: GenericQ [RecordInfo ]
567
569
collectRecords = everythingBut (<>) (([] , False ) `mkQ` getRecPatterns `extQ` getRecCons)
@@ -641,3 +643,18 @@ getRecPatterns conPat@(conPatDetails . unLoc -> Just (RecCon flds))
641
643
mkRecInfo pat =
642
644
[ RecordInfoPat realSpan' (unLoc pat) | RealSrcSpan realSpan' _ <- [ getLoc pat ]]
643
645
getRecPatterns _ = ([] , False )
646
+
647
+ printFieldName :: Outputable a => a -> Text
648
+ printFieldName = stripPrefix . printOutputable
649
+
650
+ {- When e.g. DuplicateRecordFields is enabled, compiler generates
651
+ names like "$sel:accessor:One" and "$sel:accessor:Two" to
652
+ disambiguate record selectors
653
+ https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/DuplicateRecordFields#Implementation
654
+ -}
655
+ -- See also:
656
+ -- https://github.com/haskell/haskell-language-server/blob/master/ghcide/src/Development/IDE/Plugin/Completions/Logic.hs#L811
657
+ stripPrefix :: T. Text -> T. Text
658
+ stripPrefix name = T. takeWhile (/= ' :' ) $ fromMaybe name $
659
+ getFirst $ foldMap (First . (`T.stripPrefix` name))
660
+ occNamePrefixes
0 commit comments