Skip to content

Commit 5cb306a

Browse files
authored
Merge branch 'master' into sp/clientcapailities-textDocument-violation
2 parents 7b58c7e + 3b13cc5 commit 5cb306a

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

src/requests/hover.jl

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ function get_hover(b::StaticLint.Binding, documentation::String, server)
4949
else
5050
documentation = try
5151
documentation = if binding_has_preceding_docs(b)
52-
string(documentation, to_codeobject(parentof(b.val).args[3]))
52+
string(documentation, to_codeobject(maybe_get_doc_expr(b.val).args[3]))
5353
elseif const_binding_has_preceding_docs(b)
54-
string(documentation, to_codeobject(parentof(parentof(b.val)).args[3]))
54+
string(documentation, to_codeobject(maybe_get_doc_expr(parentof(b.val)).args[3]))
5555
else
5656
documentation
5757
end
58-
documentation = string(documentation, "```julia\n", prettify_expr(to_codeobject(b.val)), "\n```\n")
58+
documentation = string(ensure_ends_with(documentation), "```julia\n", prettify_expr(to_codeobject(b.val)), "\n```\n")
5959
catch err
6060
@error "get_hover failed to convert Expr" exception = (err, catch_backtrace())
6161
throw(LSHoverError(string("get_hover failed to convert Expr")))
@@ -128,9 +128,9 @@ get_func_hover(x::SymbolServer.SymStore, documentation, server) = get_hover(x, d
128128

129129
function get_preceding_docs(expr::EXPR, documentation)
130130
if expr_has_preceding_docs(expr)
131-
string(documentation, to_codeobject(parentof(expr).args[3]))
131+
string(documentation, to_codeobject(maybe_get_doc_expr(expr).args[3]))
132132
elseif is_const_expr(parentof(expr)) && expr_has_preceding_docs(parentof(expr))
133-
string(documentation, to_codeobject(parentof(parentof(expr)).args[3]))
133+
string(documentation, to_codeobject(maybe_get_doc_expr(parentof(expr)).args[3]))
134134
else
135135
documentation
136136
end
@@ -145,18 +145,28 @@ function const_binding_has_preceding_docs(b::StaticLint.Binding)
145145
is_const_expr(p) && expr_has_preceding_docs(p)
146146
end
147147

148+
function maybe_get_doc_expr(x)
149+
# The expression may be nested in any number of macros
150+
while CSTParser.hasparent(x) &&
151+
CSTParser.ismacrocall(parentof(x))
152+
x = parentof(x)
153+
headof(x.args[1]) === :globalrefdoc && return x
154+
end
155+
return x
156+
end
157+
148158
expr_has_preceding_docs(x) = false
149-
expr_has_preceding_docs(x::EXPR) = is_doc_expr(parentof(x))
159+
expr_has_preceding_docs(x::EXPR) = is_doc_expr(maybe_get_doc_expr(x))
150160

151161
is_const_expr(x) = false
152162
is_const_expr(x::EXPR) = headof(x) === :const
153163

154164
is_doc_expr(x) = false
155165
function is_doc_expr(x::EXPR)
156166
return CSTParser.ismacrocall(x) &&
157-
length(x.args) == 4 &&
158-
headof(x.args[1]) === :globalrefdoc &&
159-
CSTParser.isstring(x.args[3])
167+
length(x.args) == 4 &&
168+
headof(x.args[1]) === :globalrefdoc &&
169+
CSTParser.isstring(x.args[3])
160170
end
161171

162172
get_fcall_position(x, documentation, visited=nothing) = documentation
@@ -187,7 +197,7 @@ function get_fcall_position(x::EXPR, documentation, visited=Set{EXPR}())
187197

188198
fname = CSTParser.get_name(parentof(x))
189199
if StaticLint.hasref(fname) &&
190-
(refof(fname) isa StaticLint.Binding && refof(fname).val isa EXPR && CSTParser.defines_struct(refof(fname).val) && StaticLint.struct_nargs(refof(fname).val)[1] == minargs)
200+
(refof(fname) isa StaticLint.Binding && refof(fname).val isa EXPR && CSTParser.defines_struct(refof(fname).val) && StaticLint.struct_nargs(refof(fname).val)[1] == minargs)
191201
dt_ex = refof(fname).val
192202
args = dt_ex.args[3]
193203
args.args === nothing || arg_i > length(args.args) && return documentation

test/requests/hover.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,13 @@ S(a,b,c,d,e,f,g)
4646
@test hover_test(15, 2) !== nothing
4747
@test hover_test(15, 5) === nothing
4848
@test hover_test(25, 15) !== nothing
49+
50+
@testset "hover docs" begin
51+
settestdoc("""
52+
"I have a docstring"
53+
Base.@kwdef struct SomeStruct
54+
a
55+
end
56+
""")
57+
@test startswith(hover_test(1, 20).contents.value, "I have a docstring")
58+
end

0 commit comments

Comments
 (0)