on master help sign in
Add record fields to doucment symbols outline (#564)

By collecting the fieldOcc names in the data con args

commita1cb4eb8fa27821a28b48ce05bb690d82792a18f authorLuke Lau <luke_lau@icloud.com> dateMon 18 May 2020, 15:04 (6 years ago) parentd54fd38
3 files changed+40−1
src/Development/IDE/GHC/Compat.hs+14−1 src/Development/IDE/LSP/Outline.hs+12 test/exe/Main.hs+14
src/Development/IDE/GHC/Compat.hs+14−1
@@ -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)
4849import qualified Module
4950
5051import 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+ )
5258import qualified HeaderInfo as Hdr
5359import Avail
5460import ErrUtils (ErrorMessages)
@@ -289,3 +295,10 @@ getModuleHash = mi_mod_hash . mi_final_exts
289295#else
290296getModuleHash = 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
@@ -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
116128documentSymbolForDecl (L l (TyClD SynDecl { tcdLName = L l' n })) = Just
117129 (defDocumentSymbol l :: DocumentSymbol) { _name = showRdrName n
118130 , _kind = SkTypeParameter
test/exe/Main.hs+14
@@ -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