Skip to content

Commit da3b59b

Browse files
committed
add diagnostics to lsp
1 parent 294c059 commit da3b59b

File tree

7 files changed

+97
-16
lines changed

7 files changed

+97
-16
lines changed

.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:5432/postgres
1+
DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres

crates/pg_lsp_new/src/handlers/text_document.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use pg_workspace_new::workspace::{
55
ChangeFileParams, ChangeParams, CloseFileParams, GetFileContentParams, OpenFileParams,
66
};
77
use tower_lsp::lsp_types;
8-
use tracing::field;
8+
use tracing::{error, field};
99

1010
/// Handler for `textDocument/didOpen` LSP notification
1111
#[tracing::instrument(
@@ -35,9 +35,9 @@ pub(crate) async fn did_open(
3535

3636
session.insert_document(url.clone(), doc);
3737

38-
// if let Err(err) = session.update_diagnostics(url).await {
39-
// error!("Failed to update diagnostics: {}", err);
40-
// }
38+
if let Err(err) = session.update_diagnostics(url).await {
39+
error!("Failed to update diagnostics: {}", err);
40+
}
4141

4242
Ok(())
4343
}
@@ -89,9 +89,9 @@ pub(crate) async fn did_change(
8989

9090
session.insert_document(url.clone(), new_doc);
9191

92-
// if let Err(err) = session.update_diagnostics(url).await {
93-
// error!("Failed to update diagnostics: {}", err);
94-
// }
92+
if let Err(err) = session.update_diagnostics(url).await {
93+
error!("Failed to update diagnostics: {}", err);
94+
}
9595

9696
Ok(())
9797
}

crates/pg_lsp_new/src/server.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ impl LanguageServer for LSPServer {
160160
self.setup_capabilities().await;
161161

162162
// Diagnostics are disabled by default, so update them after fetching workspace config
163-
// self.session.update_all_diagnostics().await;
163+
self.session.update_all_diagnostics().await;
164164
}
165165

