Skip to content

Commit 92f9d4e

Browse files
committed
Start outdated marking
1 parent da2d6a6 commit 92f9d4e

File tree

5 files changed

+162
-138
lines changed

5 files changed

+162
-138
lines changed

src/languageserverinstance.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,11 @@ function Base.run(server::LanguageServerInstance; timings = [])
447447
end
448448

449449
function relintserver(server)
450+
JuliaWorkspaces.mark_current_diagnostics(server.workspace)
451+
JuliaWorkspaces.mark_current_testitems(server.workspace)
452+
450453
roots = Set{Document}()
451-
documents = getdocuments_value(server)
454+
documents = collect(getdocuments_value(server))
452455
for doc in documents
453456
StaticLint.clear_meta(getcst(doc))
454457
set_doc(getcst(doc), doc)
@@ -468,4 +471,6 @@ function relintserver(server)
468471
lint!(doc, server)
469472
end
470473
end
474+
publish_diagnostics(get_uri.(documents), server, server.jr_endpoint, "relintserver")
475+
publish_tests(server)
471476
end

src/requests/init.jl

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,12 @@ function load_rootpath(path)
9090
end
9191
end
9292

93-
function load_folder(wf::WorkspaceFolder, server)
93+
function load_folder(wf::WorkspaceFolder, server, added_docs)
9494
path = uri2filepath(wf.uri)
95-
load_folder(path, server)
95+
load_folder(path, server, added_docs)
9696
end
9797

98-
function load_folder(path::String, server)
98+
function load_folder(path::String, server, added_docs)
9999
if load_rootpath(path)
100100
try
101101
for (root, _, files) in walkdir(path, onerror=x -> x)
@@ -119,6 +119,7 @@ function load_folder(path::String, server)
119119
setdocument!(server, uri, doc)
120120
try
121121
parse_all(doc, server)
122+
push!(added_docs, doc)
122123
catch ex
123124
@error "Error parsing file $(uri)"
124125
rethrow()
@@ -196,6 +197,10 @@ function initialized_notification(params::InitializedParams, server::LanguageSer
196197
)
197198
end
198199

