mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-31 23:38:45 +00:00
Migrate add_missing_match_arms
to mutable ast
Requires a hack in order to work inside of macros
This commit is contained in:
parent
35f2e82e0b
commit
6ab2788978
1 changed files with 33 additions and 21 deletions
|
@ -8,10 +8,7 @@ use itertools::Itertools;
|
||||||
use syntax::ast::edit_in_place::Removable;
|
use syntax::ast::edit_in_place::Removable;
|
||||||
use syntax::ast::{self, make, AstNode, HasName, MatchArmList, MatchExpr, Pat};
|
use syntax::ast::{self, make, AstNode, HasName, MatchArmList, MatchExpr, Pat};
|
||||||
|
|
||||||
use crate::{
|
use crate::{utils, AssistContext, AssistId, AssistKind, Assists};
|
||||||
utils::{self, render_snippet, Cursor},
|
|
||||||
AssistContext, AssistId, AssistKind, Assists,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Assist: add_missing_match_arms
|
// Assist: add_missing_match_arms
|
||||||
//
|
//
|
||||||
|
@ -202,7 +199,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
|
||||||
AssistId("add_missing_match_arms", AssistKind::QuickFix),
|
AssistId("add_missing_match_arms", AssistKind::QuickFix),
|
||||||
"Fill match arms",
|
"Fill match arms",
|
||||||
target_range,
|
target_range,
|
||||||
|builder| {
|
|edit| {
|
||||||
let new_match_arm_list = match_arm_list.clone_for_update();
|
let new_match_arm_list = match_arm_list.clone_for_update();
|
||||||
|
|
||||||
// having any hidden variants means that we need a catch-all arm
|
// having any hidden variants means that we need a catch-all arm
|
||||||
|
@ -252,24 +249,39 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
|
||||||
new_match_arm_list.add_arm(arm);
|
new_match_arm_list.add_arm(arm);
|
||||||
}
|
}
|
||||||
|
|
||||||
let old_range = ctx.sema.original_range(match_arm_list.syntax()).range;
|
if let (Some(first_new_arm), Some(cap)) = (first_new_arm, ctx.config.snippet_cap) {
|
||||||
match (first_new_arm, ctx.config.snippet_cap) {
|
match first_new_arm.syntax().descendants().find_map(ast::WildcardPat::cast) {
|
||||||
(Some(first_new_arm), Some(cap)) => {
|
Some(it) => edit.add_placeholder_snippet(cap, it),
|
||||||
let extend_lifetime;
|
None => edit.add_tabstop_before(cap, first_new_arm),
|
||||||
let cursor =
|
}
|
||||||
match first_new_arm.syntax().descendants().find_map(ast::WildcardPat::cast)
|
}
|
||||||
{
|
|
||||||
Some(it) => {
|
// FIXME: Hack for mutable syntax trees not having great support for macros
|
||||||
extend_lifetime = it.syntax().clone();
|
// Just replace the element that the original range came from
|
||||||
Cursor::Replace(&extend_lifetime)
|
let old_place = {
|
||||||
|
// Find the original element
|
||||||
|
let old_file_range = ctx.sema.original_range(match_arm_list.syntax());
|
||||||
|
let file = ctx.sema.parse(old_file_range.file_id);
|
||||||
|
let old_place = file.syntax().covering_element(old_file_range.range);
|
||||||
|
|
||||||
|
// Make `old_place` mut
|
||||||
|
match old_place {
|
||||||
|
syntax::SyntaxElement::Node(it) => {
|
||||||
|
syntax::SyntaxElement::from(edit.make_syntax_mut(it))
|
||||||
|
}
|
||||||
|
syntax::SyntaxElement::Token(it) => {
|
||||||
|
// Don't have a way to make tokens mut, so instead make the parent mut
|
||||||
|
// and find the token again
|
||||||
|
let parent = edit.make_syntax_mut(it.parent().unwrap());
|
||||||
|
let mut_token =
|
||||||
|
parent.covering_element(it.text_range()).into_token().unwrap();
|
||||||
|
|
||||||
|
syntax::SyntaxElement::from(mut_token)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
None => Cursor::Before(first_new_arm.syntax()),
|
|
||||||
};
|
};
|
||||||
let snippet = render_snippet(cap, new_match_arm_list.syntax(), cursor);
|
|
||||||
builder.replace_snippet(cap, old_range, snippet);
|
syntax::ted::replace(old_place, new_match_arm_list.syntax());
|
||||||
}
|
|
||||||
_ => builder.replace(old_range, new_match_arm_list.to_string()),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue