index libraies off the main thread

This commit is contained in:
Aleksey Kladov 2018-09-03 21:26:59 +03:00
parent 47cbaeba6f
commit 5ba645c009
5 changed files with 39 additions and 13 deletions

View file

@ -57,9 +57,8 @@ impl AnalysisHostImpl {
} }
self.data_mut().crate_graph = graph; self.data_mut().crate_graph = graph;
} }
pub fn add_library(&mut self, files: impl Iterator<Item=(FileId, String)>) { pub fn add_library(&mut self, root: ReadonlySourceRoot) {
let libs = ReadonlySourceRoot::new(files); self.data_mut().libs.push(Arc::new(root));
self.data_mut().libs.push(Arc::new(libs));
} }
fn data_mut(&mut self) -> &mut WorldData { fn data_mut(&mut self) -> &mut WorldData {
Arc::make_mut(&mut self.data) Arc::make_mut(&mut self.data)

View file

@ -68,8 +68,8 @@ impl AnalysisHost {
pub fn set_crate_graph(&mut self, graph: CrateGraph) { pub fn set_crate_graph(&mut self, graph: CrateGraph) {
self.imp.set_crate_graph(graph) self.imp.set_crate_graph(graph)
} }
pub fn add_library(&mut self, files: impl Iterator<Item=(FileId, String)>) { pub fn add_library(&mut self, data: LibraryData) {
self.imp.add_library(files) self.imp.add_library(data.root)
} }
} }
@ -216,3 +216,15 @@ impl Analysis {
self.imp.diagnostics(file_id) self.imp.diagnostics(file_id)
} }
} }
#[derive(Debug)]
pub struct LibraryData {
root: roots::ReadonlySourceRoot
}
impl LibraryData {
pub fn prepare(files: Vec<(FileId, String)>) -> LibraryData {
let root = roots::ReadonlySourceRoot::new(files);
LibraryData { root }
}
}

View file

@ -136,9 +136,10 @@ pub(crate) struct ReadonlySourceRoot {
} }
impl ReadonlySourceRoot { impl ReadonlySourceRoot {
pub fn new(files: impl Iterator<Item=(FileId, String)>) -> ReadonlySourceRoot { pub fn new(files: Vec<(FileId, String)>) -> ReadonlySourceRoot {
let mut module_map = ModuleMap::new(); let mut module_map = ModuleMap::new();
let file_map: HashMap<FileId, FileData> = files let file_map: HashMap<FileId, FileData> = files
.into_iter()
.map(|(id, text)| { .map(|(id, text)| {
module_map.update_file(id, ChangeKind::Insert); module_map.update_file(id, ChangeKind::Insert);
(id, FileData::new(text)) (id, FileData::new(text))

View file

@ -10,7 +10,7 @@ use threadpool::ThreadPool;
use serde::{Serialize, de::DeserializeOwned}; use serde::{Serialize, de::DeserializeOwned};
use crossbeam_channel::{bounded, Sender, Receiver}; use crossbeam_channel::{bounded, Sender, Receiver};
use languageserver_types::{NumberOrString}; use languageserver_types::{NumberOrString};
use libanalysis::{FileId, JobHandle, JobToken}; use libanalysis::{FileId, JobHandle, JobToken, LibraryData};
use gen_lsp_server::{ use gen_lsp_server::{
RawRequest, RawNotification, RawMessage, RawResponse, ErrorCode, RawRequest, RawNotification, RawMessage, RawResponse, ErrorCode,
handle_shutdown, handle_shutdown,
@ -94,6 +94,7 @@ fn main_loop_inner(
pending_requests: &mut HashMap<u64, JobHandle>, pending_requests: &mut HashMap<u64, JobHandle>,
subs: &mut Subscriptions, subs: &mut Subscriptions,
) -> Result<()> { ) -> Result<()> {
let (libdata_sender, libdata_receiver) = bounded(1024);
ws_sender.send(ws_root.clone()); ws_sender.send(ws_root.clone());
fs_sender.send(ws_root.clone()); fs_sender.send(ws_root.clone());
loop { loop {
@ -103,6 +104,7 @@ fn main_loop_inner(
Task(Task), Task(Task),
Fs(PathBuf, Vec<FileEvent>), Fs(PathBuf, Vec<FileEvent>),
Ws(Result<CargoWorkspace>), Ws(Result<CargoWorkspace>),
Lib(LibraryData),
} }
trace!("selecting"); trace!("selecting");
let event = select! { let event = select! {
@ -119,6 +121,7 @@ fn main_loop_inner(
None => bail!("workspace watcher died"), None => bail!("workspace watcher died"),
Some(ws) => Event::Ws(ws), Some(ws) => Event::Ws(ws),
} }
recv(libdata_receiver, data) => Event::Lib(data.unwrap())
}; };
trace!("selected {:?}", event); trace!("selected {:?}", event);
let mut state_changed = false; let mut state_changed = false;
@ -129,7 +132,12 @@ fn main_loop_inner(
if root == ws_root { if root == ws_root {
state.apply_fs_changes(events); state.apply_fs_changes(events);
} else { } else {
state.add_library(events); let files = state.events_to_files(events);
let sender = libdata_sender.clone();
pool.execute(move || {
let data = LibraryData::prepare(files);
sender.send(data);
});
} }
state_changed = true; state_changed = true;
} }
@ -152,6 +160,9 @@ fn main_loop_inner(
Err(e) => warn!("loading workspace failed: {}", e), Err(e) => warn!("loading workspace failed: {}", e),
} }
} }
Event::Lib(lib) => {
state.add_lib(lib);
}
Event::Msg(msg) => { Event::Msg(msg) => {
match msg { match msg {
RawMessage::Request(req) => { RawMessage::Request(req) => {

View file

@ -6,7 +6,7 @@ use std::{
}; };
use languageserver_types::Url; use languageserver_types::Url;
use libanalysis::{FileId, AnalysisHost, Analysis, CrateGraph, CrateId}; use libanalysis::{FileId, AnalysisHost, Analysis, CrateGraph, CrateId, LibraryData};
use { use {
Result, Result,
@ -64,17 +64,20 @@ impl ServerWorldState {
self.analysis_host.change_files(changes); self.analysis_host.change_files(changes);
} }
pub fn add_library(&mut self, events: Vec<FileEvent>) { pub fn events_to_files(&mut self, events: Vec<FileEvent>) -> Vec<(FileId, String)> {
let pm = &mut self.path_map; let pm = &mut self.path_map;
let files = events.into_iter() events.into_iter()
.map(|event| { .map(|event| {
let text = match event.kind { let text = match event.kind {
FileEventKind::Add(text) => text, FileEventKind::Add(text) => text,
}; };
(event.path, text) (event.path, text)
}) })
.map(|(path, text)| (pm.get_or_insert(path), text)); .map(|(path, text)| (pm.get_or_insert(path), text))
self.analysis_host.add_library(files); .collect()
}
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 { pub fn add_mem_file(&mut self, path: PathBuf, text: String) -> FileId {