diff --git a/src/lsp/ext.rs b/src/lsp/ext.rs index 037bfec..7e0fbbd 100644 --- a/src/lsp/ext.rs +++ b/src/lsp/ext.rs @@ -76,6 +76,21 @@ impl Notification for ProcMacroServerInitializationFailed { const METHOD: &'static str = "cairo/procMacroServerInitializationFailed"; } +/// Notifies about `cairo_project.toml` parsing failure. +#[derive(Debug)] +pub struct ProjectConfigParsingFailed; + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ProjectConfigParsingFailedParams { + pub project_config_path: String, +} + +impl Notification for ProjectConfigParsingFailed { + type Params = ProjectConfigParsingFailedParams; + const METHOD: &'static str = "cairo/projectConfigParsingFailed"; +} + #[cfg(feature = "testing")] pub mod testing { use lsp_types::notification::Notification; diff --git a/src/project/mod.rs b/src/project/mod.rs index b68e693..84cf309 100644 --- a/src/project/mod.rs +++ b/src/project/mod.rs @@ -10,7 +10,9 @@ use tracing::{debug, error, trace, warn}; pub use self::crate_data::Crate; pub use self::project_manifest_path::*; -use crate::lsp::ext::CorelibVersionMismatch; +use crate::lsp::ext::{ + CorelibVersionMismatch, ProjectConfigParsingFailed, ProjectConfigParsingFailedParams, +}; use crate::project::scarb::{extract_crates, get_workspace_members_manifests}; use crate::project::unmanaged_core_crate::try_to_init_unmanaged_core; use crate::server::client::Notifier; @@ -41,12 +43,16 @@ impl ProjectController { /// /// The background thread is responsible for fetching changes to the project model: check /// [`ProjectControllerThread::send_project_update_for_file`] for more information. - pub fn initialize(scarb_toolchain: ScarbToolchain) -> Self { + pub fn initialize(scarb_toolchain: ScarbToolchain, notifier: Notifier) -> Self { let (requests_sender, requests_receiver) = crossbeam::channel::unbounded(); let (response_sender, response_receiver) = crossbeam::channel::unbounded(); - let thread = - ProjectControllerThread::spawn(requests_receiver, response_sender, scarb_toolchain); + let thread = ProjectControllerThread::spawn( + requests_receiver, + response_sender, + scarb_toolchain, + notifier, + ); ProjectController { requests_sender, response_receiver, _thread: thread } } @@ -132,6 +138,7 @@ struct ProjectControllerThread { requests_receiver: Receiver, response_sender: Sender, scarb_toolchain: ScarbToolchain, + notifier: Notifier, } impl ProjectControllerThread { @@ -140,12 +147,14 @@ impl ProjectControllerThread { requests_receiver: Receiver, response_sender: Sender, scarb_toolchain: ScarbToolchain, + notifier: Notifier, ) -> JoinHandle { let this = Self { loaded_scarb_manifests: Default::default(), requests_receiver, response_sender, scarb_toolchain, + notifier, }; thread::Builder::new(ThreadPriority::Worker) @@ -211,8 +220,14 @@ impl ProjectControllerThread { assert!(config_path.is_absolute()); let maybe_project_config = ProjectConfig::from_file(&config_path) - // TODO: send failure notification - .inspect_err(|err| error!("{err:?}")) + .inspect_err(|err| { + error!("{err:?}"); + self.notifier.notify::( + ProjectConfigParsingFailedParams { + project_config_path: config_path.to_string_lossy().into(), + }, + ); + }) .ok(); ProjectUpdate::CairoProjectToml(maybe_project_config) } diff --git a/src/state.rs b/src/state.rs index bae723c..72e7525 100644 --- a/src/state.rs +++ b/src/state.rs @@ -48,9 +48,9 @@ impl State { scarb_toolchain: scarb_toolchain.clone(), db_swapper: AnalysisDatabaseSwapper::new(), tricks: Owned::new(tricks.into()), - diagnostics_controller: DiagnosticsController::new(notifier), + diagnostics_controller: DiagnosticsController::new(notifier.clone()), proc_macro_controller, - project_controller: ProjectController::initialize(scarb_toolchain), + project_controller: ProjectController::initialize(scarb_toolchain, notifier), } } diff --git a/tests/e2e/support/mock_client.rs b/tests/e2e/support/mock_client.rs index da69b61..2ac3e76 100644 --- a/tests/e2e/support/mock_client.rs +++ b/tests/e2e/support/mock_client.rs @@ -5,11 +5,12 @@ use std::time::Duration; use std::{fmt, mem, process}; use cairo_language_server::build_service_for_e2e_tests; +use cairo_language_server::lsp::ext::testing::ProjectUpdatingFinished; use lsp_server::{Message, Notification, Request, Response}; use lsp_types::request::{RegisterCapability, Request as LspRequest}; use lsp_types::{lsp_notification, lsp_request}; use serde_json::Value; -use cairo_language_server::lsp::ext::testing::ProjectUpdatingFinished; + use crate::support::fixture::Fixture; use crate::support::jsonrpc::RequestIdGenerator;