Provide a setting to disable showing rename conflicts
This commit is contained in:
parent
ec84b26c1c
commit
562b485585
14 changed files with 108 additions and 28 deletions
|
|
@ -9,6 +9,7 @@ use ide_db::{
|
|||
SnippetCap,
|
||||
assists::ExprFillDefaultMode,
|
||||
imports::{import_assets::ImportPathConfig, insert_use::InsertUseConfig},
|
||||
rename::RenameConfig,
|
||||
};
|
||||
|
||||
use crate::AssistKind;
|
||||
|
|
@ -27,6 +28,7 @@ pub struct AssistConfig {
|
|||
pub code_action_grouping: bool,
|
||||
pub expr_fill_default: ExprFillDefaultMode,
|
||||
pub prefer_self_ty: bool,
|
||||
pub show_rename_conflicts: bool,
|
||||
}
|
||||
|
||||
impl AssistConfig {
|
||||
|
|
@ -46,4 +48,8 @@ impl AssistConfig {
|
|||
allow_unstable,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rename_config(&self) -> RenameConfig {
|
||||
RenameConfig { show_conflicts: self.show_rename_conflicts }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ pub(crate) fn remove_underscore(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
|
|||
"Remove underscore from a used variable",
|
||||
text_range,
|
||||
|builder| {
|
||||
let changes = def.rename(&ctx.sema, new_name, RenameDefinition::Yes).unwrap();
|
||||
let changes = def
|
||||
.rename(&ctx.sema, new_name, RenameDefinition::Yes, &ctx.config.rename_config())
|
||||
.unwrap();
|
||||
builder.source_change = changes;
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig {
|
|||
code_action_grouping: true,
|
||||
expr_fill_default: ExprFillDefaultMode::Todo,
|
||||
prefer_self_ty: false,
|
||||
show_rename_conflicts: true,
|
||||
};
|
||||
|
||||
pub(crate) const TEST_CONFIG_NO_GROUPING: AssistConfig = AssistConfig {
|
||||
|
|
@ -59,6 +60,7 @@ pub(crate) const TEST_CONFIG_NO_GROUPING: AssistConfig = AssistConfig {
|
|||
code_action_grouping: false,
|
||||
expr_fill_default: ExprFillDefaultMode::Todo,
|
||||
prefer_self_ty: false,
|
||||
show_rename_conflicts: true,
|
||||
};
|
||||
|
||||
pub(crate) const TEST_CONFIG_NO_SNIPPET_CAP: AssistConfig = AssistConfig {
|
||||
|
|
@ -80,6 +82,7 @@ pub(crate) const TEST_CONFIG_NO_SNIPPET_CAP: AssistConfig = AssistConfig {
|
|||
code_action_grouping: true,
|
||||
expr_fill_default: ExprFillDefaultMode::Todo,
|
||||
prefer_self_ty: false,
|
||||
show_rename_conflicts: true,
|
||||
};
|
||||
|
||||
pub(crate) const TEST_CONFIG_IMPORT_ONE: AssistConfig = AssistConfig {
|
||||
|
|
@ -101,6 +104,7 @@ pub(crate) const TEST_CONFIG_IMPORT_ONE: AssistConfig = AssistConfig {
|
|||
code_action_grouping: true,
|
||||
expr_fill_default: ExprFillDefaultMode::Todo,
|
||||
prefer_self_ty: false,
|
||||
show_rename_conflicts: true,
|
||||
};
|
||||
|
||||
fn assists(
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ use crate::{
|
|||
traits::convert_to_def_in_trait,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct RenameConfig {
|
||||
pub show_conflicts: bool,
|
||||
}
|
||||
|
||||
pub type Result<T, E = RenameError> = std::result::Result<T, E>;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -81,6 +86,7 @@ impl Definition {
|
|||
sema: &Semantics<'_, RootDatabase>,
|
||||
new_name: &str,
|
||||
rename_definition: RenameDefinition,
|
||||
config: &RenameConfig,
|
||||
) -> Result<SourceChange> {
|
||||
// self.krate() returns None if
|
||||
// self is a built-in attr, built-in type or tool module.
|
||||
|
|
@ -109,10 +115,15 @@ impl Definition {
|
|||
bail!("Cannot rename a builtin attr.")
|
||||
}
|
||||
Definition::SelfType(_) => bail!("Cannot rename `Self`"),
|
||||
Definition::Macro(mac) => {
|
||||
rename_reference(sema, Definition::Macro(mac), new_name, rename_definition, edition)
|
||||
}
|
||||
def => rename_reference(sema, def, new_name, rename_definition, edition),
|
||||
Definition::Macro(mac) => rename_reference(
|
||||
sema,
|
||||
Definition::Macro(mac),
|
||||
new_name,
|
||||
rename_definition,
|
||||
edition,
|
||||
config,
|
||||
),
|
||||
def => rename_reference(sema, def, new_name, rename_definition, edition, config),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -338,6 +349,7 @@ fn rename_reference(
|
|||
new_name: &str,
|
||||
rename_definition: RenameDefinition,
|
||||
edition: Edition,
|
||||
config: &RenameConfig,
|
||||
) -> Result<SourceChange> {
|
||||
let (mut new_name, ident_kind) = IdentifierKind::classify(edition, new_name)?;
|
||||
|
||||
|
|
@ -396,7 +408,8 @@ fn rename_reference(
|
|||
if rename_definition == RenameDefinition::Yes {
|
||||
// This needs to come after the references edits, because we change the annotation of existing edits
|
||||
// if a conflict is detected.
|
||||
let (file_id, edit) = source_edit_from_def(sema, def, &new_name, &mut source_change)?;
|
||||
let (file_id, edit) =
|
||||
source_edit_from_def(sema, config, def, &new_name, &mut source_change)?;
|
||||
source_change.insert_source_edit(file_id, edit);
|
||||
}
|
||||
Ok(source_change)
|
||||
|
|
@ -554,6 +567,7 @@ fn source_edit_from_name_ref(
|
|||
|
||||
fn source_edit_from_def(
|
||||
sema: &Semantics<'_, RootDatabase>,
|
||||
config: &RenameConfig,
|
||||
def: Definition,
|
||||
new_name: &Name,
|
||||
source_change: &mut SourceChange,
|
||||
|
|
@ -562,21 +576,22 @@ fn source_edit_from_def(
|
|||
if let Definition::Local(local) = def {
|
||||
let mut file_id = None;
|
||||
|
||||
let conflict_annotation = if !sema.rename_conflicts(&local, new_name).is_empty() {
|
||||
Some(
|
||||
source_change.insert_annotation(ChangeAnnotation {
|
||||
label: "This rename will change the program's meaning".to_owned(),
|
||||
needs_confirmation: true,
|
||||
description: Some(
|
||||
"Some variable(s) will shadow the renamed variable \
|
||||
let conflict_annotation =
|
||||
if config.show_conflicts && !sema.rename_conflicts(&local, new_name).is_empty() {
|
||||
Some(
|
||||
source_change.insert_annotation(ChangeAnnotation {
|
||||
label: "This rename will change the program's meaning".to_owned(),
|
||||
needs_confirmation: true,
|
||||
description: Some(
|
||||
"Some variable(s) will shadow the renamed variable \
|
||||
or be shadowed by it if the rename is performed"
|
||||
.to_owned(),
|
||||
),
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
.to_owned(),
|
||||
),
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
for source in local.sources(sema.db) {
|
||||
let source = match source.source.clone().original_ast_node_rooted(sema.db) {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,12 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::IncorrectCase) -> Option<Vec<Ass
|
|||
let label = format!("Rename to {}", d.suggested_text);
|
||||
let mut res = unresolved_fix("change_case", &label, frange.range);
|
||||
if ctx.resolve.should_resolve(&res.id) {
|
||||
let source_change = def.rename(&ctx.sema, &d.suggested_text, RenameDefinition::Yes);
|
||||
let source_change = def.rename(
|
||||
&ctx.sema,
|
||||
&d.suggested_text,
|
||||
RenameDefinition::Yes,
|
||||
&ctx.config.rename_config(),
|
||||
);
|
||||
res.source_change = Some(source_change.ok().unwrap_or_default());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ use ide_db::{
|
|||
generated::lints::{CLIPPY_LINT_GROUPS, DEFAULT_LINT_GROUPS, DEFAULT_LINTS, Lint, LintGroup},
|
||||
imports::insert_use::InsertUseConfig,
|
||||
label::Label,
|
||||
rename::RenameConfig,
|
||||
source_change::SourceChange,
|
||||
syntax_helpers::node_ext::parse_tt_as_comma_sep_paths,
|
||||
};
|
||||
|
|
@ -236,6 +237,7 @@ pub struct DiagnosticsConfig {
|
|||
pub prefer_absolute: bool,
|
||||
pub term_search_fuel: u64,
|
||||
pub term_search_borrowck: bool,
|
||||
pub show_rename_conflicts: bool,
|
||||
}
|
||||
|
||||
impl DiagnosticsConfig {
|
||||
|
|
@ -264,8 +266,13 @@ impl DiagnosticsConfig {
|
|||
prefer_absolute: false,
|
||||
term_search_fuel: 400,
|
||||
term_search_borrowck: true,
|
||||
show_rename_conflicts: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rename_config(&self) -> RenameConfig {
|
||||
RenameConfig { show_conflicts: self.show_rename_conflicts }
|
||||
}
|
||||
}
|
||||
|
||||
struct DiagnosticsContext<'a> {
|
||||
|
|
|
|||
|
|
@ -846,8 +846,9 @@ impl Analysis {
|
|||
&self,
|
||||
file_id: FileId,
|
||||
new_name_stem: &str,
|
||||
config: &RenameConfig,
|
||||
) -> Cancellable<Option<SourceChange>> {
|
||||
self.with_db(|db| rename::will_rename_file(db, file_id, new_name_stem))
|
||||
self.with_db(|db| rename::will_rename_file(db, file_id, new_name_stem, config))
|
||||
}
|
||||
|
||||
pub fn structural_search_replace(
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ pub struct RenameConfig {
|
|||
pub prefer_no_std: bool,
|
||||
pub prefer_prelude: bool,
|
||||
pub prefer_absolute: bool,
|
||||
pub show_conflicts: bool,
|
||||
}
|
||||
|
||||
impl RenameConfig {
|
||||
|
|
@ -42,6 +43,10 @@ impl RenameConfig {
|
|||
allow_unstable: true,
|
||||
}
|
||||
}
|
||||
|
||||
fn ide_db_config(&self) -> ide_db::rename::RenameConfig {
|
||||
ide_db::rename::RenameConfig { show_conflicts: self.show_conflicts }
|
||||
}
|
||||
}
|
||||
|
||||
/// This is similar to `collect::<Result<Vec<_>, _>>`, but unlike it, it succeeds if there is *any* `Ok` item.
|
||||
|
|
@ -190,7 +195,7 @@ pub(crate) fn rename(
|
|||
return rename_to_self(&sema, local);
|
||||
}
|
||||
}
|
||||
def.rename(&sema, new_name.as_str(), rename_def)
|
||||
def.rename(&sema, new_name.as_str(), rename_def, &config.ide_db_config())
|
||||
})),
|
||||
};
|
||||
|
||||
|
|
@ -205,11 +210,13 @@ pub(crate) fn will_rename_file(
|
|||
db: &RootDatabase,
|
||||
file_id: FileId,
|
||||
new_name_stem: &str,
|
||||
config: &RenameConfig,
|
||||
) -> Option<SourceChange> {
|
||||
let sema = Semantics::new(db);
|
||||
let module = sema.file_to_module_def(file_id)?;
|
||||
let def = Definition::Module(module);
|
||||
let mut change = def.rename(&sema, new_name_stem, RenameDefinition::Yes).ok()?;
|
||||
let mut change =
|
||||
def.rename(&sema, new_name_stem, RenameDefinition::Yes, &config.ide_db_config()).ok()?;
|
||||
change.file_system_edits.clear();
|
||||
Some(change)
|
||||
}
|
||||
|
|
@ -803,8 +810,12 @@ mod tests {
|
|||
|
||||
use super::{RangeInfo, RenameConfig, RenameError};
|
||||
|
||||
const TEST_CONFIG: RenameConfig =
|
||||
RenameConfig { prefer_no_std: false, prefer_prelude: true, prefer_absolute: false };
|
||||
const TEST_CONFIG: RenameConfig = RenameConfig {
|
||||
prefer_no_std: false,
|
||||
prefer_prelude: true,
|
||||
prefer_absolute: false,
|
||||
show_conflicts: true,
|
||||
};
|
||||
|
||||
#[track_caller]
|
||||
fn check(
|
||||
|
|
@ -893,7 +904,7 @@ mod tests {
|
|||
) {
|
||||
let (analysis, position) = fixture::position(ra_fixture);
|
||||
let source_change = analysis
|
||||
.will_rename_file(position.file_id, new_name)
|
||||
.will_rename_file(position.file_id, new_name, &TEST_CONFIG)
|
||||
.unwrap()
|
||||
.expect("Expect returned a RenameError");
|
||||
expect.assert_eq(&filter_expect(source_change))
|
||||
|
|
|
|||
|
|
@ -1153,6 +1153,7 @@ impl flags::AnalysisStats {
|
|||
style_lints: false,
|
||||
term_search_fuel: 400,
|
||||
term_search_borrowck: true,
|
||||
show_rename_conflicts: true,
|
||||
},
|
||||
ide::AssistResolveStrategy::All,
|
||||
analysis.editioned_file_id_to_vfs(file_id),
|
||||
|
|
|
|||
|
|
@ -707,6 +707,9 @@ config_data! {
|
|||
///
|
||||
/// E.g. `use ::std::io::Read;`.
|
||||
imports_prefixExternPrelude: bool = false,
|
||||
|
||||
/// Whether to warn when a rename will cause conflicts (change the meaning of the code).
|
||||
rename_showConflicts: bool = true,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1702,6 +1705,7 @@ impl Config {
|
|||
ExprFillDefaultDef::Underscore => ExprFillDefaultMode::Underscore,
|
||||
},
|
||||
prefer_self_ty: *self.assist_preferSelf(source_root),
|
||||
show_rename_conflicts: *self.rename_showConflicts(source_root),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1710,6 +1714,7 @@ impl Config {
|
|||
prefer_no_std: self.imports_preferNoStd(source_root).to_owned(),
|
||||
prefer_prelude: self.imports_preferPrelude(source_root).to_owned(),
|
||||
prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(),
|
||||
show_conflicts: *self.rename_showConflicts(source_root),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1809,6 +1814,7 @@ impl Config {
|
|||
style_lints: self.diagnostics_styleLints_enable(source_root).to_owned(),
|
||||
term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64,
|
||||
term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(),
|
||||
show_rename_conflicts: *self.rename_showConflicts(source_root),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -787,7 +787,11 @@ pub(crate) fn handle_will_rename_files(
|
|||
}
|
||||
})
|
||||
.filter_map(|(file_id, new_name)| {
|
||||
snap.analysis.will_rename_file(file_id?, &new_name).ok()?
|
||||
let file_id = file_id?;
|
||||
let source_root = snap.analysis.source_root_id(file_id).ok();
|
||||
snap.analysis
|
||||
.will_rename_file(file_id, &new_name, &snap.config.rename(source_root))
|
||||
.ok()?
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
|
|
|||
|
|
@ -363,6 +363,7 @@ fn integrated_diagnostics_benchmark() {
|
|||
prefer_absolute: false,
|
||||
term_search_fuel: 400,
|
||||
term_search_borrowck: true,
|
||||
show_rename_conflicts: true,
|
||||
};
|
||||
host.analysis()
|
||||
.full_diagnostics(&diagnostics_config, ide::AssistResolveStrategy::None, file_id)
|
||||
|
|
|
|||
|
|
@ -1303,6 +1303,13 @@ Default: `false`
|
|||
Exclude tests from find-all-references and call-hierarchy.
|
||||
|
||||
|
||||
## rust-analyzer.rename.showConflicts {#rename.showConflicts}
|
||||
|
||||
Default: `true`
|
||||
|
||||
Whether to warn when a rename will cause conflicts (change the meaning of the code).
|
||||
|
||||
|
||||
## rust-analyzer.runnables.command {#runnables.command}
|
||||
|
||||
Default: `null`
|
||||
|
|
|
|||
|
|
@ -2769,6 +2769,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Rename",
|
||||
"properties": {
|
||||
"rust-analyzer.rename.showConflicts": {
|
||||
"markdownDescription": "Whether to warn when a rename will cause conflicts (change the meaning of the code).",
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Runnables",
|
||||
"properties": {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue