mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 20:43:21 +00:00
Move cargo metadata off the main loop
This commit is contained in:
parent
83f3cdca4f
commit
6c7578bd7a
4 changed files with 56 additions and 43 deletions
|
@ -150,7 +150,7 @@ impl ProjectManifest {
|
|||
impl ProjectWorkspace {
|
||||
pub fn load(
|
||||
manifest: ProjectManifest,
|
||||
cargo_features: &CargoConfig,
|
||||
cargo_config: &CargoConfig,
|
||||
with_sysroot: bool,
|
||||
) -> Result<ProjectWorkspace> {
|
||||
let res = match manifest {
|
||||
|
@ -166,7 +166,7 @@ impl ProjectWorkspace {
|
|||
ProjectWorkspace::Json { project }
|
||||
}
|
||||
ProjectManifest::CargoToml(cargo_toml) => {
|
||||
let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features)
|
||||
let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_config)
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Failed to read Cargo metadata from Cargo.toml file {}",
|
||||
|
|
|
@ -21,6 +21,7 @@ use crate::{
|
|||
lsp_utils::{apply_document_changes, is_canceled, notification_is, Progress},
|
||||
Result,
|
||||
};
|
||||
use ra_project_model::ProjectWorkspace;
|
||||
|
||||
pub fn main_loop(config: Config, connection: Connection) -> Result<()> {
|
||||
log::info!("initial config: {:#?}", config);
|
||||
|
@ -58,6 +59,7 @@ enum Event {
|
|||
pub(crate) enum Task {
|
||||
Response(Response),
|
||||
Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>),
|
||||
Workspaces(Vec<anyhow::Result<ProjectWorkspace>>),
|
||||
Unit,
|
||||
}
|
||||
|
||||
|
@ -111,6 +113,14 @@ impl GlobalState {
|
|||
}
|
||||
|
||||
fn run(mut self, inbox: Receiver<lsp_server::Message>) -> Result<()> {
|
||||
if self.config.linked_projects.is_empty() && self.config.notifications.cargo_toml_not_found
|
||||
{
|
||||
self.show_message(
|
||||
lsp_types::MessageType::Error,
|
||||
"rust-analyzer failed to discover workspace".to_string(),
|
||||
);
|
||||
};
|
||||
|
||||
let registration_options = lsp_types::TextDocumentRegistrationOptions {
|
||||
document_selector: Some(vec![
|
||||
lsp_types::DocumentFilter {
|
||||
|
@ -140,7 +150,7 @@ impl GlobalState {
|
|||
|_, _| (),
|
||||
);
|
||||
|
||||
self.reload();
|
||||
self.fetch_workspaces();
|
||||
|
||||
while let Some(event) = self.next_event(&inbox) {
|
||||
if let Event::Lsp(lsp_server::Message::Notification(not)) = &event {
|
||||
|
@ -182,6 +192,7 @@ impl GlobalState {
|
|||
self.diagnostics.set_native_diagnostics(file_id, diagnostics)
|
||||
}
|
||||
}
|
||||
Task::Workspaces(workspaces) => self.switch_workspaces(workspaces),
|
||||
Task::Unit => (),
|
||||
}
|
||||
self.analysis_host.maybe_collect_garbage();
|
||||
|
@ -320,7 +331,7 @@ impl GlobalState {
|
|||
self.register_request(&req, request_received);
|
||||
|
||||
RequestDispatcher { req: Some(req), global_state: self }
|
||||
.on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.reload()))?
|
||||
.on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces()))?
|
||||
.on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))?
|
||||
.on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))?
|
||||
.on_sync::<lsp_types::request::Shutdown>(|_, ()| Ok(()))?
|
||||
|
|
|
@ -11,6 +11,7 @@ use vfs::{file_set::FileSetConfig, AbsPath};
|
|||
use crate::{
|
||||
config::{Config, FilesWatcher, LinkedProject},
|
||||
global_state::{GlobalState, Handle},
|
||||
main_loop::Task,
|
||||
};
|
||||
|
||||
impl GlobalState {
|
||||
|
@ -20,51 +21,51 @@ impl GlobalState {
|
|||
self.analysis_host.update_lru_capacity(old_config.lru_capacity);
|
||||
}
|
||||
if self.config.linked_projects != old_config.linked_projects {
|
||||
self.reload()
|
||||
self.fetch_workspaces()
|
||||
} else if self.config.flycheck != old_config.flycheck {
|
||||
self.reload_flycheck();
|
||||
}
|
||||
}
|
||||
pub(crate) fn reload(&mut self) {
|
||||
log::info!("reloading projects: {:?}", self.config.linked_projects);
|
||||
if self.config.linked_projects.is_empty() && self.config.notifications.cargo_toml_not_found
|
||||
{
|
||||
self.show_message(
|
||||
lsp_types::MessageType::Error,
|
||||
"rust-analyzer failed to discover workspace".to_string(),
|
||||
);
|
||||
};
|
||||
|
||||
let workspaces = {
|
||||
self.config
|
||||
.linked_projects
|
||||
.iter()
|
||||
.map(|project| match project {
|
||||
LinkedProject::ProjectManifest(manifest) => {
|
||||
ra_project_model::ProjectWorkspace::load(
|
||||
manifest.clone(),
|
||||
&self.config.cargo,
|
||||
self.config.with_sysroot,
|
||||
)
|
||||
}
|
||||
LinkedProject::InlineJsonProject(it) => {
|
||||
Ok(ra_project_model::ProjectWorkspace::Json { project: it.clone() })
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
.filter_map(|res| {
|
||||
res.map_err(|err| {
|
||||
log::error!("failed to load workspace: {:#}", err);
|
||||
self.show_message(
|
||||
lsp_types::MessageType::Error,
|
||||
format!("rust-analyzer failed to load workspace: {:#}", err),
|
||||
);
|
||||
pub(crate) fn fetch_workspaces(&mut self) {
|
||||
self.task_pool.handle.spawn({
|
||||
let linked_projects = self.config.linked_projects.clone();
|
||||
let cargo_config = self.config.cargo.clone();
|
||||
let with_sysroot = self.config.with_sysroot.clone();
|
||||
move || {
|
||||
let workspaces = linked_projects
|
||||
.iter()
|
||||
.map(|project| match project {
|
||||
LinkedProject::ProjectManifest(manifest) => {
|
||||
ra_project_model::ProjectWorkspace::load(
|
||||
manifest.clone(),
|
||||
&cargo_config,
|
||||
with_sysroot,
|
||||
)
|
||||
}
|
||||
LinkedProject::InlineJsonProject(it) => {
|
||||
Ok(ra_project_model::ProjectWorkspace::Json { project: it.clone() })
|
||||
}
|
||||
})
|
||||
.ok()
|
||||
.collect::<Vec<_>>();
|
||||
Task::Workspaces(workspaces)
|
||||
}
|
||||
});
|
||||
}
|
||||
pub(crate) fn switch_workspaces(&mut self, workspaces: Vec<anyhow::Result<ProjectWorkspace>>) {
|
||||
log::info!("reloading projects: {:?}", self.config.linked_projects);
|
||||
let workspaces = workspaces
|
||||
.into_iter()
|
||||
.filter_map(|res| {
|
||||
res.map_err(|err| {
|
||||
log::error!("failed to load workspace: {:#}", err);
|
||||
self.show_message(
|
||||
lsp_types::MessageType::Error,
|
||||
format!("rust-analyzer failed to load workspace: {:#}", err),
|
||||
);
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
.ok()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if let FilesWatcher::Client = self.config.files.watcher {
|
||||
let registration_options = lsp_types::DidChangeWatchedFilesRegistrationOptions {
|
||||
|
|
|
@ -447,6 +447,7 @@ version = \"0.0.0\"
|
|||
",
|
||||
)
|
||||
.server();
|
||||
server.wait_until_workspace_is_loaded();
|
||||
|
||||
server.request::<OnEnter>(
|
||||
TextDocumentPositionParams {
|
||||
|
|
Loading…
Reference in a new issue