From e3a3a95a3fedd4c79d276d494f8c377b6d5062dc Mon Sep 17 00:00:00 2001 From: JoshuaBatty Date: Tue, 1 Aug 2023 10:15:40 +1000 Subject: [PATCH 1/5] add resync logic to sync module --- sway-lsp/src/core/sync.rs | 14 ++++++++++++++ sway-lsp/src/handlers/notification.rs | 16 ++-------------- sway-lsp/src/server.rs | 2 +- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/sway-lsp/src/core/sync.rs b/sway-lsp/src/core/sync.rs index 099bc395754..f38952e29be 100644 --- a/sway-lsp/src/core/sync.rs +++ b/sway-lsp/src/core/sync.rs @@ -45,6 +45,20 @@ impl SyncWorkspace { } } + /// Overwrite the contents of the tmp/folder with everything in + /// the current workspace. + pub fn resync(&self) -> Result<(), LanguageServerError> { + self.clone_manifest_dir_to_temp()?; + self.manifest_path() + .and_then(|manifest_path| PackageManifestFile::from_dir(&manifest_path).ok()) + .map(|manifest| { + if let Some(temp_manifest_path) = &self.temp_manifest_path() { + edit_manifest_dependency_paths(&manifest, temp_manifest_path) + } + }); + Ok(()) + } + /// Clean up the temp directory that was created once the /// server closes down. pub(crate) fn remove_temp_dir(&self) { diff --git a/sway-lsp/src/handlers/notification.rs b/sway-lsp/src/handlers/notification.rs index bfe2ee2f494..2cff9d8d73e 100644 --- a/sway-lsp/src/handlers/notification.rs +++ b/sway-lsp/src/handlers/notification.rs @@ -58,21 +58,9 @@ pub(crate) async fn handle_did_save_text_document( .uri_and_session_from_workspace(¶ms.text_document.uri) { Ok((uri, session)) => { - // overwrite the contents of the tmp/folder with everything in - // the current workspace. (resync) - if let Err(err) = session.sync.clone_manifest_dir_to_temp() { + if let Err(err) = session.sync.resync() { tracing::error!("{}", err.to_string().as_str()); } - - let _ = session - .sync - .manifest_path() - .and_then(|manifest_path| PackageManifestFile::from_dir(&manifest_path).ok()) - .map(|manifest| { - if let Some(temp_manifest_path) = &session.sync.temp_manifest_path() { - sync::edit_manifest_dependency_paths(&manifest, temp_manifest_path) - } - }); state .parse_project(uri, params.text_document.uri, session) .await; @@ -81,7 +69,7 @@ pub(crate) async fn handle_did_save_text_document( } } -pub(crate) async fn handle_did_change_watched_files( +pub(crate) fn handle_did_change_watched_files( state: &ServerState, params: DidChangeWatchedFilesParams, ) { diff --git a/sway-lsp/src/server.rs b/sway-lsp/src/server.rs index a2e131f761a..a8e3815dba5 100644 --- a/sway-lsp/src/server.rs +++ b/sway-lsp/src/server.rs @@ -45,7 +45,7 @@ impl LanguageServer for ServerState { } async fn did_change_watched_files(&self, params: DidChangeWatchedFilesParams) { - notification::handle_did_change_watched_files(self, params).await; + notification::handle_did_change_watched_files(self, params); } async fn hover(&self, params: HoverParams) -> Result> { From f5852dca363ae132b539c7af9964f7cc644a685e Mon Sep 17 00:00:00 2001 From: JoshuaBatty Date: Tue, 1 Aug 2023 10:51:20 +1000 Subject: [PATCH 2/5] bubble up errors --- sway-lsp/src/handlers/notification.rs | 70 ++++++++++----------------- sway-lsp/src/server.rs | 12 +++-- 2 files changed, 34 insertions(+), 48 deletions(-) diff --git a/sway-lsp/src/handlers/notification.rs b/sway-lsp/src/handlers/notification.rs index 2cff9d8d73e..e386d9a61b5 100644 --- a/sway-lsp/src/handlers/notification.rs +++ b/sway-lsp/src/handlers/notification.rs @@ -1,8 +1,7 @@ //! This module is responsible for implementing handlers for Language Server //! Protocol. This module specifically handles notification messages sent by the Client. -use crate::{core::sync, server_state::ServerState}; -use forc_pkg::PackageManifestFile; +use crate::{error::LanguageServerError, server_state::ServerState}; use lsp_types::{ DidChangeTextDocumentParams, DidChangeWatchedFilesParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams, FileChangeType, @@ -11,62 +10,43 @@ use lsp_types::{ pub(crate) async fn handle_did_open_text_document( state: &ServerState, params: DidOpenTextDocumentParams, -) { - match state +) -> Result<(), LanguageServerError> { + let (uri, session) = state .sessions - .uri_and_session_from_workspace(¶ms.text_document.uri) - { - Ok((uri, session)) => { - session.handle_open_file(&uri); - state - .parse_project(uri, params.text_document.uri, session.clone()) - .await; - } - Err(err) => tracing::error!("{}", err.to_string()), - } + .uri_and_session_from_workspace(¶ms.text_document.uri)?; + session.handle_open_file(&uri); + state + .parse_project(uri, params.text_document.uri, session.clone()) + .await; + Ok(()) } pub(crate) async fn handle_did_change_text_document( state: &ServerState, params: DidChangeTextDocumentParams, -) { - match state +) -> Result<(), LanguageServerError> { + let (uri, session) = state .sessions - .uri_and_session_from_workspace(¶ms.text_document.uri) - { - Ok((uri, session)) => { - // update this file with the new changes and write to disk - match session.write_changes_to_file(&uri, params.content_changes) { - Ok(_) => { - state - .parse_project(uri, params.text_document.uri.clone(), session) - .await; - } - Err(err) => tracing::error!("{}", err.to_string()), - } - } - Err(err) => tracing::error!("{}", err.to_string()), - } + .uri_and_session_from_workspace(¶ms.text_document.uri)?; + session.write_changes_to_file(&uri, params.content_changes)?; + state + .parse_project(uri, params.text_document.uri, session.clone()) + .await; + Ok(()) } pub(crate) async fn handle_did_save_text_document( state: &ServerState, params: DidSaveTextDocumentParams, -) { - match state +) -> Result<(), LanguageServerError> { + let (uri, session) = state .sessions - .uri_and_session_from_workspace(¶ms.text_document.uri) - { - Ok((uri, session)) => { - if let Err(err) = session.sync.resync() { - tracing::error!("{}", err.to_string().as_str()); - } - state - .parse_project(uri, params.text_document.uri, session) - .await; - } - Err(err) => tracing::error!("{}", err.to_string()), - } + .uri_and_session_from_workspace(¶ms.text_document.uri)?; + session.sync.resync()?; + state + .parse_project(uri, params.text_document.uri, session.clone()) + .await; + Ok(()) } pub(crate) fn handle_did_change_watched_files( diff --git a/sway-lsp/src/server.rs b/sway-lsp/src/server.rs index a8e3815dba5..15aa5b635dd 100644 --- a/sway-lsp/src/server.rs +++ b/sway-lsp/src/server.rs @@ -33,15 +33,21 @@ impl LanguageServer for ServerState { } async fn did_open(&self, params: DidOpenTextDocumentParams) { - notification::handle_did_open_text_document(self, params).await; + if let Err(err) = notification::handle_did_open_text_document(self, params).await { + tracing::error!("{}", err.to_string()); + } } async fn did_change(&self, params: DidChangeTextDocumentParams) { - notification::handle_did_change_text_document(self, params).await; + if let Err(err) = notification::handle_did_change_text_document(self, params).await { + tracing::error!("{}", err.to_string()); + } } async fn did_save(&self, params: DidSaveTextDocumentParams) { - notification::handle_did_save_text_document(self, params).await; + if let Err(err) = notification::handle_did_save_text_document(self, params).await { + tracing::error!("{}", err.to_string()); + } } async fn did_change_watched_files(&self, params: DidChangeWatchedFilesParams) { From da988fbae54c9001efa93f4bd52e399d210883bf Mon Sep 17 00:00:00 2001 From: JoshuaBatty Date: Tue, 1 Aug 2023 10:54:10 +1000 Subject: [PATCH 3/5] clippy --- sway-lsp/src/core/sync.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sway-lsp/src/core/sync.rs b/sway-lsp/src/core/sync.rs index f38952e29be..0ca8a032bb8 100644 --- a/sway-lsp/src/core/sync.rs +++ b/sway-lsp/src/core/sync.rs @@ -49,13 +49,14 @@ impl SyncWorkspace { /// the current workspace. pub fn resync(&self) -> Result<(), LanguageServerError> { self.clone_manifest_dir_to_temp()?; - self.manifest_path() + if let Some(manifest) = self + .manifest_path() .and_then(|manifest_path| PackageManifestFile::from_dir(&manifest_path).ok()) - .map(|manifest| { - if let Some(temp_manifest_path) = &self.temp_manifest_path() { - edit_manifest_dependency_paths(&manifest, temp_manifest_path) - } - }); + { + if let Some(temp_manifest_path) = &self.temp_manifest_path() { + edit_manifest_dependency_paths(&manifest, temp_manifest_path) + } + } Ok(()) } From c65c7efdd6f60e84800eeadcd176ae03629bae2f Mon Sep 17 00:00:00 2001 From: JoshuaBatty Date: Tue, 1 Aug 2023 11:16:06 +1000 Subject: [PATCH 4/5] diagnostics --- sway-lsp/src/server_state.rs | 56 ++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/sway-lsp/src/server_state.rs b/sway-lsp/src/server_state.rs index c939b03a983..0868f0b94f9 100644 --- a/sway-lsp/src/server_state.rs +++ b/sway-lsp/src/server_state.rs @@ -9,7 +9,7 @@ use crate::{ }; use dashmap::DashMap; use forc_pkg::PackageManifestFile; -use lsp_types::Url; +use lsp_types::{Diagnostic, Url}; use parking_lot::RwLock; use std::{path::PathBuf, sync::Arc}; use tokio::task; @@ -45,40 +45,40 @@ impl ServerState { Ok(()) } - async fn publish_diagnostics(&self, uri: &Url, workspace_uri: &Url, session: Arc) { - let diagnostics_res = { - let mut diagnostics_to_publish = vec![]; - let config = &self.config.read(); - let engines = session.engines.read(); - let tokens = session.token_map().tokens_for_file(engines.se(), uri); - match config.debug.show_collected_tokens_as_warnings { - // If collected_tokens_as_warnings is Parsed or Typed, - // take over the normal error and warning display behavior - // and instead show the either the parsed or typed tokens as warnings. - // This is useful for debugging the lsp parser. - Warnings::Parsed => { - diagnostics_to_publish = debug::generate_warnings_for_parsed_tokens(tokens) - } - Warnings::Typed => { - diagnostics_to_publish = debug::generate_warnings_for_typed_tokens(tokens) + pub(crate) fn diagnostics(&self, uri: &Url, session: Arc) -> Vec { + let mut diagnostics_to_publish = vec![]; + let config = &self.config.read(); + let engines = session.engines.read(); + let tokens = session.token_map().tokens_for_file(engines.se(), uri); + match config.debug.show_collected_tokens_as_warnings { + // If collected_tokens_as_warnings is Parsed or Typed, + // take over the normal error and warning display behavior + // and instead show the either the parsed or typed tokens as warnings. + // This is useful for debugging the lsp parser. + Warnings::Parsed => { + diagnostics_to_publish = debug::generate_warnings_for_parsed_tokens(tokens) + } + Warnings::Typed => { + diagnostics_to_publish = debug::generate_warnings_for_typed_tokens(tokens) + } + Warnings::Default => { + let diagnostics = session.wait_for_parsing(); + if config.diagnostic.show_warnings { + diagnostics_to_publish.extend(diagnostics.warnings); } - Warnings::Default => { - let diagnostics = session.wait_for_parsing(); - if config.diagnostic.show_warnings { - diagnostics_to_publish.extend(diagnostics.warnings); - } - if config.diagnostic.show_errors { - diagnostics_to_publish.extend(diagnostics.errors); - } + if config.diagnostic.show_errors { + diagnostics_to_publish.extend(diagnostics.errors); } } - diagnostics_to_publish - }; + } + diagnostics_to_publish + } + async fn publish_diagnostics(&self, uri: &Url, workspace_uri: &Url, session: Arc) { // Note: Even if the computed diagnostics vec is empty, we still have to push the empty Vec // in order to clear former diagnostics. Newly pushed diagnostics always replace previously pushed diagnostics. self.client - .publish_diagnostics(workspace_uri.clone(), diagnostics_res, None) + .publish_diagnostics(workspace_uri.clone(), self.diagnostics(uri, session), None) .await; } From c8408ac579f2685eca18f79b4fd05720cdc64a10 Mon Sep 17 00:00:00 2001 From: JoshuaBatty Date: Tue, 1 Aug 2023 11:18:51 +1000 Subject: [PATCH 5/5] clean up --- sway-lsp/src/server_state.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/sway-lsp/src/server_state.rs b/sway-lsp/src/server_state.rs index 0868f0b94f9..6c77ce48dae 100644 --- a/sway-lsp/src/server_state.rs +++ b/sway-lsp/src/server_state.rs @@ -74,18 +74,13 @@ impl ServerState { diagnostics_to_publish } - async fn publish_diagnostics(&self, uri: &Url, workspace_uri: &Url, session: Arc) { - // Note: Even if the computed diagnostics vec is empty, we still have to push the empty Vec - // in order to clear former diagnostics. Newly pushed diagnostics always replace previously pushed diagnostics. - self.client - .publish_diagnostics(workspace_uri.clone(), self.diagnostics(uri, session), None) - .await; - } - pub(crate) async fn parse_project(&self, uri: Url, workspace_uri: Url, session: Arc) { let should_publish = run_blocking_parse_project(uri.clone(), session.clone()).await; if should_publish { - self.publish_diagnostics(&uri, &workspace_uri, session) + // Note: Even if the computed diagnostics vec is empty, we still have to push the empty Vec + // in order to clear former diagnostics. Newly pushed diagnostics always replace previously pushed diagnostics. + self.client + .publish_diagnostics(workspace_uri.clone(), self.diagnostics(&uri, session), None) .await; } }