Skip to content

Commit a1cb4eb

Browse files
authored
Add record fields to doucment symbols outline (#564)
By collecting the fieldOcc names in the data con args
1 parent d54fd38 commit a1cb4eb

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

src/Development/IDE/GHC/Compat.hs

+14-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ module Development.IDE.GHC.Compat(
3737
GHC.ModLocation,
3838
Module.addBootSuffix,
3939
pattern ModLocation,
40+
getConArgs,
4041

4142
module GHC
4243
) where
@@ -48,7 +49,12 @@ import Fingerprint (Fingerprint)
4849
import qualified Module
4950

5051
import qualified GHC
51-
import GHC hiding (ClassOpSig, DerivD, ForD, IEThingAll, IEThingWith, InstD, TyClD, ValD, ModLocation)
52+
import GHC hiding (
53+
ClassOpSig, DerivD, ForD, IEThingAll, IEThingWith, InstD, TyClD, ValD, ModLocation
54+
#if MIN_GHC_API_VERSION(8,6,0)
55+
, getConArgs
56+
#endif
57+
)
5258
import qualified HeaderInfo as Hdr
5359
import Avail
5460
import ErrUtils (ErrorMessages)
@@ -289,3 +295,10 @@ getModuleHash = mi_mod_hash . mi_final_exts
289295
#else
290296
getModuleHash = mi_mod_hash
291297
#endif
298+
299+
getConArgs :: ConDecl pass -> HsConDeclDetails pass
300+
#if MIN_GHC_API_VERSION(8,6,0)
301+
getConArgs = GHC.getConArgs
302+
#else
303+
getConArgs = GHC.getConDetails
304+
#endif

src/Development/IDE/LSP/Outline.hs

+12
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,23 @@ documentSymbolForDecl (L l (TyClD DataDecl { tcdLName = L _ name, tcdDataDefn =
108108
{ _name = showRdrName n
109109
, _kind = SkConstructor
110110
, _selectionRange = srcSpanToRange l'
111+
, _children = conArgRecordFields (getConArgs x)
111112
}
112113
| L l x <- dd_cons
113114
, L l' n <- getConNames x
114115
]
115116
}
117+
where
118+
-- | Extract the record fields of a constructor
119+
conArgRecordFields (RecCon (L _ lcdfs)) = Just $ List
120+
[ (defDocumentSymbol l :: DocumentSymbol)
121+
{ _name = showRdrName n
122+
, _kind = SkField
123+
}
124+
| L _ cdf <- lcdfs
125+
, L l n <- rdrNameFieldOcc . unLoc <$> cd_fld_names cdf
126+
]
127+
conArgRecordFields _ = Nothing
116128
documentSymbolForDecl (L l (TyClD SynDecl { tcdLName = L l' n })) = Just
117129
(defDocumentSymbol l :: DocumentSymbol) { _name = showRdrName n
118130
, _kind = SkTypeParameter

test/exe/Main.hs

+14
Original file line numberDiff line numberDiff line change
@@ -1853,6 +1853,18 @@ outlineTests = testGroup
18531853
(R 0 0 0 10)
18541854
[docSymbol "C" SkConstructor (R 0 9 0 10)]
18551855
]
1856+
, testSessionWait "record fields" $ do
1857+
let source = T.unlines ["data A = B {", " x :: Int", " , y :: Int}"]
1858+
docId <- createDoc "A.hs" "haskell" source
1859+
symbols <- getDocumentSymbols docId
1860+
liftIO $ symbols @=? Left
1861+
[ docSymbolWithChildren "A" SkStruct (R 0 0 2 13)
1862+
[ docSymbolWithChildren' "B" SkConstructor (R 0 9 2 13) (R 0 9 0 10)
1863+
[ docSymbol "x" SkField (R 1 2 1 3)
1864+
, docSymbol "y" SkField (R 2 4 2 5)
1865+
]
1866+
]
1867+
]
18561868
, testSessionWait "import" $ do
18571869
let source = T.unlines ["import Data.Maybe"]
18581870
docId <- createDoc "A.hs" "haskell" source
@@ -1902,6 +1914,8 @@ outlineTests = testGroup
19021914
DocumentSymbol name (Just detail) kind Nothing loc loc Nothing
19031915
docSymbolWithChildren name kind loc cc =
19041916
DocumentSymbol name Nothing kind Nothing loc loc (Just $ List cc)
1917+
docSymbolWithChildren' name kind loc selectionLoc cc =
1918+
DocumentSymbol name Nothing kind Nothing loc selectionLoc (Just $ List cc)
19051919
moduleSymbol name loc cc = DocumentSymbol name
19061920
Nothing
19071921
SkFile

0 commit comments

Comments
 (0)