Skip to content

Commit 56c1712

Browse files
committed
Supoort call hierarchy on type signatures
1 parent 80fbec9 commit 56c1712

File tree

3 files changed

+59
-20
lines changed

3 files changed

+59
-20
lines changed

plugins/hls-call-hierarchy-plugin/hls-call-hierarchy-plugin.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 2.4
22
name: hls-call-hierarchy-plugin
3-
version: 1.0.0.0
3+
version: 1.0.1.0
44
synopsis: Call hierarchy plugin for Haskell Language Server
55
license: Apache-2.0
66
license-file: LICENSE

plugins/hls-call-hierarchy-plugin/src/Ide/Plugin/CallHierarchy/Internal.hs

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,38 +62,43 @@ constructFromAst nfp pos =
6262
\case
6363
Nothing -> pure Nothing
6464
Just (HAR _ hf _ _ _) -> do
65-
case listToMaybe $ pointCommand hf pos extract of
66-
Just res -> pure $ Just $ mapMaybe (construct nfp) res
67-
Nothing -> pure Nothing
65+
resolveIntoCallHierarchy hf pos nfp
66+
67+
resolveIntoCallHierarchy :: Applicative f => HieASTs a -> Position -> NormalizedFilePath -> f (Maybe [CallHierarchyItem])
68+
resolveIntoCallHierarchy hf pos nfp =
69+
case listToMaybe $ pointCommand hf pos extract of
70+
Just res -> pure $ Just $ mapMaybe (construct nfp hf) res
71+
Nothing -> pure Nothing
6872

6973
extract :: HieAST a -> [(Identifier, S.Set ContextInfo, Span)]
7074
extract ast = let span = nodeSpan ast
7175
infos = M.toList $ M.map identInfo (Compat.getNodeIds ast)
7276
in [ (ident, contexts, span) | (ident, contexts) <- infos ]
7377

7478
recFieldInfo, declInfo, valBindInfo, classTyDeclInfo,
75-
useInfo, patternBindInfo :: S.Set ContextInfo -> Maybe ContextInfo
76-
recFieldInfo ctxs = listToMaybe [ctx | ctx@RecField{} <- S.toList ctxs]
77-
declInfo ctxs = listToMaybe [ctx | ctx@Decl{} <- S.toList ctxs]
78-
valBindInfo ctxs = listToMaybe [ctx | ctx@ValBind{} <- S.toList ctxs]
79-
classTyDeclInfo ctxs = listToMaybe [ctx | ctx@ClassTyDecl{} <- S.toList ctxs]
80-
useInfo ctxs = listToMaybe [Use | Use <- S.toList ctxs]
81-
patternBindInfo ctxs = listToMaybe [ctx | ctx@PatternBind{} <- S.toList ctxs]
82-
83-
construct :: NormalizedFilePath -> (Identifier, S.Set ContextInfo, Span) -> Maybe CallHierarchyItem
84-
construct nfp (ident, contexts, ssp)
79+
useInfo, patternBindInfo, tyDeclInfo :: [ContextInfo] -> Maybe ContextInfo
80+
recFieldInfo ctxs = listToMaybe [ctx | ctx@RecField{} <- ctxs]
81+
declInfo ctxs = listToMaybe [ctx | ctx@Decl{} <- ctxs]
82+
valBindInfo ctxs = listToMaybe [ctx | ctx@ValBind{} <- ctxs]
83+
classTyDeclInfo ctxs = listToMaybe [ctx | ctx@ClassTyDecl{} <- ctxs]
84+
useInfo ctxs = listToMaybe [Use | Use <- ctxs]
85+
patternBindInfo ctxs = listToMaybe [ctx | ctx@PatternBind{} <- ctxs]
86+
tyDeclInfo ctxs = listToMaybe [TyDecl | TyDecl <- ctxs]
87+
88+
construct :: NormalizedFilePath -> HieASTs a -> (Identifier, S.Set ContextInfo, Span) -> Maybe CallHierarchyItem
89+
construct nfp hf (ident, contexts, ssp)
8590
| isInternalIdentifier ident = Nothing
8691

87-
| Just (RecField RecFieldDecl _) <- recFieldInfo contexts
92+
| Just (RecField RecFieldDecl _) <- recFieldInfo ctxList
8893
-- ignored type span
8994
= Just $ mkCallHierarchyItem' ident SkField ssp ssp
9095

