move
This commit is contained in:
parent
0d6d74e78e
commit
1f2fb4e27f
@ -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)
|
||||
}
|
||||
|
@ -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<Diagnostic> {
|
||||
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<FileId>;
|
||||
}
|
||||
|
||||
#[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<String>) {
|
||||
self.change_files(::std::iter::once((file_id, text)));
|
||||
}
|
||||
|
||||
pub fn change_files(&mut self, changes: impl Iterator<Item=(FileId, Option<String>)>) {
|
||||
self.imp.change_files(changes)
|
||||
}
|
||||
}
|
||||
|
@ -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<WorldData>
|
||||
}
|
||||
|
||||
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<Item=(FileId, Option<String>)>) {
|
||||
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,
|
||||
|
@ -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<T> = ::std::result::Result<T, ::failure::Error>;
|
||||
|
||||
pub trait FileResolver: Send + Sync + 'static {
|
||||
fn file_stem(&self, id: FileId) -> String;
|
||||
fn resolve(&self, id: FileId, path: &RelativePath) -> Option<FileId>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WorldState {
|
||||
data: Arc<WorldData>
|
||||
}
|
||||
|
||||
#[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<String>) {
|
||||
self.change_files(::std::iter::once((file_id, text)));
|
||||
}
|
||||
|
||||
pub fn change_files(&mut self, changes: impl Iterator<Item=(FileId, Option<String>)>) {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
@ -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<FileId, Option<String>>,
|
||||
}
|
||||
@ -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<FileEvent>) {
|
||||
}
|
||||
});
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user