Skip to content

Commit

Permalink
Merge pull request #1338 from julia-vscode/add-diag-testitem-marking-…
Browse files Browse the repository at this point in the history
…logic

Move all marking logic for testitems and diag here
  • Loading branch information
davidanthoff authored Dec 20, 2024
2 parents 236009f + 5c26bbc commit 2633b63
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 121 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ JSONRPC = "1.1"
JuliaFormatter = "0.20.0, 0.21, 0.22, 0.23, 1"
PrecompileTools = "1"
StaticLint = "8.0"
JuliaWorkspaces = "4.7"
JuliaWorkspaces = "5"
SymbolServer = "8"
Tokenize = "0.5.10"
URIs = "1.3"
Expand Down
1 change: 1 addition & 0 deletions src/LanguageServer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ include("languageserverinstance.jl")
include("multienv.jl")
include("runserver.jl")
include("staticlint.jl")
include("testitem_diagnostic_marking.jl")

include("requests/misc.jl")
include("requests/textdocument.jl")
Expand Down
6 changes: 2 additions & 4 deletions src/languageserverinstance.jl
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,7 @@ function Base.run(server::LanguageServerInstance; timings = [])
end

function relintserver(server)
JuliaWorkspaces.mark_current_diagnostics(server.workspace)
JuliaWorkspaces.mark_current_testitems(server.workspace)
marked_versions = mark_current_diagnostics_testitems(server.workspace)

