This commit is contained in:
Aleksey Kladov 2018-12-19 15:40:42 +03:00
parent a5ef8ad05b
commit 7b6bafa631
5 changed files with 55 additions and 13 deletions

View file

@ -73,6 +73,7 @@ struct RemoveFile {
impl fmt::Debug for AnalysisChange { impl fmt::Debug for AnalysisChange {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("AnalysisChange") fmt.debug_struct("AnalysisChange")
.field("new_roots", &self.new_roots)
.field("roots_changed", &self.roots_changed) .field("roots_changed", &self.roots_changed)
.field("files_changed", &self.files_changed.len()) .field("files_changed", &self.files_changed.len())
.field("libraries_added", &self.libraries_added.len()) .field("libraries_added", &self.libraries_added.len())

View file

@ -143,6 +143,7 @@ fn main_loop_inner(
} }
recv(libdata_receiver, data) => Event::Lib(data.unwrap()) recv(libdata_receiver, data) => Event::Lib(data.unwrap())
}; };
log::info!("{:?}", event);
let mut state_changed = false; let mut state_changed = false;
match event { match event {
Event::Task(task) => on_task(task, msg_sender, pending_requests), Event::Task(task) => on_task(task, msg_sender, pending_requests),
@ -192,6 +193,9 @@ fn main_loop_inner(
sender.send(data); sender.send(data);
}); });
} }
if state.roots_to_scan == 0 {
feedback(internal_mode, "workspace loaded", msg_sender);
}
if state_changed { if state_changed {
update_file_notifications_on_threadpool( update_file_notifications_on_threadpool(

View file

@ -21,6 +21,8 @@ use crate::{
#[derive(Debug)] #[derive(Debug)]
pub struct ServerWorldState { pub struct ServerWorldState {
pub roots_to_scan: usize,
pub root: PathBuf,
pub workspaces: Arc<Vec<CargoWorkspace>>, pub workspaces: Arc<Vec<CargoWorkspace>>,
pub analysis_host: AnalysisHost, pub analysis_host: AnalysisHost,
pub vfs: Arc<RwLock<Vfs>>, pub vfs: Arc<RwLock<Vfs>>,
@ -37,12 +39,13 @@ impl ServerWorldState {
let mut change = AnalysisChange::new(); let mut change = AnalysisChange::new();
let mut roots = Vec::new(); let mut roots = Vec::new();
roots.push(root); roots.push(root.clone());
for ws in workspaces.iter() { for ws in workspaces.iter() {
for pkg in ws.packages() { for pkg in ws.packages() {
roots.push(pkg.root(&ws).to_path_buf()); roots.push(pkg.root(&ws).to_path_buf());
} }
} }
let roots_to_scan = roots.len();
let (mut vfs, roots) = Vfs::new(roots); let (mut vfs, roots) = Vfs::new(roots);
for r in roots { for r in roots {
change.add_root(SourceRootId(r.0)); change.add_root(SourceRootId(r.0));
@ -83,6 +86,8 @@ impl ServerWorldState {
let mut analysis_host = AnalysisHost::default(); let mut analysis_host = AnalysisHost::default();
analysis_host.apply_change(change); analysis_host.apply_change(change);
ServerWorldState { ServerWorldState {
roots_to_scan,
root,
workspaces: Arc::new(workspaces), workspaces: Arc::new(workspaces),
analysis_host, analysis_host,
vfs: Arc::new(RwLock::new(vfs)), vfs: Arc::new(RwLock::new(vfs)),
@ -94,16 +99,29 @@ impl ServerWorldState {
pub fn process_changes( pub fn process_changes(
&mut self, &mut self,
) -> Vec<(SourceRootId, Vec<(FileId, RelativePathBuf, Arc<String>)>)> { ) -> Vec<(SourceRootId, Vec<(FileId, RelativePathBuf, Arc<String>)>)> {
let changes = self.vfs.write().commit_changes();
if changes.is_empty() {
return Vec::new();
}
let mut libs = Vec::new(); let mut libs = Vec::new();
let mut change = AnalysisChange::new(); let mut change = AnalysisChange::new();
for c in self.vfs.write().commit_changes() { for c in changes {
log::info!("vfs change {:?}", c);
match c { match c {
VfsChange::AddRoot { root, files } => { VfsChange::AddRoot { root, files } => {
let files = files let root_path = self.vfs.read().root2path(root);
.into_iter() if root_path.starts_with(&self.root) {
.map(|(vfsfile, path, text)| (FileId(vfsfile.0), path, text)) self.roots_to_scan -= 1;
.collect(); for (file, path, text) in files {
libs.push((SourceRootId(root.0), files)); change.add_file(SourceRootId(root.0), FileId(file.0), path, text);
}
} else {
let files = files
.into_iter()
.map(|(vfsfile, path, text)| (FileId(vfsfile.0), path, text))
.collect();
libs.push((SourceRootId(root.0), files));
}
} }
VfsChange::AddFile { VfsChange::AddFile {
root, root,
@ -126,6 +144,7 @@ impl ServerWorldState {
} }
pub fn add_lib(&mut self, data: LibraryData) { pub fn add_lib(&mut self, data: LibraryData) {
self.roots_to_scan -= 1;
let mut change = AnalysisChange::new(); let mut change = AnalysisChange::new();
change.add_library(data); change.add_library(data);
self.analysis_host.apply_change(change); self.analysis_host.apply_change(change);

View file

@ -1,9 +1,7 @@
mod support; mod support;
use serde_json::json; use serde_json::json;
use ra_lsp_server::req::{Runnables, RunnablesParams, CodeActionRequest, CodeActionParams}; use ra_lsp_server::req::{Runnables, RunnablesParams, CodeActionRequest, CodeActionParams};
use languageserver_types::{Position, Range, CodeActionContext}; use languageserver_types::{Position, Range, CodeActionContext};
use crate::support::project; use crate::support::project;
@ -20,6 +18,7 @@ fn foo() {
} }
", ",
); );
server.wait_for_feedback("workspace loaded");
server.request::<Runnables>( server.request::<Runnables>(
RunnablesParams { RunnablesParams {
text_document: server.doc_id("lib.rs"), text_document: server.doc_id("lib.rs"),

View file

@ -132,6 +132,7 @@ impl Vfs {
roots.sort_by_key(|it| Reverse(it.as_os_str().len())); roots.sort_by_key(|it| Reverse(it.as_os_str().len()));
for (i, path) in roots.iter().enumerate() { for (i, path) in roots.iter().enumerate() {
let root = res.roots.alloc(RootFilter::new(path.clone())); let root = res.roots.alloc(RootFilter::new(path.clone()));
res.root2files.insert(root, Default::default());
let nested = roots[..i] let nested = roots[..i]
.iter() .iter()
.filter(|it| it.starts_with(path)) .filter(|it| it.starts_with(path))
@ -155,6 +156,10 @@ impl Vfs {
(res, roots) (res, roots)
} }
pub fn root2path(&self, root: VfsRoot) -> PathBuf {
self.roots[root].root.clone()
}
pub fn path2file(&self, path: &Path) -> Option<VfsFile> { pub fn path2file(&self, path: &Path) -> Option<VfsFile> {
if let Some((_root, _path, Some(file))) = self.find_root(path) { if let Some((_root, _path, Some(file))) = self.find_root(path) {
return Some(file); return Some(file);
@ -176,6 +181,23 @@ impl Vfs {
} }
pub fn load(&mut self, path: &Path) -> Option<VfsFile> { pub fn load(&mut self, path: &Path) -> Option<VfsFile> {
if let Some((root, rel_path, file)) = self.find_root(path) {
return if let Some(file) = file {
Some(file)
} else {
let text = fs::read_to_string(path).unwrap_or_default();
let text = Arc::new(text);
let file = self.add_file(root, rel_path.clone(), Arc::clone(&text));
let change = VfsChange::AddFile {
file,
text,
root,
path: rel_path,
};
self.pending_changes.push(change);
Some(file)
};
}
None None
} }
@ -262,10 +284,7 @@ impl Vfs {
fn add_file(&mut self, root: VfsRoot, path: RelativePathBuf, text: Arc<String>) -> VfsFile { fn add_file(&mut self, root: VfsRoot, path: RelativePathBuf, text: Arc<String>) -> VfsFile {
let data = VfsFileData { root, path, text }; let data = VfsFileData { root, path, text };
let file = self.files.alloc(data); let file = self.files.alloc(data);
self.root2files self.root2files.get_mut(&root).unwrap().insert(file);
.entry(root)
.or_insert_with(FxHashSet::default)
.insert(file);
file file
} }