From 4dd5afb7fe2eb20748ade9141e74b04f5dd2f922 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 22 Aug 2019 11:08:22 +0300 Subject: show error to the user when deserializing config --- crates/ra_lsp_server/src/lib.rs | 5 ++++- crates/ra_lsp_server/src/main.rs | 19 +++++++++++++------ crates/ra_lsp_server/src/main_loop.rs | 6 +++++- 3 files changed, 22 insertions(+), 8 deletions(-) (limited to 'crates/ra_lsp_server') diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs index ca388e472..2c5d7c72d 100644 --- a/crates/ra_lsp_server/src/lib.rs +++ b/crates/ra_lsp_server/src/lib.rs @@ -11,5 +11,8 @@ mod world; pub type Result = std::result::Result>; pub use crate::{ - caps::server_capabilities, config::ServerConfig, main_loop::main_loop, main_loop::LspError, + caps::server_capabilities, + config::ServerConfig, + main_loop::LspError, + main_loop::{main_loop, show_message}, }; diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index 36d4898bd..ae1392cb5 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs @@ -1,8 +1,7 @@ use flexi_logger::{Duplicate, Logger}; use gen_lsp_server::{run_server, stdio_transport}; -use serde::Deserialize; -use ra_lsp_server::{Result, ServerConfig}; +use ra_lsp_server::{show_message, Result, ServerConfig}; use ra_prof; fn main() -> Result<()> { @@ -46,15 +45,23 @@ fn main_inner() -> Result<()> { .filter(|workspaces| !workspaces.is_empty()) .unwrap_or_else(|| vec![root]); - let opts = params + let server_config: ServerConfig = params .initialization_options .and_then(|v| { - ServerConfig::deserialize(v) - .map_err(|e| log::error!("failed to deserialize config: {}", e)) + serde_json::from_value(v) + .map_err(|e| { + log::error!("failed to deserialize config: {}", e); + show_message( + lsp_types::MessageType::Error, + format!("failed to deserialize config: {}", e), + s, + ); + }) .ok() }) .unwrap_or_default(); - ra_lsp_server::main_loop(workspace_roots, params.capabilities, opts, r, s) + + ra_lsp_server::main_loop(workspace_roots, params.capabilities, server_config, r, s) })?; log::info!("shutting down IO..."); threads.join()?; diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index fcb782386..c0395c6d8 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -617,7 +617,11 @@ fn update_file_notifications_on_threadpool( }); } -fn show_message(typ: req::MessageType, message: impl Into, sender: &Sender) { +pub fn show_message( + typ: req::MessageType, + message: impl Into, + sender: &Sender, +) { let message = message.into(); let params = req::ShowMessageParams { typ, message }; let not = RawNotification::new::(¶ms); -- cgit v1.2.3 From 69bbe79c5037eb3cd00744593d1836e45a6f56e1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 22 Aug 2019 14:44:16 +0300 Subject: implement feature flags --- crates/ra_lsp_server/src/config.rs | 13 +++++------ crates/ra_lsp_server/src/main_loop.rs | 42 +++++++++++++++++++++++++---------- crates/ra_lsp_server/src/world.rs | 15 ++++++++++--- 3 files changed, 48 insertions(+), 22 deletions(-) (limited to 'crates/ra_lsp_server') diff --git a/crates/ra_lsp_server/src/config.rs b/crates/ra_lsp_server/src/config.rs index 71838b89c..5c5ae3e18 100644 --- a/crates/ra_lsp_server/src/config.rs +++ b/crates/ra_lsp_server/src/config.rs @@ -1,3 +1,5 @@ +use rustc_hash::FxHashMap; + use serde::{Deserialize, Deserializer}; /// Client provided initialization options @@ -12,12 +14,6 @@ pub struct ServerConfig { #[serde(deserialize_with = "nullable_bool_false")] pub publish_decorations: bool, - /// Whether or not the workspace loaded notification should be sent - /// - /// Defaults to `true` - #[serde(deserialize_with = "nullable_bool_true")] - pub show_workspace_loaded: bool, - pub exclude_globs: Vec, pub lru_capacity: Option, @@ -25,16 +21,19 @@ pub struct ServerConfig { /// For internal usage to make integrated tests faster. #[serde(deserialize_with = "nullable_bool_true")] pub with_sysroot: bool, + + /// Fine grained feature flags to disable specific features. + pub feature_flags: FxHashMap, } impl Default for ServerConfig { fn default() -> ServerConfig { ServerConfig { publish_decorations: false, - show_workspace_loaded: true, exclude_globs: Vec::new(), lru_capacity: None, with_sysroot: true, + feature_flags: FxHashMap::default(), } } } diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index c0395c6d8..ce25ff162 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -9,7 +9,7 @@ use gen_lsp_server::{ handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, }; use lsp_types::{ClientCapabilities, NumberOrString}; -use ra_ide_api::{Canceled, FileId, LibraryData}; +use ra_ide_api::{Canceled, FeatureFlags, FileId, LibraryData}; use ra_prof::profile; use ra_vfs::VfsTask; use serde::{de::DeserializeOwned, Serialize}; @@ -56,7 +56,7 @@ pub fn main_loop( msg_receiver: &Receiver, msg_sender: &Sender, ) -> Result<()> { - log::debug!("server_config: {:?}", config); + log::info!("server_config: {:#?}", config); // FIXME: support dynamic workspace loading. let workspaces = { let ws_worker = workspace_loader(config.with_sysroot); @@ -83,6 +83,21 @@ pub fn main_loop( .iter() .map(|glob| ra_vfs_glob::Glob::new(glob)) .collect::, _>>()?; + let feature_flags = { + let mut ff = FeatureFlags::default(); + for (flag, value) in config.feature_flags { + if let Err(_) = ff.set(flag.as_str(), value) { + log::error!("unknown feature flag: {:?}", flag); + show_message( + req::MessageType::Error, + format!("unknown feature flag: {:?}", flag), + msg_sender, + ); + } + } + ff + }; + log::info!("feature_flags: {:#?}", feature_flags); let mut state = WorldState::new( ws_roots, workspaces, @@ -90,13 +105,13 @@ pub fn main_loop( &globs, Options { publish_decorations: config.publish_decorations, - show_workspace_loaded: config.show_workspace_loaded, supports_location_link: client_caps .text_document .and_then(|it| it.definition) .and_then(|it| it.link_support) .unwrap_or(false), }, + feature_flags, ); let pool = ThreadPool::new(THREADPOOL_SIZE); @@ -276,7 +291,7 @@ fn main_loop_inner( && in_flight_libraries == 0 { let n_packages: usize = state.workspaces.iter().map(|it| it.n_packages()).sum(); - if state.options.show_workspace_loaded { + if state.feature_flags().get("notifications.workspace-loaded") { let msg = format!("workspace loaded, {} rust packages", n_packages); show_message(req::MessageType::Info, msg, msg_sender); } @@ -587,17 +602,20 @@ fn update_file_notifications_on_threadpool( subscriptions: Vec, ) { log::trace!("updating notifications for {:?}", subscriptions); + let publish_diagnostics = world.feature_flags().get("lsp.diagnostics"); pool.execute(move || { for file_id in subscriptions { - match handlers::publish_diagnostics(&world, file_id) { - Err(e) => { - if !is_canceled(&e) { - log::error!("failed to compute diagnostics: {:?}", e); + if publish_diagnostics { + match handlers::publish_diagnostics(&world, file_id) { + Err(e) => { + if !is_canceled(&e) { + log::error!("failed to compute diagnostics: {:?}", e); + } + } + Ok(params) => { + let not = RawNotification::new::(¶ms); + sender.send(Task::Notify(not)).unwrap(); } - } - Ok(params) => { - let not = RawNotification::new::(¶ms); - sender.send(Task::Notify(not)).unwrap(); } } if publish_decorations { diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index 10f96812f..6696dff71 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs @@ -7,7 +7,8 @@ use gen_lsp_server::ErrorCode; use lsp_types::Url; use parking_lot::RwLock; use ra_ide_api::{ - Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, + Analysis, AnalysisChange, AnalysisHost, CrateGraph, FeatureFlags, FileId, LibraryData, + SourceRootId, }; use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot}; use ra_vfs_glob::{Glob, RustPackageFilterBuilder}; @@ -22,7 +23,6 @@ use crate::{ #[derive(Debug, Clone)] pub struct Options { pub publish_decorations: bool, - pub show_workspace_loaded: bool, pub supports_location_link: bool, } @@ -58,6 +58,7 @@ impl WorldState { lru_capacity: Option, exclude_globs: &[Glob], options: Options, + feature_flags: FeatureFlags, ) -> WorldState { let mut change = AnalysisChange::new(); @@ -99,7 +100,7 @@ impl WorldState { } change.set_crate_graph(crate_graph); - let mut analysis_host = AnalysisHost::new(lru_capacity); + let mut analysis_host = AnalysisHost::new(lru_capacity, feature_flags); analysis_host.apply_change(change); WorldState { options, @@ -184,6 +185,10 @@ impl WorldState { pub fn complete_request(&mut self, request: CompletedRequest) { self.latest_requests.write().record(request) } + + pub fn feature_flags(&self) -> &FeatureFlags { + self.analysis_host.feature_flags() + } } impl WorldSnapshot { @@ -246,4 +251,8 @@ impl WorldSnapshot { let path = self.vfs.read().file2path(VfsFile(file_id.0)); self.workspaces.iter().find_map(|ws| ws.workspace_root_for(&path)) } + + pub fn feature_flags(&self) -> &FeatureFlags { + self.analysis.feature_flags() + } } -- cgit v1.2.3