From e075e096cf4970014d2c0829476fd7a45a3f32b1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 8 Jul 2019 14:09:38 +0300 Subject: don't send LocationLink unless the client opts-in closes #1474 --- crates/ra_lsp_server/src/conv.rs | 10 ++++++++- crates/ra_lsp_server/src/main.rs | 2 +- crates/ra_lsp_server/src/main_loop.rs | 26 +++++++++++++++++------ crates/ra_lsp_server/src/world.rs | 12 +++++++++++ crates/ra_lsp_server/tests/heavy_tests/support.rs | 24 ++++++++++++++++++--- 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index d0bdc94aa..82c7e757f 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs @@ -421,7 +421,15 @@ impl TryConvWith for (FileId, RangeInfo>) { .into_iter() .map(|nav| (file_id, RangeInfo::new(range, nav))) .try_conv_with_to_vec(world)?; - Ok(links.into()) + if world.options.supports_location_link { + Ok(links.into()) + } else { + let locations: Vec = links + .into_iter() + .map(|link| Location { uri: link.target_uri, range: link.target_selection_range }) + .collect(); + Ok(locations.into()) + } } } diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index 6aa6dd49f..c1f8243be 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs @@ -51,7 +51,7 @@ fn main_inner() -> Result<()> { .and_then(|v| InitializationOptions::deserialize(v).ok()) .unwrap_or_default(); - ra_lsp_server::main_loop(workspace_roots, opts, r, s) + ra_lsp_server::main_loop(workspace_roots, params.capabilities, opts, 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 c44fc6603..f7becd8fb 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -8,7 +8,7 @@ use crossbeam_channel::{select, unbounded, Receiver, RecvError, Sender}; use gen_lsp_server::{ handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, }; -use lsp_types::NumberOrString; +use lsp_types::{ClientCapabilities, NumberOrString}; use ra_ide_api::{Canceled, FileId, LibraryData}; use ra_prof::profile; use ra_vfs::VfsTask; @@ -22,7 +22,7 @@ use crate::{ }, project_model::workspace_loader, req, - world::{WorldSnapshot, WorldState}, + world::{Options, WorldSnapshot, WorldState}, InitializationOptions, Result, }; @@ -51,6 +51,7 @@ impl Error for LspError {} pub fn main_loop( ws_roots: Vec, + client_caps: ClientCapabilities, options: InitializationOptions, msg_receiver: &Receiver, msg_sender: &Sender, @@ -77,7 +78,20 @@ pub fn main_loop( loaded_workspaces }; - let mut state = WorldState::new(ws_roots, workspaces, options.lru_capacity); + let mut state = WorldState::new( + ws_roots, + workspaces, + options.lru_capacity, + Options { + publish_decorations: options.publish_decorations, + show_workspace_loaded: options.show_workspace_loaded, + supports_location_link: client_caps + .text_document + .and_then(|it| it.definition) + .and_then(|it| it.link_support) + .unwrap_or(false), + }, + ); let pool = ThreadPool::new(THREADPOOL_SIZE); let (task_sender, task_receiver) = unbounded::(); @@ -85,7 +99,6 @@ pub fn main_loop( log::info!("server initialized, serving requests"); let main_res = main_loop_inner( - options, &pool, msg_sender, msg_receiver, @@ -159,7 +172,6 @@ impl fmt::Debug for Event { } fn main_loop_inner( - options: InitializationOptions, pool: &ThreadPool, msg_sender: &Sender, msg_receiver: &Receiver, @@ -258,7 +270,7 @@ fn main_loop_inner( && in_flight_libraries == 0 { let n_packages: usize = state.workspaces.iter().map(|it| it.count()).sum(); - if options.show_workspace_loaded { + if state.options.show_workspace_loaded { let msg = format!("workspace loaded, {} rust packages", n_packages); show_message(req::MessageType::Info, msg, msg_sender); } @@ -270,7 +282,7 @@ fn main_loop_inner( update_file_notifications_on_threadpool( pool, state.snapshot(), - options.publish_decorations, + state.options.publish_decorations, task_sender.clone(), subs.subscriptions(), ) diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index fdc577622..9fd654305 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs @@ -19,6 +19,13 @@ use crate::{ LspError, Result, }; +#[derive(Debug, Clone)] +pub struct Options { + pub publish_decorations: bool, + pub show_workspace_loaded: bool, + pub supports_location_link: bool, +} + /// `WorldState` is the primary mutable state of the language server /// /// The most interesting components are `vfs`, which stores a consistent @@ -26,6 +33,7 @@ use crate::{ /// incremental salsa database. #[derive(Debug)] pub struct WorldState { + pub options: Options, pub roots_to_scan: usize, pub roots: Vec, pub workspaces: Arc>, @@ -36,6 +44,7 @@ pub struct WorldState { /// An immutable snapshot of the world's state at a point in time. pub struct WorldSnapshot { + pub options: Options, pub workspaces: Arc>, pub analysis: Analysis, pub vfs: Arc>, @@ -47,6 +56,7 @@ impl WorldState { folder_roots: Vec, workspaces: Vec, lru_capacity: Option, + options: Options, ) -> WorldState { let mut change = AnalysisChange::new(); @@ -78,6 +88,7 @@ impl WorldState { let mut analysis_host = AnalysisHost::new(lru_capacity); analysis_host.apply_change(change); WorldState { + options, roots_to_scan, roots: folder_roots, workspaces: Arc::new(workspaces), @@ -140,6 +151,7 @@ impl WorldState { pub fn snapshot(&self) -> WorldSnapshot { WorldSnapshot { + options: self.options.clone(), workspaces: Arc::clone(&self.workspaces), analysis: self.analysis_host.analysis(), vfs: Arc::clone(&self.vfs), diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index a5e352da1..5dddbbe17 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs @@ -13,7 +13,8 @@ use lsp_types::{ notification::DidOpenTextDocument, notification::{Notification, ShowMessage}, request::{Request, Shutdown}, - DidOpenTextDocumentParams, TextDocumentIdentifier, TextDocumentItem, Url, + ClientCapabilities, DidOpenTextDocumentParams, GotoCapability, TextDocumentClientCapabilities, + TextDocumentIdentifier, TextDocumentItem, Url, }; use serde::Serialize; use serde_json::{to_string_pretty, Value}; @@ -92,8 +93,25 @@ impl Server { "test server", 128, move |msg_receiver, msg_sender| { - main_loop(roots, InitializationOptions::default(), &msg_receiver, &msg_sender) - .unwrap() + main_loop( + roots, + ClientCapabilities { + workspace: None, + text_document: Some(TextDocumentClientCapabilities { + definition: Some(GotoCapability { + dynamic_registration: None, + link_support: Some(true), + }), + ..Default::default() + }), + window: None, + experimental: None, + }, + InitializationOptions::default(), + &msg_receiver, + &msg_sender, + ) + .unwrap() }, ); let res = Server { req_id: Cell::new(1), dir, messages: Default::default(), worker }; -- cgit v1.2.3