diff --git a/crates/ra_lsp_server/src/cargo_target_spec.rs b/crates/ra_lsp_server/src/cargo_target_spec.rs index cdf2ec10b6..7423611555 100644 --- a/crates/ra_lsp_server/src/cargo_target_spec.rs +++ b/crates/ra_lsp_server/src/cargo_target_spec.rs @@ -1,13 +1,13 @@ use crate::{ project_model::{self, TargetKind}, - server_world::ServerWorld, + world::WorldSnapshot, Result }; use ra_ide_api::{FileId, RunnableKind}; pub(crate) fn runnable_args( - world: &ServerWorld, + world: &WorldSnapshot, file_id: FileId, kind: &RunnableKind, ) -> Result> { @@ -58,7 +58,7 @@ pub struct CargoTargetSpec { } impl CargoTargetSpec { - pub fn for_file(world: &ServerWorld, file_id: FileId) -> Result> { + pub fn for_file(world: &WorldSnapshot, file_id: FileId) -> Result> { let &crate_id = match world.analysis().crate_for(file_id)?.first() { Some(crate_id) => crate_id, None => return Ok(None), diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 1b349d02a4..88d29b2563 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs @@ -12,7 +12,7 @@ use ra_ide_api::{ use ra_syntax::{SyntaxKind, TextRange, TextUnit}; use ra_text_edit::{AtomTextEdit, TextEdit}; -use crate::{req, server_world::ServerWorld, Result}; +use crate::{req, world::WorldSnapshot, Result}; pub trait Conv { type Output; @@ -228,49 +228,49 @@ impl ConvWith for Option { } impl<'a> TryConvWith for &'a Url { - type Ctx = ServerWorld; + type Ctx = WorldSnapshot; type Output = FileId; - fn try_conv_with(self, world: &ServerWorld) -> Result { + fn try_conv_with(self, world: &WorldSnapshot) -> Result { world.uri_to_file_id(self) } } impl TryConvWith for FileId { - type Ctx = ServerWorld; + type Ctx = WorldSnapshot; type Output = Url; - fn try_conv_with(self, world: &ServerWorld) -> Result { + fn try_conv_with(self, world: &WorldSnapshot) -> Result { world.file_id_to_uri(self) } } impl<'a> TryConvWith for &'a TextDocumentItem { - type Ctx = ServerWorld; + type Ctx = WorldSnapshot; type Output = FileId; - fn try_conv_with(self, world: &ServerWorld) -> Result { + fn try_conv_with(self, world: &WorldSnapshot) -> Result { self.uri.try_conv_with(world) } } impl<'a> TryConvWith for &'a VersionedTextDocumentIdentifier { - type Ctx = ServerWorld; + type Ctx = WorldSnapshot; type Output = FileId; - fn try_conv_with(self, world: &ServerWorld) -> Result { + fn try_conv_with(self, world: &WorldSnapshot) -> Result { self.uri.try_conv_with(world) } } impl<'a> TryConvWith for &'a TextDocumentIdentifier { - type Ctx = ServerWorld; + type Ctx = WorldSnapshot; type Output = FileId; - fn try_conv_with(self, world: &ServerWorld) -> Result { + fn try_conv_with(self, world: &WorldSnapshot) -> Result { world.uri_to_file_id(&self.uri) } } impl<'a> TryConvWith for &'a TextDocumentPositionParams { - type Ctx = ServerWorld; + type Ctx = WorldSnapshot; type Output = FilePosition; - fn try_conv_with(self, world: &ServerWorld) -> Result { + fn try_conv_with(self, world: &WorldSnapshot) -> Result { let file_id = self.text_document.try_conv_with(world)?; let line_index = world.analysis().file_line_index(file_id); let offset = self.position.conv_with(&line_index); @@ -279,9 +279,9 @@ impl<'a> TryConvWith for &'a TextDocumentPositionParams { } impl<'a> TryConvWith for (&'a TextDocumentIdentifier, Range) { - type Ctx = ServerWorld; + type Ctx = WorldSnapshot; type Output = FileRange; - fn try_conv_with(self, world: &ServerWorld) -> Result { + fn try_conv_with(self, world: &WorldSnapshot) -> Result { let file_id = self.0.try_conv_with(world)?; let line_index = world.analysis().file_line_index(file_id); let range = self.1.conv_with(&line_index); @@ -302,9 +302,9 @@ impl TryConvWith for Vec { } impl TryConvWith for SourceChange { - type Ctx = ServerWorld; + type Ctx = WorldSnapshot; type Output = req::SourceChange; - fn try_conv_with(self, world: &ServerWorld) -> Result { + fn try_conv_with(self, world: &WorldSnapshot) -> Result { let cursor_position = match self.cursor_position { None => None, Some(pos) => { @@ -342,9 +342,9 @@ impl TryConvWith for SourceChange { } impl TryConvWith for SourceFileEdit { - type Ctx = ServerWorld; + type Ctx = WorldSnapshot; type Output = TextDocumentEdit; - fn try_conv_with(self, world: &ServerWorld) -> Result { + fn try_conv_with(self, world: &WorldSnapshot) -> Result { let text_document = VersionedTextDocumentIdentifier { uri: self.file_id.try_conv_with(world)?, version: None, @@ -356,9 +356,9 @@ impl TryConvWith for SourceFileEdit { } impl TryConvWith for FileSystemEdit { - type Ctx = ServerWorld; + type Ctx = WorldSnapshot; type Output = ResourceOp; - fn try_conv_with(self, world: &ServerWorld) -> Result { + fn try_conv_with(self, world: &WorldSnapshot) -> Result { let res = match self { FileSystemEdit::CreateFile { source_root, path } => { let uri = world.path_to_uri(source_root, &path)?; @@ -375,9 +375,9 @@ impl TryConvWith for FileSystemEdit { } impl TryConvWith for &NavigationTarget { - type Ctx = ServerWorld; + type Ctx = WorldSnapshot; type Output = Location; - fn try_conv_with(self, world: &ServerWorld) -> Result { + fn try_conv_with(self, world: &WorldSnapshot) -> Result { let line_index = world.analysis().file_line_index(self.file_id()); let range = self.range(); to_location(self.file_id(), range, &world, &line_index) @@ -386,7 +386,7 @@ impl TryConvWith for &NavigationTarget { pub fn to_location_link( target: &RangeInfo, - world: &ServerWorld, + world: &WorldSnapshot, // line index for original range file line_index: &LineIndex, ) -> Result { @@ -410,7 +410,7 @@ pub fn to_location_link( pub fn to_location( file_id: FileId, range: TextRange, - world: &ServerWorld, + world: &WorldSnapshot, line_index: &LineIndex, ) -> Result { let url = file_id.try_conv_with(world)?; diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs index 113883bdde..aabde420b4 100644 --- a/crates/ra_lsp_server/src/lib.rs +++ b/crates/ra_lsp_server/src/lib.rs @@ -7,7 +7,7 @@ mod project_model; mod vfs_filter; pub mod req; pub mod init; -mod server_world; +mod world; pub type Result = ::std::result::Result; pub use crate::{caps::server_capabilities, main_loop::main_loop, main_loop::LspError, init::InitializationOptions}; diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index e6a7dc6417..6080a3a4e6 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs @@ -24,7 +24,7 @@ use crate::{ }, project_model::workspace_loader, req, - server_world::{ServerWorld, ServerWorldState}, + world::{WorldSnapshot, WorldState}, Result, InitializationOptions, }; @@ -73,7 +73,7 @@ pub fn main_loop( loaded_workspaces }; - let mut state = ServerWorldState::new(ws_roots, workspaces); + let mut state = WorldState::new(ws_roots, workspaces); let pool = ThreadPool::new(THREADPOOL_SIZE); let (task_sender, task_receiver) = unbounded::(); @@ -161,7 +161,7 @@ fn main_loop_inner( msg_receiver: &Receiver, task_sender: Sender, task_receiver: Receiver, - state: &mut ServerWorldState, + state: &mut WorldState, pending_requests: &mut PendingRequests, ) -> Result<()> { let mut subs = Subscriptions::default(); @@ -278,7 +278,7 @@ fn on_task( task: Task, msg_sender: &Sender, pending_requests: &mut PendingRequests, - state: &mut ServerWorldState, + state: &mut WorldState, ) { match task { Task::Respond(response) => { @@ -295,7 +295,7 @@ fn on_task( } fn on_request( - world: &mut ServerWorldState, + world: &mut WorldState, pending_requests: &mut PendingRequests, pool: &ThreadPool, sender: &Sender, @@ -352,7 +352,7 @@ fn on_request( fn on_notification( msg_sender: &Sender, - state: &mut ServerWorldState, + state: &mut WorldState, pending_requests: &mut PendingRequests, subs: &mut Subscriptions, not: RawNotification, @@ -422,7 +422,7 @@ fn on_notification( struct PoolDispatcher<'a> { req: Option, pool: &'a ThreadPool, - world: &'a mut ServerWorldState, + world: &'a mut WorldState, pending_requests: &'a mut PendingRequests, msg_sender: &'a Sender, sender: &'a Sender, @@ -433,7 +433,7 @@ impl<'a> PoolDispatcher<'a> { /// Dispatches the request onto the current thread fn on_sync( &mut self, - f: fn(&mut ServerWorldState, R::Params) -> Result, + f: fn(&mut WorldState, R::Params) -> Result, ) -> Result<&mut Self> where R: req::Request + 'static, @@ -453,7 +453,7 @@ impl<'a> PoolDispatcher<'a> { } /// Dispatches the request onto thread pool - fn on(&mut self, f: fn(ServerWorld, R::Params) -> Result) -> Result<&mut Self> + fn on(&mut self, f: fn(WorldSnapshot, R::Params) -> Result) -> Result<&mut Self> where R: req::Request + 'static, R::Params: DeserializeOwned + Send + 'static, @@ -557,7 +557,7 @@ where fn update_file_notifications_on_threadpool( pool: &ThreadPool, - world: ServerWorld, + world: WorldSnapshot, publish_decorations: bool, sender: Sender, subscriptions: Vec, diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 8cfb6a1925..6373240d5f 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -24,11 +24,11 @@ use crate::{ cargo_target_spec::{runnable_args, CargoTargetSpec}, conv::{to_location, to_location_link, Conv, ConvWith, MapConvWith, TryConvWith}, req::{self, Decoration}, - server_world::ServerWorld, + world::WorldSnapshot, LspError, Result, }; -pub fn handle_analyzer_status(world: ServerWorld, _: ()) -> Result { +pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result { let mut buf = world.status(); writeln!(buf, "\n\nrequests:").unwrap(); let requests = world.latest_requests.read(); @@ -39,7 +39,7 @@ pub fn handle_analyzer_status(world: ServerWorld, _: ()) -> Result { Ok(buf) } -pub fn handle_syntax_tree(world: ServerWorld, params: req::SyntaxTreeParams) -> Result { +pub fn handle_syntax_tree(world: WorldSnapshot, params: req::SyntaxTreeParams) -> Result { let id = params.text_document.try_conv_with(&world)?; let line_index = world.analysis().file_line_index(id); let text_range = params.range.map(|p| p.conv_with(&line_index)); @@ -49,7 +49,7 @@ pub fn handle_syntax_tree(world: ServerWorld, params: req::SyntaxTreeParams) -> // FIXME: drop this API pub fn handle_extend_selection( - world: ServerWorld, + world: WorldSnapshot, params: req::ExtendSelectionParams, ) -> Result { log::error!( @@ -69,7 +69,7 @@ pub fn handle_extend_selection( } pub fn handle_selection_range( - world: ServerWorld, + world: WorldSnapshot, params: req::SelectionRangeParams, ) -> Result> { let _p = profile("handle_selection_range"); @@ -110,7 +110,7 @@ pub fn handle_selection_range( } pub fn handle_find_matching_brace( - world: ServerWorld, + world: WorldSnapshot, params: req::FindMatchingBraceParams, ) -> Result> { let _p = profile("handle_find_matching_brace"); @@ -129,7 +129,7 @@ pub fn handle_find_matching_brace( } pub fn handle_join_lines( - world: ServerWorld, + world: WorldSnapshot, params: req::JoinLinesParams, ) -> Result { let _p = profile("handle_join_lines"); @@ -138,7 +138,7 @@ pub fn handle_join_lines( } pub fn handle_on_enter( - world: ServerWorld, + world: WorldSnapshot, params: req::TextDocumentPositionParams, ) -> Result> { let _p = profile("handle_on_enter"); @@ -150,7 +150,7 @@ pub fn handle_on_enter( } pub fn handle_on_type_formatting( - world: ServerWorld, + world: WorldSnapshot, params: req::DocumentOnTypeFormattingParams, ) -> Result>> { let _p = profile("handle_on_type_formatting"); @@ -181,7 +181,7 @@ pub fn handle_on_type_formatting( } pub fn handle_document_symbol( - world: ServerWorld, + world: WorldSnapshot, params: req::DocumentSymbolParams, ) -> Result> { let file_id = params.text_document.try_conv_with(&world)?; @@ -219,7 +219,7 @@ pub fn handle_document_symbol( } pub fn handle_workspace_symbol( - world: ServerWorld, + world: WorldSnapshot, params: req::WorkspaceSymbolParams, ) -> Result>> { let all_symbols = params.query.contains('#'); @@ -245,7 +245,7 @@ pub fn handle_workspace_symbol( return Ok(Some(res)); - fn exec_query(world: &ServerWorld, query: Query) -> Result> { + fn exec_query(world: &WorldSnapshot, query: Query) -> Result> { let mut res = Vec::new(); for nav in world.analysis().symbol_search(query)? { let info = SymbolInformation { @@ -262,7 +262,7 @@ pub fn handle_workspace_symbol( } pub fn handle_goto_definition( - world: ServerWorld, + world: WorldSnapshot, params: req::TextDocumentPositionParams, ) -> Result> { let position = params.try_conv_with(&world)?; @@ -282,7 +282,7 @@ pub fn handle_goto_definition( } pub fn handle_goto_implementation( - world: ServerWorld, + world: WorldSnapshot, params: req::TextDocumentPositionParams, ) -> Result> { let position = params.try_conv_with(&world)?; @@ -302,7 +302,7 @@ pub fn handle_goto_implementation( } pub fn handle_goto_type_definition( - world: ServerWorld, + world: WorldSnapshot, params: req::TextDocumentPositionParams, ) -> Result> { let position = params.try_conv_with(&world)?; @@ -322,7 +322,7 @@ pub fn handle_goto_type_definition( } pub fn handle_parent_module( - world: ServerWorld, + world: WorldSnapshot, params: req::TextDocumentPositionParams, ) -> Result> { let position = params.try_conv_with(&world)?; @@ -335,7 +335,7 @@ pub fn handle_parent_module( } pub fn handle_runnables( - world: ServerWorld, + world: WorldSnapshot, params: req::RunnablesParams, ) -> Result> { let file_id = params.text_document.try_conv_with(&world)?; @@ -396,7 +396,7 @@ pub fn handle_runnables( } pub fn handle_decorations( - world: ServerWorld, + world: WorldSnapshot, params: TextDocumentIdentifier, ) -> Result> { let file_id = params.try_conv_with(&world)?; @@ -404,7 +404,7 @@ pub fn handle_decorations( } pub fn handle_completion( - world: ServerWorld, + world: WorldSnapshot, params: req::CompletionParams, ) -> Result> { let _p = profile("handle_completion"); @@ -447,7 +447,7 @@ pub fn handle_completion( } pub fn handle_folding_range( - world: ServerWorld, + world: WorldSnapshot, params: FoldingRangeParams, ) -> Result>> { let file_id = params.text_document.try_conv_with(&world)?; @@ -481,7 +481,7 @@ pub fn handle_folding_range( } pub fn handle_signature_help( - world: ServerWorld, + world: WorldSnapshot, params: req::TextDocumentPositionParams, ) -> Result> { let position = params.try_conv_with(&world)?; @@ -500,7 +500,7 @@ pub fn handle_signature_help( } pub fn handle_hover( - world: ServerWorld, + world: WorldSnapshot, params: req::TextDocumentPositionParams, ) -> Result> { let position = params.try_conv_with(&world)?; @@ -522,7 +522,7 @@ pub fn handle_hover( /// Test doc comment pub fn handle_prepare_rename( - world: ServerWorld, + world: WorldSnapshot, params: req::TextDocumentPositionParams, ) -> Result> { let position = params.try_conv_with(&world)?; @@ -543,7 +543,7 @@ pub fn handle_prepare_rename( Ok(Some(PrepareRenameResponse::Range(loc.range))) } -pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result> { +pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result> { let file_id = params.text_document.try_conv_with(&world)?; let line_index = world.analysis().file_line_index(file_id); let offset = params.position.conv_with(&line_index); @@ -569,7 +569,7 @@ pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result Result>> { let file_id = params.text_document.try_conv_with(&world)?; @@ -597,7 +597,7 @@ pub fn handle_references( } pub fn handle_formatting( - world: ServerWorld, + world: WorldSnapshot, params: DocumentFormattingParams, ) -> Result>> { let file_id = params.text_document.try_conv_with(&world)?; @@ -641,7 +641,7 @@ pub fn handle_formatting( } pub fn handle_code_action( - world: ServerWorld, + world: WorldSnapshot, params: req::CodeActionParams, ) -> Result> { let _p = profile("handle_code_action"); @@ -704,7 +704,7 @@ pub fn handle_code_action( } pub fn handle_code_lens( - world: ServerWorld, + world: WorldSnapshot, params: req::CodeLensParams, ) -> Result>> { let file_id = params.text_document.try_conv_with(&world)?; @@ -781,7 +781,7 @@ enum CodeLensResolveData { Impls(req::TextDocumentPositionParams), } -pub fn handle_code_lens_resolve(world: ServerWorld, code_lens: CodeLens) -> Result { +pub fn handle_code_lens_resolve(world: WorldSnapshot, code_lens: CodeLens) -> Result { let data = code_lens.data.unwrap(); let resolve = serde_json::from_value(data)?; match resolve { @@ -826,7 +826,7 @@ pub fn handle_code_lens_resolve(world: ServerWorld, code_lens: CodeLens) -> Resu } pub fn handle_document_highlight( - world: ServerWorld, + world: WorldSnapshot, params: req::TextDocumentPositionParams, ) -> Result>> { let file_id = params.text_document.try_conv_with(&world)?; @@ -845,7 +845,7 @@ pub fn handle_document_highlight( } pub fn publish_diagnostics( - world: &ServerWorld, + world: &WorldSnapshot, file_id: FileId, ) -> Result { let uri = world.file_id_to_uri(file_id)?; @@ -867,14 +867,14 @@ pub fn publish_diagnostics( } pub fn publish_decorations( - world: &ServerWorld, + world: &WorldSnapshot, file_id: FileId, ) -> Result { let uri = world.file_id_to_uri(file_id)?; Ok(req::PublishDecorationsParams { uri, decorations: highlight(&world, file_id)? }) } -fn highlight(world: &ServerWorld, file_id: FileId) -> Result> { +fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result> { let line_index = world.analysis().file_line_index(file_id); let res = world .analysis() diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/world.rs similarity index 93% rename from crates/ra_lsp_server/src/server_world.rs rename to crates/ra_lsp_server/src/world.rs index 6076a6cd6b..e0d2f63061 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/world.rs @@ -22,8 +22,13 @@ use crate::{ LspError, }; +/// `WorldState` is the primary mutable state of the language server +/// +/// The most interesting components are `vfs`, which stores a consistent +/// snapshot of the file systems, and `analysis_host`, which stores our +/// incremental salsa database. #[derive(Debug)] -pub struct ServerWorldState { +pub struct WorldState { pub roots_to_scan: usize, pub roots: Vec, pub workspaces: Arc>, @@ -32,15 +37,16 @@ pub struct ServerWorldState { pub latest_requests: Arc>, } -pub struct ServerWorld { +/// An immutable snapshot of the world's state at a point in time. +pub struct WorldSnapshot { pub workspaces: Arc>, pub analysis: Analysis, pub vfs: Arc>, pub latest_requests: Arc>, } -impl ServerWorldState { - pub fn new(folder_roots: Vec, workspaces: Vec) -> ServerWorldState { +impl WorldState { + pub fn new(folder_roots: Vec, workspaces: Vec) -> WorldState { let mut change = AnalysisChange::new(); let mut roots = Vec::new(); @@ -70,7 +76,7 @@ impl ServerWorldState { let mut analysis_host = AnalysisHost::default(); analysis_host.apply_change(change); - ServerWorldState { + WorldState { roots_to_scan, roots: folder_roots, workspaces: Arc::new(workspaces), @@ -136,8 +142,8 @@ impl ServerWorldState { self.analysis_host.apply_change(change); } - pub fn snapshot(&self) -> ServerWorld { - ServerWorld { + pub fn snapshot(&self) -> WorldSnapshot { + WorldSnapshot { workspaces: Arc::clone(&self.workspaces), analysis: self.analysis_host.analysis(), vfs: Arc::clone(&self.vfs), @@ -158,7 +164,7 @@ impl ServerWorldState { } } -impl ServerWorld { +impl WorldSnapshot { pub fn analysis(&self) -> &Analysis { &self.analysis }