200+
JuliaWorkspaces.mark_current_diagnostics(server.workspace)
201+
JuliaWorkspaces.mark_current_testitems(server.workspace)
202+
added_docs = Document[]
203+
199204
if server.workspaceFolders !== nothing
200205
for i in server.workspaceFolders
201206
files = JuliaWorkspaces.read_path_into_textdocuments(filepath2uri(i))
@@ -241,10 +246,17 @@ function initialized_notification(params::InitializedParams, server::LanguageSer
241246
JuliaWorkspaces.set_input_fallback_test_project!(server.workspace.runtime, isempty(server.env_path) ? nothing : filepath2uri(server.env_path))
242247

243248
for wkspc in server.workspaceFolders
244-
load_folder(wkspc, server)
249+
load_folder(wkspc, server, added_docs)
250+
end
251+
252+
for doc in added_docs
253+
lint!(doc, server)
245254
end
246255
end
247256

257+
publish_diagnostics(get_uri.(added_docs), server, conn, "initialized_notification")
258+
publish_tests(server)
259+
248260
request_julia_config(server, conn)
249261

250262
if server.number_of_outstanding_symserver_requests > 0

src/requests/textdocument.jl

Lines changed: 113 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
function textDocument_didOpen_notification(params::DidOpenTextDocumentParams, server::LanguageServerInstance, conn)
2+
JuliaWorkspaces.mark_current_diagnostics(server.workspace)
3+
JuliaWorkspaces.mark_current_testitems(server.workspace)
4+
25
uri = params.textDocument.uri
36
if hasdocument(server, uri)
47
doc = getdocument(server, uri)
@@ -28,18 +31,19 @@ function textDocument_didOpen_notification(params::DidOpenTextDocumentParams, se
2831
end
2932
server._open_file_versions[uri] = params.textDocument.version
3033

31-
if uri.scheme=="file" && lowercase(basename(uri2filepath(uri)))==".julialint.toml"
32-
relintserver(server)
33-
else
34-
parse_all(doc, server)
35-
end
34+
parse_all(doc, server)
35+
lint!(doc, server)
36+
publish_diagnostics([get_uri(doc)], server, conn, "textDocument_didOpen_notification")
37+
publish_tests(server)
3638
end
3739

3840

3941
function textDocument_didClose_notification(params::DidCloseTextDocumentParams, server::LanguageServerInstance, conn)
4042
uri = params.textDocument.uri
4143
doc = getdocument(server, uri)
4244

45+
JuliaWorkspaces.mark_current_testitems(server.workspace)
46+
4347
if is_workspace_file(doc)
4448
set_open_in_editor(doc, false)
4549
else
@@ -52,7 +56,7 @@ function textDocument_didClose_notification(params::DidCloseTextDocumentParams,
5256
if getroot(d) == getroot(doc)
5357
deletedocument!(server, u)
5458
empty!(doc.diagnostics)
55-
publish_diagnostics(doc, server, conn)
59+
# publish_diagnostics(Document[doc], server, conn)
5660
end
5761
end
5862
end
@@ -66,13 +70,11 @@ function textDocument_didClose_notification(params::DidCloseTextDocumentParams,
6670
# If the file exists on disc, we go back to that version
6771
if haskey(server._files_from_disc, uri)
6872
JuliaWorkspaces.update_file!(server.workspace, server._files_from_disc[uri])
69-
# TODO Should update tests
7073
else
7174
JuliaWorkspaces.remove_file!(server.workspace, uri)
72-
if !ismissing(server.initialization_options) && get(server.initialization_options, "julialangTestItemIdentification", false)
73-
JSONRPC.send(conn, textDocument_publishTests_notification_type, PublishTestsParams(uri, missing, TestItemDetail[], TestSetupDetail[], TestErrorDetail[]))
74-
end
7575
end
76+
77+
publish_tests(server)
7678
end
7779

7880
function textDocument_didSave_notification(params::DidSaveTextDocumentParams, server::LanguageServerInstance, conn)
@@ -91,7 +93,7 @@ function textDocument_didSave_notification(params::DidSaveTextDocumentParams, se
9193
throw(LSSyncMismatch("Mismatch between server and client text for $(get_uri(doc)). _open_in_editor is $(doc._open_in_editor). _workspace_file is $(doc._workspace_file). _version is $(get_version(doc))."))
9294
end
9395
end
94-
parse_all(doc, server)
96+
# parse_all(doc, server)
9597
end
9698

9799
function textDocument_willSave_notification(params::WillSaveTextDocumentParams, server::LanguageServerInstance, conn)
@@ -112,6 +114,9 @@ function comp(x::CSTParser.EXPR, y::CSTParser.EXPR)
112114
end
113115

114116
function textDocument_didChange_notification(params::DidChangeTextDocumentParams, server::LanguageServerInstance, conn)
117+
JuliaWorkspaces.mark_current_diagnostics(server.workspace)
118+
JuliaWorkspaces.mark_current_testitems(server.workspace)
119+
115120
uri = params.textDocument.uri
116121

117122
doc = getdocument(server, params.textDocument.uri)
@@ -139,26 +144,26 @@ function textDocument_didChange_notification(params::DidChangeTextDocumentParams
139144
new_text_file = JuliaWorkspaces.TextFile(uri, JuliaWorkspaces.SourceText(get_text(new_text_document), get_language_id(doc)))
140145
JuliaWorkspaces.update_file!(server.workspace, new_text_file)
141146

142-
if uri.scheme=="file" && lowercase(basename(uri2filepath(uri)))==".julialint.toml"
143-
relintserver(server)
144-
else
145-
if get_language_id(doc) in ("markdown", "juliamarkdown")
146-
parse_all(doc, server)
147-
else get_language_id(doc) == "julia"
148-
cst0, cst1 = getcst(doc), CSTParser.parse(get_text(doc), true)
149-
r1, r2, r3 = CSTParser.minimal_reparse(s0, get_text(doc), cst0, cst1, inds = true)
150-
for i in setdiff(1:length(cst0.args), r1 , r3) # clean meta from deleted expr
151-
StaticLint.clear_meta(cst0[i])
152-
end
153-
setcst(doc, EXPR(cst0.head, EXPR[cst0.args[r1]; cst1.args[r2]; cst0.args[r3]], nothing))
154-
sizeof(get_text(doc)) == getcst(doc).fullspan || @error "CST does not match input string length."
155-
headof(doc.cst) === :file ? set_doc(doc.cst, doc) : @info "headof(doc) isn't :file for $(doc._path)"
156-
157-
target_exprs = getcst(doc).args[last(r1) .+ (1:length(r2))]
158-
semantic_pass(getroot(doc), target_exprs)
159-
lint!(doc, server)
147+
if get_language_id(doc) in ("markdown", "juliamarkdown")
148+
parse_all(doc, server)
149+
lint!(doc, server)
150+
elseif get_language_id(doc) == "julia"
151+
cst0, cst1 = getcst(doc), CSTParser.parse(get_text(doc), true)
152+
r1, r2, r3 = CSTParser.minimal_reparse(s0, get_text(doc), cst0, cst1, inds = true)
153+
for i in setdiff(1:length(cst0.args), r1 , r3) # clean meta from deleted expr
154+
StaticLint.clear_meta(cst0[i])
160155
end
156+
setcst(doc, EXPR(cst0.head, EXPR[cst0.args[r1]; cst1.args[r2]; cst0.args[r3]], nothing))
157+
sizeof(get_text(doc)) == getcst(doc).fullspan || @error "CST does not match input string length."
158+
headof(doc.cst) === :file ? set_doc(doc.cst, doc) : @info "headof(doc) isn't :file for $(doc._path)"
159+
160+
target_exprs = getcst(doc).args[last(r1) .+ (1:length(r2))]
161+
semantic_pass(getroot(doc), target_exprs)
162+
lint!(doc, server)
161163
end
164+
165+
publish_diagnostics([get_uri(doc)], server, conn, "textDocument_didChange_notification")
166+
publish_tests(server)
162167
end
163168

164169
function parse_all(doc::Document, server::LanguageServerInstance)
@@ -182,8 +187,6 @@ function parse_all(doc::Document, server::LanguageServerInstance)
182187
set_doc(doc.cst, doc)
183188
end
184189
semantic_pass(getroot(doc))
185-
186-
lint!(doc, server)
187190
end
188191

189192
function mark_errors(doc, out=Diagnostic[])
@@ -266,57 +269,6 @@ function is_diag_dependent_on_env(diag::Diagnostic)
266269
startswith(diag.message, "An imported")
267270
end
268271

269-
270-
function publish_diagnostics(doc::Document, server, conn)
271-
diagnostics = if server.runlinter && (is_workspace_file(doc) || isunsavedfile(doc))
272-
pkgpath = getpath(doc)
273-
if any(is_in_target_dir_of_package.(Ref(pkgpath), server.lint_disableddirs))
274-
filter!(!is_diag_dependent_on_env, doc.diagnostics)
275-
end
276-
doc.diagnostics
277-
else
278-
Diagnostic[]
279-
end
280-
281-
st = JuliaWorkspaces.get_text_file(server.workspace, get_uri(doc)).content
282-
283-
append!(diagnostics, Diagnostic(
284-
Range(st, i.range),
285-
if i.severity==:error
286-
DiagnosticSeverities.Error
287-
elseif i.severity==:warning
288-
DiagnosticSeverities.Warning
289-
elseif i.severity==:info
290-
DiagnosticSeverities.Information
291-
else
292-
error("Unknown severity $(i.severity)")
293-
end,
294-
missing,
295-
missing,
296-
i.source,
297-
i.message,
298-
missing,
299-
missing
300-
) for i in JuliaWorkspaces.get_diagnostic(server.workspace, get_uri(doc)))
301-
302-
text_document = get_text_document(doc)
303-
params = PublishDiagnosticsParams(get_uri(text_document), get_version(text_document), diagnostics)
304-
JSONRPC.send(conn, textDocument_publishDiagnostics_notification_type, params)
305-
end
306-
307-
function clear_diagnostics(uri::URI, server, conn)
308-
doc = getdocument(server, uri)
309-
empty!(doc.diagnostics)
310-
publishDiagnosticsParams = PublishDiagnosticsParams(get_uri(doc), get_version(doc), Diagnostic[])
311-
JSONRPC.send(conn, textDocument_publishDiagnostics_notification_type, publishDiagnosticsParams)
312-
end
313-
314-
function clear_diagnostics(server, conn)
315-
for uri in getdocuments_key(server)
316-
clear_diagnostics(uri, server, conn)
317-
end
318-
end
319-
320272
function print_substitute_line(io::IO, line)
321273
if endswith(line, '\n')
322274
println(io, ' '^(sizeof(line) - 1))
@@ -405,7 +357,6 @@ function is_parentof(parent_path, child_path, server)
405357
if any(getpath(d) == child_path for (k, d) in getdocuments_pair(server) if !(k in previous_server_docs))
406358
cdoc = getdocument(server, filepath2uri(child_path))
407359
parse_all(cdoc, server)
408-
semantic_pass(getroot(cdoc))
409360
return true, "", CSTParser.Tokens.STRING
410361
else
411362
# clean up
@@ -424,35 +375,89 @@ function try_to_load_parents(child_path, server)
424375
end
425376
end
426377

427-
function publish_tests!(doc, server::LanguageServerInstance, jr_endpoint)
428-
if !ismissing(server.initialization_options) && get(server.initialization_options, "julialangTestItemIdentification", false)
429-
uri = get_uri(doc)
378+
const our_count = Ref{Int}(0)
430379

431-
# This is only needed because lint! is called for files that aren't tracked by workspaces
432-
if !JuliaWorkspaces.has_file(server.workspace, get_uri(doc))
433-
return
380+
function publish_diagnostics(uris::Vector{URI}, server, conn, source)
381+
our_count[] = our_count[] + 1
382+
jw_diagnostics_updated, jw_diagnostics_deleted = JuliaWorkspaces.get_files_with_updated_diagnostics(server.workspace)
383+
@info "From JW DAIG we have" jw_diagnostics_deleted jw_diagnostics_updated source our_count[]
384+
385+
diagnostics = Dict{URI,Vector{Diagnostic}}()
386+
387+
for uri in uris
388+
push!(jw_diagnostics_updated, uri)
389+
end
390+
391+
for uri in uris
392+
diags = get!(diagnostics, uri, Diagnostic[])
393+
doc = getdocument(server, uri)
394+
395+
if server.runlinter && (is_workspace_file(doc) || isunsavedfile(doc))
396+
pkgpath = getpath(doc)
397+
if any(is_in_target_dir_of_package.(Ref(pkgpath), server.lint_disableddirs))
398+
filter!(!is_diag_dependent_on_env, doc.diagnostics)
399+
end
400+
append!(diags, doc.diagnostics)
434401
end
435402

436-
testitems_results = JuliaWorkspaces.get_test_items(server.workspace, uri)
437403
st = JuliaWorkspaces.get_text_file(server.workspace, uri).content
438404

439-
testitems = TestItemDetail[TestItemDetail(i.id, i.name, Range(st, i.range), get_text(doc)[i.code_range], Range(st, i.code_range), i.option_default_imports, string.(i.option_tags), string.(i.option_setup)) for i in testitems_results.testitems]
440-
testsetups= TestSetupDetail[TestSetupDetail(string(i.name), string(i.kind), Range(st, i.range), get_text(doc)[i.code_range], Range(st, i.code_range), ) for i in testitems_results.testsetups]
441-
testerrors = TestErrorDetail[TestErrorDetail(te.id, te.name, Range(st, te.range), te.message) for te in testitems_results.testerrors]
442-
# TODO SALSA
443-
# # Find which workspace folder the doc is in.
444-
# parent_workspaceFolders = sort(filter(f -> startswith(doc._path, f), collect(server.workspaceFolders)), by=length, rev=true)
445-
446-
# # If the file is not in the workspace, we don't report nothing
447-
# isempty(parent_workspaceFolders) && return
448-
449-
params = PublishTestsParams(
450-
uri,
451-
get_version(doc),
452-
testitems,
453-
testsetups,
454-
testerrors
455-
)
456-
JSONRPC.send(jr_endpoint, textDocument_publishTests_notification_type, params)
405+
append!(diags, Diagnostic(
406+
Range(st, i.range),
407+
if i.severity==:error
408+
DiagnosticSeverities.Error
409+
elseif i.severity==:warning
410+
DiagnosticSeverities.Warning
411+
elseif i.severity==:info
412+
DiagnosticSeverities.Information
413+
else
414+
error("Unknown severity $(i.severity)")
415+
end,
416+
missing,
417+
missing,
418+
i.source,
419+
i.message,
420+
missing,
421+
missing
422+
) for i in JuliaWorkspaces.get_diagnostic(server.workspace, uri))
423+
end
424+
425+
for (uri,diags) in diagnostics
426+
version = get(server._open_file_versions, uri, missing)
427+
params = PublishDiagnosticsParams(uri, version, diags)
428+
JSONRPC.send(conn, textDocument_publishDiagnostics_notification_type, params)
429+
end
430+
end
431+
432+
function publish_tests(server::LanguageServerInstance)
433+
our_count[] = our_count[] + 1
434+
if !ismissing(server.initialization_options) && get(server.initialization_options, "julialangTestItemIdentification", false)
435+
updated_files, deleted_files = JuliaWorkspaces.get_files_with_updated_testitems(server.workspace)
436+
437+
@info "From JW TEST we have" deleted_files updated_files our_count[]
438+
439+
for uri in updated_files
440+
testitems_results = JuliaWorkspaces.get_test_items(server.workspace, uri)
441+
st = JuliaWorkspaces.get_text_file(server.workspace, uri).content
442+
443+
testitems = TestItemDetail[TestItemDetail(i.id, i.name, Range(st, i.range), st.content[i.code_range], Range(st, i.code_range), i.option_default_imports, string.(i.option_tags), string.(i.option_setup)) for i in testitems_results.testitems]
444+
testsetups= TestSetupDetail[TestSetupDetail(string(i.name), string(i.kind), Range(st, i.range), st.content[i.code_range], Range(st, i.code_range), ) for i in testitems_results.testsetups]
445+
testerrors = TestErrorDetail[TestErrorDetail(te.id, te.name, Range(st, te.range), te.message) for te in testitems_results.testerrors]
446+
447+
version = get(server._open_file_versions, uri, missing)
448+
449+
params = PublishTestsParams(
450+
uri,
451+
version,
452+
testitems,
453+
testsetups,
454+
testerrors
455+
)
456+
JSONRPC.send(server.jr_endpoint, textDocument_publishTests_notification_type, params)
457+
end
458+
459+
for uri in deleted_files
460+
JSONRPC.send(server.jr_endpoint, textDocument_publishTests_notification_type, PublishTestsParams(uri, missing, TestItemDetail[], TestSetupDetail[], TestErrorDetail[]))
461+
end
457462
end
458463
end

0 commit comments

Comments
 (0)