dont change readonly files

This commit is contained in:
Aleksey Kladov 2018-09-04 11:40:45 +03:00
parent a668f703fa
commit 3a017aaa52
2 changed files with 34 additions and 22 deletions

View file

@ -3,41 +3,47 @@ use im;
use relative_path::RelativePath; use relative_path::RelativePath;
use libanalysis::{FileId, FileResolver}; use libanalysis::{FileId, FileResolver};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Root {
Workspace, Lib
}
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct PathMap { pub struct PathMap {
next_id: u32, next_id: u32,
path2id: im::HashMap<PathBuf, FileId>, path2id: im::HashMap<PathBuf, FileId>,
id2path: im::HashMap<FileId, PathBuf>, id2path: im::HashMap<FileId, PathBuf>,
id2root: im::HashMap<FileId, Root>,
} }
impl PathMap { impl PathMap {
pub fn new() -> PathMap { pub fn new() -> PathMap {
Default::default() Default::default()
} }
pub fn get_or_insert(&mut self, path: PathBuf, root: Root) -> FileId {
pub fn get_or_insert(&mut self, path: PathBuf) -> FileId {
self.path2id.get(path.as_path()) self.path2id.get(path.as_path())
.map(|&id| id) .map(|&id| id)
.unwrap_or_else(|| { .unwrap_or_else(|| {
let id = self.new_file_id(); let id = self.new_file_id();
self.insert(path, id); self.insert(path, id, root);
id id
}) })
} }
pub fn get_id(&self, path: &Path) -> Option<FileId> { pub fn get_id(&self, path: &Path) -> Option<FileId> {
self.path2id.get(path).map(|&id| id) self.path2id.get(path).map(|&id| id)
} }
pub fn get_path(&self, file_id: FileId) -> &Path {
pub fn get_path(&self, id: FileId) -> &Path { self.id2path.get(&file_id)
self.id2path.get(&id)
.unwrap() .unwrap()
.as_path() .as_path()
} }
pub fn get_root(&self, file_id: FileId) -> Root {
fn insert(&mut self, path: PathBuf, id: FileId) { self.id2root[&file_id]
self.path2id.insert(path.clone(), id); }
self.id2path.insert(id, path.clone()); fn insert(&mut self, path: PathBuf, file_id: FileId, root: Root) {
self.path2id.insert(path.clone(), file_id);
self.id2path.insert(file_id, path.clone());
self.id2root.insert(file_id, root);
} }
fn new_file_id(&mut self) -> FileId { fn new_file_id(&mut self) -> FileId {
@ -48,12 +54,12 @@ impl PathMap {
} }
impl FileResolver for PathMap { impl FileResolver for PathMap {
fn file_stem(&self, id: FileId) -> String { fn file_stem(&self, file_id: FileId) -> String {
self.get_path(id).file_stem().unwrap().to_str().unwrap().to_string() self.get_path(file_id).file_stem().unwrap().to_str().unwrap().to_string()
} }
fn resolve(&self, id: FileId, path: &RelativePath) -> Option<FileId> { fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId> {
let path = path.to_path(&self.get_path(id)); let path = path.to_path(&self.get_path(file_id));
let path = normalize(&path); let path = normalize(&path);
self.get_id(&path) self.get_id(&path)
} }

View file

@ -10,7 +10,7 @@ use libanalysis::{FileId, AnalysisHost, Analysis, CrateGraph, CrateId, LibraryDa
use { use {
Result, Result,
path_map::PathMap, path_map::{PathMap, Root},
vfs::{FileEvent, FileEventKind}, vfs::{FileEvent, FileEventKind},
project_model::CargoWorkspace, project_model::CargoWorkspace,
}; };
@ -51,7 +51,7 @@ impl ServerWorldState {
(event.path, text) (event.path, text)
}) })
.map(|(path, text)| { .map(|(path, text)| {
(pm.get_or_insert(path), text) (pm.get_or_insert(path, Root::Workspace), text)
}) })
.filter_map(|(id, text)| { .filter_map(|(id, text)| {
if mm.contains_key(&id) { if mm.contains_key(&id) {
@ -73,7 +73,7 @@ impl ServerWorldState {
}; };
(event.path, text) (event.path, text)
}) })
.map(|(path, text)| (pm.get_or_insert(path), text)) .map(|(path, text)| (pm.get_or_insert(path, Root::Lib), text))
.collect() .collect()
} }
pub fn add_lib(&mut self, data: LibraryData) { pub fn add_lib(&mut self, data: LibraryData) {
@ -81,9 +81,11 @@ impl ServerWorldState {
} }
pub fn add_mem_file(&mut self, path: PathBuf, text: String) -> FileId { pub fn add_mem_file(&mut self, path: PathBuf, text: String) -> FileId {
let file_id = self.path_map.get_or_insert(path); let file_id = self.path_map.get_or_insert(path, Root::Workspace);
self.mem_map.insert(file_id, None); self.mem_map.insert(file_id, None);
self.analysis_host.change_file(file_id, Some(text)); if self.path_map.get_root(file_id) != Root::Lib {
self.analysis_host.change_file(file_id, Some(text));
}
file_id file_id
} }
@ -91,7 +93,9 @@ impl ServerWorldState {
let file_id = self.path_map.get_id(path).ok_or_else(|| { let file_id = self.path_map.get_id(path).ok_or_else(|| {
format_err!("change to unknown file: {}", path.display()) format_err!("change to unknown file: {}", path.display())
})?; })?;
self.analysis_host.change_file(file_id, Some(text)); if self.path_map.get_root(file_id) != Root::Lib {
self.analysis_host.change_file(file_id, Some(text));
}
Ok(()) Ok(())
} }
@ -105,7 +109,9 @@ impl ServerWorldState {
}; };
// Do this via file watcher ideally. // Do this via file watcher ideally.
let text = fs::read_to_string(path).ok(); let text = fs::read_to_string(path).ok();
self.analysis_host.change_file(file_id, text); if self.path_map.get_root(file_id) != Root::Lib {
self.analysis_host.change_file(file_id, text);
}
Ok(file_id) Ok(file_id)
} }
pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) { pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) {