Report config errors via status

This commit is contained in:
Lukas Wirth 2023-05-26 15:21:00 +02:00
parent 79fe11ced3
commit a2b59b110f
5 changed files with 19 additions and 14 deletions

View File

@ -720,11 +720,11 @@ pub struct ClientCommandsConfig {
}
#[derive(Debug)]
pub struct ConfigUpdateError {
pub struct ConfigError {
errors: Vec<(String, serde_json::Error)>,
}
impl fmt::Display for ConfigUpdateError {
impl fmt::Display for ConfigError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let errors = self.errors.iter().format_with("\n", |(key, e), f| {
f(key)?;
@ -733,7 +733,7 @@ impl fmt::Display for ConfigUpdateError {
});
write!(
f,
"rust-analyzer found {} invalid config value{}:\n{}",
"invalid config value{}:\n{}",
self.errors.len(),
if self.errors.len() == 1 { "" } else { "s" },
errors
@ -777,7 +777,7 @@ impl Config {
self.workspace_roots.extend(paths);
}
pub fn update(&mut self, mut json: serde_json::Value) -> Result<(), ConfigUpdateError> {
pub fn update(&mut self, mut json: serde_json::Value) -> Result<(), ConfigError> {
tracing::info!("updating config from JSON: {:#}", json);
if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) {
return Ok(());
@ -824,7 +824,7 @@ impl Config {
if errors.is_empty() {
Ok(())
} else {
Err(ConfigUpdateError { errors })
Err(ConfigError { errors })
}
}

View File

@ -19,7 +19,7 @@ use triomphe::Arc;
use vfs::AnchoredPathBuf;
use crate::{
config::Config,
config::{Config, ConfigError},
diagnostics::{CheckFixes, DiagnosticCollection},
from_proto,
line_index::{LineEndings, LineIndex},
@ -56,6 +56,7 @@ pub(crate) struct GlobalState {
pub(crate) task_pool: Handle<TaskPool<Task>, Receiver<Task>>,
pub(crate) config: Arc<Config>,
pub(crate) config_errors: Option<ConfigError>,
pub(crate) analysis_host: AnalysisHost,
pub(crate) diagnostics: DiagnosticCollection,
pub(crate) mem_docs: MemDocs,
@ -168,6 +169,7 @@ impl GlobalState {
shutdown_requested: false,
last_reported_status: None,
source_root_config: SourceRootConfig::default(),
config_errors: Default::default(),
proc_macro_changed: false,
// FIXME: use `Arc::from_iter` when it becomes available

View File

@ -169,13 +169,7 @@ pub(crate) fn handle_did_change_configuration(
// Note that json can be null according to the spec if the client can't
// provide a configuration. This is handled in Config::update below.
let mut config = Config::clone(&*this.config);
if let Err(error) = config.update(json.take()) {
this.show_message(
lsp_types::MessageType::WARNING,
error.to_string(),
false,
);
}
config.update(json.take());
this.update_configuration(config);
}
}

View File

@ -419,7 +419,11 @@ impl GlobalState {
if self.config.server_status_notification() {
self.send_notification::<lsp_ext::ServerStatusNotification>(status);
} else if let (health, Some(message)) = (status.health, &status.message) {
} else if let (
health @ (lsp_ext::Health::Warning | lsp_ext::Health::Error),
Some(message),
) = (status.health, &status.message)
{
let open_log_button = tracing::enabled!(tracing::Level::ERROR)
&& (self.fetch_build_data_error().is_err()
|| self.fetch_workspace_error().is_err());

View File

@ -27,6 +27,7 @@ use ide_db::{
use itertools::Itertools;
use proc_macro_api::{MacroDylib, ProcMacroServer};
use project_model::{PackageRoot, ProjectWorkspace, WorkspaceBuildScripts};
use stdx::format_to;
use syntax::SmolStr;
use triomphe::Arc;
use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind};
@ -134,6 +135,10 @@ impl GlobalState {
message.push_str("Failed to discover workspace.\n");
message.push_str("Consider adding the `Cargo.toml` of the workspace to the [`linkedProjects`](https://rust-analyzer.github.io/manual.html#rust-analyzer.linkedProjects) setting.\n\n");
}
if let Some(err) = &self.config_errors {
status.health = lsp_ext::Health::Warning;
format_to!(message, "{err}\n");
}
for ws in self.workspaces.iter() {
let (ProjectWorkspace::Cargo { sysroot, .. }