aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r--crates/ra_lsp_server/src/config.rs13
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs42
-rw-r--r--crates/ra_lsp_server/src/world.rs15
3 files changed, 48 insertions, 22 deletions
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 @@
1use rustc_hash::FxHashMap;
2
1use serde::{Deserialize, Deserializer}; 3use serde::{Deserialize, Deserializer};
2 4
3/// Client provided initialization options 5/// Client provided initialization options
@@ -12,12 +14,6 @@ pub struct ServerConfig {
12 #[serde(deserialize_with = "nullable_bool_false")] 14 #[serde(deserialize_with = "nullable_bool_false")]
13 pub publish_decorations: bool, 15 pub publish_decorations: bool,
14 16
15 /// Whether or not the workspace loaded notification should be sent
16 ///
17 /// Defaults to `true`
18 #[serde(deserialize_with = "nullable_bool_true")]
19 pub show_workspace_loaded: bool,
20
21 pub exclude_globs: Vec<String>, 17 pub exclude_globs: Vec<String>,
22 18
23 pub lru_capacity: Option<usize>, 19 pub lru_capacity: Option<usize>,
@@ -25,16 +21,19 @@ pub struct ServerConfig {
25 /// For internal usage to make integrated tests faster. 21 /// For internal usage to make integrated tests faster.
26 #[serde(deserialize_with = "nullable_bool_true")] 22 #[serde(deserialize_with = "nullable_bool_true")]
27 pub with_sysroot: bool, 23 pub with_sysroot: bool,
24
25 /// Fine grained feature flags to disable specific features.
26 pub feature_flags: FxHashMap<String, bool>,
28} 27}
29 28
30impl Default for ServerConfig { 29impl Default for ServerConfig {
31 fn default() -> ServerConfig { 30 fn default() -> ServerConfig {
32 ServerConfig { 31 ServerConfig {
33 publish_decorations: false, 32 publish_decorations: false,
34 show_workspace_loaded: true,
35 exclude_globs: Vec::new(), 33 exclude_globs: Vec::new(),
36 lru_capacity: None, 34 lru_capacity: None,
37 with_sysroot: true, 35 with_sysroot: true,
36 feature_flags: FxHashMap::default(),
38 } 37 }
39 } 38 }
40} 39}
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::{
9 handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, 9 handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse,
10}; 10};
11use lsp_types::{ClientCapabilities, NumberOrString}; 11use lsp_types::{ClientCapabilities, NumberOrString};
12use ra_ide_api::{Canceled, FileId, LibraryData}; 12use ra_ide_api::{Canceled, FeatureFlags, FileId, LibraryData};
13use ra_prof::profile; 13use ra_prof::profile;
14use ra_vfs::VfsTask; 14use ra_vfs::VfsTask;
15use serde::{de::DeserializeOwned, Serialize}; 15use serde::{de::DeserializeOwned, Serialize};
@@ -56,7 +56,7 @@ pub fn main_loop(
56 msg_receiver: &Receiver<RawMessage>, 56 msg_receiver: &Receiver<RawMessage>,
57 msg_sender: &Sender<RawMessage>, 57 msg_sender: &Sender<RawMessage>,
58) -> Result<()> { 58) -> Result<()> {
59 log::debug!("server_config: {:?}", config); 59 log::info!("server_config: {:#?}", config);
60 // FIXME: support dynamic workspace loading. 60 // FIXME: support dynamic workspace loading.
61 let workspaces = { 61 let workspaces = {
62 let ws_worker = workspace_loader(config.with_sysroot); 62 let ws_worker = workspace_loader(config.with_sysroot);
@@ -83,6 +83,21 @@ pub fn main_loop(
83 .iter() 83 .iter()
84 .map(|glob| ra_vfs_glob::Glob::new(glob)) 84 .map(|glob| ra_vfs_glob::Glob::new(glob))
85 .collect::<std::result::Result<Vec<_>, _>>()?; 85 .collect::<std::result::Result<Vec<_>, _>>()?;
86 let feature_flags = {
87 let mut ff = FeatureFlags::default();
88 for (flag, value) in config.feature_flags {
89 if let Err(_) = ff.set(flag.as_str(), value) {
90 log::error!("unknown feature flag: {:?}", flag);
91 show_message(
92 req::MessageType::Error,
93 format!("unknown feature flag: {:?}", flag),
94 msg_sender,
95 );
96 }
97 }
98 ff
99 };
100 log::info!("feature_flags: {:#?}", feature_flags);
86 let mut state = WorldState::new( 101 let mut state = WorldState::new(
87 ws_roots, 102 ws_roots,
88 workspaces, 103 workspaces,
@@ -90,13 +105,13 @@ pub fn main_loop(
90 &globs, 105 &globs,
91 Options { 106 Options {
92 publish_decorations: config.publish_decorations, 107 publish_decorations: config.publish_decorations,
93 show_workspace_loaded: config.show_workspace_loaded,
94 supports_location_link: client_caps 108 supports_location_link: client_caps
95 .text_document 109 .text_document
96 .and_then(|it| it.definition) 110 .and_then(|it| it.definition)
97 .and_then(|it| it.link_support) 111 .and_then(|it| it.link_support)
98 .unwrap_or(false), 112 .unwrap_or(false),
99 }, 113 },
114 feature_flags,
100 ); 115 );
101 116
102 let pool = ThreadPool::new(THREADPOOL_SIZE); 117 let pool = ThreadPool::new(THREADPOOL_SIZE);
@@ -276,7 +291,7 @@ fn main_loop_inner(
276 && in_flight_libraries == 0 291 && in_flight_libraries == 0
277 { 292 {
278 let n_packages: usize = state.workspaces.iter().map(|it| it.n_packages()).sum(); 293 let n_packages: usize = state.workspaces.iter().map(|it| it.n_packages()).sum();
279 if state.options.show_workspace_loaded { 294 if state.feature_flags().get("notifications.workspace-loaded") {
280 let msg = format!("workspace loaded, {} rust packages", n_packages); 295 let msg = format!("workspace loaded, {} rust packages", n_packages);
281 show_message(req::MessageType::Info, msg, msg_sender); 296 show_message(req::MessageType::Info, msg, msg_sender);
282 } 297 }
@@ -587,17 +602,20 @@ fn update_file_notifications_on_threadpool(
587 subscriptions: Vec<FileId>, 602 subscriptions: Vec<FileId>,
588) { 603) {
589 log::trace!("updating notifications for {:?}", subscriptions); 604 log::trace!("updating notifications for {:?}", subscriptions);
605 let publish_diagnostics = world.feature_flags().get("lsp.diagnostics");
590 pool.execute(move || { 606 pool.execute(move || {
591 for file_id in subscriptions { 607 for file_id in subscriptions {
592 match handlers::publish_diagnostics(&world, file_id) { 608 if publish_diagnostics {
593 Err(e) => { 609 match handlers::publish_diagnostics(&world, file_id) {
594 if !is_canceled(&e) { 610 Err(e) => {
595 log::error!("failed to compute diagnostics: {:?}", e); 611 if !is_canceled(&e) {
612 log::error!("failed to compute diagnostics: {:?}", e);
613 }
614 }
615 Ok(params) => {
616 let not = RawNotification::new::<req::PublishDiagnostics>(&params);
617 sender.send(Task::Notify(not)).unwrap();
596 } 618 }
597 }
598 Ok(params) => {
599 let not = RawNotification::new::<req::PublishDiagnostics>(&params);
600 sender.send(Task::Notify(not)).unwrap();
601 } 619 }
602 } 620 }
603 if publish_decorations { 621 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;
7use lsp_types::Url; 7use lsp_types::Url;
8use parking_lot::RwLock; 8use parking_lot::RwLock;
9use ra_ide_api::{ 9use ra_ide_api::{
10 Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId, 10 Analysis, AnalysisChange, AnalysisHost, CrateGraph, FeatureFlags, FileId, LibraryData,
11 SourceRootId,
11}; 12};
12use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot}; 13use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot};
13use ra_vfs_glob::{Glob, RustPackageFilterBuilder}; 14use ra_vfs_glob::{Glob, RustPackageFilterBuilder};
@@ -22,7 +23,6 @@ use crate::{
22#[derive(Debug, Clone)] 23#[derive(Debug, Clone)]
23pub struct Options { 24pub struct Options {
24 pub publish_decorations: bool, 25 pub publish_decorations: bool,
25 pub show_workspace_loaded: bool,
26 pub supports_location_link: bool, 26 pub supports_location_link: bool,
27} 27}
28 28
@@ -58,6 +58,7 @@ impl WorldState {
58 lru_capacity: Option<usize>, 58 lru_capacity: Option<usize>,
59 exclude_globs: &[Glob], 59 exclude_globs: &[Glob],
60 options: Options, 60 options: Options,
61 feature_flags: FeatureFlags,
61 ) -> WorldState { 62 ) -> WorldState {
62 let mut change = AnalysisChange::new(); 63 let mut change = AnalysisChange::new();
63 64
@@ -99,7 +100,7 @@ impl WorldState {
99 } 100 }
100 change.set_crate_graph(crate_graph); 101 change.set_crate_graph(crate_graph);
101 102
102 let mut analysis_host = AnalysisHost::new(lru_capacity); 103 let mut analysis_host = AnalysisHost::new(lru_capacity, feature_flags);
103 analysis_host.apply_change(change); 104 analysis_host.apply_change(change);
104 WorldState { 105 WorldState {
105 options, 106 options,
@@ -184,6 +185,10 @@ impl WorldState {
184 pub fn complete_request(&mut self, request: CompletedRequest) { 185 pub fn complete_request(&mut self, request: CompletedRequest) {
185 self.latest_requests.write().record(request) 186 self.latest_requests.write().record(request)
186 } 187 }
188
189 pub fn feature_flags(&self) -> &FeatureFlags {
190 self.analysis_host.feature_flags()
191 }
187} 192}
188 193
189impl WorldSnapshot { 194impl WorldSnapshot {
@@ -246,4 +251,8 @@ impl WorldSnapshot {
246 let path = self.vfs.read().file2path(VfsFile(file_id.0)); 251 let path = self.vfs.read().file2path(VfsFile(file_id.0));
247 self.workspaces.iter().find_map(|ws| ws.workspace_root_for(&path)) 252 self.workspaces.iter().find_map(|ws| ws.workspace_root_for(&path))
248 } 253 }
254
255 pub fn feature_flags(&self) -> &FeatureFlags {
256 self.analysis.feature_flags()
257 }
249} 258}