Move resolved severity from diagnostic to rule - #1017
Conversation
| @runner.run.diagnostics.each do |diagnostic| | ||
| linter_config = @config.linter | ||
|
|
||
| @runner.run.each do |diagnostic| |
There was a problem hiding this comment.
By removing the sort from Runner, the LSP now publishes diagnostics in whatever order @graph.diagnostics returns. Native diagnostics come from the Rust graph, so the order can be nondeterministic and cause diagnostic churn in the editor. Can we keep a deterministic sort either in Runner using the config severity or before this loop?
There was a problem hiding this comment.
The LSP spec makes no promises about sorting of any responses because they place the responsibility of displaying the information on the clients (editors). For example, we always wanted to sort completion items based on the ancestor chain so that "closest" entries appear first, but that's simply not possible because the editor ignores it.
Diagnostics would be the same case. We can order the response, but there are zero guarantees that clients will actually honour it.
Another reason for this, which I found in an issue somewhere in the LSP spec repo a long time ago, is that you can have multiple language servers connected for the same language and then how would you define the ordering between them? We have this case using the Sorbet and Ruby LSP together. If both produce sorted diagnostics, how do you decide the order between the two lists?
This is ultimately the reason why I moved sorting out of the runner. It's something very useful for the CLI, but likely unnecessary work for the LSP.
Another step (the second to last one) for #1000
This PR is similar to what we did on the Rust side and moves the severity out of
Diagnostic. It's the rule identity + config combination that determines the ultimate severity applied to errors and not the specific occurrences of the errors themselves. Now thatDiagnosticholds a reference to the rule identity, we can easily make this change.This PR:
DiagnosticConfigtoRule. Config was over-reaching here. It should only be responsible for returning what was configured, but not making the final decision about the applied severity. This does mean we need to pass the configuration in the final steps for associating severities, but the code actually becomes simpler