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::{
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<Vec<String>> {
@ -58,7 +58,7 @@ pub struct 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() {
Some(crate_id) => crate_id,
None => return Ok(None),

View file

@ -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<T: ConvWith> ConvWith for Option<T> {
}
impl<'a> TryConvWith for &'a Url {
type Ctx = ServerWorld;
type Ctx = WorldSnapshot;
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)
}
}
impl TryConvWith for FileId {
type Ctx = ServerWorld;
type Ctx = WorldSnapshot;
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)
}
}
impl<'a> TryConvWith for &'a TextDocumentItem {
type Ctx = ServerWorld;
type Ctx = WorldSnapshot;
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)
}
}
impl<'a> TryConvWith for &'a VersionedTextDocumentIdentifier {
type Ctx = ServerWorld;
type Ctx = WorldSnapshot;
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)
}
}
impl<'a> TryConvWith for &'a TextDocumentIdentifier {
type Ctx = ServerWorld;
type Ctx = WorldSnapshot;
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)
}
}
impl<'a> TryConvWith for &'a TextDocumentPositionParams {
type Ctx = ServerWorld;
type Ctx = WorldSnapshot;
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 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<FileRange> {
fn try_conv_with(self, world: &WorldSnapshot) -> Result<FileRange> {
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<T: TryConvWith> TryConvWith for Vec<T> {
}
impl TryConvWith for SourceChange {
type Ctx = ServerWorld;
type Ctx = WorldSnapshot;
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 {
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<TextDocumentEdit> {
fn try_conv_with(self, world: &WorldSnapshot) -> Result<TextDocumentEdit> {
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<ResourceOp> {
fn try_conv_with(self, world: &WorldSnapshot) -> Result<ResourceOp> {
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<Location> {
fn try_conv_with(self, world: &WorldSnapshot) -> Result<Location> {
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<NavigationTarget>,
world: &ServerWorld,
world: &WorldSnapshot,
// line index for original range file
line_index: &LineIndex,
) -> Result<LocationLink> {
@ -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<Location> {
let url = file_id.try_conv_with(world)?;

View file

@ -7,7 +7,7 @@ mod project_model;
mod vfs_filter;
pub mod req;
pub mod init;
mod server_world;
mod world;
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};

View file

@ -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::<Task>();
@ -161,7 +161,7 @@ fn main_loop_inner(
msg_receiver: &Receiver<RawMessage>,
task_sender: Sender<Task>,
task_receiver: Receiver<Task>,
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<RawMessage>,
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<Task>,
@ -352,7 +352,7 @@ fn on_request(
fn on_notification(
msg_sender: &Sender<RawMessage>,
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<RawRequest>,
pool: &'a ThreadPool,
world: &'a mut ServerWorldState,
world: &'a mut WorldState,
pending_requests: &'a mut PendingRequests,
msg_sender: &'a Sender<RawMessage>,
sender: &'a Sender<Task>,
@ -433,7 +433,7 @@ impl<'a> PoolDispatcher<'a> {
/// Dispatches the request onto the current thread
fn on_sync<R>(
&mut self,
f: fn(&mut ServerWorldState, R::Params) -> Result<R::Result>,
f: fn(&mut WorldState, R::Params) -> Result<R::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<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
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<Task>,
subscriptions: Vec<FileId>,

View file

@ -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<String> {
pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result<String> {
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<String> {
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 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<req::ExtendSelectionResult> {
log::error!(
@ -69,7 +69,7 @@ pub fn handle_extend_selection(
}
pub fn handle_selection_range(
world: ServerWorld,
world: WorldSnapshot,
params: req::SelectionRangeParams,
) -> Result<Vec<req::SelectionRange>> {
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<Vec<Position>> {
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<req::SourceChange> {
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<Option<req::SourceChange>> {
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<Option<Vec<TextEdit>>> {
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<Option<req::DocumentSymbolResponse>> {
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<Option<Vec<SymbolInformation>>> {
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<Vec<SymbolInformation>> {
fn exec_query(world: &WorldSnapshot, query: Query) -> Result<Vec<SymbolInformation>> {
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<Option<req::GotoDefinitionResponse>> {
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<Option<req::GotoImplementationResponse>> {
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<Option<req::GotoTypeDefinitionResponse>> {
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<Vec<Location>> {
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<Vec<req::Runnable>> {
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<Vec<Decoration>> {
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<Option<req::CompletionResponse>> {
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<Option<Vec<FoldingRange>>> {
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<Option<req::SignatureHelp>> {
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<Option<Hover>> {
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<Option<PrepareRenameResponse>> {
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<Option<WorkspaceEdit>> {
pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Option<WorkspaceEdit>> {
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<Option<
}
pub fn handle_references(
world: ServerWorld,
world: WorldSnapshot,
params: req::ReferenceParams,
) -> Result<Option<Vec<Location>>> {
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<Option<Vec<TextEdit>>> {
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<Option<CodeActionResponse>> {
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<Option<Vec<CodeLens>>> {
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<CodeLens> {
pub fn handle_code_lens_resolve(world: WorldSnapshot, code_lens: CodeLens) -> Result<CodeLens> {
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<Option<Vec<DocumentHighlight>>> {
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<req::PublishDiagnosticsParams> {
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<req::PublishDecorationsParams> {
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<Vec<Decoration>> {
fn highlight(world: &WorldSnapshot, file_id: FileId) -> Result<Vec<Decoration>> {
let line_index = world.analysis().file_line_index(file_id);
let res = world
.analysis()

View file

@ -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<PathBuf>,
pub workspaces: Arc<Vec<ProjectWorkspace>>,
@ -32,15 +37,16 @@ pub struct ServerWorldState {
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 analysis: Analysis,
pub vfs: Arc<RwLock<Vfs>>,
pub latest_requests: Arc<RwLock<LatestRequests>>,
}
impl ServerWorldState {
pub fn new(folder_roots: Vec<PathBuf>, workspaces: Vec<ProjectWorkspace>) -> ServerWorldState {
impl WorldState {
pub fn new(folder_roots: Vec<PathBuf>, workspaces: Vec<ProjectWorkspace>) -> 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
}