Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/convert_bool_to_enum.rs')
-rw-r--r--crates/ide-assists/src/handlers/convert_bool_to_enum.rs89
1 files changed, 52 insertions, 37 deletions
diff --git a/crates/ide-assists/src/handlers/convert_bool_to_enum.rs b/crates/ide-assists/src/handlers/convert_bool_to_enum.rs
index 434fbbae05..9347798100 100644
--- a/crates/ide-assists/src/handlers/convert_bool_to_enum.rs
+++ b/crates/ide-assists/src/handlers/convert_bool_to_enum.rs
@@ -12,9 +12,10 @@ use ide_db::{
};
use itertools::Itertools;
use syntax::ast::edit::AstNodeEdit;
+use syntax::ast::syntax_factory::SyntaxFactory;
use syntax::{
AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T,
- ast::{self, HasName, edit::IndentLevel, make},
+ ast::{self, HasName, edit::IndentLevel},
};
use crate::{
@@ -62,19 +63,28 @@ pub(crate) fn convert_bool_to_enum(acc: &mut Assists, ctx: &AssistContext<'_>) -
"Convert boolean to enum",
target,
|edit| {
+ let make = SyntaxFactory::without_mappings();
if let Some(ty) = &ty_annotation {
cov_mark::hit!(replaces_ty_annotation);
edit.replace(ty.syntax().text_range(), "Bool");
}
if let Some(initializer) = initializer {
- replace_bool_expr(edit, initializer);
+ replace_bool_expr(edit, initializer, &make);
}
let usages = definition.usages(&ctx.sema).all();
- add_enum_def(edit, ctx, &usages, target_node, &target_module);
+ add_enum_def(edit, ctx, &usages, target_node, &target_module, &make);
let mut delayed_mutations = Vec::new();
- replace_usages(edit, ctx, usages, definition, &target_module, &mut delayed_mutations);
+ replace_usages(
+ edit,
+ ctx,
+ usages,
+ definition,
+ &target_module,
+ &mut delayed_mutations,
+ &make,
+ );
for (scope, path) in delayed_mutations {
insert_use(&scope, path, &ctx.config.insert_use);
}
@@ -168,16 +178,16 @@ fn find_bool_node(ctx: &AssistContext<'_>) -> Option<BoolNodeData> {
}
}
-fn replace_bool_expr(edit: &mut SourceChangeBuilder, expr: ast::Expr) {
+fn replace_bool_expr(edit: &mut SourceChangeBuilder, expr: ast::Expr, make: &SyntaxFactory) {
let expr_range = expr.syntax().text_range();
- let enum_expr = bool_expr_to_enum_expr(expr);
+ let enum_expr = bool_expr_to_enum_expr(expr, make);
edit.replace(expr_range, enum_expr.syntax().text())
}
/// Converts an expression of type `bool` to one of the new enum type.
-fn bool_expr_to_enum_expr(expr: ast::Expr) -> ast::Expr {
- let true_expr = make::expr_path(make::path_from_text("Bool::True"));
- let false_expr = make::expr_path(make::path_from_text("Bool::False"));
+fn bool_expr_to_enum_expr(expr: ast::Expr, make: &SyntaxFactory) -> ast::Expr {
+ let true_expr = make.expr_path(make.path_from_text("Bool::True"));
+ let false_expr = make.expr_path(make.path_from_text("Bool::False"));
if let ast::Expr::Literal(literal) = &expr {
match literal.kind() {
@@ -186,10 +196,10 @@ fn bool_expr_to_enum_expr(expr: ast::Expr) -> ast::Expr {
_ => expr,
}
} else {
- make::expr_if(
+ make.expr_if(
expr,
- make::tail_only_block_expr(true_expr),
- Some(ast::ElseBranch::Block(make::tail_only_block_expr(false_expr))),
+ make.tail_only_block_expr(true_expr),
+ Some(ast::ElseBranch::Block(make.tail_only_block_expr(false_expr))),
)
.into()
}
@@ -203,11 +213,13 @@ fn replace_usages(
target_definition: Definition,
target_module: &hir::Module,
delayed_mutations: &mut Vec<(ImportScope, ast::Path)>,
+ make: &SyntaxFactory,
) {
for (file_id, references) in usages {
edit.edit_file(file_id.file_id(ctx.db()));
- let refs_with_imports = augment_references_with_imports(ctx, references, target_module);
+ let refs_with_imports =
+ augment_references_with_imports(ctx, references, target_module, make);
refs_with_imports.into_iter().rev().for_each(
|FileReferenceWithImport { range, name, import_data }| {
@@ -224,12 +236,13 @@ fn replace_usages(
target_definition,
target_module,
delayed_mutations,
+ make,
)
}
} else if let Some(initializer) = find_assignment_usage(&name) {
cov_mark::hit!(replaces_assignment);
- replace_bool_expr(edit, initializer);
+ replace_bool_expr(edit, initializer, make);
} else if let Some((prefix_expr, inner_expr)) = find_negated_usage(&name) {
cov_mark::hit!(replaces_negation);
@@ -247,7 +260,7 @@ fn replace_usages(
{
cov_mark::hit!(replaces_record_expr);
- let enum_expr = bool_expr_to_enum_expr(initializer);
+ let enum_expr = bool_expr_to_enum_expr(initializer, make);
utils::replace_record_field_expr(ctx, edit, record_field, enum_expr);
} else if let Some(pat) = find_record_pat_field_usage(&name) {
match pat {
@@ -263,6 +276,7 @@ fn replace_usages(
target_definition,
target_module,
delayed_mutations,
+ make,
)
}
}
@@ -272,14 +286,14 @@ fn replace_usages(
if let Some(expr) = literal_pat.literal().and_then(|literal| {
literal.syntax().ancestors().find_map(ast::Expr::cast)
}) {
- replace_bool_expr(edit, expr);
+ replace_bool_expr(edit, expr, make);
}
}
_ => (),
}
} else if let Some((ty_annotation, initializer)) = find_assoc_const_usage(&name) {
edit.replace(ty_annotation.syntax().text_range(), "Bool");
- replace_bool_expr(edit, initializer);
+ replace_bool_expr(edit, initializer, make);
} else if let Some(receiver) = find_method_call_expr_usage(&name) {
edit.replace(
receiver.syntax().text_range(),
@@ -296,10 +310,10 @@ fn replace_usages(
ctx,
edit,
record_field,
- make::expr_bin_op(
+ make.expr_bin_op(
expr,
ast::BinaryOp::CmpOp(ast::CmpOp::Eq { negated: false }),
- make::expr_path(make::path_from_text("Bool::True")),
+ make.expr_path(make.path_from_text("Bool::True")),
),
);
} else {
@@ -327,6 +341,7 @@ fn augment_references_with_imports(
ctx: &AssistContext<'_>,
references: Vec<FileReference>,
target_module: &hir::Module,
+ make: &SyntaxFactory,
) -> Vec<FileReferenceWithImport> {
let mut visited_modules = FxHashSet::default();
@@ -357,9 +372,9 @@ fn augment_references_with_imports(
cfg,
)
.map(|mod_path| {
- make::path_concat(
+ make.path_concat(
mod_path_to_ast(&mod_path, edition),
- make::path_from_text("Bool"),
+ make.path_from_text("Bool"),
)
})?;
@@ -458,6 +473,7 @@ fn add_enum_def(
usages: &UsageSearchResult,
target_node: SyntaxNode,
target_module: &hir::Module,
+ make: &SyntaxFactory,
) -> Option<()> {
let insert_before = node_to_insert_before(target_node);
@@ -482,7 +498,7 @@ fn add_enum_def(
.any(|module| module.nearest_non_block_module(ctx.db()) != *target_module);
let indent = IndentLevel::from_node(&insert_before);
- let enum_def = make_bool_enum(make_enum_pub).reset_indent().indent(indent);
+ let enum_def = make_bool_enum(make_enum_pub, make).reset_indent().indent(indent);
edit.insert(
insert_before.text_range().start(),
@@ -504,31 +520,30 @@ fn node_to_insert_before(target_node: SyntaxNode) -> SyntaxNode {
.unwrap_or(target_node)
}
-fn make_bool_enum(make_pub: bool) -> ast::Enum {
- let derive_eq = make::attr_outer(make::meta_token_tree(
- make::ext::ident_path("derive"),
- make::token_tree(
+fn make_bool_enum(make_pub: bool, make: &SyntaxFactory) -> ast::Enum {
+ let derive_eq = make.attr_outer(make.meta_token_tree(
+ make.ident_path("derive"),
+ make.token_tree(
T!['('],
vec![
- NodeOrToken::Token(make::tokens::ident("PartialEq")),
- NodeOrToken::Token(make::token(T![,])),
- NodeOrToken::Token(make::tokens::single_space()),
- NodeOrToken::Token(make::tokens::ident("Eq")),
+ NodeOrToken::Token(make.ident("PartialEq")),
+ NodeOrToken::Token(make.token(T![,])),
+ NodeOrToken::Token(make.whitespace(" ")),
+ NodeOrToken::Token(make.ident("Eq")),
],
),
));
- make::enum_(
+ make.enum_(
[derive_eq],
- if make_pub { Some(make::visibility_pub()) } else { None },
- make::name("Bool"),
+ if make_pub { Some(make.visibility_pub()) } else { None },
+ make.name("Bool"),
None,
None,
- make::variant_list(vec![
- make::variant(None, make::name("True"), None, None),
- make::variant(None, make::name("False"), None, None),
+ make.variant_list(vec![
+ make.variant(None, make.name("True"), None, None),
+ make.variant(None, make.name("False"), None, None),
]),
)
- .clone_for_update()
}
#[cfg(test)]