mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 02:54:00 +00:00
Merge #5116
5116: Categorize assists r=matklad a=kjeremy Categorize assists so that editors can use them. Follows the LSP spec pretty close (and some things may need adjustments) but this populates the Refactor menu in vscode and pushes quickfixes through again. This is a prerequisite to filtering out assists that the client doesn't care about. Fixes #4147 Co-authored-by: Jeremy Kolb <kjeremy@gmail.com> Co-authored-by: kjeremy <kjeremy@gmail.com>
This commit is contained in:
commit
f51b0cfdd6
@ -8,7 +8,7 @@ use stdx::SepBy;
|
||||
|
||||
use crate::{
|
||||
assist_context::{AssistContext, Assists},
|
||||
AssistId,
|
||||
AssistId, AssistKind,
|
||||
};
|
||||
|
||||
// Assist: add_custom_impl
|
||||
@ -52,7 +52,7 @@ pub(crate) fn add_custom_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<
|
||||
format!("Add custom impl `{}` for `{}`", trait_token.text().as_str(), annotated_name);
|
||||
|
||||
let target = attr.syntax().text_range();
|
||||
acc.add(AssistId("add_custom_impl"), label, target, |builder| {
|
||||
acc.add(AssistId("add_custom_impl", AssistKind::Refactor), label, target, |builder| {
|
||||
let new_attr_input = input
|
||||
.syntax()
|
||||
.descendants_with_tokens()
|
||||
|
@ -4,7 +4,7 @@ use ra_syntax::{
|
||||
TextSize,
|
||||
};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: add_derive
|
||||
//
|
||||
@ -29,7 +29,7 @@ pub(crate) fn add_derive(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?;
|
||||
let node_start = derive_insertion_offset(&nominal)?;
|
||||
let target = nominal.syntax().text_range();
|
||||
acc.add(AssistId("add_derive"), "Add `#[derive]`", target, |builder| {
|
||||
acc.add(AssistId("add_derive", AssistKind::None), "Add `#[derive]`", target, |builder| {
|
||||
let derive_attr = nominal
|
||||
.attrs()
|
||||
.filter_map(|x| x.as_simple_call())
|
||||
|
@ -4,7 +4,7 @@ use ra_syntax::{
|
||||
TextRange,
|
||||
};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: add_explicit_type
|
||||
//
|
||||
@ -59,7 +59,7 @@ pub(crate) fn add_explicit_type(acc: &mut Assists, ctx: &AssistContext) -> Optio
|
||||
|
||||
let inferred_type = ty.display_source_code(ctx.db(), module.into()).ok()?;
|
||||
acc.add(
|
||||
AssistId("add_explicit_type"),
|
||||
AssistId("add_explicit_type", AssistKind::RefactorRewrite),
|
||||
format!("Insert explicit type `{}`", inferred_type),
|
||||
pat_range,
|
||||
|builder| match ascribed_ty {
|
||||
|
@ -2,7 +2,7 @@ use ra_ide_db::RootDatabase;
|
||||
use ra_syntax::ast::{self, AstNode, NameOwner};
|
||||
use test_utils::mark;
|
||||
|
||||
use crate::{utils::FamousDefs, AssistContext, AssistId, Assists};
|
||||
use crate::{utils::FamousDefs, AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: add_from_impl_for_enum
|
||||
//
|
||||
@ -45,7 +45,7 @@ pub(crate) fn add_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) ->
|
||||
|
||||
let target = variant.syntax().text_range();
|
||||
acc.add(
|
||||
AssistId("add_from_impl_for_enum"),
|
||||
AssistId("add_from_impl_for_enum", AssistKind::Refactor),
|
||||
"Add From impl for this enum variant",
|
||||
target,
|
||||
|edit| {
|
||||
|
@ -13,7 +13,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use crate::{
|
||||
assist_config::SnippetCap,
|
||||
utils::{render_snippet, Cursor},
|
||||
AssistContext, AssistId, Assists,
|
||||
AssistContext, AssistId, AssistKind, Assists,
|
||||
};
|
||||
|
||||
// Assist: add_function
|
||||
@ -62,7 +62,7 @@ pub(crate) fn add_function(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
||||
let function_builder = FunctionBuilder::from_call(&ctx, &call, &path, target_module)?;
|
||||
|
||||
let target = call.syntax().text_range();
|
||||
acc.add(AssistId("add_function"), "Add function", target, |builder| {
|
||||
acc.add(AssistId("add_function", AssistKind::None), "Add function", target, |builder| {
|
||||
let function_template = function_builder.render();
|
||||
builder.edit_file(function_template.file);
|
||||
let new_fn = function_template.to_string(ctx.config.snippet_cap);
|
||||
|
@ -1,7 +1,7 @@
|
||||
use ra_syntax::ast::{self, AstNode, NameOwner, TypeParamsOwner};
|
||||
use stdx::{format_to, SepBy};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: add_impl
|
||||
//
|
||||
@ -26,7 +26,11 @@ pub(crate) fn add_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
let nominal = ctx.find_node_at_offset::<ast::NominalDef>()?;
|
||||
let name = nominal.name()?;
|
||||
let target = nominal.syntax().text_range();
|
||||
acc.add(AssistId("add_impl"), format!("Implement {}", name.text().as_str()), target, |edit| {
|
||||
acc.add(
|
||||
AssistId("add_impl", AssistKind::Refactor),
|
||||
format!("Implement {}", name.text().as_str()),
|
||||
target,
|
||||
|edit| {
|
||||
let type_params = nominal.type_param_list();
|
||||
let start_offset = nominal.syntax().text_range().end();
|
||||
let mut buf = String::new();
|
||||
@ -41,8 +45,10 @@ pub(crate) fn add_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
.lifetime_params()
|
||||
.filter_map(|it| it.lifetime_token())
|
||||
.map(|it| it.text().clone());
|
||||
let type_params =
|
||||
type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone());
|
||||
let type_params = type_params
|
||||
.type_params()
|
||||
.filter_map(|it| it.name())
|
||||
.map(|it| it.text().clone());
|
||||
|
||||
let generic_params = lifetime_params.chain(type_params).sep_by(", ");
|
||||
format_to!(buf, "<{}>", generic_params)
|
||||
@ -57,7 +63,8 @@ pub(crate) fn add_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
edit.insert(start_offset, buf);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
assist_context::{AssistContext, Assists},
|
||||
ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams},
|
||||
utils::{get_missing_assoc_items, render_snippet, resolve_target_trait, Cursor},
|
||||
AssistId,
|
||||
AssistId, AssistKind,
|
||||
};
|
||||
|
||||
#[derive(PartialEq)]
|
||||
@ -147,7 +147,7 @@ fn add_missing_impl_members_inner(
|
||||
}
|
||||
|
||||
let target = impl_def.syntax().text_range();
|
||||
acc.add(AssistId(assist_id), label, target, |builder| {
|
||||
acc.add(AssistId(assist_id, AssistKind::QuickFix), label, target, |builder| {
|
||||
let n_existing_items = impl_item_list.assoc_items().count();
|
||||
let source_scope = ctx.sema.scope_for_def(trait_);
|
||||
let target_scope = ctx.sema.scope(impl_item_list.syntax());
|
||||
|
@ -7,7 +7,7 @@ use ra_syntax::{
|
||||
};
|
||||
use stdx::{format_to, SepBy};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: add_new
|
||||
//
|
||||
@ -42,7 +42,7 @@ pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
let impl_def = find_struct_impl(&ctx, &strukt)?;
|
||||
|
||||
let target = strukt.syntax().text_range();
|
||||
acc.add(AssistId("add_new"), "Add default constructor", target, |builder| {
|
||||
acc.add(AssistId("add_new", AssistKind::None), "Add default constructor", target, |builder| {
|
||||
let mut buf = String::with_capacity(512);
|
||||
|
||||
if impl_def.is_some() {
|
||||
|
@ -4,7 +4,7 @@ use test_utils::mark;
|
||||
|
||||
use crate::{
|
||||
assist_context::{AssistContext, Assists},
|
||||
AssistId,
|
||||
AssistId, AssistKind,
|
||||
};
|
||||
|
||||
// Assist: add_turbo_fish
|
||||
@ -45,12 +45,15 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
|
||||
mark::hit!(add_turbo_fish_non_generic);
|
||||
return None;
|
||||
}
|
||||
acc.add(AssistId("add_turbo_fish"), "Add `::<>`", ident.text_range(), |builder| {
|
||||
match ctx.config.snippet_cap {
|
||||
acc.add(
|
||||
AssistId("add_turbo_fish", AssistKind::RefactorRewrite),
|
||||
"Add `::<>`",
|
||||
ident.text_range(),
|
||||
|builder| match ctx.config.snippet_cap {
|
||||
Some(cap) => builder.insert_snippet(cap, ident.text_range().end(), "::<${0:_}>"),
|
||||
None => builder.insert(ident.text_range().end(), "::<_>"),
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,6 +1,6 @@
|
||||
use ra_syntax::ast::{self, AstNode};
|
||||
|
||||
use crate::{utils::invert_boolean_expression, AssistContext, AssistId, Assists};
|
||||
use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: apply_demorgan
|
||||
//
|
||||
@ -39,11 +39,16 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext) -> Option<(
|
||||
let rhs_range = rhs.syntax().text_range();
|
||||
let not_rhs = invert_boolean_expression(rhs);
|
||||
|
||||
acc.add(AssistId("apply_demorgan"), "Apply De Morgan's law", op_range, |edit| {
|
||||
acc.add(
|
||||
AssistId("apply_demorgan", AssistKind::RefactorRewrite),
|
||||
"Apply De Morgan's law",
|
||||
op_range,
|
||||
|edit| {
|
||||
edit.replace(op_range, opposite_op);
|
||||
edit.replace(lhs_range, format!("!({}", not_lhs.syntax().text()));
|
||||
edit.replace(rhs_range, format!("{})", not_rhs.syntax().text()));
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Return the opposite text for a given logical operator, if it makes sense
|
||||
|
@ -13,7 +13,9 @@ use ra_syntax::{
|
||||
};
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use crate::{utils::insert_use_statement, AssistContext, AssistId, Assists, GroupLabel};
|
||||
use crate::{
|
||||
utils::insert_use_statement, AssistContext, AssistId, AssistKind, Assists, GroupLabel,
|
||||
};
|
||||
|
||||
// Assist: auto_import
|
||||
//
|
||||
@ -46,7 +48,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
||||
for import in proposed_imports {
|
||||
acc.add_group(
|
||||
&group,
|
||||
AssistId("auto_import"),
|
||||
AssistId("auto_import", AssistKind::QuickFix),
|
||||
format!("Import `{}`", &import),
|
||||
range,
|
||||
|builder| {
|
||||
|
@ -3,7 +3,7 @@ use ra_syntax::{
|
||||
AstNode, SyntaxNode,
|
||||
};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
use test_utils::mark;
|
||||
|
||||
// Assist: change_return_type_to_result
|
||||
@ -35,7 +35,7 @@ pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContex
|
||||
let block_expr = &fn_def.body()?;
|
||||
|
||||
acc.add(
|
||||
AssistId("change_return_type_to_result"),
|
||||
AssistId("change_return_type_to_result", AssistKind::RefactorRewrite),
|
||||
"Change return type to Result",
|
||||
type_ref.syntax().text_range(),
|
||||
|builder| {
|
||||
|
@ -6,7 +6,7 @@ use ra_syntax::{
|
||||
};
|
||||
use test_utils::mark;
|
||||
|
||||
use crate::{utils::vis_offset, AssistContext, AssistId, Assists};
|
||||
use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: change_visibility
|
||||
//
|
||||
@ -62,16 +62,21 @@ fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
return None;
|
||||
};
|
||||
|
||||
acc.add(AssistId("change_visibility"), "Change visibility to pub(crate)", target, |edit| {
|
||||
acc.add(
|
||||
AssistId("change_visibility", AssistKind::RefactorRewrite),
|
||||
"Change visibility to pub(crate)",
|
||||
target,
|
||||
|edit| {
|
||||
edit.insert(offset, "pub(crate) ");
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn change_vis(acc: &mut Assists, vis: ast::Visibility) -> Option<()> {
|
||||
if vis.syntax().text() == "pub" {
|
||||
let target = vis.syntax().text_range();
|
||||
return acc.add(
|
||||
AssistId("change_visibility"),
|
||||
AssistId("change_visibility", AssistKind::RefactorRewrite),
|
||||
"Change Visibility to pub(crate)",
|
||||
target,
|
||||
|edit| {
|
||||
@ -82,7 +87,7 @@ fn change_vis(acc: &mut Assists, vis: ast::Visibility) -> Option<()> {
|
||||
if vis.syntax().text() == "pub(crate)" {
|
||||
let target = vis.syntax().text_range();
|
||||
return acc.add(
|
||||
AssistId("change_visibility"),
|
||||
AssistId("change_visibility", AssistKind::RefactorRewrite),
|
||||
"Change visibility to pub",
|
||||
target,
|
||||
|edit| {
|
||||
|
@ -15,7 +15,7 @@ use ra_syntax::{
|
||||
use crate::{
|
||||
assist_context::{AssistContext, Assists},
|
||||
utils::invert_boolean_expression,
|
||||
AssistId,
|
||||
AssistId, AssistKind,
|
||||
};
|
||||
|
||||
// Assist: convert_to_guarded_return
|
||||
@ -99,7 +99,11 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
|
||||
then_block.syntax().last_child_or_token().filter(|t| t.kind() == R_CURLY)?;
|
||||
|
||||
let target = if_expr.syntax().text_range();
|
||||
acc.add(AssistId("convert_to_guarded_return"), "Convert to guarded return", target, |edit| {
|
||||
acc.add(
|
||||
AssistId("convert_to_guarded_return", AssistKind::RefactorRewrite),
|
||||
"Convert to guarded return",
|
||||
target,
|
||||
|edit| {
|
||||
let if_indent_level = IndentLevel::from_node(&if_expr.syntax());
|
||||
let new_block = match if_let_pat {
|
||||
None => {
|
||||
@ -108,7 +112,8 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
|
||||
let then_branch =
|
||||
make::block_expr(once(make::expr_stmt(early_expression).into()), None);
|
||||
let cond = invert_boolean_expression(cond_expr);
|
||||
make::expr_if(make::condition(cond, None), then_branch).indent(if_indent_level)
|
||||
make::expr_if(make::condition(cond, None), then_branch)
|
||||
.indent(if_indent_level)
|
||||
};
|
||||
replace(new_expr.syntax(), &then_block, &parent_block, &if_expr)
|
||||
}
|
||||
@ -178,7 +183,8 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext)
|
||||
&mut then_statements,
|
||||
)
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -10,7 +10,8 @@ use ra_syntax::{
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use crate::{
|
||||
assist_context::AssistBuilder, utils::insert_use_statement, AssistContext, AssistId, Assists,
|
||||
assist_context::AssistBuilder, utils::insert_use_statement, AssistContext, AssistId,
|
||||
AssistKind, Assists,
|
||||
};
|
||||
|
||||
// Assist: extract_struct_from_enum_variant
|
||||
@ -48,7 +49,7 @@ pub(crate) fn extract_struct_from_enum_variant(
|
||||
let current_module = enum_hir.module(ctx.db());
|
||||
let target = variant.syntax().text_range();
|
||||
acc.add(
|
||||
AssistId("extract_struct_from_enum_variant"),
|
||||
AssistId("extract_struct_from_enum_variant", AssistKind::RefactorRewrite),
|
||||
"Extract struct from enum variant",
|
||||
target,
|
||||
|builder| {
|
||||
|
@ -9,7 +9,7 @@ use ra_syntax::{
|
||||
use stdx::format_to;
|
||||
use test_utils::mark;
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: extract_variable
|
||||
//
|
||||
@ -43,7 +43,11 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
|
||||
return None;
|
||||
}
|
||||
let target = expr.syntax().text_range();
|
||||
acc.add(AssistId("extract_variable"), "Extract into variable", target, move |edit| {
|
||||
acc.add(
|
||||
AssistId("extract_variable", AssistKind::RefactorExtract),
|
||||
"Extract into variable",
|
||||
target,
|
||||
move |edit| {
|
||||
let field_shorthand = match expr.syntax().parent().and_then(ast::RecordField::cast) {
|
||||
Some(field) => field.name_ref(),
|
||||
None => None,
|
||||
@ -80,8 +84,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
|
||||
}
|
||||
match ctx.config.snippet_cap {
|
||||
Some(cap) => {
|
||||
let snip =
|
||||
buf.replace(&format!("let {}", var_name), &format!("let $0{}", var_name));
|
||||
let snip = buf
|
||||
.replace(&format!("let {}", var_name), &format!("let $0{}", var_name));
|
||||
edit.replace_snippet(cap, expr_range, snip)
|
||||
}
|
||||
None => edit.replace(expr_range, buf),
|
||||
@ -116,7 +120,8 @@ pub(crate) fn extract_variable(acc: &mut Assists, ctx: &AssistContext) -> Option
|
||||
if wrap_in_block {
|
||||
edit.insert(anchor_stmt.text_range().end(), " }");
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Check whether the node is a valid expression which can be extracted to a variable.
|
||||
|
@ -8,7 +8,7 @@ use test_utils::mark;
|
||||
|
||||
use crate::{
|
||||
utils::{render_snippet, Cursor, FamousDefs},
|
||||
AssistContext, AssistId, Assists,
|
||||
AssistContext, AssistId, AssistKind, Assists,
|
||||
};
|
||||
|
||||
// Assist: fill_match_arms
|
||||
@ -103,7 +103,11 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
|
||||
}
|
||||
|
||||
let target = match_expr.syntax().text_range();
|
||||
acc.add(AssistId("fill_match_arms"), "Fill match arms", target, |builder| {
|
||||
acc.add(
|
||||
AssistId("fill_match_arms", AssistKind::QuickFix),
|
||||
"Fill match arms",
|
||||
target,
|
||||
|builder| {
|
||||
let new_arm_list = match_arm_list.remove_placeholder();
|
||||
let n_old_arms = new_arm_list.arms().count();
|
||||
let new_arm_list = new_arm_list.append_arms(missing_arms);
|
||||
@ -120,7 +124,8 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
|
||||
}
|
||||
_ => builder.replace(old_range, new_arm_list.to_string()),
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn is_variant_missing(existing_arms: &mut Vec<MatchArm>, var: &Pat) -> bool {
|
||||
|
@ -2,7 +2,7 @@ use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution};
|
||||
use ra_db::FileId;
|
||||
use ra_syntax::{ast, AstNode, TextRange, TextSize};
|
||||
|
||||
use crate::{utils::vis_offset, AssistContext, AssistId, Assists};
|
||||
use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// FIXME: this really should be a fix for diagnostic, rather than an assist.
|
||||
|
||||
@ -58,7 +58,7 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext) -> O
|
||||
Some(name) => format!("Change visibility of {} to {}", name, missing_visibility),
|
||||
};
|
||||
|
||||
acc.add(AssistId("fix_visibility"), assist_label, target, |builder| {
|
||||
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
|
||||
builder.edit_file(target_file);
|
||||
match ctx.config.snippet_cap {
|
||||
Some(cap) => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
|
||||
@ -101,7 +101,7 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) ->
|
||||
let assist_label =
|
||||
format!("Change visibility of {}.{} to {}", parent_name, target_name, missing_visibility);
|
||||
|
||||
acc.add(AssistId("fix_visibility"), assist_label, target, |builder| {
|
||||
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
|
||||
builder.edit_file(target_file);
|
||||
match ctx.config.snippet_cap {
|
||||
Some(cap) => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use ra_syntax::ast::{AstNode, BinExpr, BinOp};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: flip_binexpr
|
||||
//
|
||||
@ -33,13 +33,18 @@ pub(crate) fn flip_binexpr(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
||||
return None;
|
||||
}
|
||||
|
||||
acc.add(AssistId("flip_binexpr"), "Flip binary expression", op_range, |edit| {
|
||||
acc.add(
|
||||
AssistId("flip_binexpr", AssistKind::RefactorRewrite),
|
||||
"Flip binary expression",
|
||||
op_range,
|
||||
|edit| {
|
||||
if let FlipAction::FlipAndReplaceOp(new_op) = action {
|
||||
edit.replace(op_range, new_op);
|
||||
}
|
||||
edit.replace(lhs.text_range(), rhs.text());
|
||||
edit.replace(rhs.text_range(), lhs.text());
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
enum FlipAction {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use ra_syntax::{algo::non_trivia_sibling, Direction, T};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: flip_comma
|
||||
//
|
||||
@ -28,10 +28,15 @@ pub(crate) fn flip_comma(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
return None;
|
||||
}
|
||||
|
||||
acc.add(AssistId("flip_comma"), "Flip comma", comma.text_range(), |edit| {
|
||||
acc.add(
|
||||
AssistId("flip_comma", AssistKind::RefactorRewrite),
|
||||
"Flip comma",
|
||||
comma.text_range(),
|
||||
|edit| {
|
||||
edit.replace(prev.text_range(), next.to_string());
|
||||
edit.replace(next.text_range(), prev.to_string());
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -4,7 +4,7 @@ use ra_syntax::{
|
||||
Direction, T,
|
||||
};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: flip_trait_bound
|
||||
//
|
||||
@ -33,10 +33,15 @@ pub(crate) fn flip_trait_bound(acc: &mut Assists, ctx: &AssistContext) -> Option
|
||||
);
|
||||
|
||||
let target = plus.text_range();
|
||||
acc.add(AssistId("flip_trait_bound"), "Flip trait bounds", target, |edit| {
|
||||
acc.add(
|
||||
AssistId("flip_trait_bound", AssistKind::RefactorRewrite),
|
||||
"Flip trait bounds",
|
||||
target,
|
||||
|edit| {
|
||||
edit.replace(before.text_range(), after.to_string());
|
||||
edit.replace(after.text_range(), before.to_string());
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -7,7 +7,7 @@ use test_utils::mark;
|
||||
|
||||
use crate::{
|
||||
assist_context::{AssistContext, Assists},
|
||||
AssistId,
|
||||
AssistId, AssistKind,
|
||||
};
|
||||
|
||||
// Assist: inline_local_variable
|
||||
@ -110,13 +110,19 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
|
||||
let init_in_paren = format!("({})", &init_str);
|
||||
|
||||
let target = bind_pat.syntax().text_range();
|
||||
acc.add(AssistId("inline_local_variable"), "Inline variable", target, move |builder| {
|
||||
acc.add(
|
||||
AssistId("inline_local_variable", AssistKind::RefactorInline),
|
||||
"Inline variable",
|
||||
target,
|
||||
move |builder| {
|
||||
builder.delete(delete_range);
|
||||
for (desc, should_wrap) in refs.iter().zip(wrap_in_parens) {
|
||||
let replacement = if should_wrap { init_in_paren.clone() } else { init_str.clone() };
|
||||
let replacement =
|
||||
if should_wrap { init_in_paren.clone() } else { init_str.clone() };
|
||||
builder.replace(desc.file_range.range, replacement)
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -4,7 +4,7 @@ use ra_syntax::{
|
||||
};
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use crate::{assist_context::AssistBuilder, AssistContext, AssistId, Assists};
|
||||
use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
static ASSIST_NAME: &str = "introduce_named_lifetime";
|
||||
static ASSIST_LABEL: &str = "Introduce named lifetime";
|
||||
@ -83,7 +83,7 @@ fn generate_fn_def_assist(
|
||||
_ => return None,
|
||||
}
|
||||
};
|
||||
acc.add(AssistId(ASSIST_NAME), ASSIST_LABEL, lifetime_loc, |builder| {
|
||||
acc.add(AssistId(ASSIST_NAME, AssistKind::Refactor), ASSIST_LABEL, lifetime_loc, |builder| {
|
||||
add_lifetime_param(fn_def, builder, end_of_fn_ident, new_lifetime_param);
|
||||
builder.replace(lifetime_loc, format!("'{}", new_lifetime_param));
|
||||
loc_needing_lifetime.map(|loc| builder.insert(loc, format!("'{} ", new_lifetime_param)));
|
||||
@ -98,7 +98,7 @@ fn generate_impl_def_assist(
|
||||
) -> Option<()> {
|
||||
let new_lifetime_param = generate_unique_lifetime_param_name(&impl_def.type_param_list())?;
|
||||
let end_of_impl_kw = impl_def.impl_token()?.text_range().end();
|
||||
acc.add(AssistId(ASSIST_NAME), ASSIST_LABEL, lifetime_loc, |builder| {
|
||||
acc.add(AssistId(ASSIST_NAME, AssistKind::Refactor), ASSIST_LABEL, lifetime_loc, |builder| {
|
||||
add_lifetime_param(impl_def, builder, end_of_impl_kw, new_lifetime_param);
|
||||
builder.replace(lifetime_loc, format!("'{}", new_lifetime_param));
|
||||
})
|
||||
|
@ -6,7 +6,7 @@ use ra_syntax::{
|
||||
use crate::{
|
||||
assist_context::{AssistContext, Assists},
|
||||
utils::invert_boolean_expression,
|
||||
AssistId,
|
||||
AssistId, AssistKind,
|
||||
};
|
||||
|
||||
// Assist: invert_if
|
||||
@ -54,7 +54,7 @@ pub(crate) fn invert_if(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
let else_node = else_block.syntax();
|
||||
let else_range = else_node.text_range();
|
||||
let then_range = then_node.text_range();
|
||||
acc.add(AssistId("invert_if"), "Invert if", if_range, |edit| {
|
||||
acc.add(AssistId("invert_if", AssistKind::RefactorRewrite), "Invert if", if_range, |edit| {
|
||||
edit.replace(cond_range, flip_cond.syntax().text());
|
||||
edit.replace(else_range, then_node.text());
|
||||
edit.replace(then_range, else_node.text());
|
||||
|
@ -8,7 +8,7 @@ use ra_syntax::{
|
||||
|
||||
use crate::{
|
||||
assist_context::{AssistContext, Assists},
|
||||
AssistId,
|
||||
AssistId, AssistKind,
|
||||
};
|
||||
|
||||
// Assist: merge_imports
|
||||
@ -56,9 +56,14 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext) -> Option<()
|
||||
};
|
||||
|
||||
let target = tree.syntax().text_range();
|
||||
acc.add(AssistId("merge_imports"), "Merge imports", target, |builder| {
|
||||
acc.add(
|
||||
AssistId("merge_imports", AssistKind::RefactorRewrite),
|
||||
"Merge imports",
|
||||
target,
|
||||
|builder| {
|
||||
builder.rewrite(rewriter);
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn next_prev() -> impl Iterator<Item = Direction> {
|
||||
|
@ -6,7 +6,7 @@ use ra_syntax::{
|
||||
Direction,
|
||||
};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists, TextRange};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists, TextRange};
|
||||
|
||||
// Assist: merge_match_arms
|
||||
//
|
||||
@ -59,7 +59,11 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option
|
||||
return None;
|
||||
}
|
||||
|
||||
acc.add(AssistId("merge_match_arms"), "Merge match arms", current_text_range, |edit| {
|
||||
acc.add(
|
||||
AssistId("merge_match_arms", AssistKind::RefactorRewrite),
|
||||
"Merge match arms",
|
||||
current_text_range,
|
||||
|edit| {
|
||||
let pats = if arms_to_merge.iter().any(contains_placeholder) {
|
||||
"_".into()
|
||||
} else {
|
||||
@ -77,7 +81,8 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option
|
||||
let end = arms_to_merge.last().unwrap().syntax().text_range().end();
|
||||
|
||||
edit.replace(TextRange::new(start, end), arm);
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn contains_placeholder(a: &ast::MatchArm) -> bool {
|
||||
|
@ -5,7 +5,7 @@ use ra_syntax::{
|
||||
T,
|
||||
};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: move_bounds_to_where_clause
|
||||
//
|
||||
@ -50,7 +50,11 @@ pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext
|
||||
};
|
||||
|
||||
let target = type_param_list.syntax().text_range();
|
||||
acc.add(AssistId("move_bounds_to_where_clause"), "Move to where clause", target, |edit| {
|
||||
acc.add(
|
||||
AssistId("move_bounds_to_where_clause", AssistKind::RefactorRewrite),
|
||||
"Move to where clause",
|
||||
target,
|
||||
|edit| {
|
||||
let new_params = type_param_list
|
||||
.type_params()
|
||||
.filter(|it| it.type_bound_list().is_some())
|
||||
@ -68,11 +72,14 @@ pub(crate) fn move_bounds_to_where_clause(acc: &mut Assists, ctx: &AssistContext
|
||||
};
|
||||
|
||||
let to_insert = match anchor.prev_sibling_or_token() {
|
||||
Some(ref elem) if elem.kind() == WHITESPACE => format!("{} ", where_clause.syntax()),
|
||||
Some(ref elem) if elem.kind() == WHITESPACE => {
|
||||
format!("{} ", where_clause.syntax())
|
||||
}
|
||||
_ => format!(" {}", where_clause.syntax()),
|
||||
};
|
||||
edit.insert(anchor.text_range().start(), to_insert);
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn build_predicate(param: ast::TypeParam) -> Option<ast::WherePred> {
|
||||
|
@ -3,7 +3,7 @@ use ra_syntax::{
|
||||
SyntaxKind::WHITESPACE,
|
||||
};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: move_guard_to_arm_body
|
||||
//
|
||||
@ -40,7 +40,11 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext) ->
|
||||
let buf = format!("if {} {{ {} }}", guard_conditions.syntax().text(), arm_expr.syntax().text());
|
||||
|
||||
let target = guard.syntax().text_range();
|
||||
acc.add(AssistId("move_guard_to_arm_body"), "Move guard to arm body", target, |edit| {
|
||||
acc.add(
|
||||
AssistId("move_guard_to_arm_body", AssistKind::RefactorRewrite),
|
||||
"Move guard to arm body",
|
||||
target,
|
||||
|edit| {
|
||||
match space_before_guard {
|
||||
Some(element) if element.kind() == WHITESPACE => {
|
||||
edit.delete(element.text_range());
|
||||
@ -50,7 +54,8 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext) ->
|
||||
|
||||
edit.delete(guard.syntax().text_range());
|
||||
edit.replace_node_and_indent(arm_expr.syntax(), buf);
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Assist: move_arm_cond_to_match_guard
|
||||
@ -100,7 +105,7 @@ pub(crate) fn move_arm_cond_to_match_guard(acc: &mut Assists, ctx: &AssistContex
|
||||
|
||||
let target = if_expr.syntax().text_range();
|
||||
acc.add(
|
||||
AssistId("move_arm_cond_to_match_guard"),
|
||||
AssistId("move_arm_cond_to_match_guard", AssistKind::RefactorRewrite),
|
||||
"Move condition to match guard",
|
||||
target,
|
||||
|edit| {
|
||||
|
@ -5,7 +5,7 @@ use ra_syntax::{
|
||||
TextSize,
|
||||
};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: make_raw_string
|
||||
//
|
||||
@ -26,14 +26,22 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext) -> Option<
|
||||
let token = ctx.find_token_at_offset(STRING).and_then(ast::String::cast)?;
|
||||
let value = token.value()?;
|
||||
let target = token.syntax().text_range();
|
||||
acc.add(AssistId("make_raw_string"), "Rewrite as raw string", target, |edit| {
|
||||
acc.add(
|
||||
AssistId("make_raw_string", AssistKind::RefactorRewrite),
|
||||
"Rewrite as raw string",
|
||||
target,
|
||||
|edit| {
|
||||
let max_hash_streak = count_hashes(&value);
|
||||
let mut hashes = String::with_capacity(max_hash_streak + 1);
|
||||
for _ in 0..hashes.capacity() {
|
||||
hashes.push('#');
|
||||
}
|
||||
edit.replace(token.syntax().text_range(), format!("r{}\"{}\"{}", hashes, value, hashes));
|
||||
})
|
||||
edit.replace(
|
||||
token.syntax().text_range(),
|
||||
format!("r{}\"{}\"{}", hashes, value, hashes),
|
||||
);
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Assist: make_usual_string
|
||||
@ -55,11 +63,16 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext) -> Optio
|
||||
let token = ctx.find_token_at_offset(RAW_STRING).and_then(ast::RawString::cast)?;
|
||||
let value = token.value()?;
|
||||
let target = token.syntax().text_range();
|
||||
acc.add(AssistId("make_usual_string"), "Rewrite as regular string", target, |edit| {
|
||||
acc.add(
|
||||
AssistId("make_usual_string", AssistKind::RefactorRewrite),
|
||||
"Rewrite as regular string",
|
||||
target,
|
||||
|edit| {
|
||||
// parse inside string to escape `"`
|
||||
let escaped = value.escape_default().to_string();
|
||||
edit.replace(token.syntax().text_range(), format!("\"{}\"", escaped));
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Assist: add_hash
|
||||
@ -80,7 +93,7 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext) -> Optio
|
||||
pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
let token = ctx.find_token_at_offset(RAW_STRING)?;
|
||||
let target = token.text_range();
|
||||
acc.add(AssistId("add_hash"), "Add # to raw string", target, |edit| {
|
||||
acc.add(AssistId("add_hash", AssistKind::Refactor), "Add # to raw string", target, |edit| {
|
||||
edit.insert(token.text_range().start() + TextSize::of('r'), "#");
|
||||
edit.insert(token.text_range().end(), "#");
|
||||
})
|
||||
@ -109,7 +122,11 @@ pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
||||
return None;
|
||||
}
|
||||
let target = token.text_range();
|
||||
acc.add(AssistId("remove_hash"), "Remove hash from raw string", target, |edit| {
|
||||
acc.add(
|
||||
AssistId("remove_hash", AssistKind::RefactorRewrite),
|
||||
"Remove hash from raw string",
|
||||
target,
|
||||
|edit| {
|
||||
let result = &text[2..text.len() - 1];
|
||||
let result = if result.starts_with('\"') {
|
||||
// FIXME: this logic is wrong, not only the last has has to handled specially
|
||||
@ -120,7 +137,8 @@ pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
||||
result.to_owned()
|
||||
};
|
||||
edit.replace(token.text_range(), format!("r{}", result));
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn count_hashes(s: &str) -> usize {
|
||||
|
@ -3,7 +3,7 @@ use ra_syntax::{
|
||||
TextSize, T,
|
||||
};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: remove_dbg
|
||||
//
|
||||
@ -38,7 +38,7 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
};
|
||||
|
||||
let target = macro_call.syntax().text_range();
|
||||
acc.add(AssistId("remove_dbg"), "Remove dbg!()", target, |builder| {
|
||||
acc.add(AssistId("remove_dbg", AssistKind::Refactor), "Remove dbg!()", target, |builder| {
|
||||
builder.replace(macro_range, macro_content);
|
||||
})
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use ra_syntax::{SyntaxKind, TextRange, T};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: remove_mut
|
||||
//
|
||||
@ -26,7 +26,12 @@ pub(crate) fn remove_mut(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
};
|
||||
|
||||
let target = mut_token.text_range();
|
||||
acc.add(AssistId("remove_mut"), "Remove `mut` keyword", target, |builder| {
|
||||
acc.add(
|
||||
AssistId("remove_mut", AssistKind::Refactor),
|
||||
"Remove `mut` keyword",
|
||||
target,
|
||||
|builder| {
|
||||
builder.delete(TextRange::new(delete_from, delete_to));
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use hir::{Adt, ModuleDef, PathResolution, Semantics, Struct};
|
||||
use ra_ide_db::RootDatabase;
|
||||
use ra_syntax::{algo, ast, match_ast, AstNode, SyntaxKind, SyntaxKind::*, SyntaxNode};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: reorder_fields
|
||||
//
|
||||
@ -42,11 +42,16 @@ fn reorder<R: AstNode>(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
}
|
||||
|
||||
let target = record.syntax().text_range();
|
||||
acc.add(AssistId("reorder_fields"), "Reorder record fields", target, |edit| {
|
||||
acc.add(
|
||||
AssistId("reorder_fields", AssistKind::RefactorRewrite),
|
||||
"Reorder record fields",
|
||||
target,
|
||||
|edit| {
|
||||
for (old, new) in fields.iter().zip(&sorted_fields) {
|
||||
algo::diff(old, new).into_text_edit(edit.text_edit_builder());
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn get_fields_kind(node: &SyntaxNode) -> Vec<SyntaxKind> {
|
||||
|
@ -8,7 +8,7 @@ use ra_syntax::{
|
||||
AstNode,
|
||||
};
|
||||
|
||||
use crate::{utils::TryEnum, AssistContext, AssistId, Assists};
|
||||
use crate::{utils::TryEnum, AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: replace_if_let_with_match
|
||||
//
|
||||
@ -48,7 +48,11 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext)
|
||||
};
|
||||
|
||||
let target = if_expr.syntax().text_range();
|
||||
acc.add(AssistId("replace_if_let_with_match"), "Replace with match", target, move |edit| {
|
||||
acc.add(
|
||||
AssistId("replace_if_let_with_match", AssistKind::RefactorRewrite),
|
||||
"Replace with match",
|
||||
target,
|
||||
move |edit| {
|
||||
let match_expr = {
|
||||
let then_arm = {
|
||||
let then_block = then_block.reset_indent().indent(IndentLevel(1));
|
||||
@ -65,12 +69,14 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext)
|
||||
let else_expr = unwrap_trivial_block(else_block);
|
||||
make::match_arm(vec![pattern], else_expr)
|
||||
};
|
||||
let match_expr = make::expr_match(expr, make::match_arm_list(vec![then_arm, else_arm]));
|
||||
let match_expr =
|
||||
make::expr_match(expr, make::match_arm_list(vec![then_arm, else_arm]));
|
||||
match_expr.indent(IndentLevel::from_node(if_expr.syntax()))
|
||||
};
|
||||
|
||||
edit.replace_ast::<ast::Expr>(if_expr.into(), match_expr);
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -9,7 +9,7 @@ use ra_syntax::{
|
||||
AstNode, T,
|
||||
};
|
||||
|
||||
use crate::{utils::TryEnum, AssistContext, AssistId, Assists};
|
||||
use crate::{utils::TryEnum, AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: replace_let_with_if_let
|
||||
//
|
||||
@ -44,7 +44,11 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext) ->
|
||||
let happy_variant = TryEnum::from_ty(&ctx.sema, &ty).map(|it| it.happy_case());
|
||||
|
||||
let target = let_kw.text_range();
|
||||
acc.add(AssistId("replace_let_with_if_let"), "Replace with if-let", target, |edit| {
|
||||
acc.add(
|
||||
AssistId("replace_let_with_if_let", AssistKind::RefactorRewrite),
|
||||
"Replace with if-let",
|
||||
target,
|
||||
|edit| {
|
||||
let with_placeholder: ast::Pat = match happy_variant {
|
||||
None => make::placeholder_pat().into(),
|
||||
Some(var_name) => make::tuple_struct_pat(
|
||||
@ -53,15 +57,18 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext) ->
|
||||
)
|
||||
.into(),
|
||||
};
|
||||
let block = make::block_expr(None, None).indent(IndentLevel::from_node(let_stmt.syntax()));
|
||||
let block =
|
||||
make::block_expr(None, None).indent(IndentLevel::from_node(let_stmt.syntax()));
|
||||
let if_ = make::expr_if(make::condition(init, Some(with_placeholder)), block);
|
||||
let stmt = make::expr_stmt(if_);
|
||||
|
||||
let placeholder = stmt.syntax().descendants().find_map(ast::PlaceholderPat::cast).unwrap();
|
||||
let placeholder =
|
||||
stmt.syntax().descendants().find_map(ast::PlaceholderPat::cast).unwrap();
|
||||
let stmt = stmt.replace_descendant(placeholder.into(), original_pat);
|
||||
|
||||
edit.replace_ast(ast::Stmt::from(let_stmt), ast::Stmt::from(stmt));
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -3,7 +3,7 @@ use ra_syntax::{algo::SyntaxRewriter, ast, match_ast, AstNode, SmolStr, SyntaxNo
|
||||
|
||||
use crate::{
|
||||
utils::{find_insert_use_container, insert_use_statement},
|
||||
AssistContext, AssistId, Assists,
|
||||
AssistContext, AssistId, AssistKind, Assists,
|
||||
};
|
||||
|
||||
// Assist: replace_qualified_name_with_use
|
||||
@ -37,7 +37,7 @@ pub(crate) fn replace_qualified_name_with_use(
|
||||
|
||||
let target = path.syntax().text_range();
|
||||
acc.add(
|
||||
AssistId("replace_qualified_name_with_use"),
|
||||
AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite),
|
||||
"Replace qualified path with use",
|
||||
target,
|
||||
|builder| {
|
||||
|
@ -11,7 +11,7 @@ use ra_syntax::{
|
||||
|
||||
use crate::{
|
||||
utils::{render_snippet, Cursor, TryEnum},
|
||||
AssistContext, AssistId, Assists,
|
||||
AssistContext, AssistId, AssistKind, Assists,
|
||||
};
|
||||
|
||||
// Assist: replace_unwrap_with_match
|
||||
@ -46,7 +46,11 @@ pub(crate) fn replace_unwrap_with_match(acc: &mut Assists, ctx: &AssistContext)
|
||||
let ty = ctx.sema.type_of_expr(&caller)?;
|
||||
let happy_variant = TryEnum::from_ty(&ctx.sema, &ty)?.happy_case();
|
||||
let target = method_call.syntax().text_range();
|
||||
acc.add(AssistId("replace_unwrap_with_match"), "Replace unwrap with match", target, |builder| {
|
||||
acc.add(
|
||||
AssistId("replace_unwrap_with_match", AssistKind::RefactorRewrite),
|
||||
"Replace unwrap with match",
|
||||
target,
|
||||
|builder| {
|
||||
let ok_path = make::path_unqualified(make::path_segment(make::name_ref(happy_variant)));
|
||||
let it = make::bind_pat(make::name("a")).into();
|
||||
let ok_tuple = make::tuple_struct_pat(ok_path, iter::once(it)).into();
|
||||
@ -55,7 +59,8 @@ pub(crate) fn replace_unwrap_with_match(acc: &mut Assists, ctx: &AssistContext)
|
||||
let ok_arm = make::match_arm(iter::once(ok_tuple), make::expr_path(bind_path));
|
||||
|
||||
let unreachable_call = make::expr_unreachable();
|
||||
let err_arm = make::match_arm(iter::once(make::placeholder_pat().into()), unreachable_call);
|
||||
let err_arm =
|
||||
make::match_arm(iter::once(make::placeholder_pat().into()), unreachable_call);
|
||||
|
||||
let match_arm_list = make::match_arm_list(vec![ok_arm, err_arm]);
|
||||
let match_expr = make::expr_match(caller.clone(), match_arm_list)
|
||||
@ -76,7 +81,8 @@ pub(crate) fn replace_unwrap_with_match(acc: &mut Assists, ctx: &AssistContext)
|
||||
}
|
||||
None => builder.replace(range, match_expr.to_string()),
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -2,7 +2,7 @@ use std::iter::successors;
|
||||
|
||||
use ra_syntax::{ast, AstNode, T};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: split_import
|
||||
//
|
||||
@ -28,7 +28,7 @@ pub(crate) fn split_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
||||
}
|
||||
|
||||
let target = colon_colon.text_range();
|
||||
acc.add(AssistId("split_import"), "Split import", target, |edit| {
|
||||
acc.add(AssistId("split_import", AssistKind::RefactorRewrite), "Split import", target, |edit| {
|
||||
edit.replace_ast(use_tree, new_tree);
|
||||
})
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use ra_syntax::{
|
||||
AstNode, TextRange, T,
|
||||
};
|
||||
|
||||
use crate::{AssistContext, AssistId, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
|
||||
// Assist: unwrap_block
|
||||
//
|
||||
@ -27,7 +27,7 @@ use crate::{AssistContext, AssistId, Assists};
|
||||
// }
|
||||
// ```
|
||||
pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
|
||||
let assist_id = AssistId("unwrap_block");
|
||||
let assist_id = AssistId("unwrap_block", AssistKind::RefactorRewrite);
|
||||
let assist_label = "Unwrap block";
|
||||
|
||||
let l_curly_token = ctx.find_token_at_offset(T!['{'])?;
|
||||
|
@ -26,10 +26,20 @@ pub(crate) use crate::assist_context::{AssistContext, Assists};
|
||||
|
||||
pub use assist_config::AssistConfig;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum AssistKind {
|
||||
None,
|
||||
QuickFix,
|
||||
Refactor,
|
||||
RefactorExtract,
|
||||
RefactorInline,
|
||||
RefactorRewrite,
|
||||
}
|
||||
|
||||
/// Unique identifier of the assist, should not be shown to the user
|
||||
/// directly.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct AssistId(pub &'static str);
|
||||
pub struct AssistId(pub &'static str, pub AssistKind);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GroupLabel(pub String);
|
||||
|
@ -76,7 +76,7 @@ pub use crate::{
|
||||
};
|
||||
|
||||
pub use hir::{Documentation, Semantics};
|
||||
pub use ra_assists::{Assist, AssistConfig, AssistId, ResolvedAssist};
|
||||
pub use ra_assists::{Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist};
|
||||
pub use ra_db::{
|
||||
Canceled, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot,
|
||||
SourceRootId,
|
||||
|
@ -112,8 +112,6 @@ fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProvi
|
||||
lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
|
||||
lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
|
||||
lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
|
||||
lsp_types::code_action_kind::SOURCE.to_string(),
|
||||
lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
|
||||
]),
|
||||
work_done_progress_options: Default::default(),
|
||||
})
|
||||
|
@ -4,9 +4,9 @@ use std::path::{self, Path};
|
||||
use itertools::Itertools;
|
||||
use ra_db::{FileId, FileRange};
|
||||
use ra_ide::{
|
||||
Assist, CompletionItem, CompletionItemKind, Documentation, FileSystemEdit, Fold, FoldKind,
|
||||
FunctionSignature, Highlight, HighlightModifier, HighlightTag, HighlightedRange, Indel,
|
||||
InlayHint, InlayKind, InsertTextFormat, LineIndex, NavigationTarget, ReferenceAccess,
|
||||
Assist, AssistKind, CompletionItem, CompletionItemKind, Documentation, FileSystemEdit, Fold,
|
||||
FoldKind, FunctionSignature, Highlight, HighlightModifier, HighlightTag, HighlightedRange,
|
||||
Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, NavigationTarget, ReferenceAccess,
|
||||
ResolvedAssist, Runnable, Severity, SourceChange, SourceFileEdit, TextEdit,
|
||||
};
|
||||
use ra_syntax::{SyntaxKind, TextRange, TextSize};
|
||||
@ -627,6 +627,18 @@ pub(crate) fn call_hierarchy_item(
|
||||
Ok(lsp_types::CallHierarchyItem { name, kind, tags: None, detail, uri, range, selection_range })
|
||||
}
|
||||
|
||||
pub(crate) fn code_action_kind(kind: AssistKind) -> String {
|
||||
match kind {
|
||||
AssistKind::None => lsp_types::code_action_kind::EMPTY,
|
||||
AssistKind::QuickFix => lsp_types::code_action_kind::QUICKFIX,
|
||||
AssistKind::Refactor => lsp_types::code_action_kind::REFACTOR,
|
||||
AssistKind::RefactorExtract => lsp_types::code_action_kind::REFACTOR_EXTRACT,
|
||||
AssistKind::RefactorInline => lsp_types::code_action_kind::REFACTOR_INLINE,
|
||||
AssistKind::RefactorRewrite => lsp_types::code_action_kind::REFACTOR_REWRITE,
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub(crate) fn unresolved_code_action(
|
||||
snap: &GlobalStateSnapshot,
|
||||
assist: Assist,
|
||||
@ -636,7 +648,7 @@ pub(crate) fn unresolved_code_action(
|
||||
title: assist.label,
|
||||
id: Some(format!("{}:{}", assist.id.0.to_owned(), index.to_string())),
|
||||
group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0),
|
||||
kind: Some(String::new()),
|
||||
kind: Some(code_action_kind(assist.id.1)),
|
||||
edit: None,
|
||||
command: None,
|
||||
};
|
||||
|
@ -66,7 +66,7 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
|
||||
return Promise.resolve(null);
|
||||
});
|
||||
},
|
||||
// Using custom handling of CodeActions where each code action is resloved lazily
|
||||
// Using custom handling of CodeActions where each code action is resolved lazily
|
||||
// That's why we are not waiting for any command or edits
|
||||
async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) {
|
||||
const params: lc.CodeActionParams = {
|
||||
@ -87,7 +87,8 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
|
||||
continue;
|
||||
}
|
||||
assert(isCodeActionWithoutEditsAndCommands(item), "We don't expect edits or commands here");
|
||||
const action = new vscode.CodeAction(item.title);
|
||||
const kind = client.protocol2CodeConverter.asCodeActionKind((item as any).kind);
|
||||
const action = new vscode.CodeAction(item.title, kind);
|
||||
const group = (item as any).group;
|
||||
const id = (item as any).id;
|
||||
const resolveParams: ra.ResolveCodeActionParams = {
|
||||
@ -116,6 +117,7 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
|
||||
result[index] = items[0];
|
||||
} else {
|
||||
const action = new vscode.CodeAction(group);
|
||||
action.kind = items[0].kind;
|
||||
action.command = {
|
||||
command: "rust-analyzer.applyActionGroup",
|
||||
title: "",
|
||||
|
Loading…
Reference in New Issue
Block a user