Skip to content

Commit 5015526

Browse files
committed
[ty] Don't send publish diagnostics for clients supporting pull diagnostics
1 parent f68080b commit 5015526

File tree

5 files changed

+109
-7
lines changed

5 files changed

+109
-7
lines changed

crates/ruff_db/src/system/path.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,13 @@ impl Deref for SystemPathBuf {
667667
}
668668
}
669669

670+
impl AsRef<Path> for SystemPathBuf {
671+
#[inline]
672+
fn as_ref(&self) -> &Path {
673+
self.0.as_std_path()
674+
}
675+
}
676+
670677
impl<P: AsRef<SystemPath>> FromIterator<P> for SystemPathBuf {
671678
fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> Self {
672679
let mut buf = SystemPathBuf::new();

crates/ty_server/src/server/api/notifications/did_change_watched_files.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::document::DocumentKey;
22
use crate::server::Result;
3-
use crate::server::api::diagnostics::{publish_diagnostics, publish_settings_diagnostics};
3+
use crate::server::api::diagnostics::{
4+
publish_diagnostics_if_needed, publish_settings_diagnostics,
5+
};
46
use crate::server::api::traits::{NotificationHandler, SyncNotificationHandler};
57
use crate::session::Session;
68
use crate::session::client::Client;
@@ -92,7 +94,7 @@ impl SyncNotificationHandler for DidChangeWatchedFiles {
9294
);
9395
} else {
9496
for key in session.text_document_handles() {
95-
publish_diagnostics(&key, session, client);
97+
publish_diagnostics_if_needed(&key, session, client);
9698
}
9799
}
98100

crates/ty_server/tests/e2e/main.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -742,15 +742,18 @@ impl TestServer {
742742
}
743743

744744
pub(crate) fn file_uri(&self, path: impl AsRef<SystemPath>) -> Url {
745-
Url::from_file_path(self.test_context.root().join(path.as_ref()).as_std_path())
746-
.expect("Path must be a valid URL")
745+
Url::from_file_path(self.file_path(path).as_std_path()).expect("Path must be a valid URL")
746+
}
747+
748+
pub(crate) fn file_path(&self, path: impl AsRef<SystemPath>) -> SystemPathBuf {
749+
self.test_context.root().join(path)
747750
}
748751

749752
/// Send a `textDocument/didOpen` notification
750753
pub(crate) fn open_text_document(
751754
&mut self,
752755
path: impl AsRef<SystemPath>,
753-
content: &impl ToString,
756+
content: impl ToString,
754757
version: i32,
755758
) {
756759
let params = DidOpenTextDocumentParams {
@@ -793,7 +796,6 @@ impl TestServer {
793796
}
794797

795798
/// Send a `workspace/didChangeWatchedFiles` notification with the given file events
796-
#[expect(dead_code)]
797799
pub(crate) fn did_change_watched_files(&mut self, events: Vec<FileEvent>) {
798800
let params = DidChangeWatchedFilesParams { changes: events };
799801
self.send_notification::<DidChangeWatchedFiles>(params);

crates/ty_server/tests/e2e/publish_diagnostics.rs

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
use std::time::Duration;
2+
13
use anyhow::Result;
2-
use lsp_types::notification::PublishDiagnostics;
4+
use lsp_types::{FileChangeType, FileEvent, notification::PublishDiagnostics};
35
use ruff_db::system::SystemPath;
46

57
use crate::TestServerBuilder;
@@ -27,3 +29,83 @@ def foo() -> str:
2729

2830
Ok(())
2931
}
32+
33+
#[test]
34+
fn on_did_change_watched_files() -> Result<()> {
35+
let workspace_root = SystemPath::new("src");
36+
let foo = SystemPath::new("src/foo.py");
37+
let foo_content = "\
38+
def foo() -> str:
39+
print(a)
40+
";
41+
42+
let mut server = TestServerBuilder::new()?
43+
.with_workspace(workspace_root, None)?
44+
.with_file(foo, "")?
45+
.enable_pull_diagnostics(false)
46+
.build()
47+
.wait_until_workspaces_are_initialized();
48+
49+
let foo = server.file_path(foo);
50+
51+
server.open_text_document(&foo, "", 1);
52+
53+
let _open_diagnostics = server.await_notification::<PublishDiagnostics>();
54+
55+
std::fs::write(&foo, foo_content)?;
56+
57+
server.did_change_watched_files(vec![FileEvent {
58+
uri: server.file_uri(foo),
59+
typ: FileChangeType::CHANGED,
60+
}]);
61+
62+
let diagnostics = server.await_notification::<PublishDiagnostics>();
63+
64+
// Note how ty reports no diagnostics here. This is because
65+
// the contents received by didOpen/didChange take precedence over the file
66+
// content on disk. Or, more specifically, because the revision
67+
// of the file is not bumped, because it still uses the version
68+
// from the `didOpen` notification but we don't have any notification
69+
// that we can use here.
70+
insta::assert_json_snapshot!(diagnostics);
71+
72+
Ok(())
73+
}
74+
75+
#[test]
76+
fn on_did_change_watched_files_pull_diagnostics() -> Result<()> {
77+
let workspace_root = SystemPath::new("src");
78+
let foo = SystemPath::new("src/foo.py");
79+
let foo_content = "\
80+
def foo() -> str:
81+
print(a)
82+
";
83+
84+
let mut server = TestServerBuilder::new()?
85+
.with_workspace(workspace_root, None)?
86+
.with_file(foo, "")?
87+
.enable_pull_diagnostics(true)
88+
.build()
89+
.wait_until_workspaces_are_initialized();
90+
91+
let foo = server.file_path(foo);
92+
93+
server.open_text_document(&foo, "", 1);
94+
95+
std::fs::write(&foo, foo_content)?;
96+
97+
server.did_change_watched_files(vec![FileEvent {
98+
uri: server.file_uri(foo),
99+
typ: FileChangeType::CHANGED,
100+
}]);
101+
102+
let diagnostics =
103+
server.try_await_notification::<PublishDiagnostics>(Some(Duration::from_millis(100)));
104+
105+
assert!(
106+
diagnostics.is_err(),
107+
"Server should not send a publish diagnostic notification if the client supports pull diagnostics"
108+
);
109+
110+
Ok(())
111+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
source: crates/ty_server/tests/e2e/publish_diagnostics.rs
3+
expression: diagnostics
4+
---
5+
{
6+
"uri": "file://<temp_dir>/src/foo.py",
7+
"diagnostics": [],
8+
"version": 1
9+
}

0 commit comments

Comments
 (0)