166166
async fn shutdown(&self) -> LspResult<()> {
@@ -172,7 +172,7 @@ impl LanguageServer for LSPServer {
172172
let _ = params;
173173
self.session.load_workspace_settings().await;
174174
self.setup_capabilities().await;
175-
// self.session.update_all_diagnostics().await;
175+
self.session.update_all_diagnostics().await;
176176
}
177177

178178
#[tracing::instrument(level = "trace", skip(self))]
@@ -378,6 +378,7 @@ impl ServerFactory {
378378
workspace_method!(builder, open_file);
379379
workspace_method!(builder, change_file);
380380
workspace_method!(builder, close_file);
381+
workspace_method!(builder, pull_diagnostics);
381382

382383
let (service, socket) = builder.finish();
383384
ServerConnection { socket, service }

crates/pg_lsp_new/src/session.rs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1+
use crate::diagnostics::LspError;
12
use crate::documents::Document;
3+
use crate::utils;
24
use anyhow::Result;
5+
use futures::stream::FuturesUnordered;
6+
use futures::StreamExt;
37
use pg_configuration::ConfigurationPathHint;
48
use pg_diagnostics::{DiagnosticExt, Error};
59
use pg_fs::{FileSystem, PgLspPath};
610
use pg_lsp_converters::{negotiated_encoding, PositionEncoding, WideEncoding};
711
use pg_workspace_new::configuration::{load_configuration, LoadedConfiguration};
812
use pg_workspace_new::settings::PartialConfigurationExt;
9-
use pg_workspace_new::workspace::UpdateSettingsParams;
13+
use pg_workspace_new::workspace::{PullDiagnosticsParams, UpdateSettingsParams};
1014
use pg_workspace_new::Workspace;
1115
use pg_workspace_new::{DynRef, WorkspaceError};
1216
use rustc_hash::FxHashMap;
@@ -237,6 +241,75 @@ impl Session {
237241
}
238242
}
239243

244+
/// Computes diagnostics for the file matching the provided url and publishes
245+
/// them to the client. Called from [`handlers::text_document`] when a file's
246+
/// contents changes.
247+
#[tracing::instrument(level = "trace", skip_all, fields(url = display(&url), diagnostic_count), err)]
248+
pub(crate) async fn update_diagnostics(&self, url: lsp_types::Url) -> Result<(), LspError> {
249+
let pglsp_path = self.file_path(&url)?;
250+
let doc = self.document(&url)?;
251+
if self.configuration_status().is_error() && !self.notified_broken_configuration() {
252+
self.set_notified_broken_configuration();
253+
self.client
254+
.show_message(MessageType::WARNING, "The configuration file has errors. Biome will report only parsing errors until the configuration is fixed.")
255+
.await;
256+
}
257+
258+
let diagnostics: Vec<lsp_types::Diagnostic> = {
259+
let result = self.workspace.pull_diagnostics(PullDiagnosticsParams {
260+
path: pglsp_path.clone(),
261+
max_diagnostics: u64::MAX,
262+
})?;
263+
264+
tracing::trace!("biome diagnostics: {:#?}", result.diagnostics);
265+
266+
result
267+
.diagnostics
268+
.into_iter()
269+
.filter_map(|d| {
270+
match utils::diagnostic_to_lsp(
271+
d,
272+
&url,
273+
&doc.line_index,
274+
self.position_encoding(),
275+
None,
276+
) {
277+
Ok(diag) => Some(diag),
278+
Err(err) => {
279+
error!("failed to convert diagnostic to LSP: {err:?}");
280+
None
281+
}
282+
}
283+
})
284+
.collect()
285+
};
286+
287+
tracing::Span::current().record("diagnostic_count", diagnostics.len());
288+
289+
self.client
290+
.publish_diagnostics(url, diagnostics, Some(doc.version))
291+
.await;
292+
293+
Ok(())
294+
}
295+
296+
/// Updates diagnostics for every [`Document`] in this [`Session`]
297+
pub(crate) async fn update_all_diagnostics(&self) {
298+
let mut futures: FuturesUnordered<_> = self
299+
.documents
300+
.read()
301+
.unwrap()
302+
.keys()
303+
.map(|url| self.update_diagnostics(url.clone()))
304+
.collect();
305+
306+
while let Some(result) = futures.next().await {
307+
if let Err(e) = result {
308+
error!("Error while updating diagnostics: {}", e);
309+
}
310+
}
311+
}
312+
240313
/// Get a [`Document`] matching the provided [`lsp_types::Url`]
241314
///
242315
/// If document does not exist, result is [WorkspaceError::NotFound]

crates/pg_workspace_new/src/workspace/server.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,16 @@ impl Workspace for WorkspaceServer {
214214
#[tracing::instrument(level = "trace", skip(self))]
215215
fn open_file(&self, params: OpenFileParams) -> Result<(), WorkspaceError> {
216216
tracing::info!("Opening file: {:?}", params.path);
217-
self.documents.insert(
218-
params.path.clone(),
219-
Document::new(params.path, params.content, params.version),
220-
);
217+
218+
let doc = Document::new(params.path.clone(), params.content, params.version);
219+
220+
doc.statements.iter().for_each(|s| {
221+
let stmt = doc.statement(s);
222+
self.tree_sitter.add_statement(&stmt);
223+
self.pg_query.add_statement(&stmt);
224+
});
225+
226+
self.documents.insert(params.path, doc);
221227

222228
Ok(())
223229
}

crates/pg_workspace_new/src/workspace/server/pg_query.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ impl Store<pg_query_ext::NodeEnum> for PgQueryStore {
6363
if let Ok(ast) = r {
6464
self.ast_db.insert(statement.ref_.clone(), Arc::new(ast));
6565
} else {
66+
tracing::info!("adding diagnostics");
6667
self.diagnostics.insert(
6768
statement.ref_.clone(),
6869
SyntaxDiagnostic::from(r.unwrap_err()),

test.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ select 14433313331333333333
44

55
select * from test;
66

7-
alter table test drop column id;
7+
alter tqjable test drop column id;
88

99
select lower();

0 commit comments

Comments
 (0)