mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 22:01:37 +00:00
Merge #5940
5940: Implement "Replace `impl Trait` function argument with the named generic" assist. r=matklad a=alekseysidorov Fixes #5085 Co-authored-by: Aleksei Sidorov <gorthauer87@yandex.ru>
This commit is contained in:
commit
0275b08d15
5 changed files with 267 additions and 1 deletions
|
@ -13,7 +13,7 @@ use crate::{
|
|||
ast::{
|
||||
self,
|
||||
make::{self, tokens},
|
||||
AstNode, TypeBoundsOwner,
|
||||
AstNode, GenericParamsOwner, NameOwner, TypeBoundsOwner,
|
||||
},
|
||||
AstToken, Direction, InsertPosition, SmolStr, SyntaxElement, SyntaxKind,
|
||||
SyntaxKind::{ATTR, COMMENT, WHITESPACE},
|
||||
|
@ -46,6 +46,19 @@ impl ast::Fn {
|
|||
to_insert.push(body.syntax().clone().into());
|
||||
self.replace_children(single_node(old_body_or_semi), to_insert)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_generic_param_list(&self, generic_args: ast::GenericParamList) -> ast::Fn {
|
||||
if let Some(old) = self.generic_param_list() {
|
||||
return self.replace_descendant(old, generic_args);
|
||||
}
|
||||
|
||||
let anchor = self.name().expect("The function must have a name").syntax().clone();
|
||||
|
||||
let mut to_insert: ArrayVec<[SyntaxElement; 1]> = ArrayVec::new();
|
||||
to_insert.push(generic_args.syntax().clone().into());
|
||||
self.insert_children(InsertPosition::After(anchor.into()), to_insert)
|
||||
}
|
||||
}
|
||||
|
||||
fn make_multiline<N>(node: N) -> N
|
||||
|
@ -459,6 +472,61 @@ impl ast::MatchArmList {
|
|||
}
|
||||
}
|
||||
|
||||
impl ast::GenericParamList {
|
||||
#[must_use]
|
||||
pub fn append_params(
|
||||
&self,
|
||||
params: impl IntoIterator<Item = ast::GenericParam>,
|
||||
) -> ast::GenericParamList {
|
||||
let mut res = self.clone();
|
||||
params.into_iter().for_each(|it| res = res.append_param(it));
|
||||
res
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn append_param(&self, item: ast::GenericParam) -> ast::GenericParamList {
|
||||
let space = tokens::single_space();
|
||||
|
||||
let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new();
|
||||
if self.generic_params().next().is_some() {
|
||||
to_insert.push(space.into());
|
||||
}
|
||||
to_insert.push(item.syntax().clone().into());
|
||||
|
||||
macro_rules! after_l_angle {
|
||||
() => {{
|
||||
let anchor = match self.l_angle_token() {
|
||||
Some(it) => it.into(),
|
||||
None => return self.clone(),
|
||||
};
|
||||
InsertPosition::After(anchor)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! after_field {
|
||||
($anchor:expr) => {
|
||||
if let Some(comma) = $anchor
|
||||
.syntax()
|
||||
.siblings_with_tokens(Direction::Next)
|
||||
.find(|it| it.kind() == T![,])
|
||||
{
|
||||
InsertPosition::After(comma)
|
||||
} else {
|
||||
to_insert.insert(0, make::token(T![,]).into());
|
||||
InsertPosition::After($anchor.syntax().clone().into())
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
let position = match self.generic_params().last() {
|
||||
Some(it) => after_field!(it),
|
||||
None => after_l_angle!(),
|
||||
};
|
||||
|
||||
self.insert_children(position, to_insert)
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn remove_attrs_and_docs<N: ast::AttrsOwner>(node: &N) -> N {
|
||||
N::cast(remove_attrs_and_docs_inner(node.syntax().clone())).unwrap()
|
||||
|
|
|
@ -294,6 +294,21 @@ pub fn param_list(pats: impl IntoIterator<Item = ast::Param>) -> ast::ParamList
|
|||
ast_from_text(&format!("fn f({}) {{ }}", args))
|
||||
}
|
||||
|
||||
pub fn generic_param(name: String, ty: Option<ast::TypeBoundList>) -> ast::GenericParam {
|
||||
let bound = match ty {
|
||||
Some(it) => format!(": {}", it),
|
||||
None => String::new(),
|
||||
};
|
||||
ast_from_text(&format!("fn f<{}{}>() {{ }}", name, bound))
|
||||
}
|
||||
|
||||
pub fn generic_param_list(
|
||||
pats: impl IntoIterator<Item = ast::GenericParam>,
|
||||
) -> ast::GenericParamList {
|
||||
let args = pats.into_iter().join(", ");
|
||||
ast_from_text(&format!("fn f<{}>() {{ }}", args))
|
||||
}
|
||||
|
||||
pub fn visibility_pub_crate() -> ast::Visibility {
|
||||
ast_from_text("pub(crate) struct S")
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue