@@ -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 ),
@@ -226,7 +228,7 @@ inlayHintDotdotProvider _ state pId InlayHintParams {_textDocument = TextDocumen
226
228
-- checks if 'a' is equal to 'Name' if the 'Either' is 'Right a', otherwise return 'False'
227
229
nameEq = either (const False ) ((==) name)
228
230
in fmap fst $ find (nameEq . snd ) filteredLocations
229
- valueWithLoc = [ (T. pack $ printName name, findLocation name defnLocs') | name <- names' ]
231
+ valueWithLoc = [ (stripPrefix $ T. pack $ printName name, findLocation name defnLocs') | name <- names' ]
230
232
-- use `, ` to separate labels with definition location
231
233
label = intersperse (mkInlayHintLabelPart (" , " , Nothing )) $ fmap mkInlayHintLabelPart valueWithLoc
232
234
pure $ InlayHint { _position = currentEnd -- at the end of dotdot
@@ -275,7 +277,7 @@ inlayHintPosRecProvider _ state _pId InlayHintParams {_textDocument = TextDocume
275
277
, _data_ = Nothing
276
278
}
277
279
278
- mkInlayHintLabelPart name loc = InlayHintLabelPart (printOutputable (pprNameUnqualified name) <> " =" ) Nothing loc Nothing
280
+ mkInlayHintLabelPart name loc = InlayHintLabelPart (printFieldName (pprNameUnqualified name) <> " =" ) Nothing loc Nothing
279
281
280
282
mkTitle :: [Extension ] -> Text
281
283
mkTitle exts = " Expand record wildcard"
@@ -389,10 +391,10 @@ data RecordInfo
389
391
deriving (Generic )
390
392
391
393
instance Pretty RecordInfo where
392
- pretty (RecordInfoPat ss p) = pretty (printOutputable ss) <> " :" <+> pretty (printOutputable p)
393
- pretty (RecordInfoCon ss e) = pretty (printOutputable ss) <> " :" <+> pretty (printOutputable e)
394
+ pretty (RecordInfoPat ss p) = pretty (printFieldName ss) <> " :" <+> pretty (printOutputable p)
395
+ pretty (RecordInfoCon ss e) = pretty (printFieldName ss) <> " :" <+> pretty (printOutputable e)
394
396
pretty (RecordInfoApp ss (RecordAppExpr _ fla))
395
- = pretty (printOutputable ss) <> " :" <+> hsep (map (pretty . printOutputable) fla)
397
+ = pretty (printFieldName ss) <> " :" <+> hsep (map (pretty . printOutputable) fla)
396
398
397
399
recordInfoToRange :: RecordInfo -> Range
398
400
recordInfoToRange (RecordInfoPat ss _) = realSrcSpanToRange ss
@@ -499,7 +501,7 @@ processRecordFlds flds = flds { rec_dotdot = Nothing , rec_flds = puns' }
499
501
500
502
501
503
showRecordPat :: Outputable (Pat GhcTc ) => UniqFM Name [Name ] -> Pat GhcTc -> Maybe Text
502
- showRecordPat names = fmap printOutputable . mapConPatDetail (\ case
504
+ showRecordPat names = fmap printFieldName . mapConPatDetail (\ case
503
505
RecCon flds -> Just $ RecCon (preprocessRecordPat names flds)
504
506
_ -> Nothing )
505
507
@@ -540,7 +542,7 @@ showRecordApp (RecordAppExpr recConstr fla)
540
542
= Just $ printOutputable recConstr <> " { "
541
543
<> T. intercalate " , " (showFieldWithArg <$> fla)
542
544
<> " }"
543
- where showFieldWithArg (field, arg) = printOutputable field <> " = " <> printOutputable arg
545
+ where showFieldWithArg (field, arg) = printFieldName field <> " = " <> printOutputable arg
544
546
545
547
collectRecords :: GenericQ [RecordInfo ]
546
548
collectRecords = everythingBut (<>) (([] , False ) `mkQ` getRecPatterns `extQ` getRecCons)
@@ -614,3 +616,18 @@ getRecPatterns conPat@(conPatDetails . unLoc -> Just (RecCon flds))
614
616
mkRecInfo pat =
615
617
[ RecordInfoPat realSpan' (unLoc pat) | RealSrcSpan realSpan' _ <- [ getLoc pat ]]
616
618
getRecPatterns _ = ([] , False )
619
+
620
+ printFieldName :: Outputable a => a -> Text
621
+ printFieldName = stripPrefix . printOutputable
622
+
623
+ {- When e.g. DuplicateRecordFields is enabled, compiler generates
624
+ names like "$sel:accessor:One" and "$sel:accessor:Two" to
625
+ disambiguate record selectors
626
+ https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/DuplicateRecordFields#Implementation
627
+ -}
628
+ -- See also:
629
+ -- https://github.com/haskell/haskell-language-server/blob/master/ghcide/src/Development/IDE/Plugin/Completions/Logic.hs#L811
630
+ stripPrefix :: T. Text -> T. Text
631
+ stripPrefix name = T. takeWhile (/= ' :' ) $ fromMaybe name $
632
+ getFirst $ foldMap (First . (`T.stripPrefix` name))
633
+ occNamePrefixes
0 commit comments