Skip to content

Commit d22ba1f

Browse files
wczyzfendor
andauthored
Explicit record fields inlay hints for polymorphic records (#4510)
Co-authored-by: fendor <[email protected]>
1 parent ba85783 commit d22ba1f

File tree

4 files changed

+69
-4
lines changed

4 files changed

+69
-4
lines changed

plugins/hls-explicit-record-fields-plugin/src/Ide/Plugin/ExplicitFields.hs

+9-2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import Development.IDE.GHC.Compat (FieldLabel (flSelector),
5656
HsExpr (HsApp, HsVar, XExpr),
5757
HsFieldBind (hfbLHS),
5858
HsRecFields (..),
59+
HsWrap (HsWrap),
5960
Identifier, LPat,
6061
Located,
6162
NamedThing (getName),
@@ -577,13 +578,19 @@ getRecCons expr@(unLoc -> app@(HsApp _ _ _)) =
577578
[ RecordInfoApp realSpan' appExpr | RealSrcSpan realSpan' _ <- [ getLoc expr ] ]
578579

579580
getFields :: HsExpr GhcTc -> [LHsExpr GhcTc] -> Maybe RecordAppExpr
580-
getFields (HsApp _ constr@(unLoc -> (XExpr (ConLikeTc (conLikeFieldLabels -> fls) _ _))) arg) args
581+
getFields (HsApp _ constr@(unLoc -> expr) arg) args
581582
| not (null fls)
582583
= Just (RecordAppExpr constr labelWithArgs)
583-
where labelWithArgs = zipWith mkLabelWithArg fls (arg : args)
584+
where fls = getExprFields expr
585+
labelWithArgs = zipWith mkLabelWithArg fls (arg : args)
584586
mkLabelWithArg label arg = (L (getLoc arg) label, unLoc arg)
585587
getFields (HsApp _ constr arg) args = getFields (unLoc constr) (arg : args)
586588
getFields _ _ = Nothing
589+
590+
getExprFields :: HsExpr GhcTc -> [FieldLabel]
591+
getExprFields (XExpr (ConLikeTc (conLikeFieldLabels -> fls) _ _)) = fls
592+
getExprFields (XExpr (WrapExpr (HsWrap _ expr))) = getExprFields expr
593+
getExprFields _ = []
587594
getRecCons _ = ([], False)
588595

589596
getRecPatterns :: LPat GhcTc -> ([RecordInfo], Bool)

plugins/hls-explicit-record-fields-plugin/test/Main.hs

+28-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ test = testGroup "explicit-fields"
3636
, mkTestNoAction "Puns" "Puns" 12 10 12 31
3737
, mkTestNoAction "Infix" "Infix" 11 11 11 31
3838
, mkTestNoAction "Prefix" "Prefix" 10 11 10 28
39+
, mkTest "PolymorphicRecordConstruction" "PolymorphicRecordConstruction" 15 5 15 15
3940
]
4041
, testGroup "inlay hints"
4142
[ mkInlayHintsTest "Construction" Nothing 16 $ \ih -> do
@@ -212,6 +213,31 @@ test = testGroup "explicit-fields"
212213
, _tooltip = Just $ InL "Expand record wildcard"
213214
, _paddingLeft = Just True
214215
}]
216+
, mkInlayHintsTest "PolymorphicRecordConstruction" Nothing 15 $ \ih -> do
217+
let mkLabelPart' = mkLabelPartOffsetLengthSub1 "PolymorphicRecordConstruction"
218+
foo <- mkLabelPart' 5 4 "foo="
219+
bar <- mkLabelPart' 6 4 "bar="
220+
baz <- mkLabelPart' 7 4 "baz="
221+
(@?=) ih
222+
[ defInlayHint { _position = Position 15 11
223+
, _label = InR [ foo ]
224+
, _textEdits = Just [ mkLineTextEdit "MyRec { foo = a, bar = b, baz = c }" 15 5 16 ]
225+
, _tooltip = Just $ InL "Expand positional record"
226+
, _paddingLeft = Nothing
227+
}
228+
, defInlayHint { _position = Position 15 13
229+
, _label = InR [ bar ]
230+
, _textEdits = Just [ mkLineTextEdit "MyRec { foo = a, bar = b, baz = c }" 15 5 16 ]
231+
, _tooltip = Just $ InL "Expand positional record"
232+
, _paddingLeft = Nothing
233+
}
234+
, defInlayHint { _position = Position 15 15
235+
, _label = InR [ baz ]
236+
, _textEdits = Just [ mkLineTextEdit "MyRec { foo = a, bar = b, baz = c }" 15 5 16 ]
237+
, _tooltip = Just $ InL "Expand positional record"
238+
, _paddingLeft = Nothing
239+
}
240+
]
215241
]
216242
]
217243

@@ -285,10 +311,10 @@ mkLabelPart offset fp line start value = do
285311
uri = canonicalizeUri $ toUri (testDataDir </> (fp ++ ".hs"))
286312
location uri line char = Location uri (Range (Position line char) (Position line (char + offset value)))
287313

288-
mkLabelPartOffsetLength ::FilePath -> UInt -> UInt -> Text -> IO InlayHintLabelPart
314+
mkLabelPartOffsetLength :: FilePath -> UInt -> UInt -> Text -> IO InlayHintLabelPart
289315
mkLabelPartOffsetLength = mkLabelPart (fromIntegral . T.length)
290316

291-
mkLabelPartOffsetLengthSub1 ::FilePath -> UInt -> UInt -> Text -> IO InlayHintLabelPart
317+
mkLabelPartOffsetLengthSub1 :: FilePath -> UInt -> UInt -> Text -> IO InlayHintLabelPart
292318
mkLabelPartOffsetLengthSub1 = mkLabelPart (fromIntegral . subtract 1 . T.length)
293319

294320
commaPart :: InlayHintLabelPart
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{-# LANGUAGE Haskell2010 #-}
2+
3+
module PolymorphicRecordConstruction where
4+
5+
data MyRec m = MyRec
6+
{ foo :: Int
7+
, bar :: Int
8+
, baz :: Char
9+
}
10+
11+
convertMe :: () -> MyRec ()
12+
convertMe _ =
13+
let a = 3
14+
b = 5
15+
c = 'a'
16+
in MyRec { foo = a, bar = b, baz = c }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{-# LANGUAGE Haskell2010 #-}
2+
3+
module PolymorphicRecordConstruction where
4+
5+
data MyRec m = MyRec
6+
{ foo :: Int
7+
, bar :: Int
8+
, baz :: Char
9+
}
10+
11+
convertMe :: () -> MyRec ()
12+
convertMe _ =
13+
let a = 3
14+
b = 5
15+
c = 'a'
16+
in MyRec a b c

0 commit comments

Comments
 (0)