roots = Set{Document}()
documents = collect(getdocuments_value(server))
Expand All @@ -514,6 +513,5 @@ function relintserver(server)
lint!(doc, server)
end
end
publish_diagnostics(get_uri.(documents), server, server.jr_endpoint, "relintserver")
publish_tests(server)
publish_diagnostics_testitems(server, marked_versions, get_uri.(documents))
end
6 changes: 2 additions & 4 deletions src/requests/init.jl
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,7 @@ function initialized_notification(params::InitializedParams, server::LanguageSer

end

JuliaWorkspaces.mark_current_diagnostics(server.workspace)
JuliaWorkspaces.mark_current_testitems(server.workspace)
marked_versions = mark_current_diagnostics_testitems(server.workspace)
added_docs = Document[]

if server.workspaceFolders !== nothing
Expand Down Expand Up @@ -289,8 +288,7 @@ function initialized_notification(params::InitializedParams, server::LanguageSer
end
end

publish_diagnostics(get_uri.(added_docs), server, conn, "initialized_notification")
publish_tests(server)
publish_diagnostics_testitems(server, marked_versions, get_uri.(added_docs))

request_julia_config(server, conn)

Expand Down
110 changes: 6 additions & 104 deletions src/requests/textdocument.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
function textDocument_didOpen_notification(params::DidOpenTextDocumentParams, server::LanguageServerInstance, conn)
JuliaWorkspaces.mark_current_diagnostics(server.workspace)
JuliaWorkspaces.mark_current_testitems(server.workspace)
marked_versions = mark_current_diagnostics_testitems(server.workspace)

uri = params.textDocument.uri
if hasdocument(server, uri)
Expand Down Expand Up @@ -33,16 +32,15 @@ function textDocument_didOpen_notification(params::DidOpenTextDocumentParams, se

parse_all(doc, server)
lint!(doc, server)
publish_diagnostics([get_uri(doc)], server, conn, "textDocument_didOpen_notification")
publish_tests(server)
publish_diagnostics_testitems(server, marked_versions, [get_uri(doc)])
end


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

JuliaWorkspaces.mark_current_testitems(server.workspace)
marked_versions = mark_current_diagnostics_testitems(server.workspace)

if is_workspace_file(doc)
set_open_in_editor(doc, false)
Expand Down Expand Up @@ -74,7 +72,7 @@ function textDocument_didClose_notification(params::DidCloseTextDocumentParams,
JuliaWorkspaces.remove_file!(server.workspace, uri)
end

publish_tests(server)
publish_diagnostics_testitems(server, marked_versions, JuliaWorkspaces.URIs2.URI[])
end

function textDocument_didSave_notification(params::DidSaveTextDocumentParams, server::LanguageServerInstance, conn)
Expand Down Expand Up @@ -137,8 +135,7 @@ function measure_sub_operation(f, request_name, server)
end

function textDocument_didChange_notification(params::DidChangeTextDocumentParams, server::LanguageServerInstance, conn)
JuliaWorkspaces.mark_current_diagnostics(server.workspace)
JuliaWorkspaces.mark_current_testitems(server.workspace)
marked_versions = mark_current_diagnostics_testitems(server.workspace)

uri = params.textDocument.uri

Expand Down Expand Up @@ -186,8 +183,7 @@ function textDocument_didChange_notification(params::DidChangeTextDocumentParams
lint!(doc, server)
end

publish_diagnostics([get_uri(doc)], server, conn, "textDocument_didChange_notification")
publish_tests(server)
publish_diagnostics_testitems(server, marked_versions, [get_uri(doc)])
end

function parse_all(doc::Document, server::LanguageServerInstance)
Expand Down Expand Up @@ -398,97 +394,3 @@ function try_to_load_parents(child_path, server)
end
end
end

function publish_diagnostics(uris::Vector{URI}, server, conn, source)
jw_diagnostics_updated, jw_diagnostics_deleted = JuliaWorkspaces.get_files_with_updated_diagnostics(server.workspace)

all_uris_with_updates = Set{URI}()

for uri in uris
push!(all_uris_with_updates, uri)
end

for uri in jw_diagnostics_updated
push!(all_uris_with_updates, uri)
end

diagnostics = Dict{URI,Vector{Diagnostic}}()

for uri in all_uris_with_updates
diags = Diagnostic[]
diagnostics[uri] = diags

if hasdocument(server, uri)
doc = getdocument(server, uri)

if server.runlinter && (is_workspace_file(doc) || isunsavedfile(doc))
pkgpath = getpath(doc)
if any(is_in_target_dir_of_package.(Ref(pkgpath), server.lint_disableddirs))
filter!(!is_diag_dependent_on_env, doc.diagnostics)
end
append!(diags, doc.diagnostics)
end
end

if JuliaWorkspaces.has_file(server.workspace, uri)
st = JuliaWorkspaces.get_text_file(server.workspace, uri).content

new_diags = JuliaWorkspaces.get_diagnostic(server.workspace, uri)

append!(diags, Diagnostic(
Range(st, i.range),
if i.severity==:error
DiagnosticSeverities.Error
elseif i.severity==:warning
DiagnosticSeverities.Warning
elseif i.severity==:info
DiagnosticSeverities.Information
else
error("Unknown severity $(i.severity)")
end,
missing,
missing,
i.source,
i.message,
missing,
missing
) for i in new_diags)
end
end

for (uri,diags) in diagnostics
version = get(server._open_file_versions, uri, missing)
params = PublishDiagnosticsParams(uri, version, diags)
JSONRPC.send(conn, textDocument_publishDiagnostics_notification_type, params)
end
end

function publish_tests(server::LanguageServerInstance)
if !ismissing(server.initialization_options) && get(server.initialization_options, "julialangTestItemIdentification", false)
updated_files, deleted_files = JuliaWorkspaces.get_files_with_updated_testitems(server.workspace)

for uri in updated_files
testitems_results = JuliaWorkspaces.get_test_items(server.workspace, uri)
st = JuliaWorkspaces.get_text_file(server.workspace, uri).content

testitems = TestItemDetail[TestItemDetail(i.id, i.name, Range(st, i.range), i.code, Range(st, i.code_range), i.option_default_imports, string.(i.option_tags), string.(i.option_setup)) for i in testitems_results.testitems]
testsetups= TestSetupDetail[TestSetupDetail(string(i.name), string(i.kind), Range(st, i.range), i.code, Range(st, i.code_range), ) for i in testitems_results.testsetups]
testerrors = TestErrorDetail[TestErrorDetail(te.id, te.name, Range(st, te.range), te.message) for te in testitems_results.testerrors]

version = get(server._open_file_versions, uri, missing)

params = PublishTestsParams(
uri,
version,
testitems,
testsetups,
testerrors
)
JSONRPC.send(server.jr_endpoint, textDocument_publishTests_notification_type, params)
end

for uri in deleted_files
JSONRPC.send(server.jr_endpoint, textDocument_publishTests_notification_type, PublishTestsParams(uri, missing, TestItemDetail[], TestSetupDetail[], TestErrorDetail[]))
end
end
end
14 changes: 6 additions & 8 deletions src/requests/workspace.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
function workspace_didChangeWatchedFiles_notification(params::DidChangeWatchedFilesParams, server::LanguageServerInstance, conn)
JuliaWorkspaces.mark_current_diagnostics(server.workspace)
JuliaWorkspaces.mark_current_testitems(server.workspace)
marked_versions = mark_current_diagnostics_testitems(server.workspace)

docs_to_lint = Document[]

Expand Down Expand Up @@ -82,8 +81,8 @@ function workspace_didChangeWatchedFiles_notification(params::DidChangeWatchedFi
for lint_doc in docs_to_lint
lint!(lint_doc, server)
end
publish_diagnostics(get_uri.(docs_to_lint), server, conn, "workspace_didChangeWatchedFiles_notification")
publish_tests(server)

publish_diagnostics_testitems(server, marked_versions, get_uri.(docs_to_lint))
end

function workspace_didChangeConfiguration_notification(params::DidChangeConfigurationParams, server::LanguageServerInstance, conn)
Expand Down Expand Up @@ -174,8 +173,7 @@ function gc_files_from_workspace(server::LanguageServerInstance)
end

function workspace_didChangeWorkspaceFolders_notification(params::DidChangeWorkspaceFoldersParams, server::LanguageServerInstance, conn)
JuliaWorkspaces.mark_current_diagnostics(server.workspace)
JuliaWorkspaces.mark_current_testitems(server.workspace)
marked_versions = mark_current_diagnostics_testitems(server.workspace)

added_docs = Document[]

Expand Down Expand Up @@ -209,8 +207,8 @@ function workspace_didChangeWorkspaceFolders_notification(params::DidChangeWorks
for doc in added_docs
lint!(doc, server)
end
publish_diagnostics(get_uri.(added_docs), server, conn, "workspace_didChangeWorkspaceFolders_notification")
publish_tests(server)

publish_diagnostics_testitems(server, marked_versions, get_uri.(added_docs))
end

function workspace_symbol_request(params::WorkspaceSymbolParams, server::LanguageServerInstance, conn)
Expand Down
147 changes: 147 additions & 0 deletions src/testitem_diagnostic_marking.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
function mark_current_diagnostics_testitems(jw::JuliaWorkspace)
ti_results = Dict{URI,UInt}(k => hash(v) for (k,v) in JuliaWorkspaces.get_test_items(jw))

diag_results = Dict{URI,UInt}(k => hash(v) for (k,v) in JuliaWorkspaces.get_diagnostics(jw))

return (testitems=ti_results, diagnostics=diag_results)
end

function get_files_with_updated_diagnostics_testitems(jw::JuliaWorkspace, old_marked_versions::@NamedTuple{testitems::Dict{URI,UInt},diagnostics::Dict{URI,UInt}})
# Testitems
new_marked_versions_ti = Dict{URI,UInt}(k => hash(v) for (k,v) in JuliaWorkspaces.get_test_items(jw))

old_text_files_ti = Set{URI}(keys(old_marked_versions.testitems))
new_text_files_ti = Set{URI}(keys(new_marked_versions_ti))

deleted_files_ti = setdiff(old_text_files_ti, new_text_files_ti)
updated_files_ti = Set{URI}()

for (uri,hash_value) in new_marked_versions_ti
if !(uri in old_text_files_ti)
push!(updated_files_ti, uri)
else
if hash_value != old_marked_versions.testitems[uri]
push!(updated_files_ti, uri)
end
end
end

# Diagnostics
new_marked_versions_diag = Dict{URI,UInt}(k => hash(v) for (k,v) in JuliaWorkspaces.get_diagnostics(jw))

old_text_files_diag = Set{URI}(keys(old_marked_versions.diagnostics))
new_text_files_diag = Set{URI}(keys(new_marked_versions_diag))

deleted_files_diag = setdiff(old_text_files_diag, new_text_files_diag)
updated_files_diag = Set{URI}()

for (uri,hash_value) in new_marked_versions_diag
if !(uri in old_text_files_diag)
push!(updated_files_diag, uri)
else
if hash_value != old_marked_versions.diagnostics[uri]
push!(updated_files_diag, uri)
end
end
end

return (;updated_files_ti, deleted_files_ti, updated_files_diag, deleted_files_diag)
end

function publish_diagnostics(server, jw_diagnostics_updated, jw_diagnostics_deleted, uris::Vector{URI})
all_uris_with_updates = Set{URI}()

for uri in uris
push!(all_uris_with_updates, uri)
end

for uri in jw_diagnostics_updated
push!(all_uris_with_updates, uri)
end

diagnostics = Dict{URI,Vector{Diagnostic}}()

for uri in all_uris_with_updates
diags = Diagnostic[]
diagnostics[uri] = diags

if hasdocument(server, uri)
doc = getdocument(server, uri)

if server.runlinter && (is_workspace_file(doc) || isunsavedfile(doc))
pkgpath = getpath(doc)
if any(is_in_target_dir_of_package.(Ref(pkgpath), server.lint_disableddirs))
filter!(!is_diag_dependent_on_env, doc.diagnostics)
end
append!(diags, doc.diagnostics)
end
end

if JuliaWorkspaces.has_file(server.workspace, uri)
st = JuliaWorkspaces.get_text_file(server.workspace, uri).content

new_diags = JuliaWorkspaces.get_diagnostic(server.workspace, uri)

append!(diags, Diagnostic(
Range(st, i.range),
if i.severity==:error
DiagnosticSeverities.Error
elseif i.severity==:warning
DiagnosticSeverities.Warning
elseif i.severity==:info
DiagnosticSeverities.Information
else
error("Unknown severity $(i.severity)")
end,
missing,
missing,
i.source,
i.message,
missing,
missing
) for i in new_diags)
end
end

for (uri,diags) in diagnostics
version = get(server._open_file_versions, uri, missing)
params = PublishDiagnosticsParams(uri, version, diags)
JSONRPC.send(server.jr_endpoint, textDocument_publishDiagnostics_notification_type, params)
end
end

function publish_tests(server::LanguageServerInstance, updated_files, deleted_files)
if !ismissing(server.initialization_options) && get(server.initialization_options, "julialangTestItemIdentification", false)
for uri in updated_files
testitems_results = JuliaWorkspaces.get_test_items(server.workspace, uri)
st = JuliaWorkspaces.get_text_file(server.workspace, uri).content

testitems = TestItemDetail[TestItemDetail(i.id, i.name, Range(st, i.range), i.code, Range(st, i.code_range), i.option_default_imports, string.(i.option_tags), string.(i.option_setup)) for i in testitems_results.testitems]
testsetups= TestSetupDetail[TestSetupDetail(string(i.name), string(i.kind), Range(st, i.range), i.code, Range(st, i.code_range), ) for i in testitems_results.testsetups]
testerrors = TestErrorDetail[TestErrorDetail(te.id, te.name, Range(st, te.range), te.message) for te in testitems_results.testerrors]

version = get(server._open_file_versions, uri, missing)

params = PublishTestsParams(
uri,
version,
testitems,
testsetups,
testerrors
)
JSONRPC.send(server.jr_endpoint, textDocument_publishTests_notification_type, params)
end

for uri in deleted_files
JSONRPC.send(server.jr_endpoint, textDocument_publishTests_notification_type, PublishTestsParams(uri, missing, TestItemDetail[], TestSetupDetail[], TestErrorDetail[]))
end
end
end


function publish_diagnostics_testitems(server, marked_versions, uris::Vector{URI})
updated_files = get_files_with_updated_diagnostics_testitems(server.workspace, marked_versions)

publish_diagnostics(server, updated_files.updated_files_diag, updated_files.deleted_files_diag, uris)
publish_tests(server, updated_files.updated_files_ti, updated_files.deleted_files_ti)
end

0 comments on commit 2633b63

Please sign in to comment.