Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(lsp): respect diagnostic tag client capabilities #909

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- Do not offer related diagnostic information unless the user enables in client
capabilities (#905)

- Do not offer diagnostic tags unless the client supports them (#909)

# 1.14.1

## Fixes
Expand Down
40 changes: 24 additions & 16 deletions ocaml-lsp-server/src/diagnostics.ml
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,29 @@ type t =
; send : PublishDiagnosticsParams.t list -> unit Fiber.t
; mutable dirty_uris : Uri_set.t
; related_information : bool
; tags : DiagnosticTag.t list
}

let workspace_root t = Lazy.force t.workspace_root

let create (capabilities : PublishDiagnosticsClientCapabilities.t option)
~workspace_root send =
let related_information =
let related_information, tags =
match capabilities with
| None -> false
| Some c -> Option.value ~default:false c.relatedInformation
| None -> (false, [])
| Some c -> (
( Option.value ~default:false c.relatedInformation
, match c.tagSupport with
| None -> []
| Some { valueSet } -> valueSet ))
in
{ dune = Table.create (module Dune) 32
; merlin = Table.create (module Uri) 32
; dirty_uris = Uri_set.empty
; send
; workspace_root
; related_information
; tags
}

let send =
Expand Down Expand Up @@ -207,18 +213,20 @@ let disconnect t dune =
t.dirty_uris <- Uri_set.add t.dirty_uris uri);
Table.remove t.dune dune)

(* this is not inlined in [tags_of_message] for reusability *)
let diagnostic_tags_unnecessary = Some [ DiagnosticTag.Unnecessary ]

let tags_of_message ~src message =
match src with
| `Dune when String.is_prefix message ~prefix:"unused" ->
diagnostic_tags_unnecessary
| `Merlin when Diagnostic_util.is_unused_var_warning message ->
diagnostic_tags_unnecessary
| `Merlin when Diagnostic_util.is_deprecated_warning message ->
Some [ DiagnosticTag.Deprecated ]
| `Dune | `Merlin -> None
let tags_of_message =
let tags_of_message ~src message : DiagnosticTag.t option =
match src with
| `Dune when String.is_prefix message ~prefix:"unused" -> Some Unnecessary
| `Merlin when Diagnostic_util.is_unused_var_warning message ->
Some Unnecessary
| `Merlin when Diagnostic_util.is_deprecated_warning message ->
Some Deprecated
| `Dune | `Merlin -> None
in
fun t ~src message ->
match tags_of_message ~src message with
| None -> None
| Some tag -> Option.some_if (List.mem t.tags tag ~equal:Poly.equal) [ tag ]

let extract_related_errors uri raw_message =
match Ocamlc_loc.parse_raw raw_message with
Expand Down Expand Up @@ -320,7 +328,7 @@ let merlin_diagnostics diagnostics merlin =
~location
~message)) ))
in
let tags = tags_of_message ~src:`Merlin message in
let tags = tags_of_message diagnostics ~src:`Merlin message in
create_diagnostic
?tags
?relatedInformation
Expand Down
2 changes: 1 addition & 1 deletion ocaml-lsp-server/src/diagnostics.mli
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ val remove :
val disconnect : t -> Dune.t -> unit

val tags_of_message :
src:[< `Dune | `Merlin ] -> string -> DiagnosticTag.t list option
t -> src:[< `Dune | `Merlin ] -> string -> DiagnosticTag.t list option

val merlin_diagnostics : t -> Document.Merlin.t -> unit Fiber.t

Expand Down
10 changes: 6 additions & 4 deletions ocaml-lsp-server/src/dune.ml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ end = struct

let source t = t.source

let lsp_of_dune ~include_promotions diagnostic =
let lsp_of_dune diagnostics ~include_promotions diagnostic =
let module D = Drpc.Diagnostic in
let range_of_loc loc =
let loc =
Expand Down Expand Up @@ -214,7 +214,7 @@ end = struct
DiagnosticRelatedInformation.create ~location ~message))
in
let message = make_message (D.message diagnostic) in
let tags = Diagnostics.tags_of_message ~src:`Dune message in
let tags = Diagnostics.tags_of_message diagnostics ~src:`Dune message in
let data =
match include_promotions with
| false -> None
Expand Down Expand Up @@ -343,8 +343,10 @@ end = struct
( running.diagnostics_id
, id
, uri
, lsp_of_dune ~include_promotions:config.include_promotions d
));
, lsp_of_dune
diagnostics
~include_promotions:config.include_promotions
d ));
(promotions, requests :: add, remove))
in
(promotions, List.flatten add, List.flatten remove)
Expand Down