From 1f2fb4e27f8ba1cb7b1d96a332b7ffc2ee659921 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Aug 2018 12:51:46 +0300 Subject: [PATCH] move --- code/src/extension.ts | 2 +- crates/libanalysis/src/api.rs | 35 ++++++++++++- crates/libanalysis/src/imp.rs | 58 ++++++++++++++++++++- crates/libanalysis/src/lib.rs | 86 +------------------------------ crates/server/src/server_world.rs | 16 +++--- 5 files changed, 101 insertions(+), 96 deletions(-) diff --git a/code/src/extension.ts b/code/src/extension.ts index f2589ef2f8d..53ef83aab78 100644 --- a/code/src/extension.ts +++ b/code/src/extension.ts @@ -395,7 +395,7 @@ async function applySourceChange(change: SourceChange) { let uri = client.protocol2CodeConverter.asUri(toReveal.textDocument.uri) let position = client.protocol2CodeConverter.asPosition(toReveal.position) let editor = vscode.window.activeTextEditor; - if (!editor || editor.document.uri != uri) return + if (!editor || editor.document.uri.toString() != uri.toString()) return if (!editor.selection.isEmpty) return editor!.selection = new vscode.Selection(position, position) } diff --git a/crates/libanalysis/src/api.rs b/crates/libanalysis/src/api.rs index 02eaf7b1cfb..ded88cd15fc 100644 --- a/crates/libanalysis/src/api.rs +++ b/crates/libanalysis/src/api.rs @@ -1,7 +1,7 @@ -use relative_path::RelativePathBuf; +use relative_path::{RelativePath, RelativePathBuf}; use libsyntax2::{File, TextRange, TextUnit, AtomEdit}; use libeditor; -use {imp::AnalysisImpl, FileId, Query}; +use {imp::{AnalysisImpl, AnalysisHostImpl}, Query}; pub use libeditor::{ LocalEdit, StructureNode, LineIndex, FileSymbol, @@ -109,3 +109,34 @@ pub fn diagnostics(&self, file_id: FileId) -> Vec { self.imp.diagnostics(file_id) } } + +pub trait FileResolver: Send + Sync + 'static { + fn file_stem(&self, id: FileId) -> String; + fn resolve(&self, id: FileId, path: &RelativePath) -> Option; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct FileId(pub u32); + +#[derive(Debug)] +pub struct AnalysisHost { + pub(crate) imp: AnalysisHostImpl +} + +impl AnalysisHost { + pub fn new() -> AnalysisHost { + AnalysisHost { imp: AnalysisHostImpl::new() } + } + + pub fn analysis(&self, file_resolver: impl FileResolver) -> Analysis { + Analysis { imp: self.imp.analysis(file_resolver) } + } + + pub fn change_file(&mut self, file_id: FileId, text: Option) { + self.change_files(::std::iter::once((file_id, text))); + } + + pub fn change_files(&mut self, changes: impl Iterator)>) { + self.imp.change_files(changes) + } +} diff --git a/crates/libanalysis/src/imp.rs b/crates/libanalysis/src/imp.rs index 5f451f53f9e..06bbc7cf25b 100644 --- a/crates/libanalysis/src/imp.rs +++ b/crates/libanalysis/src/imp.rs @@ -22,9 +22,65 @@ FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit, module_map::Problem, symbol_index::FileSymbols, - module_map::ModuleMap, + module_map::{ModuleMap, ChangeKind}, }; +#[derive(Debug)] +pub(crate) struct AnalysisHostImpl { + data: Arc +} + +impl AnalysisHostImpl { + pub fn new() -> AnalysisHostImpl { + AnalysisHostImpl { + data: Arc::new(WorldData::default()), + } + } + + pub fn analysis( + &self, + file_resolver: impl FileResolver, + ) -> AnalysisImpl { + AnalysisImpl { + needs_reindex: AtomicBool::new(false), + file_resolver: Arc::new(file_resolver), + data: self.data.clone() + } + } + + pub fn change_files(&mut self, changes: impl Iterator)>) { + let data = self.data_mut(); + for (file_id, text) in changes { + let change_kind = if data.file_map.remove(&file_id).is_some() { + if text.is_some() { + ChangeKind::Update + } else { + ChangeKind::Delete + } + } else { + ChangeKind::Insert + }; + data.module_map.update_file(file_id, change_kind); + data.file_map.remove(&file_id); + if let Some(text) = text { + let file_data = FileData::new(text); + data.file_map.insert(file_id, Arc::new(file_data)); + } else { + data.file_map.remove(&file_id); + } + } + } + + fn data_mut(&mut self) -> &mut WorldData { + if Arc::get_mut(&mut self.data).is_none() { + self.data = Arc::new(WorldData { + file_map: self.data.file_map.clone(), + module_map: self.data.module_map.clone(), + }); + } + Arc::get_mut(&mut self.data).unwrap() + } +} pub(crate) struct AnalysisImpl { pub(crate) needs_reindex: AtomicBool, diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index 027d7439b38..a39141941ff 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs @@ -14,92 +14,10 @@ mod api; mod imp; -use std::{ - sync::{ - Arc, - atomic::{AtomicBool}, - }, -}; - -use relative_path::RelativePath; - -use self::{ - module_map::{ChangeKind}, - imp::{WorldData, FileData}, -}; pub use self::symbol_index::Query; pub use self::api::{ - Analysis, SourceChange, SourceFileEdit, FileSystemEdit, Position, Diagnostic, Runnable, RunnableKind + AnalysisHost, Analysis, SourceChange, SourceFileEdit, FileSystemEdit, Position, Diagnostic, Runnable, RunnableKind, + FileId, FileResolver, }; pub type Result = ::std::result::Result; - -pub trait FileResolver: Send + Sync + 'static { - fn file_stem(&self, id: FileId) -> String; - fn resolve(&self, id: FileId, path: &RelativePath) -> Option; -} - -#[derive(Debug)] -pub struct WorldState { - data: Arc -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct FileId(pub u32); - -impl WorldState { - pub fn new() -> WorldState { - WorldState { - data: Arc::new(WorldData::default()), - } - } - - pub fn analysis( - &self, - file_resolver: impl FileResolver, - ) -> Analysis { - let imp = imp::AnalysisImpl { - needs_reindex: AtomicBool::new(false), - file_resolver: Arc::new(file_resolver), - data: self.data.clone() - }; - Analysis { imp } - } - - pub fn change_file(&mut self, file_id: FileId, text: Option) { - self.change_files(::std::iter::once((file_id, text))); - } - - pub fn change_files(&mut self, changes: impl Iterator)>) { - let data = self.data_mut(); - for (file_id, text) in changes { - let change_kind = if data.file_map.remove(&file_id).is_some() { - if text.is_some() { - ChangeKind::Update - } else { - ChangeKind::Delete - } - } else { - ChangeKind::Insert - }; - data.module_map.update_file(file_id, change_kind); - data.file_map.remove(&file_id); - if let Some(text) = text { - let file_data = FileData::new(text); - data.file_map.insert(file_id, Arc::new(file_data)); - } else { - data.file_map.remove(&file_id); - } - } - } - - fn data_mut(&mut self) -> &mut WorldData { - if Arc::get_mut(&mut self.data).is_none() { - self.data = Arc::new(WorldData { - file_map: self.data.file_map.clone(), - module_map: self.data.module_map.clone(), - }); - } - Arc::get_mut(&mut self.data).unwrap() - } -} diff --git a/crates/server/src/server_world.rs b/crates/server/src/server_world.rs index 6c85914ba3c..9ba7df0b853 100644 --- a/crates/server/src/server_world.rs +++ b/crates/server/src/server_world.rs @@ -5,7 +5,7 @@ }; use languageserver_types::Url; -use libanalysis::{FileId, WorldState, Analysis}; +use libanalysis::{FileId, AnalysisHost, Analysis}; use { Result, @@ -15,7 +15,7 @@ #[derive(Debug)] pub struct ServerWorldState { - pub analysis: WorldState, + pub analysis_host: AnalysisHost, pub path_map: PathMap, pub mem_map: HashMap>, } @@ -29,7 +29,7 @@ pub struct ServerWorld { impl ServerWorldState { pub fn new() -> ServerWorldState { ServerWorldState { - analysis: WorldState::new(), + analysis_host: AnalysisHost::new(), path_map: PathMap::new(), mem_map: HashMap::new(), } @@ -58,20 +58,20 @@ pub fn apply_fs_changes(&mut self, events: Vec) { } }); - self.analysis.change_files(changes); + self.analysis_host.change_files(changes); } pub fn add_mem_file(&mut self, path: PathBuf, text: String) { let file_id = self.path_map.get_or_insert(path); self.mem_map.insert(file_id, None); - self.analysis.change_file(file_id, Some(text)); + self.analysis_host.change_file(file_id, Some(text)); } pub fn change_mem_file(&mut self, path: &Path, text: String) -> Result<()> { let file_id = self.path_map.get_id(path).ok_or_else(|| { format_err!("change to unknown file: {}", path.display()) })?; - self.analysis.change_file(file_id, Some(text)); + self.analysis_host.change_file(file_id, Some(text)); Ok(()) } @@ -85,13 +85,13 @@ pub fn remove_mem_file(&mut self, path: &Path) -> Result<()> { }; // Do this via file watcher ideally. let text = fs::read_to_string(path).ok(); - self.analysis.change_file(file_id, text); + self.analysis_host.change_file(file_id, text); Ok(()) } pub fn snapshot(&self) -> ServerWorld { ServerWorld { - analysis: self.analysis.analysis(self.path_map.clone()), + analysis: self.analysis_host.analysis(self.path_map.clone()), path_map: self.path_map.clone() } }