Commit graph

11342 commits

Author SHA1 Message Date
Brent Westbrook
2f8bc9a30b port remaining tests, delete json and json_tests modules 2025-07-07 16:40:18 -04:00
Brent Westbrook
339cfd30ce port create_notebook_diagnostics and corresponding json test 2025-07-07 16:40:18 -04:00
Brent Westbrook
f7511b44af delete message::azure 2025-07-07 16:40:18 -04:00
Brent Westbrook
d03013f50a port syntax error tests 2025-07-07 16:40:18 -04:00
Brent Westbrook
6ab4a409c8 port azure output tests, create_diagnostics, add azure module 2025-07-07 16:40:17 -04:00
Brent Westbrook
17708049a3 message_to_json_value -> diagnostic_to_json_value 2025-07-07 13:10:05 -04:00
Brent Westbrook
8fab1e17da make JSON conversion infallible 2025-07-07 13:07:37 -04:00
Brent Westbrook
6705327305 add a link for jsonlines 2025-07-07 12:56:34 -04:00
Brent Westbrook
c69b46415e revert ty changes (except schema?) 2025-07-07 10:45:14 -04:00
Brent Westbrook
c3e307739b update option docs 2025-07-04 12:04:07 -04:00
Brent Westbrook
8c905be063 use DisplayDiagnostics in MainLoop, fix JSON snapshot 2025-07-04 12:04:07 -04:00
Brent Westbrook
70b226f0ab add FileResolver::is_notebook, restore fallback location for azure 2025-07-04 12:04:07 -04:00
Brent Westbrook
99bfb5521c LazyLock homepage replacement 2025-07-04 12:04:07 -04:00
Brent Westbrook
8a9a1bf588 update Diagnostic::to_url for ty docs 2025-07-04 12:04:07 -04:00
Brent Westbrook
c67a898935 add json and json-lines to cli, add cli tests 2025-07-04 12:04:07 -04:00
Brent Westbrook
ae467c372a add JsonLines support 2025-07-04 12:04:07 -04:00
Brent Westbrook
9648beebce update schema 2025-07-04 12:04:07 -04:00
Brent Westbrook
bcab7723cd add FileResolver::notebook_index and pass JSON tests 2025-07-04 12:04:07 -04:00
Brent Westbrook
7547863807 implement FileResolver for EmitterContext instead of separate type 2025-07-04 12:04:07 -04:00
Brent Westbrook
af7137de17 Revert "give up and pass down notebook_indexes"
This reverts commit 5d918e963a.
2025-07-04 12:04:07 -04:00
Brent Westbrook
2f730a5f0f add serde feature for ruff_diagnostics 2025-07-04 12:04:07 -04:00
Brent Westbrook
305075cbcd give up and pass down notebook_indexes 2025-07-04 12:04:07 -04:00
Brent Westbrook
4ccc7e33ea move json module to its own file 2025-07-04 12:04:07 -04:00
Brent Westbrook
0021a7e0f1 render json, except for notebooks 2025-07-04 12:04:06 -04:00
Brent Westbrook
69176672d2 suppress summary messages for structured formats 2025-07-04 12:04:06 -04:00
Brent Westbrook
232efc305b add ty cli test 2025-07-04 12:04:06 -04:00
Brent Westbrook
28c27fa0c5 use severity and report diagnostics even without a span or range 2025-07-04 12:04:06 -04:00
Brent Westbrook
c885225efc update schema 2025-07-04 12:04:06 -04:00
Brent Westbrook
8bc5b71079 port azure output format 2025-07-04 12:04:06 -04:00
Brent Westbrook
ddba240f4e add DummyFileResolver for ruff 2025-07-04 12:04:06 -04:00
Carl Meyer
411cccb35e
[ty] detect cycles in Type::is_disjoint_from (#19139) 2025-07-04 06:31:44 -07:00
Carl Meyer
7712c2fd15
[ty] don't allow first-party code to shadow stdlib types module (#19128)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
2025-07-04 10:36:26 +00:00
David Peter
25bdb67d9a
[ty] Remove TODOs regarding legacy generics (#19141) 2025-07-04 10:45:06 +02:00
Matthew Mckee
3be83d36a5
[ty] Add into_callable method for Type (#19130)
Some checks are pending
[ty Playground] Release / publish (push) Waiting to run
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / mkdocs (push) Waiting to run
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
## Summary

Was just playing around with this, there's definitely more to do with
this function, but it seems like maybe a better option than having so
many arms in has_relation_to for (_, Callable).

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Carl Meyer <carl@astral.sh>
2025-07-03 19:04:03 -07:00
Alex Waygood
333191b7f7
[ty] Rewrite Type::any_over_type using a new generalised TypeVisitor trait (#19094)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / mkdocs (push) Waiting to run
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
2025-07-03 18:19:23 +00:00
Brent Westbrook
77a5c5ac80
Combine OldDiagnostic and Diagnostic (#19053)
## Summary

This PR is a collaboration with @AlexWaygood from our pairing session
last Friday.

The main goal here is removing `ruff_linter::message::OldDiagnostic` in
favor of
using `ruff_db::diagnostic::Diagnostic` directly. This involved a few
major steps:

- Transferring the fields
- Transferring the methods and trait implementations, where possible
- Converting some constructor methods to free functions
- Moving the `SecondaryCode` struct
- Updating the method names

I'm hoping that some of the methods, especially those in the
`expect_ruff_*`
family, won't be necessary long-term, but I avoided trying to replace
them
entirely for now to keep the already-large diff a bit smaller.

### Related refactors

Alex and I noticed a few refactoring opportunities while looking at the
code,
specifically the very similar implementations for
`create_parse_diagnostic`,
`create_unsupported_syntax_diagnostic`, and
`create_semantic_syntax_diagnostic`.
We combined these into a single generic function, which I then copied
into
`ruff_linter::message` with some small changes and a TODO to combine
them in the
future.

I also deleted the `DisplayParseErrorType` and `TruncateAtNewline` types
for
reporting parse errors. These were added in #4124, I believe to work
around the
error messages from LALRPOP. Removing these didn't affect any tests, so
I think
they were unnecessary now that we fully control the error messages from
the
parser.

On a more minor note, I factored out some calls to the
`OldDiagnostic::filename`
(now `Diagnostic::expect_ruff_filename`) function to avoid repeatedly
allocating
`String`s in some places.

### Snapshot changes

The `show_statistics_syntax_errors` integration test changed because the
`OldDiagnostic::name` method used `syntax-error` instead of
`invalid-syntax`
like in ty. I think this (`--statistics`) is one of the only places we
actually
use this name for syntax errors, so I hope this is okay. An alternative
is to
use `syntax-error` in ty too.

The other snapshot changes are from removing this code, as discussed on

[Discord](1388252408):


34052a1185/crates/ruff_linter/src/message/mod.rs (L128-L135)

I think both of these are technically breaking changes, but they only
affect
syntax errors and are very narrow in scope, while also pretty
substantially
simplifying the refactor, so I hope they're okay to include in a patch
release.

## Test plan

Existing tests, with the adjustments mentioned above

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-07-03 13:01:09 -04:00
Brent Westbrook
9bee8376a1
Bump 0.12.2 (#19126) 2025-07-03 12:27:24 -04:00
Zanie Blue
1c6717b149
Filter private symbols from stubs if they are internal types (#19121)
This implements filtering of private symbols from stub files based on
type information as discussed in
https://github.com/astral-sh/ruff/pull/19102. It extends the previous
implementation to apply to all stub files, instead of just the
`builtins` module, and uses type information to retain private names
that are may be relevant at runtime.
2025-07-03 10:19:21 -05:00
Leander Cain Slotosch
1b813cd5f1
Fix description of the format.skip-magic-trailing-comma example (#19095)
## Summary

This PR fixes a typo in the docs, where both variants of a config have
the same description.
2025-07-03 10:39:59 -04:00
Brent Westbrook
b00f68a23c
[ruff] Allow more field calls from attrs (RUF009) (#19021)
Summary
--

Closes #19014 by identifying more `field` functions from `attrs`. We
already detected these when imported from `attrs` but not the `attr`
module from the same package. These functions are identical to the
`attrs` versions:

```pycon
>>> import attrs, attr
>>> attrs.field is attr.field
True
>>> attrs.Factory is attr.Factory
True
>>>
```

Test Plan
--

Regression tests based on the issue
2025-07-03 10:29:55 -04:00
GiGaGon
710c60f713
[flake8-pytest-style] Make example error out-of-the-box (PT023) (#19104)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Part of #18972

This PR makes [pytest-incorrect-mark-parentheses-style
(PT023)](https://docs.astral.sh/ruff/rules/pytest-incorrect-mark-parentheses-style/#pytest-incorrect-mark-parentheses-style-pt023)'s
example error out-of-the-box

[Old example](https://play.ruff.rs/48989153-6d4a-493a-a287-07f330f270bc)
```py
import pytest


@pytest.mark.foo
def test_something(): ...
```

[New example](https://play.ruff.rs/741f4d19-4607-4777-a77e-4ea6c62845e1)
```py
import pytest


@pytest.mark.foo()
def test_something(): ...
```

This just swaps the parenthesis in the "Example" and "Use instead"
sections since the default configuration is no parenthesis

## Test Plan

<!-- How was it tested? -->

N/A, no functionality/tests affected
2025-07-03 10:29:26 -04:00
GiGaGon
811e25d16e
[flake8-pytest-style] Make example error out-of-the-box (PT030) (#19105)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Part of #18972

This PR makes [pytest-warns-too-broad
(PT030)](https://docs.astral.sh/ruff/rules/pytest-warns-too-broad/#pytest-warns-too-broad-pt030)'s
example error out-of-the-box

[Old example](https://play.ruff.rs/2296ae7e-c775-427a-a020-6fb25321f3f7)
```py
import pytest


def test_foo():
    with pytest.warns(RuntimeWarning):
        ...

    # empty string is also an error
    with pytest.warns(RuntimeWarning, match=""):
        ...
```

[New example](https://play.ruff.rs/af35a482-1c2f-47ee-aff3-ff1e9fa447de)
```py
import pytest


def test_foo():
    with pytest.warns(Warning):
        ...

    # empty string is also an error
    with pytest.warns(Warning, match=""):
        ...
```

`RuntimeWarning` is not in the default
[warns-require-match-for](https://docs.astral.sh/ruff/settings/#lint_flake8-pytest-style_warns-require-match-for)
list, while `Warning` is. The "Use instead" section was also updated
similarly

## Test Plan

<!-- How was it tested? -->

N/A, no functionality/tests affected
2025-07-03 10:27:31 -04:00
GiGaGon
b78af2db48
[flake8-quotes] Make example error out-of-the-box (Q003) (#19106)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Part of #18972

This PR makes [avoidable-escaped-quote
(Q003)](https://docs.astral.sh/ruff/rules/avoidable-escaped-quote/#avoidable-escaped-quote-q003)'s
example error out-of-the-box

[Old example](https://play.ruff.rs/fb319d0f-8016-46a1-b6bb-42b1b054feea)
```py
foo = 'bar\'s'
```

[New example](https://play.ruff.rs/d9626561-0646-448f-9282-3f0691b90831)
```py
foo = "bar\"s"
```

The original example got overwritten by `Q000`, since double quotes is
the default config. The quotes were also switched in the "Use instead"
section.

## Test Plan

<!-- How was it tested? -->

N/A, no functionality/tests affected
2025-07-03 10:25:46 -04:00
Avasam
4f36f0677f
Document link between import-outside-top-level (PLC0415) and lint.flake8-tidy-imports.banned-module-level-imports (#18733)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

As mentioned in
https://github.com/astral-sh/ruff/issues/18728#issuecomment-2981330666
CC @ntBre


![image](https://github.com/user-attachments/assets/ac0e9ea6-6510-48be-b775-47b30bdf7efe)

![image](https://github.com/user-attachments/assets/2a69df6f-1973-4d81-8985-9e0ce70f8175)


## Test Plan

Run the docs locally as per
a2cd6df429/CONTRIBUTING.md (mkdocs)

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
2025-07-03 14:11:53 +00:00
GiGaGon
2589a2938e
[flake8-simplify] Make example error out-of-the-box (SIM113) (#19109)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Part of #18972

This PR makes [enumerate-for-loop
(SIM113)](https://docs.astral.sh/ruff/rules/enumerate-for-loop/#enumerate-for-loop-sim113)'s
example error out-of-the-box

[Old example](https://play.ruff.rs/a6ef6fec-eb6b-477c-a962-616f0b8e1491)
```py
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(f"{i + 1}. {fruit}")
    i += 1
```

[New example](https://play.ruff.rs/1811d608-1aa0-45d8-96dc-18105e74b8cc)
```py
fruits = ["apple", "banana", "cherry"]
i = 0
for fruit in fruits:
    print(f"{i + 1}. {fruit}")
    i += 1
```

## Test Plan

<!-- How was it tested? -->

N/A, no functionality/tests affected
2025-07-03 10:08:17 -04:00
GiGaGon
26bb8f7b71
[flake8-simplify] Make example error out-of-the-box (SIM401) (#19110)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Part of #18972

This PR makes [enumerate-for-loop [if-else-block-instead-of-dict-get
(SIM401)](https://docs.astral.sh/ruff/rules/if-else-block-instead-of-dict-get/#if-else-block-instead-of-dict-get-sim401)'s
example error out-of-the-box

[Old example](https://play.ruff.rs/635629eb-7146-45a8-9e0c-4a0aa9446ded)
```py
if "bar" in foo:
    value = foo["bar"]
else:
    value = 0
```

[New example](https://play.ruff.rs/a1227ec9-05c2-4a22-800d-c76cb7abe249)
```py
foo = {}
if "bar" in foo:
    value = foo["bar"]
else:
    value = 0
```

The "Use instead" section was also updated similarly.

The docs for `SIM401` also has another section on the preview ternary
version, but it does not seem to check that the variable is a dict
(bug?) https://play.ruff.rs/c0feada8-a7fe-43f7-b57e-c10520fdcdca

## Test Plan

<!-- How was it tested? -->

N/A, no functionality/tests affected
2025-07-03 10:00:08 -04:00
GiGaGon
bf88fee428
[flake8-simplify] Make example error out-of-the-box (SIM110) (#19113)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Part of #18972

This PR makes [reimplemented-builtin
(SIM110)](https://docs.astral.sh/ruff/rules/reimplemented-builtin/#reimplemented-builtin-sim110)'s
example error out-of-the-box

[Old example](https://play.ruff.rs/1c192e8b-13f8-4f07-8c35-9dcd516a4a02)
```py
for item in iterable:
    if predicate(item):
        return True
return False
```

[New example](https://play.ruff.rs/f77393ad-20b1-436f-a872-d3bccec7c829)
```py
def foo():
    for item in iterable:
        if predicate(item):
            return True
    return False
```

The "Use instead" section was also updated to reflect the change.

## Test Plan

<!-- How was it tested? -->

N/A, no functionality/tests affected
2025-07-03 09:57:35 -04:00
David Peter
fc43d3c83e
[ty] Temporarily disable the multithreaded pydantic benchmark (#19119)
The benchmark is currently very noisy (± 10%). This leads to codspeed
reports on PRs, because we often exceed the trigger threshold. This is
confusing to ty contributors who are not aware about the flakiness.
Let's disable it for now.
2025-07-03 14:34:52 +02:00
GiGaGon
d0f0577ac7
[flake8-pyi] Make example error out-of-the-box (PYI014, PYI015) (#19097) 2025-07-03 12:54:35 +01:00
Dhruv Manilawala
dc56c33618
[ty] Initial support for workspace diagnostics (#18939)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
## Summary

This PR adds initial support for workspace diagnostics in the ty server.

Reference spec:
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_diagnostic

This is currently implemented via the **pull diagnostics method** which
was added in the current version (3.17) and the server advertises it via
the `diagnosticProvider.workspaceDiagnostics` server capability.

**Note:** This might be a bit confusing but a workspace diagnostics is
not for a single workspace but for all the workspaces that the server
handles. These are the ones that the server received during
initialization. Currently, the ty server doesn't support multiple
workspaces so this capability is also limited to provide diagnostics
only for a single workspace (the first one if the client provided
multiple).

A new `ty.diagnosticMode` server setting is added which can be either
`workspace` (for workspace diagnostics) or `openFilesOnly` (for checking
only open files) (default). This is same as
`python.analysis.diagnosticMode` that Pyright / Pylance utilizes. In the
future, we could use the value under `python.*` namespace as fallback to
improve the experience on user side to avoid setting the value multiple
times.

Part of: astral-sh/ty#81

## Test Plan

This capability was introduced in the current LSP version (~3 years) and
the way it's implemented by various clients are a bit different. I've
provided notes on what I've noticed and what would need to be done on
our side to further improve the experience.

### VS Code

VS Code sends the `workspace/diagnostic` requests every ~2 second:

```
[Trace - 12:12:32 PM] Sending request 'workspace/diagnostic - (403)'.
[Trace - 12:12:32 PM] Received response 'workspace/diagnostic - (403)' in 2ms.
[Trace - 12:12:34 PM] Sending request 'workspace/diagnostic - (404)'.
[Trace - 12:12:34 PM] Received response 'workspace/diagnostic - (404)' in 2ms.
[Trace - 12:12:36 PM] Sending request 'workspace/diagnostic - (405)'.
[Trace - 12:12:36 PM] Received response 'workspace/diagnostic - (405)' in 2ms.
[Trace - 12:12:38 PM] Sending request 'workspace/diagnostic - (406)'.
[Trace - 12:12:38 PM] Received response 'workspace/diagnostic - (406)' in 3ms.
[Trace - 12:12:40 PM] Sending request 'workspace/diagnostic - (407)'.
[Trace - 12:12:40 PM] Received response 'workspace/diagnostic - (407)' in 2ms.
...
```

I couldn't really find any resource that explains this behavior. But,
this does mean that we'd need to implement the caching layer via the
previous result ids sooner. This will allow the server to avoid sending
all the diagnostics on every request and instead just send a response
stating that the diagnostics hasn't changed yet. This could possibly be
achieved by using the salsa ID.

If we switch from workspace diagnostics to open-files diagnostics, the
server would send the diagnostics only via the `textDocument/diagnostic`
endpoint. Here, when a document containing the diagnostic is closed, the
server would send a publish diagnostics notification with an empty list
of diagnostics to clear the diagnostics from that document. The issue is
the VS Code doesn't seem to be clearing the diagnostics in this case
even though it receives the notification. (I'm going to open an issue on
VS Code side for this today.)


https://github.com/user-attachments/assets/b0c0833d-386c-49f5-8a15-0ac9133e15ed

### Zed

Zed's implementation works by refreshing the workspace diagnostics
whenever the content of the documents are changed. This seems like a
very reasonable behavior and I was a bit surprised that VS Code didn't
use this heuristic.


https://github.com/user-attachments/assets/71c7b546-7970-434a-9ba0-4fa620647f6c

### Neovim

Neovim only recently added support for workspace diagnostics
(https://github.com/neovim/neovim/pull/34262, merged ~3 weeks ago) so
it's only available on nightly versions.

The initial support is limited and requires fetching the workspace
diagnostics manually as demonstrated in the video. It doesn't support
refreshing the workspace diagnostics either, so that would need to be
done manually as well. I'm assuming that these are just a temporary
limitation and will be implemented before the stable release.


https://github.com/user-attachments/assets/25b4a0e5-9833-4877-88ad-279904fffaf9
2025-07-03 11:04:54 +00:00