feat(diagnostics): add new config to fill default expression

Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
This commit is contained in:
Benjamin Coenen 2021-12-31 16:11:17 +01:00
parent 0435463439
commit df6fa50f92
6 changed files with 69 additions and 13 deletions

View file

@ -118,7 +118,7 @@ pub use ide_db::{
symbol_index::Query,
RootDatabase, SymbolKind,
};
pub use ide_diagnostics::{Diagnostic, DiagnosticsConfig, Severity};
pub use ide_diagnostics::{Diagnostic, DiagnosticsConfig, ExprFillDefaultMode, Severity};
pub use ide_ssr::SsrError;
pub use syntax::{TextRange, TextSize};
pub use text_edit::{Indel, TextEdit};

View file

@ -64,15 +64,18 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
});
let missing_fields = ctx.sema.record_literal_missing_fields(&field_list_parent);
let generate_default_expr = |ty: &Type| {
let krate = ctx.sema.to_module_def(d.file.original_file(ctx.sema.db))?.krate();
let default_trait = FamousDefs(&ctx.sema, Some(krate)).core_default_Default();
let generate_fill_expr = |ty: &Type| match ctx.config.expr_fill_default {
crate::ExprFillDefaultMode::Todo => Some(make::ext::expr_todo()),
crate::ExprFillDefaultMode::DefaultImpl => {
let krate = ctx.sema.to_module_def(d.file.original_file(ctx.sema.db))?.krate();
let default_trait = FamousDefs(&ctx.sema, Some(krate)).core_default_Default();
match default_trait {
Some(default_trait) if ty.impls_trait(ctx.sema.db, default_trait, &[]) => {
Some(make::ext::expr_default())
match default_trait {
Some(default_trait) if ty.impls_trait(ctx.sema.db, default_trait, &[]) => {
Some(make::ext::expr_default())
}
_ => Some(make::ext::expr_todo()),
}
_ => Some(make::ext::expr_todo()),
}
};
@ -83,10 +86,10 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
if ty.could_unify_with(ctx.sema.db, &candidate_ty) {
None
} else {
generate_default_expr(ty)
generate_fill_expr(ty)
}
} else {
generate_default_expr(ty)
generate_fill_expr(ty)
};
let field =
make::record_expr_field(make::name_ref(&f.name(ctx.sema.db).to_smol_str()), field_expr)

View file

@ -129,10 +129,22 @@ pub enum Severity {
WeakWarning,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ExprFillDefaultMode {
Todo,
DefaultImpl,
}
impl Default for ExprFillDefaultMode {
fn default() -> Self {
Self::Todo
}
}
#[derive(Default, Debug, Clone)]
pub struct DiagnosticsConfig {
pub disable_experimental: bool,
pub disabled: FxHashSet<String>,
pub expr_fill_default: ExprFillDefaultMode,
}
struct DiagnosticsContext<'a> {

View file

@ -11,8 +11,8 @@ use std::{ffi::OsString, iter, path::PathBuf};
use flycheck::FlycheckConfig;
use ide::{
AssistConfig, CompletionConfig, DiagnosticsConfig, HighlightRelatedConfig, HoverConfig,
HoverDocFormat, InlayHintsConfig, JoinLinesConfig, Snippet, SnippetScope,
AssistConfig, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode, HighlightRelatedConfig,
HoverConfig, HoverDocFormat, InlayHintsConfig, JoinLinesConfig, Snippet, SnippetScope,
};
use ide_db::helpers::{
insert_use::{ImportGranularity, InsertUseConfig, PrefixKind},
@ -45,6 +45,8 @@ use crate::{
// parsing the old name.
config_data! {
struct ConfigData {
/// How assists will fill missing elements in an expression.
assist_exprFillDefault: ExprFillDefaultDef = "\"todo\"",
/// How imports should be grouped into use statements.
assist_importGranularity |
assist_importMergeBehavior |
@ -694,6 +696,10 @@ impl Config {
DiagnosticsConfig {
disable_experimental: !self.data.diagnostics_enableExperimental,
disabled: self.data.diagnostics_disabled.clone(),
expr_fill_default: match self.data.assist_exprFillDefault {
ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo,
ExprFillDefaultDef::DefaultImpl => ExprFillDefaultMode::DefaultImpl,
},
}
}
pub fn diagnostics_map(&self) -> DiagnosticsMapConfig {
@ -1059,6 +1065,15 @@ enum ManifestOrProjectJson {
ProjectJson(ProjectJsonData),
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
pub enum ExprFillDefaultDef {
#[serde(alias = "todo")]
Todo,
#[serde(alias = "defaultImpl")]
DefaultImpl,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
enum ImportGranularityDef {
@ -1253,6 +1268,14 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
"Merge imports from the same module into a single `use` statement."
],
},
"ExprFillDefaultDef" => set! {
"type": "string",
"enum": ["todo", "defaultImpl"],
"enumDescriptions": [
"Fill missing elements with 'todo' macro",
"Fill missing elements with Default::default()"
],
},
"ImportGranularityDef" => set! {
"type": "string",
"enum": ["preserve", "crate", "module", "item"],

View file

@ -1,3 +1,8 @@
[[rust-analyzer.assist.exprFillDefault]]rust-analyzer.assist.exprFillDefault (default: `"todo"`)::
+
--
How assists will fill missing elements in an expression.
--
[[rust-analyzer.assist.importGranularity]]rust-analyzer.assist.importGranularity (default: `"crate"`)::
+
--

View file

@ -378,6 +378,19 @@
"markdownDescription": "Optional settings passed to the debug engine. Example: `{ \"lldb\": { \"terminal\":\"external\"} }`"
},
"$generated-start": {},
"rust-analyzer.assist.exprFillDefault": {
"markdownDescription": "How assists will fill missing elements in an expression.",
"default": "todo",
"type": "string",
"enum": [
"todo",
"defaultImpl"
],
"enumDescriptions": [
"Fill missing elements with 'todo' macro",
"Fill missing elements with Default::default()"
]
},
"rust-analyzer.assist.importGranularity": {
"markdownDescription": "How imports should be grouped into use statements.",
"default": "crate",