mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 06:41:48 +00:00
rename all things
This commit is contained in:
parent
ba0bfeee12
commit
b5021411a8
478 changed files with 219 additions and 204 deletions
167
crates/ra_lsp_server/src/server_world.rs
Normal file
167
crates/ra_lsp_server/src/server_world.rs
Normal file
|
@ -0,0 +1,167 @@
|
|||
use std::{
|
||||
fs,
|
||||
path::{PathBuf, Path},
|
||||
collections::HashMap,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use languageserver_types::Url;
|
||||
use ra_analysis::{FileId, AnalysisHost, Analysis, CrateGraph, CrateId, LibraryData, FileResolver};
|
||||
|
||||
use {
|
||||
Result,
|
||||
path_map::{PathMap, Root},
|
||||
vfs::{FileEvent, FileEventKind},
|
||||
project_model::CargoWorkspace,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ServerWorldState {
|
||||
pub workspaces: Arc<Vec<CargoWorkspace>>,
|
||||
pub analysis_host: AnalysisHost,
|
||||
pub path_map: PathMap,
|
||||
pub mem_map: HashMap<FileId, Option<String>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ServerWorld {
|
||||
pub workspaces: Arc<Vec<CargoWorkspace>>,
|
||||
pub analysis: Analysis,
|
||||
pub path_map: PathMap,
|
||||
}
|
||||
|
||||
impl ServerWorldState {
|
||||
pub fn new() -> ServerWorldState {
|
||||
ServerWorldState {
|
||||
workspaces: Arc::new(Vec::new()),
|
||||
analysis_host: AnalysisHost::new(),
|
||||
path_map: PathMap::new(),
|
||||
mem_map: HashMap::new(),
|
||||
}
|
||||
}
|
||||
pub fn apply_fs_changes(&mut self, events: Vec<FileEvent>) {
|
||||
{
|
||||
let pm = &mut self.path_map;
|
||||
let mm = &mut self.mem_map;
|
||||
let changes = events.into_iter()
|
||||
.map(|event| {
|
||||
let text = match event.kind {
|
||||
FileEventKind::Add(text) => Some(text),
|
||||
};
|
||||
(event.path, text)
|
||||
})
|
||||
.map(|(path, text)| {
|
||||
(pm.get_or_insert(path, Root::Workspace), text)
|
||||
})
|
||||
.filter_map(|(id, text)| {
|
||||
if mm.contains_key(&id) {
|
||||
mm.insert(id, text);
|
||||
None
|
||||
} else {
|
||||
Some((id, text))
|
||||
}
|
||||
});
|
||||
self.analysis_host.change_files(changes);
|
||||
}
|
||||
self.analysis_host.set_file_resolver(Arc::new(self.path_map.clone()));
|
||||
}
|
||||
pub fn events_to_files(&mut self, events: Vec<FileEvent>) -> (Vec<(FileId, String)>, Arc<FileResolver>) {
|
||||
let files = {
|
||||
let pm = &mut self.path_map;
|
||||
events.into_iter()
|
||||
.map(|event| {
|
||||
let text = match event.kind {
|
||||
FileEventKind::Add(text) => text,
|
||||
};
|
||||
(event.path, text)
|
||||
})
|
||||
.map(|(path, text)| (pm.get_or_insert(path, Root::Lib), text))
|
||||
.collect()
|
||||
};
|
||||
let resolver = Arc::new(self.path_map.clone());
|
||||
(files, resolver)
|
||||
}
|
||||
pub fn add_lib(&mut self, data: LibraryData) {
|
||||
self.analysis_host.add_library(data);
|
||||
}
|
||||
|
||||
pub fn add_mem_file(&mut self, path: PathBuf, text: String) -> FileId {
|
||||
let file_id = self.path_map.get_or_insert(path, Root::Workspace);
|
||||
self.analysis_host.set_file_resolver(Arc::new(self.path_map.clone()));
|
||||
self.mem_map.insert(file_id, None);
|
||||
if self.path_map.get_root(file_id) != Root::Lib {
|
||||
self.analysis_host.change_file(file_id, Some(text));
|
||||
}
|
||||
file_id
|
||||
}
|
||||
|
||||
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())
|
||||
})?;
|
||||
if self.path_map.get_root(file_id) != Root::Lib {
|
||||
self.analysis_host.change_file(file_id, Some(text));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn remove_mem_file(&mut self, path: &Path) -> Result<FileId> {
|
||||
let file_id = self.path_map.get_id(path).ok_or_else(|| {
|
||||
format_err!("change to unknown file: {}", path.display())
|
||||
})?;
|
||||
match self.mem_map.remove(&file_id) {
|
||||
Some(_) => (),
|
||||
None => bail!("unmatched close notification"),
|
||||
};
|
||||
// Do this via file watcher ideally.
|
||||
let text = fs::read_to_string(path).ok();
|
||||
if self.path_map.get_root(file_id) != Root::Lib {
|
||||
self.analysis_host.change_file(file_id, text);
|
||||
}
|
||||
Ok(file_id)
|
||||
}
|
||||
pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) {
|
||||
let mut crate_roots = HashMap::new();
|
||||
ws.iter()
|
||||
.flat_map(|ws| {
|
||||
ws.packages()
|
||||
.flat_map(move |pkg| pkg.targets(ws))
|
||||
.map(move |tgt| tgt.root(ws))
|
||||
})
|
||||
.for_each(|root| {
|
||||
if let Some(file_id) = self.path_map.get_id(root) {
|
||||
let crate_id = CrateId(crate_roots.len() as u32);
|
||||
crate_roots.insert(crate_id, file_id);
|
||||
}
|
||||
});
|
||||
let crate_graph = CrateGraph { crate_roots };
|
||||
self.workspaces = Arc::new(ws);
|
||||
self.analysis_host.set_crate_graph(crate_graph);
|
||||
}
|
||||
pub fn snapshot(&self) -> ServerWorld {
|
||||
ServerWorld {
|
||||
workspaces: Arc::clone(&self.workspaces),
|
||||
analysis: self.analysis_host.analysis(),
|
||||
path_map: self.path_map.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ServerWorld {
|
||||
pub fn analysis(&self) -> &Analysis {
|
||||
&self.analysis
|
||||
}
|
||||
|
||||
pub fn uri_to_file_id(&self, uri: &Url) -> Result<FileId> {
|
||||
let path = uri.to_file_path()
|
||||
.map_err(|()| format_err!("invalid uri: {}", uri))?;
|
||||
self.path_map.get_id(&path).ok_or_else(|| format_err!("unknown file: {}", path.display()))
|
||||
}
|
||||
|
||||
pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> {
|
||||
let path = self.path_map.get_path(id);
|
||||
let url = Url::from_file_path(path)
|
||||
.map_err(|()| format_err!("can't convert path to url: {}", path.display()))?;
|
||||
Ok(url)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue