Skip to content

Commit 452b736

Browse files
committed
Use hsConDeclsBinders in Outline generation
1 parent e360035 commit 452b736

File tree

1 file changed

+53
-3
lines changed

1 file changed

+53
-3
lines changed

ghcide/src/Development/IDE/LSP/Outline.hs

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,21 @@ documentSymbolForDecl (L (locA -> (RealSrcSpan l _)) (TyClD _ DataDecl { tcdLNam
111111
{ _name = showRdrName n
112112
, _kind = SkConstructor
113113
, _selectionRange = realSrcSpanToRange l'
114-
, _children = conArgRecordFields (con_args x)
114+
, _children = Just $ List $ childs
115115
}
116-
| L (locA -> (RealSrcSpan l _ )) x <- dd_cons
117-
, L (locA -> (RealSrcSpan l' _)) n <- getConNames' x
116+
| con <- dd_cons
117+
, let (cs, flds) = hsConDeclsBinders con
118+
, let childs = mapMaybe cvtFld flds
119+
, L (RealSrcSpan l' _) n <- cs
118120
]
119121
}
120122
where
123+
cvtFld :: LFieldOcc GhcPs -> Maybe DocumentSymbol
124+
cvtFld (L (RealSrcSpan l _) n) = Just $ (defDocumentSymbol l :: DocumentSymbol)
125+
{ _name = showRdrName (unLoc (rdrNameFieldOcc n))
126+
, _kind = SkField
127+
}
128+
cvtFld _ = Nothing
121129
-- | Extract the record fields of a constructor
122130
conArgRecordFields (RecCon (L _ lcdfs)) = Just $ List
123131
[ (defDocumentSymbol l :: DocumentSymbol)
@@ -244,3 +252,45 @@ getConNames' (XConDecl NoExt) = []
244252
#elif !MIN_VERSION_ghc(9,0,0)
245253
getConNames' (XConDecl x) = noExtCon x
246254
#endif
255+
256+
hsConDeclsBinders :: LConDecl GhcPs
257+
-> ([Located (IdP GhcPs)], [LFieldOcc GhcPs])
258+
-- See hsLTyClDeclBinders for what this does
259+
-- The function is boringly complicated because of the records
260+
-- And since we only have equality, we have to be a little careful
261+
hsConDeclsBinders cons
262+
= go cons
263+
where
264+
go :: LConDecl GhcPs
265+
-> ([Located (IdP GhcPs)], [LFieldOcc GhcPs])
266+
go r
267+
-- Don't re-mangle the location of field names, because we don't
268+
-- have a record of the full location of the field declaration anyway
269+
= let loc = getLoc (reLoc r)
270+
in case unLoc r of
271+
-- remove only the first occurrence of any seen field in order to
272+
-- avoid circumventing detection of duplicate fields (#9156)
273+
ConDeclGADT { con_names = names, con_g_args = args }
274+
-> (map (L loc . unLoc) names, flds)
275+
where
276+
(flds) = get_flds_gadt args
277+
278+
ConDeclH98 { con_name = name, con_args = args }
279+
-> ([L loc (unLoc name)], flds)
280+
where
281+
flds = get_flds_h98 args
282+
283+
get_flds_h98 :: HsConDeclH98Details GhcPs
284+
-> [LFieldOcc GhcPs]
285+
get_flds_h98 (RecCon flds) = get_flds (reLoc flds)
286+
get_flds_h98 _ = []
287+
288+
get_flds_gadt :: HsConDeclGADTDetails GhcPs
289+
-> ([LFieldOcc GhcPs])
290+
get_flds_gadt (RecConGADT flds) = get_flds (reLoc flds)
291+
get_flds_gadt _ = []
292+
293+
get_flds :: Located [LConDeclField GhcPs]
294+
-> ([LFieldOcc GhcPs])
295+
get_flds flds = concatMap (cd_fld_names . unLoc) (unLoc flds)
296+

0 commit comments

Comments
 (0)