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