91-
| Just ctx <- valBindInfo contexts
96+
| Just ctx <- valBindInfo ctxList
9297
= Just $ case ctx of
9398
ValBind _ _ span -> mkCallHierarchyItem' ident SkFunction (renderSpan span) ssp
9499
_ -> mkCallHierarchyItem' ident skUnknown ssp ssp
95100

96-
| Just ctx <- declInfo contexts
101+
| Just ctx <- declInfo ctxList
97102
= Just $ case ctx of
98103
Decl ClassDec span -> mkCallHierarchyItem' ident SkInterface (renderSpan span) ssp
99104
Decl ConDec span -> mkCallHierarchyItem' ident SkConstructor (renderSpan span) ssp
@@ -103,15 +108,18 @@ construct nfp (ident, contexts, ssp)
103108
Decl SynDec span -> mkCallHierarchyItem' ident SkTypeParameter (renderSpan span) ssp
104109
_ -> mkCallHierarchyItem' ident skUnknown ssp ssp
105110

106-
| Just (ClassTyDecl span) <- classTyDeclInfo contexts
111+
| Just (ClassTyDecl span) <- classTyDeclInfo ctxList
107112
= Just $ mkCallHierarchyItem' ident SkMethod (renderSpan span) ssp
108113

109-
| Just (PatternBind _ _ span) <- patternBindInfo contexts
114+
| Just (PatternBind _ _ span) <- patternBindInfo ctxList
110115
= Just $ mkCallHierarchyItem' ident SkFunction (renderSpan span) ssp
111116

112-
| Just Use <- useInfo contexts
117+
| Just Use <- useInfo ctxList
113118
= Just $ mkCallHierarchyItem' ident SkInterface ssp ssp
114119

120+
| Just _ <- tyDeclInfo ctxList
121+
= renderTyDecl
122+
115123
| otherwise = Nothing
116124
where
117125
renderSpan = \case Just span -> span
@@ -125,6 +133,16 @@ construct nfp (ident, contexts, ssp)
125133
Left _ -> False
126134
Right name -> isInternalName name
127135

136+
ctxList = S.toList contexts
137+
138+
renderTyDecl = case ident of
139+
Left _ -> Nothing
140+
Right name -> case getNameBindingInClass name ssp (getAsts hf) of
141+
Nothing -> Nothing
142+
Just sp -> case resolveIntoCallHierarchy hf (realSrcSpanToRange sp ^. L.start) nfp of
143+
Just (Just items) -> listToMaybe items
144+
_ -> Nothing
145+
128146
mkCallHierarchyItem :: NormalizedFilePath -> Identifier -> SymbolKind -> Span -> Span -> CallHierarchyItem
129147
mkCallHierarchyItem nfp ident kind span selSpan =
130148
CallHierarchyItem

plugins/hls-call-hierarchy-plugin/test/Main.hs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ main = defaultTestRunner $
3131
, outgoingCallsTests
3232
]
3333

34+
main1 = defaultTestRunner $ testCase "t1" $ do
35+
let contents = T.unlines ["a :: Int", "f=3","a = 3"]
36+
range = mkRange 2 0 2 5
37+
selRange = mkRange 2 0 2 1
38+
expected = mkCallHierarchyItemV "a" SkFunction range selRange
39+
oneCaseWithCreate contents 0 0 expected
40+
3441
prepareCallHierarchyTests :: TestTree
3542
prepareCallHierarchyTests =
3643
testGroup
@@ -164,6 +171,20 @@ prepareCallHierarchyTests =
164171
selRange = mkRange 1 13 1 14
165172
expected = mkCallHierarchyItemC "A" SkConstructor range selRange
166173
oneCaseWithCreate contents 1 13 expected
174+
, testGroup "type singature"
175+
[ testCase "next line" $ do
176+
let contents = T.unlines ["a::Int", "a=3"]
177+
range = mkRange 1 0 1 3
178+
selRange = mkRange 1 0 1 1
179+
expected = mkCallHierarchyItemV "a" SkFunction range selRange
180+
oneCaseWithCreate contents 0 0 expected
181+
, testCase "multi functions" $ do
182+
let contents = T.unlines [ "a,b::Int", "a=3", "b=4"]
183+
range = mkRange 2 0 2 3
184+
selRange = mkRange 2 0 2 1
185+
expected = mkCallHierarchyItemV "b" SkFunction range selRange
186+
oneCaseWithCreate contents 0 2 expected
187+
]
167188
]
168189

169190
incomingCallsTests :: TestTree

0 commit comments

Comments
 (0)