Prep dynamic workspace loading

This commit is contained in:
Aleksey Kladov
2020-06-25 23:26:21 +02:00
parent 73d73077fe
commit 3d0f782138
2 changed files with 79 additions and 96 deletions

View File

@@ -11,17 +11,14 @@ use lsp_types::{notification::Notification as _, request::Request as _};
use ra_db::VfsPath;
use ra_ide::{Canceled, FileId};
use ra_prof::profile;
use ra_project_model::{PackageRoot, ProjectWorkspace};
use crate::{
config::{Config, FilesWatcher, LinkedProject},
config::Config,
dispatch::{NotificationDispatcher, RequestDispatcher},
from_proto,
global_state::{file_id_to_url, GlobalState, Status},
handlers, lsp_ext,
lsp_utils::{
apply_document_changes, is_canceled, notification_is, notification_new, show_message,
},
lsp_utils::{apply_document_changes, is_canceled, notification_is, notification_new},
Result,
};
@@ -47,81 +44,8 @@ pub fn main_loop(config: Config, connection: Connection) -> Result<()> {
SetThreadPriority(thread, thread_priority_above_normal);
}
let global_state = {
let workspaces = {
if config.linked_projects.is_empty() && config.notifications.cargo_toml_not_found {
show_message(
lsp_types::MessageType::Error,
"rust-analyzer failed to discover workspace".to_string(),
&connection.sender,
);
};
config
.linked_projects
.iter()
.filter_map(|project| match project {
LinkedProject::ProjectManifest(manifest) => {
ra_project_model::ProjectWorkspace::load(
manifest.clone(),
&config.cargo,
config.with_sysroot,
)
.map_err(|err| {
log::error!("failed to load workspace: {:#}", err);
show_message(
lsp_types::MessageType::Error,
format!("rust-analyzer failed to load workspace: {:#}", err),
&connection.sender,
);
})
.ok()
}
LinkedProject::InlineJsonProject(it) => {
Some(ra_project_model::ProjectWorkspace::Json { project: it.clone() })
}
})
.collect::<Vec<_>>()
};
let mut req_queue = ReqQueue::default();
if let FilesWatcher::Client = config.files.watcher {
let registration_options = lsp_types::DidChangeWatchedFilesRegistrationOptions {
watchers: workspaces
.iter()
.flat_map(ProjectWorkspace::to_roots)
.filter(PackageRoot::is_member)
.map(|root| format!("{}/**/*.rs", root.path().display()))
.map(|glob_pattern| lsp_types::FileSystemWatcher { glob_pattern, kind: None })
.collect(),
};
let registration = lsp_types::Registration {
id: "file-watcher".to_string(),
method: "workspace/didChangeWatchedFiles".to_string(),
register_options: Some(serde_json::to_value(registration_options).unwrap()),
};
let params = lsp_types::RegistrationParams { registrations: vec![registration] };
let request = req_queue.outgoing.register(
lsp_types::request::RegisterCapability::METHOD.to_string(),
params,
DO_NOTHING,
);
connection.sender.send(request.into()).unwrap();
}
GlobalState::new(
connection.sender.clone(),
workspaces,
config.lru_capacity,
config,
req_queue,
)
};
log::info!("server initialized, serving requests");
global_state.run(connection.receiver)?;
Ok(())
GlobalState::new(connection.sender.clone(), config.lru_capacity, config)
.run(connection.receiver)
}
enum Event {
@@ -188,23 +112,26 @@ impl GlobalState {
}
fn run(mut self, inbox: Receiver<lsp_server::Message>) -> Result<()> {
self.reload();
while let Some(event) = self.next_event(&inbox) {
if let Event::Lsp(lsp_server::Message::Notification(not)) = &event {
if not.method == lsp_types::notification::Exit::METHOD {
return Ok(());
}
}
self.loop_turn(event)?
self.handle_event(event)?
}
Err("client exited without proper shutdown sequence")?
}
fn loop_turn(&mut self, event: Event) -> Result<()> {
fn handle_event(&mut self, event: Event) -> Result<()> {
let loop_start = Instant::now();
// NOTE: don't count blocking select! call as a loop-turn time
let _p = profile("main_loop_inner/loop-turn");
let _p = profile("GlobalState::handle_event");
log::info!("loop turn = {:?}", event);
log::info!("handle_event({:?})", event);
let queue_count = self.task_pool.0.len();
if queue_count > 0 {
log::info!("queued count = {}", queue_count);