This PR adds server-side support for incremental diagnostics via a new `isIncremental` field on `PublishDiagnosticsParams` that is only used by the language server when clients set `incrementalDiagnosticSupport` in `LeanClientCapabilities`. ### Context The goal of this new feature is to avoid quadratic reporting of diagnostics. LSP has two means of reporting diagnostics; pull diagnostics (where the client decides when to fetch the diagnostics of a project) and push diagnostics (where the server decides when to update the set of diagnostics of a file in the client). Pull diagnostics have the inherent problem that clients need to heuristically decide when the set of diagnostics should be updated, and that diagnostics can only be incrementally reported per file, so the Lean language server has always stuck with push diagnostics instead. In principle, push diagnostics were also intended to only be reported once for a full file, but all major language clients also support replacing the old set of diagnostics for a file when a new set of diagnostics is reported for the same version of the file, so we have always reported diagnostics incrementally while the file is being processed in this way. However, this approach has a major limitation: all notifications must be a full set of diagnostics, which means that we have to report a quadratic amount of diagnostics while processing a file to the end. ### Semantics When `LeanClientCapabilities.incrementalDiagnosticSupport` is set, the language server will set `PublishDiagnosticsParams.isIncremental` when it is reporting a set of diagnostics that should simply be appended to the previously reported set of diagnostics instead of replacing it. Specifically, clients implementing this new feature should implement the following behaviour: - If `PublishDiagnosticsParams.isIncremental` is `false` or the field is missing, the current diagnostic report for a specific document should replace the previous diagnostic report for that document instead of appending to it. This is identical to the current behavior before this PR. - If `PublishDiagnosticsParams.isIncremental` is `true`, the current diagnostic report for a specific document should append to the previous diagnostic report for that document instead of replacing it. - Versions should be ignored when deciding whether to replace or append to a previous set of diagnostics. The language server ensures that the `isIncremental` flag is set correctly. ### Client-side implementation A client-side implementation for the VS Code extension can be found at [vscode-lean4#752](https://github.com/leanprover/vscode-lean4/pull/752). --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Wojciech Nawrocki <13901751+Vtec234@users.noreply.github.com>
55 lines
1.6 KiB
Text
55 lines
1.6 KiB
Text
{"version": 2,
|
|
"uri": "file:///incrementalCommand.lean",
|
|
"isIncremental": false,
|
|
"diagnostics": []}
|
|
{"version": 2,
|
|
"uri": "file:///incrementalCommand.lean",
|
|
"isIncremental": false,
|
|
"diagnostics": []}
|
|
w
|
|
w
|
|
{"version": 1,
|
|
"uri": "file:///incrementalCommand.lean",
|
|
"isIncremental": false,
|
|
"diagnostics": []}
|
|
{"version": 1,
|
|
"uri": "file:///incrementalCommand.lean",
|
|
"isIncremental": false,
|
|
"diagnostics":
|
|
[{"source": "Lean 4",
|
|
"severity": 3,
|
|
"range":
|
|
{"start": {"line": 5, "character": 0}, "end": {"line": 5, "character": 5}},
|
|
"message": "\"import\"",
|
|
"fullRange":
|
|
{"start": {"line": 5, "character": 0}, "end": {"line": 5, "character": 5}}}]}
|
|
{"version": 2,
|
|
"uri": "file:///incrementalCommand.lean",
|
|
"isIncremental": false,
|
|
"diagnostics":
|
|
[{"source": "Lean 4",
|
|
"severity": 3,
|
|
"range":
|
|
{"start": {"line": 5, "character": 0}, "end": {"line": 5, "character": 5}},
|
|
"message": "\"import\"",
|
|
"fullRange":
|
|
{"start": {"line": 5, "character": 0}, "end": {"line": 5, "character": 5}}}]}
|
|
{"version": 2,
|
|
"uri": "file:///incrementalCommand.lean",
|
|
"isIncremental": false,
|
|
"diagnostics":
|
|
[{"source": "Lean 4",
|
|
"severity": 1,
|
|
"range":
|
|
{"start": {"line": 2, "character": 2}, "end": {"line": 2, "character": 9}},
|
|
"message": "Tactic `assumption` failed\n\n⊢ False",
|
|
"fullRange":
|
|
{"start": {"line": 2, "character": 2}, "end": {"line": 2, "character": 9}}}]}
|
|
{"version": 3,
|
|
"uri": "file:///incrementalCommand.lean",
|
|
"isIncremental": false,
|
|
"diagnostics": []}
|
|
{"version": 2,
|
|
"uri": "file:///incrementalCommand.lean",
|
|
"isIncremental": false,
|
|
"diagnostics": []}
|