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