rust/crates/libanalysis/src/lib.rs

106 lines
2.7 KiB
Rust
Raw Normal View History

2018-08-10 12:07:43 +00:00
extern crate failure;
extern crate parking_lot;
2018-08-10 18:13:39 +00:00
#[macro_use]
extern crate log;
2018-08-10 19:23:17 +00:00
extern crate once_cell;
2018-08-10 18:13:39 +00:00
extern crate libsyntax2;
2018-08-10 19:23:17 +00:00
extern crate libeditor;
2018-08-13 12:10:20 +00:00
extern crate fst;
2018-08-13 16:28:34 +00:00
extern crate rayon;
2018-08-28 15:22:52 +00:00
extern crate relative_path;
2018-08-13 12:10:20 +00:00
mod symbol_index;
2018-08-21 15:30:10 +00:00
mod module_map;
2018-08-29 15:03:14 +00:00
mod api;
2018-08-29 15:23:57 +00:00
mod imp;
2018-08-10 18:13:39 +00:00
2018-08-10 12:07:43 +00:00
use std::{
2018-08-13 16:28:34 +00:00
sync::{
Arc,
2018-08-29 15:23:57 +00:00
atomic::{AtomicBool},
2018-08-13 16:28:34 +00:00
},
2018-08-10 12:07:43 +00:00
};
2018-08-13 12:10:20 +00:00
2018-08-29 15:06:46 +00:00
use relative_path::RelativePath;
2018-08-13 12:10:20 +00:00
2018-08-21 15:30:10 +00:00
use self::{
2018-08-29 15:23:57 +00:00
module_map::{ChangeKind},
imp::{WorldData, FileData},
2018-08-21 15:30:10 +00:00
};
2018-08-13 13:07:05 +00:00
pub use self::symbol_index::Query;
2018-08-29 15:09:08 +00:00
pub use self::api::{
Analysis, SourceChange, SourceFileEdit, FileSystemEdit, Position, Diagnostic, Runnable, RunnableKind
};
2018-08-10 12:07:43 +00:00
pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
2018-08-28 15:22:52 +00:00
pub trait FileResolver: Send + Sync + 'static {
fn file_stem(&self, id: FileId) -> String;
fn resolve(&self, id: FileId, path: &RelativePath) -> Option<FileId>;
}
2018-08-16 21:18:14 +00:00
2018-08-17 16:54:08 +00:00
#[derive(Debug)]
2018-08-10 12:07:43 +00:00
pub struct WorldState {
data: Arc<WorldData>
}
2018-08-14 12:03:27 +00:00
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
2018-08-15 14:24:20 +00:00
pub struct FileId(pub u32);
2018-08-14 12:03:27 +00:00
2018-08-10 12:07:43 +00:00
impl WorldState {
pub fn new() -> WorldState {
WorldState {
2018-08-21 15:30:10 +00:00
data: Arc::new(WorldData::default()),
2018-08-10 12:07:43 +00:00
}
}
2018-08-29 15:05:54 +00:00
pub fn analysis(
2018-08-21 19:24:59 +00:00
&self,
2018-08-28 15:22:52 +00:00
file_resolver: impl FileResolver,
2018-08-29 15:05:54 +00:00
) -> Analysis {
2018-08-29 15:23:57 +00:00
let imp = imp::AnalysisImpl {
2018-08-21 19:24:59 +00:00
needs_reindex: AtomicBool::new(false),
2018-08-16 21:18:14 +00:00
file_resolver: Arc::new(file_resolver),
data: self.data.clone()
2018-08-29 15:05:54 +00:00
};
Analysis { imp }
2018-08-29 15:03:14 +00:00
}
2018-08-14 12:03:27 +00:00
pub fn change_file(&mut self, file_id: FileId, text: Option<String>) {
self.change_files(::std::iter::once((file_id, text)));
2018-08-13 10:46:05 +00:00
}
2018-08-14 12:03:27 +00:00
pub fn change_files(&mut self, changes: impl Iterator<Item=(FileId, Option<String>)>) {
2018-08-21 19:24:59 +00:00
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
2018-08-21 15:30:10 +00:00
} else {
2018-08-21 19:24:59 +00:00
ChangeKind::Delete
2018-08-21 15:30:10 +00:00
}
2018-08-21 19:24:59 +00:00
} 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);
2018-08-13 10:46:05 +00:00
}
2018-08-10 12:07:43 +00:00
}
}
fn data_mut(&mut self) -> &mut WorldData {
if Arc::get_mut(&mut self.data).is_none() {
self.data = Arc::new(WorldData {
2018-08-13 10:46:05 +00:00
file_map: self.data.file_map.clone(),
2018-08-21 15:30:10 +00:00
module_map: self.data.module_map.clone(),
2018-08-10 12:07:43 +00:00
});
}
Arc::get_mut(&mut self.data).unwrap()
}
}