This commit is contained in:
Aleksey Kladov 2019-06-01 10:31:40 +03:00
parent 678a458543
commit bf801953a3
6 changed files with 86 additions and 80 deletions

View file

@ -1,13 +1,13 @@
use crate::{ use crate::{
project_model::{self, TargetKind}, project_model::{self, TargetKind},
server_world::ServerWorld, world::WorldSnapshot,
Result Result
}; };
use ra_ide_api::{FileId, RunnableKind}; use ra_ide_api::{FileId, RunnableKind};
pub(crate) fn runnable_args( pub(crate) fn runnable_args(
world: &ServerWorld, world: &WorldSnapshot,
file_id: FileId, file_id: FileId,
kind: &RunnableKind, kind: &RunnableKind,
) -> Result<Vec<String>> { ) -> Result<Vec<String>> {
@ -58,7 +58,7 @@ pub struct CargoTargetSpec {
} }
impl CargoTargetSpec { impl CargoTargetSpec {
pub fn for_file(world: &ServerWorld, file_id: FileId) -> Result<Option<CargoTargetSpec>> { pub fn for_file(world: &WorldSnapshot, file_id: FileId) -> Result<Option<CargoTargetSpec>> {
let &crate_id = match world.analysis().crate_for(file_id)?.first() { let &crate_id = match world.analysis().crate_for(file_id)?.first() {
Some(crate_id) => crate_id, Some(crate_id) => crate_id,
None => return Ok(None), None => return Ok(None),

View file

@ -12,7 +12,7 @@ use ra_ide_api::{
use ra_syntax::{SyntaxKind, TextRange, TextUnit}; use ra_syntax::{SyntaxKind, TextRange, TextUnit};
use ra_text_edit::{AtomTextEdit, TextEdit}; use ra_text_edit::{AtomTextEdit, TextEdit};
use crate::{req, server_world::ServerWorld, Result}; use crate::{req, world::WorldSnapshot, Result};
pub trait Conv { pub trait Conv {
type Output; type Output;
@ -228,49 +228,49 @@ impl<T: ConvWith> ConvWith for Option<T> {
} }
impl<'a> TryConvWith for &'a Url { impl<'a> TryConvWith for &'a Url {
type Ctx = ServerWorld; type Ctx = WorldSnapshot;
type Output = FileId; type Output = FileId;
fn try_conv_with(self, world: &ServerWorld) -> Result<FileId> { fn try_conv_with(self, world: &WorldSnapshot) -> Result<FileId> {
world.uri_to_file_id(self) world.uri_to_file_id(self)
} }
} }
impl TryConvWith for FileId { impl TryConvWith for FileId {
type Ctx = ServerWorld; type Ctx = WorldSnapshot;
type Output = Url; type Output = Url;
fn try_conv_with(self, world: &ServerWorld) -> Result<Url> { fn try_conv_with(self, world: &WorldSnapshot) -> Result<Url> {
world.file_id_to_uri(self) world.file_id_to_uri(self)
} }
} }
impl<'a> TryConvWith for &'a TextDocumentItem { impl<'a> TryConvWith for &'a TextDocumentItem {
type Ctx = ServerWorld; type Ctx = WorldSnapshot;
type Output = FileId; type Output = FileId;
fn try_conv_with(self, world: &ServerWorld) -> Result<FileId> { fn try_conv_with(self, world: &WorldSnapshot) -> Result<FileId> {
self.uri.try_conv_with(world) self.uri.try_conv_with(world)
} }
} }
impl<'a> TryConvWith for &'a VersionedTextDocumentIdentifier { impl<'a> TryConvWith for &'a VersionedTextDocumentIdentifier {
type Ctx = ServerWorld; type Ctx = WorldSnapshot;
type Output = FileId; type Output = FileId;
fn try_conv_with(self, world: &ServerWorld) -> Result<FileId> { fn try_conv_with(self, world: &WorldSnapshot) -> Result<FileId> {
self.uri.try_conv_with(world) self.uri.try_conv_with(world)
} }
} }
impl<'a> TryConvWith for &'a TextDocumentIdentifier { impl<'a> TryConvWith for &'a TextDocumentIdentifier {
type Ctx = ServerWorld; type Ctx = WorldSnapshot;
type Output = FileId; type Output = FileId;
fn try_conv_with(self, world: &ServerWorld) -> Result<FileId> { fn try_conv_with(self, world: &WorldSnapshot) -> Result<FileId> {
world.uri_to_file_id(&self.uri) world.uri_to_file_id(&self.uri)
} }
} }
impl<'a> TryConvWith for &'a TextDocumentPositionParams { impl<'a> TryConvWith for &'a TextDocumentPositionParams {
type Ctx = ServerWorld; type Ctx = WorldSnapshot;
type Output = FilePosition; type Output = FilePosition;
fn try_conv_with(self, world: &ServerWorld) -> Result<FilePosition> { fn try_conv_with(self, world: &WorldSnapshot) -> Result<FilePosition> {
let file_id = self.text_document.try_conv_with(world)?; let file_id = self.text_document.try_conv_with(world)?;
let line_index = world.analysis().file_line_index(file_id); let line_index = world.analysis().file_line_index(file_id);
let offset = self.position.conv_with(&line_index); 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) { impl<'a> TryConvWith for (&'a TextDocumentIdentifier, Range) {
type Ctx = ServerWorld; type Ctx = WorldSnapshot;
type Output = FileRange; type Output = FileRange;
fn try_conv_with(self, world: &ServerWorld) -> Result<FileRange> { fn try_conv_with(self, world: &WorldSnapshot) -> Result<FileRange> {
let file_id = self.0.try_conv_with(world)?; let file_id = self.0.try_conv_with(world)?;
let line_index = world.analysis().file_line_index(file_id); let line_index = world.analysis().file_line_index(file_id);
let range = self.1.conv_with(&line_index); let range = self.1.conv_with(&line_index);
@ -302,9 +302,9 @@ impl<T: TryConvWith> TryConvWith for Vec<T> {
} }
impl TryConvWith for SourceChange { impl TryConvWith for SourceChange {
type Ctx = ServerWorld; type Ctx = WorldSnapshot;
type Output = req::SourceChange; type Output = req::SourceChange;
fn try_conv_with(self, world: &ServerWorld) -> Result<req::SourceChange> { fn try_conv_with(self, world: &WorldSnapshot) -> Result<req::SourceChange> {
let cursor_position = match self.cursor_position { let cursor_position = match self.cursor_position {
None => None, None => None,
Some(pos) => { Some(pos) => {
@ -342,9 +342,9 @@ impl TryConvWith for SourceChange {
} }
impl TryConvWith for SourceFileEdit { impl TryConvWith for SourceFileEdit {
type Ctx = ServerWorld; type Ctx = WorldSnapshot;
type Output = TextDocumentEdit; type Output = TextDocumentEdit;
fn try_conv_with(self, world: &ServerWorld) -> Result<TextDocumentEdit> { fn try_conv_with(self, world: &WorldSnapshot) -> Result<TextDocumentEdit> {
let text_document = VersionedTextDocumentIdentifier { let text_document = VersionedTextDocumentIdentifier {
uri: self.file_id.try_conv_with(world)?, uri: self.file_id.try_conv_with(world)?,
version: None, version: None,
@ -356,9 +356,9 @@ impl TryConvWith for SourceFileEdit {
} }
impl TryConvWith for FileSystemEdit { impl TryConvWith for FileSystemEdit {
type Ctx = ServerWorld; type Ctx = WorldSnapshot;
type Output = ResourceOp; type Output = ResourceOp;
fn try_conv_with(self, world: &ServerWorld) -> Result<ResourceOp> { fn try_conv_with(self, world: &WorldSnapshot) -> Result<ResourceOp> {
let res = match self { let res = match self {
FileSystemEdit::CreateFile { source_root, path } => { FileSystemEdit::CreateFile { source_root, path } => {
let uri = world.path_to_uri(source_root, &path)?; let uri = world.path_to_uri(source_root, &path)?;
@ -375,9 +375,9 @@ impl TryConvWith for FileSystemEdit {
} }
impl TryConvWith for &NavigationTarget { impl TryConvWith for &NavigationTarget {
type Ctx = ServerWorld; type Ctx = WorldSnapshot;
type Output = Location; type Output = Location;
fn try_conv_with(self, world: &ServerWorld) -> Result<Location> { fn try_conv_with(self, world: &WorldSnapshot) -> Result<Location> {
let line_index = world.analysis().file_line_index(self.file_id()); let line_index = world.analysis().file_line_index(self.file_id());
let range = self.range(); let range = self.range();
to_location(self.file_id(), range, &world, &line_index) to_location(self.file_id(), range, &world, &line_index)
@ -386,7 +386,7 @@ impl TryConvWith for &NavigationTarget {
pub fn to_location_link( pub fn to_location_link(
target: &RangeInfo<NavigationTarget>, target: &RangeInfo<NavigationTarget>,
world: &ServerWorld, world: &WorldSnapshot,
// line index for original range file // line index for original range file
line_index: &LineIndex, line_index: &LineIndex,
) -> Result<LocationLink> { ) -> Result<LocationLink> {
@ -410,7 +410,7 @@ pub fn to_location_link(
pub fn to_location( pub fn to_location(
file_id: FileId, file_id: FileId,
range: TextRange, range: TextRange,
world: &ServerWorld, world: &WorldSnapshot,
line_index: &LineIndex, line_index: &LineIndex,
) -> Result<Location> { ) -> Result<Location> {
let url = file_id.try_conv_with(world)?; let url = file_id.try_conv_with(world)?;

View file

@ -7,7 +7,7 @@ mod project_model;
mod vfs_filter; mod vfs_filter;
pub mod req; pub mod req;
pub mod init; pub mod init;
mod server_world; mod world;
pub type Result<T> = ::std::result::Result<T, ::failure::Error>; pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
pub use crate::{caps::server_capabilities, main_loop::main_loop, main_loop::LspError, init::InitializationOptions}; pub use crate::{caps::server_capabilities, main_loop::main_loop, main_loop::LspError, init::InitializationOptions};

View file

@ -24,7 +24,7 @@ use crate::{
}, },
project_model::workspace_loader, project_model::workspace_loader,
req, req,
server_world::{ServerWorld, ServerWorldState}, world::{WorldSnapshot, WorldState},
Result, Result,
InitializationOptions, InitializationOptions,
}; };
@ -73,7 +73,7 @@ pub fn main_loop(
loaded_workspaces 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 pool = ThreadPool::new(THREADPOOL_SIZE);
let (task_sender, task_receiver) = unbounded::<Task>(); let (task_sender, task_receiver) = unbounded::<Task>();
@ -161,7 +161,7 @@ fn main_loop_inner(
msg_receiver: &Receiver<RawMessage>, msg_receiver: &Receiver<RawMessage>,
task_sender: Sender<Task>, task_sender: Sender<Task>,
task_receiver: Receiver<Task>, task_receiver: Receiver<Task>,
state: &mut ServerWorldState, state: &mut WorldState,
pending_requests: &mut PendingRequests, pending_requests: &mut PendingRequests,
) -> Result<()> { ) -> Result<()> {
let mut subs = Subscriptions::default(); let mut subs = Subscriptions::default();
@ -278,7 +278,7 @@ fn on_task(
task: Task, task: Task,
msg_sender: &Sender<RawMessage>, msg_sender: &Sender<RawMessage>,
pending_requests: &mut PendingRequests, pending_requests: &mut PendingRequests,
state: &mut ServerWorldState, state: &mut WorldState,
) { ) {
match task { match task {
Task::Respond(response) => { Task::Respond(response) => {
@ -295,7 +295,7 @@ fn on_task(
} }
fn on_request( fn on_request(
world: &mut ServerWorldState, world: &mut WorldState,
pending_requests: &mut PendingRequests, pending_requests: &mut PendingRequests,
pool: &ThreadPool, pool: &ThreadPool,
sender: &Sender<Task>, sender: &Sender<Task>,
@ -352,7 +352,7 @@ fn on_request(
fn on_notification( fn on_notification(
msg_sender: &Sender<RawMessage>, msg_sender: &Sender<RawMessage>,
state: &mut ServerWorldState, state: &mut WorldState,
pending_requests: &mut PendingRequests, pending_requests: &mut PendingRequests,
subs: &mut Subscriptions, subs: &mut Subscriptions,
not: RawNotification, not: RawNotification,
@ -422,7 +422,7 @@ fn on_notification(
struct PoolDispatcher<'a> { struct PoolDispatcher<'a> {
req: Option<RawRequest>, req: Option<RawRequest>,
pool: &'a ThreadPool, pool: &'a ThreadPool,
world: &'a mut ServerWorldState, world: &'a mut WorldState,
pending_requests: &'a mut PendingRequests, pending_requests: &'a mut PendingRequests,
msg_sender: &'a Sender<RawMessage>, msg_sender: &'a Sender<RawMessage>,
sender: &'a Sender<Task>, sender: &'a Sender<Task>,
@ -433,7 +433,7 @@ impl<'a> PoolDispatcher<'a> {
/// Dispatches the request onto the current thread /// Dispatches the request onto the current thread
fn on_sync<R>( fn on_sync<R>(
&mut self, &mut self,
f: fn(&mut ServerWorldState, R::Params) -> Result<R::Result>, f: fn(&mut WorldState, R::Params) -> Result<R::Result>,
) -> Result<&mut Self> ) -> Result<&mut Self>
where where
R: req::Request + 'static, R: req::Request + 'static,
@ -453,7 +453,7 @@ impl<'a> PoolDispatcher<'a> {
} }
/// Dispatches the request onto thread pool /// Dispatches the request onto thread pool
fn on<R>(&mut self, f: fn(ServerWorld, R::Params) -> Result<R::Result>) -> Result<&mut Self> fn on<R>(&mut self, f: fn(WorldSnapshot, R::Params) -> Result<R::Result>) -> Result<&mut Self>
where where
R: req::Request + 'static, R: req::Request + 'static,
R::Params: DeserializeOwned + Send + 'static, R::Params: DeserializeOwned + Send + 'static,
@ -557,7 +557,7 @@ where
fn update_file_notifications_on_threadpool( fn update_file_notifications_on_threadpool(
pool: &ThreadPool, pool: &ThreadPool,
world: ServerWorld, world: WorldSnapshot,
publish_decorations: bool, publish_decorations: bool,
sender: Sender<Task>, sender: Sender<Task>,
subscriptions: Vec<FileId>, subscriptions: Vec<FileId>,

View file

@ -24,11 +24,11 @@ use crate::{
cargo_target_spec::{runnable_args, CargoTargetSpec}, cargo_target_spec::{runnable_args, CargoTargetSpec},
conv::{to_location, to_location_link, Conv, ConvWith, MapConvWith, TryConvWith}, conv::{to_location, to_location_link, Conv, ConvWith, MapConvWith, TryConvWith},
req::{self, Decoration}, req::{self, Decoration},
server_world::ServerWorld, world::WorldSnapshot,
LspError, Result, LspError, Result,
}; };
pub fn handle_analyzer_status(world: ServerWorld, _: ()) -> Result<String> { pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result<String> {
let mut buf = world.status(); let mut buf = world.status();
writeln!(buf, "\n\nrequests:").unwrap(); writeln!(buf, "\n\nrequests:").unwrap();
let requests = world.latest_requests.read(); let requests = world.latest_requests.read();
@ -39,7 +39,7 @@ pub fn handle_analyzer_status(world: ServerWorld, _: ()) -> Result<String> {
Ok(buf) Ok(buf)
} }
pub fn handle_syntax_tree(world: ServerWorld, params: req::SyntaxTreeParams) -> Result<String> { pub fn handle_syntax_tree(world: WorldSnapshot, params: req::SyntaxTreeParams) -> Result<String> {
let id = params.text_document.try_conv_with(&world)?; let id = params.text_document.try_conv_with(&world)?;
let line_index = world.analysis().file_line_index(id); let line_index = world.analysis().file_line_index(id);
let text_range = params.range.map(|p| p.conv_with(&line_index)); 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 // FIXME: drop this API
pub fn handle_extend_selection( pub fn handle_extend_selection(
world: ServerWorld, world: WorldSnapshot,
params: req::ExtendSelectionParams, params: req::ExtendSelectionParams,
) -> Result<req::ExtendSelectionResult> { ) -> Result<req::ExtendSelectionResult> {
log::error!( log::error!(
@ -69,7 +69,7 @@ pub fn handle_extend_selection(
} }
pub fn handle_selection_range( pub fn handle_selection_range(
world: ServerWorld, world: WorldSnapshot,
params: req::SelectionRangeParams, params: req::SelectionRangeParams,
) -> Result<Vec<req::SelectionRange>> { ) -> Result<Vec<req::SelectionRange>> {
let _p = profile("handle_selection_range"); let _p = profile("handle_selection_range");
@ -110,7 +110,7 @@ pub fn handle_selection_range(
} }
pub fn handle_find_matching_brace( pub fn handle_find_matching_brace(
world: ServerWorld, world: WorldSnapshot,
params: req::FindMatchingBraceParams, params: req::FindMatchingBraceParams,
) -> Result<Vec<Position>> { ) -> Result<Vec<Position>> {
let _p = profile("handle_find_matching_brace"); let _p = profile("handle_find_matching_brace");
@ -129,7 +129,7 @@ pub fn handle_find_matching_brace(
} }
pub fn handle_join_lines( pub fn handle_join_lines(
world: ServerWorld, world: WorldSnapshot,
params: req::JoinLinesParams, params: req::JoinLinesParams,
) -> Result<req::SourceChange> { ) -> Result<req::SourceChange> {
let _p = profile("handle_join_lines"); let _p = profile("handle_join_lines");
@ -138,7 +138,7 @@ pub fn handle_join_lines(
} }
pub fn handle_on_enter( pub fn handle_on_enter(
world: ServerWorld, world: WorldSnapshot,
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Option<req::SourceChange>> { ) -> Result<Option<req::SourceChange>> {
let _p = profile("handle_on_enter"); let _p = profile("handle_on_enter");
@ -150,7 +150,7 @@ pub fn handle_on_enter(
} }
pub fn handle_on_type_formatting( pub fn handle_on_type_formatting(
world: ServerWorld, world: WorldSnapshot,
params: req::DocumentOnTypeFormattingParams, params: req::DocumentOnTypeFormattingParams,
) -> Result<Option<Vec<TextEdit>>> { ) -> Result<Option<Vec<TextEdit>>> {
let _p = profile("handle_on_type_formatting"); let _p = profile("handle_on_type_formatting");
@ -181,7 +181,7 @@ pub fn handle_on_type_formatting(
} }
pub fn handle_document_symbol( pub fn handle_document_symbol(
world: ServerWorld, world: WorldSnapshot,
params: req::DocumentSymbolParams, params: req::DocumentSymbolParams,
) -> Result<Option<req::DocumentSymbolResponse>> { ) -> Result<Option<req::DocumentSymbolResponse>> {
let file_id = params.text_document.try_conv_with(&world)?; let file_id = params.text_document.try_conv_with(&world)?;
@ -219,7 +219,7 @@ pub fn handle_document_symbol(
} }
pub fn handle_workspace_symbol( pub fn handle_workspace_symbol(
world: ServerWorld, world: WorldSnapshot,
params: req::WorkspaceSymbolParams, params: req::WorkspaceSymbolParams,
) -> Result<Option<Vec<SymbolInformation>>> { ) -> Result<Option<Vec<SymbolInformation>>> {
let all_symbols = params.query.contains('#'); let all_symbols = params.query.contains('#');
@ -245,7 +245,7 @@ pub fn handle_workspace_symbol(
return Ok(Some(res)); return Ok(Some(res));
fn exec_query(world: &ServerWorld, query: Query) -> Result<Vec<SymbolInformation>> { fn exec_query(world: &WorldSnapshot, query: Query) -> Result<Vec<SymbolInformation>> {
let mut res = Vec::new(); let mut res = Vec::new();
for nav in world.analysis().symbol_search(query)? { for nav in world.analysis().symbol_search(query)? {
let info = SymbolInformation { let info = SymbolInformation {
@ -262,7 +262,7 @@ pub fn handle_workspace_symbol(
} }
pub fn handle_goto_definition( pub fn handle_goto_definition(
world: ServerWorld, world: WorldSnapshot,
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Option<req::GotoDefinitionResponse>> { ) -> Result<Option<req::GotoDefinitionResponse>> {
let position = params.try_conv_with(&world)?; let position = params.try_conv_with(&world)?;
@ -282,7 +282,7 @@ pub fn handle_goto_definition(
} }
pub fn handle_goto_implementation( pub fn handle_goto_implementation(
world: ServerWorld, world: WorldSnapshot,
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Option<req::GotoImplementationResponse>> { ) -> Result<Option<req::GotoImplementationResponse>> {
let position = params.try_conv_with(&world)?; let position = params.try_conv_with(&world)?;
@ -302,7 +302,7 @@ pub fn handle_goto_implementation(
} }
pub fn handle_goto_type_definition( pub fn handle_goto_type_definition(
world: ServerWorld, world: WorldSnapshot,
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Option<req::GotoTypeDefinitionResponse>> { ) -> Result<Option<req::GotoTypeDefinitionResponse>> {
let position = params.try_conv_with(&world)?; let position = params.try_conv_with(&world)?;
@ -322,7 +322,7 @@ pub fn handle_goto_type_definition(
} }
pub fn handle_parent_module( pub fn handle_parent_module(
world: ServerWorld, world: WorldSnapshot,
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Vec<Location>> { ) -> Result<Vec<Location>> {
let position = params.try_conv_with(&world)?; let position = params.try_conv_with(&world)?;
@ -335,7 +335,7 @@ pub fn handle_parent_module(
} }
pub fn handle_runnables( pub fn handle_runnables(
world: ServerWorld, world: WorldSnapshot,
params: req::RunnablesParams, params: req::RunnablesParams,
) -> Result<Vec<req::Runnable>> { ) -> Result<Vec<req::Runnable>> {
let file_id = params.text_document.try_conv_with(&world)?; let file_id = params.text_document.try_conv_with(&world)?;
@ -396,7 +396,7 @@ pub fn handle_runnables(
} }
pub fn handle_decorations( pub fn handle_decorations(
world: ServerWorld, world: WorldSnapshot,
params: TextDocumentIdentifier, params: TextDocumentIdentifier,
) -> Result<Vec<Decoration>> { ) -> Result<Vec<Decoration>> {
let file_id = params.try_conv_with(&world)?; let file_id = params.try_conv_with(&world)?;
@ -404,7 +404,7 @@ pub fn handle_decorations(
} }
pub fn handle_completion( pub fn handle_completion(
world: ServerWorld, world: WorldSnapshot,
params: req::CompletionParams, params: req::CompletionParams,
) -> Result<Option<req::CompletionResponse>> { ) -> Result<Option<req::CompletionResponse>> {
let _p = profile("handle_completion"); let _p = profile("handle_completion");
@ -447,7 +447,7 @@ pub fn handle_completion(
} }
pub fn handle_folding_range( pub fn handle_folding_range(
world: ServerWorld, world: WorldSnapshot,
params: FoldingRangeParams, params: FoldingRangeParams,
) -> Result<Option<Vec<FoldingRange>>> { ) -> Result<Option<Vec<FoldingRange>>> {
let file_id = params.text_document.try_conv_with(&world)?; let file_id = params.text_document.try_conv_with(&world)?;
@ -481,7 +481,7 @@ pub fn handle_folding_range(
} }
pub fn handle_signature_help( pub fn handle_signature_help(
world: ServerWorld, world: WorldSnapshot,
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Option<req::SignatureHelp>> { ) -> Result<Option<req::SignatureHelp>> {
let position = params.try_conv_with(&world)?; let position = params.try_conv_with(&world)?;
@ -500,7 +500,7 @@ pub fn handle_signature_help(
} }
pub fn handle_hover( pub fn handle_hover(
world: ServerWorld, world: WorldSnapshot,
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Option<Hover>> { ) -> Result<Option<Hover>> {
let position = params.try_conv_with(&world)?; let position = params.try_conv_with(&world)?;
@ -522,7 +522,7 @@ pub fn handle_hover(
/// Test doc comment /// Test doc comment
pub fn handle_prepare_rename( pub fn handle_prepare_rename(
world: ServerWorld, world: WorldSnapshot,
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Option<PrepareRenameResponse>> { ) -> Result<Option<PrepareRenameResponse>> {
let position = params.try_conv_with(&world)?; let position = params.try_conv_with(&world)?;
@ -543,7 +543,7 @@ pub fn handle_prepare_rename(
Ok(Some(PrepareRenameResponse::Range(loc.range))) Ok(Some(PrepareRenameResponse::Range(loc.range)))
} }
pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result<Option<WorkspaceEdit>> { pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Option<WorkspaceEdit>> {
let file_id = params.text_document.try_conv_with(&world)?; let file_id = params.text_document.try_conv_with(&world)?;
let line_index = world.analysis().file_line_index(file_id); let line_index = world.analysis().file_line_index(file_id);
let offset = params.position.conv_with(&line_index); let offset = params.position.conv_with(&line_index);
@ -569,7 +569,7 @@ pub fn handle_rename(world: ServerWorld, params: RenameParams) -> Result<Option<
} }
pub fn handle_references( pub fn handle_references(
world: ServerWorld, world: WorldSnapshot,
params: req::ReferenceParams, params: req::ReferenceParams,
) -> Result<Option<Vec<Location>>> { ) -> Result<Option<Vec<Location>>> {
let file_id = params.text_document.try_conv_with(&world)?; let file_id = params.text_document.try_conv_with(&world)?;
@ -597,7 +597,7 @@ pub fn handle_references(
} }
pub fn handle_formatting( pub fn handle_formatting(
world: ServerWorld, world: WorldSnapshot,
params: DocumentFormattingParams, params: DocumentFormattingParams,
) -> Result<Option<Vec<TextEdit>>> { ) -> Result<Option<Vec<TextEdit>>> {
let file_id = params.text_document.try_conv_with(&world)?; let file_id = params.text_document.try_conv_with(&world)?;
@ -641,7 +641,7 @@ pub fn handle_formatting(
} }
pub fn handle_code_action( pub fn handle_code_action(
world: ServerWorld, world: WorldSnapshot,
params: req::CodeActionParams, params: req::CodeActionParams,
) -> Result<Option<CodeActionResponse>> { ) -> Result<Option<CodeActionResponse>> {
let _p = profile("handle_code_action"); let _p = profile("handle_code_action");
@ -704,7 +704,7 @@ pub fn handle_code_action(
} }
pub fn handle_code_lens( pub fn handle_code_lens(
world: ServerWorld, world: WorldSnapshot,
params: req::CodeLensParams, params: req::CodeLensParams,
) -> Result<Option<Vec<CodeLens>>> { ) -> Result<Option<Vec<CodeLens>>> {
let file_id = params.text_document.try_conv_with(&world)?; let file_id = params.text_document.try_conv_with(&world)?;
@ -781,7 +781,7 @@ enum CodeLensResolveData {
Impls(req::TextDocumentPositionParams), Impls(req::TextDocumentPositionParams),
} }
pub fn handle_code_lens_resolve(world: ServerWorld, code_lens: CodeLens) -> Result<CodeLens> { pub fn handle_code_lens_resolve(world: WorldSnapshot, code_lens: CodeLens) -> Result<CodeLens> {
let data = code_lens.data.unwrap(); let data = code_lens.data.unwrap();
let resolve = serde_json::from_value(data)?; let resolve = serde_json::from_value(data)?;
match resolve { match resolve {
@ -826,7 +826,7 @@ pub fn handle_code_lens_resolve(world: ServerWorld, code_lens: CodeLens) -> Resu
} }
pub fn handle_document_highlight( pub fn handle_document_highlight(
world: ServerWorld, world: WorldSnapshot,
params: req::TextDocumentPositionParams, params: req::TextDocumentPositionParams,
) -> Result<Option<Vec<DocumentHighlight>>> { ) -> Result<Option<Vec<DocumentHighlight>>> {
let file_id = params.text_document.try_conv_with(&world)?; let file_id = params.text_document.try_conv_with(&world)?;
@ -845,7 +845,7 @@ pub fn handle_document_highlight(
} }
pub fn publish_diagnostics( pub fn publish_diagnostics(
world: &ServerWorld, world: &WorldSnapshot,
file_id: FileId, file_id: FileId,
) -> Result<req::PublishDiagnosticsParams> { ) -> Result<req::PublishDiagnosticsParams> {
let uri = world.file_id_to_uri(file_id)?; let uri = world.file_id_to_uri(file_id)?;
@ -867,14 +867,14 @@ pub fn publish_diagnostics(
} }
pub fn publish_decorations( pub fn publish_decorations(
world: &ServerWorld, world: &WorldSnapshot,
file_id: FileId, file_id: FileId,
) -> Result<req::PublishDecorationsParams> { ) -> Result<req::PublishDecorationsParams> {
let uri = world.file_id_to_uri(file_id)?; let uri = world.file_id_to_uri(file_id)?;
Ok(req::PublishDecorationsParams { uri, decorations: highlight(&world, file_id)? }) Ok(req::PublishDecorationsParams { uri, decorations: highlight(&world, file_id)? })
} }
fn highlight(world: &ServerWorld, file_id: FileId) -> Result<Vec<Decoration>> { fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> {
let line_index = world.analysis().file_line_index(file_id); let line_index = world.analysis().file_line_index(file_id);
let res = world let res = world
.analysis() .analysis()

View file

@ -22,8 +22,13 @@ use crate::{
LspError, 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)] #[derive(Debug)]
pub struct ServerWorldState { pub struct WorldState {
pub roots_to_scan: usize, pub roots_to_scan: usize,
pub roots: Vec<PathBuf>, pub roots: Vec<PathBuf>,
pub workspaces: Arc<Vec<ProjectWorkspace>>, pub workspaces: Arc<Vec<ProjectWorkspace>>,
@ -32,15 +37,16 @@ pub struct ServerWorldState {
pub latest_requests: Arc<RwLock<LatestRequests>>, pub latest_requests: Arc<RwLock<LatestRequests>>,
} }
pub struct ServerWorld { /// An immutable snapshot of the world's state at a point in time.
pub struct WorldSnapshot {
pub workspaces: Arc<Vec<ProjectWorkspace>>, pub workspaces: Arc<Vec<ProjectWorkspace>>,
pub analysis: Analysis, pub analysis: Analysis,
pub vfs: Arc<RwLock<Vfs>>, pub vfs: Arc<RwLock<Vfs>>,
pub latest_requests: Arc<RwLock<LatestRequests>>, pub latest_requests: Arc<RwLock<LatestRequests>>,
} }
impl ServerWorldState { impl WorldState {
pub fn new(folder_roots: Vec<PathBuf>, workspaces: Vec<ProjectWorkspace>) -> ServerWorldState { pub fn new(folder_roots: Vec<PathBuf>, workspaces: Vec<ProjectWorkspace>) -> WorldState {
let mut change = AnalysisChange::new(); let mut change = AnalysisChange::new();
let mut roots = Vec::new(); let mut roots = Vec::new();
@ -70,7 +76,7 @@ impl ServerWorldState {
let mut analysis_host = AnalysisHost::default(); let mut analysis_host = AnalysisHost::default();
analysis_host.apply_change(change); analysis_host.apply_change(change);
ServerWorldState { WorldState {
roots_to_scan, roots_to_scan,
roots: folder_roots, roots: folder_roots,
workspaces: Arc::new(workspaces), workspaces: Arc::new(workspaces),
@ -136,8 +142,8 @@ impl ServerWorldState {
self.analysis_host.apply_change(change); self.analysis_host.apply_change(change);
} }
pub fn snapshot(&self) -> ServerWorld { pub fn snapshot(&self) -> WorldSnapshot {
ServerWorld { WorldSnapshot {
workspaces: Arc::clone(&self.workspaces), workspaces: Arc::clone(&self.workspaces),
analysis: self.analysis_host.analysis(), analysis: self.analysis_host.analysis(),
vfs: Arc::clone(&self.vfs), vfs: Arc::clone(&self.vfs),
@ -158,7 +164,7 @@ impl ServerWorldState {
} }
} }
impl ServerWorld { impl WorldSnapshot {
pub fn analysis(&self) -> &Analysis { pub fn analysis(&self) -> &Analysis {
&self.analysis &self.analysis
} }