Skip to content

Commit 952c4a6

Browse files
committed
Merge branch 'master' into nonwsopt
2 parents 17b5648 + 49afe6a commit 952c4a6

File tree

8 files changed

+75
-30
lines changed

8 files changed

+75
-30
lines changed

src/languageserverinstance.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,7 @@ function Base.run(server::LanguageServerInstance)
266266
scopepass(root, doc)
267267
end
268268

269-
StaticLint.check_all(getcst(doc), server.lint_options, server)
270-
empty!(doc.diagnostics)
271-
mark_errors(doc, doc.diagnostics)
272-
publish_diagnostics(doc, server)
269+
lint!(doc, server)
273270
end
274271
end
275272
end

src/requests/actions.jl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ function process(r::JSONRPC.Request{Val{Symbol("textDocument/codeAction")},CodeA
2121
if is_in_fexpr(x, CSTParser.defines_struct)
2222
push!(commands, Command("Add default constructor", "AddDefaultConstructor", arguments))
2323
end
24+
if is_fixable_missing_ref(x, r.params.context)
25+
push!(commands, Command("Fix missing reference", "FixMissingRef", arguments))
26+
end
2427
# if r.params.range.start.line != r.params.range.stop.line # selection across _line_offsets
2528
# push!(commands, Command("Wrap in `if` block.", "WrapIfBlock", arguments))
2629
# end
@@ -49,6 +52,8 @@ function process(r::JSONRPC.Request{Val{Symbol("workspace/executeCommand")},Exec
4952
end
5053
elseif r.params.command == "WrapIfBlock"
5154
wrap_block(get_expr(getcst(doc), r.params.arguments[2]:r.params.arguments[3]), r.id + 1, server, :if)
55+
elseif r.params.command == "FixMissingRef"
56+
applymissingreffix(x, server)
5257
end
5358
end
5459

@@ -265,3 +270,36 @@ function wrap_block(x::EXPR, id, server, type)
265270

266271
JSONRPCEndpoints.send_request(server.jr_endpoint, "workspace/applyEdit", ApplyWorkspaceEditParams(missing, WorkspaceEdit(nothing, TextDocumentEdit[tde])))
267272
end
273+
274+
275+
function is_fixable_missing_ref(x::EXPR, cac::CodeActionContext)
276+
if !isempty(cac.diagnostics) && any(startswith(d.message, "Missing reference") for d::Diagnostic in cac.diagnostics) && CSTParser.isidentifier(x)
277+
xname = StaticLint.valofid(x)
278+
tls = StaticLint.retrieve_toplevel_scope(x)
279+
if tls.modules !== nothing
280+
for (n,m) in tls.modules
281+
if (m isa SymbolServer.ModuleStore && haskey(m, Symbol(xname))) || (m isa StaticLint.Scope && StaticLint.scopehasbinding(m, xname))
282+
return true
283+
end
284+
end
285+
end
286+
end
287+
return false
288+
end
289+
290+
function applymissingreffix(x, server)
291+
xname = StaticLint.valofid(x)
292+
file, offset = get_file_loc(x)
293+
l, c = get_position_at(file, offset)
294+
tls = StaticLint.retrieve_toplevel_scope(x)
295+
if tls.modules !== nothing
296+
for (n,m) in tls.modules
297+
if (m isa SymbolServer.ModuleStore && haskey(m, Symbol(xname))) || (m isa StaticLint.Scope && StaticLint.scopehasbinding(m, xname))
298+
tde = TextDocumentEdit(VersionedTextDocumentIdentifier(file._uri, file._version), TextEdit[
299+
TextEdit(Range(file, offset .+ (0:0)), string(n, "."))
300+
])
301+
JSONRPCEndpoints.send_request(server.jr_endpoint, "workspace/applyEdit", ApplyWorkspaceEditParams(missing, WorkspaceEdit(nothing, TextDocumentEdit[tde])))
302+
end
303+
end
304+
end
305+
end

src/requests/init.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const serverCapabilities = ServerCapabilities(
2323
missing,
2424
true,
2525
false,
26-
ExecuteCommandOptions(missing, String["ExplicitPackageVarImport", "ExpandFunction", "AddDefaultConstructor", "ReexportModule"]),
26+
ExecuteCommandOptions(missing, String["ExplicitPackageVarImport", "ExpandFunction", "AddDefaultConstructor", "ReexportModule", "FixMissingRef"]),
2727
false,
2828
true,
2929
WorkspaceOptions(WorkspaceFoldersOptions(true, true)),

src/requests/textdocument.jl

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,7 @@ function process(r::JSONRPC.Request{Val{Symbol("textDocument/didChange")},DidCha
8080
tdcce = first(r.params.contentChanges)
8181
new_cst = _partial_update(doc, tdcce)
8282
scopepass(getroot(doc), doc)
83-
StaticLint.check_all(getcst(doc), server.lint_options, server)
84-
empty!(doc.diagnostics)
85-
mark_errors(doc, doc.diagnostics)
86-
publish_diagnostics(doc, server)
83+
lint!(doc, server)
8784
else
8885
for tdcce in r.params.contentChanges
8986
applytextdocumentchanges(doc, tdcce)
@@ -234,11 +231,7 @@ function parse_all(doc::Document, server::LanguageServerInstance)
234231
end
235232

236233
scopepass(getroot(doc), doc)
237-
StaticLint.check_all(getcst(doc), server.lint_options, server)
238-
empty!(doc.diagnostics)
239-
mark_errors(doc, doc.diagnostics)
240-
241-
publish_diagnostics(doc, server)
234+
lint!(doc, server)
242235
end
243236

244237
function mark_errors(doc, out = Diagnostic[])

src/requests/workspace.jl

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,25 +101,18 @@ function request_julia_config(server::LanguageServerInstance)
101101
ConfigurationItem(missing, "julia.lint.nonwsfiles")
102102
]))
103103

104-
new_DF_opts = DocumentFormat.FormatOptions([isnothing(opt) ? DocumentFormat.default_options[i] : opt for (i,opt) in enumerate(response[1:11])]...)
105-
new_SL_opts = StaticLint.LintOptions([isnothing(opt) ? StaticLint.default_options[i] : opt for (i,opt) in enumerate(response[12:21])]...)
106-
new_lintrun = isnothing(response[22]) ? true : response[22]
107-
new_missingref = isnothing(response[23]) ? :all : Symbol(response[23])
108-
new_nonwsfiles = isnothing(response[24]) ? true : response[24]
109-
104+
server.format_options = DocumentFormat.FormatOptions(response[1:11]...)
105+
server.runlinter = something(response[22], true)
106+
server.lint_missingrefs = Symbol(something(response[23], :all))
107+
108+
new_SL_opts = StaticLint.LintOptions(response[12:21]...)
109+
# TODO: implement == for StaticLint.LintOptions
110110
rerun_lint = any(getproperty(server.lint_options, opt) != getproperty(new_SL_opts, opt) for opt in fieldnames(StaticLint.LintOptions))
111-
server.format_options = new_DF_opts
112111
server.lint_options = new_SL_opts
113-
server.runlinter = new_lintrun
114-
server.lint_missingrefs = new_missingref
115-
server.lint_nonwsfiles = new_nonwsfiles
116112

117113
if rerun_lint
118114
for doc in getdocuments_value(server)
119-
StaticLint.check_all(getcst(doc), server.lint_options, server)
120-
empty!(doc.diagnostics)
121-
mark_errors(doc, doc.diagnostics)
122-
publish_diagnostics(doc, server)
115+
lint!(doc, server)
123116
end
124117
end
125118

@@ -150,4 +143,4 @@ function process(r::JSONRPC.Request{Val{Symbol("workspace/symbol")},WorkspaceSym
150143
end
151144

152145
return syms
153-
end
146+
end

src/staticlint.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,11 @@ getserver(file::Document) = file.server
5656
function setserver(file::Document, server::LanguageServerInstance)
5757
file.server = server
5858
return file
59-
end
59+
end
60+
61+
function lint!(doc, server)
62+
StaticLint.check_all(getcst(doc), server.lint_options, server)
63+
empty!(doc.diagnostics)
64+
mark_errors(doc, doc.diagnostics)
65+
publish_diagnostics(doc, server)
66+
end

test/runtests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,8 @@ end
1717
@testset "edit" begin
1818
include("text_edit.jl")
1919
end
20+
@testset "actions" begin
21+
include("test_actions.jl")
22+
end
2023

2124
end

test/test_actions.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
server = LanguageServerInstance(IOBuffer(), IOBuffer(), dirname(Pkg.Types.Context().env.project_file), first(Base.DEPOT_PATH))
2+
server.runlinter = true
3+
4+
LanguageServer.process(LanguageServer.parse(LanguageServer.JSONRPC.Request, Dict("jsonrpc"=>"2.0","id"=>0,"method"=>"initialize","params"=>init_request)), server)
5+
6+
testtext = """
7+
decode_overlong
8+
"""
9+
LanguageServer.process(LanguageServer.JSONRPC.Request{Val{Symbol("textDocument/didOpen")},LanguageServer.DidOpenTextDocumentParams}(0, LanguageServer.DidOpenTextDocumentParams(LanguageServer.TextDocumentItem("testdoc", "julia", 0, testtext))), server)
10+
11+
doc = LanguageServer.getdocument(server, LanguageServer.URI2("testdoc"))
12+
13+
@test !isempty(LanguageServer.process(LanguageServer.JSONRPC.Request{Val{Symbol("textDocument/codeAction")},LanguageServer.CodeActionParams}(0, LanguageServer.CodeActionParams(LanguageServer.TextDocumentIdentifier("testdoc"), LanguageServer.Range(LanguageServer.Position(0,1),LanguageServer.Position(0,1)), LanguageServer.CodeActionContext(LanguageServer.Diagnostic[doc.diagnostics[1]], missing))), server))
14+

0 commit comments

Comments
 (0)