Merge #8782
8782: internal: fix make API r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
2fe329db48
@ -1192,7 +1192,7 @@ fn make_ret_ty(ctx: &AssistContext, module: hir::Module, fun: &Function) -> Opti
|
||||
vec![fun_ty.make_ty(ctx, module), handler_ty],
|
||||
)
|
||||
}
|
||||
FlowHandler::If { .. } => make::ty("bool"),
|
||||
FlowHandler::If { .. } => make::ty_bool(),
|
||||
FlowHandler::IfOption { action } => {
|
||||
let handler_ty = action
|
||||
.expr_ty(ctx)
|
||||
|
@ -89,14 +89,12 @@ fn generate_fn_def_assist(
|
||||
let loc_needing_lifetime =
|
||||
loc_needing_lifetime.and_then(|it| it.make_mut(builder).to_position());
|
||||
|
||||
add_lifetime_param(fn_def.get_or_create_generic_param_list(), new_lifetime_param);
|
||||
ted::replace(
|
||||
lifetime.syntax(),
|
||||
make_ast_lifetime(new_lifetime_param).clone_for_update().syntax(),
|
||||
fn_def.get_or_create_generic_param_list().add_generic_param(
|
||||
make::lifetime_param(new_lifetime_param.clone()).clone_for_update().into(),
|
||||
);
|
||||
loc_needing_lifetime.map(|position| {
|
||||
ted::insert(position, make_ast_lifetime(new_lifetime_param).clone_for_update().syntax())
|
||||
});
|
||||
ted::replace(lifetime.syntax(), new_lifetime_param.clone_for_update().syntax());
|
||||
loc_needing_lifetime
|
||||
.map(|position| ted::insert(position, new_lifetime_param.clone_for_update().syntax()));
|
||||
})
|
||||
}
|
||||
|
||||
@ -112,11 +110,10 @@ fn generate_impl_def_assist(
|
||||
let impl_def = builder.make_ast_mut(impl_def);
|
||||
let lifetime = builder.make_ast_mut(lifetime);
|
||||
|
||||
add_lifetime_param(impl_def.get_or_create_generic_param_list(), new_lifetime_param);
|
||||
ted::replace(
|
||||
lifetime.syntax(),
|
||||
make_ast_lifetime(new_lifetime_param).clone_for_update().syntax(),
|
||||
impl_def.get_or_create_generic_param_list().add_generic_param(
|
||||
make::lifetime_param(new_lifetime_param.clone()).clone_for_update().into(),
|
||||
);
|
||||
ted::replace(lifetime.syntax(), new_lifetime_param.clone_for_update().syntax());
|
||||
})
|
||||
}
|
||||
|
||||
@ -124,31 +121,16 @@ fn generate_impl_def_assist(
|
||||
/// which is not in the list
|
||||
fn generate_unique_lifetime_param_name(
|
||||
existing_type_param_list: Option<ast::GenericParamList>,
|
||||
) -> Option<char> {
|
||||
) -> Option<ast::Lifetime> {
|
||||
match existing_type_param_list {
|
||||
Some(type_params) => {
|
||||
let used_lifetime_params: FxHashSet<_> = type_params
|
||||
.lifetime_params()
|
||||
.map(|p| p.syntax().text().to_string()[1..].to_owned())
|
||||
.collect();
|
||||
(b'a'..=b'z').map(char::from).find(|c| !used_lifetime_params.contains(&c.to_string()))
|
||||
let used_lifetime_params: FxHashSet<_> =
|
||||
type_params.lifetime_params().map(|p| p.syntax().text().to_string()).collect();
|
||||
('a'..='z').map(|it| format!("'{}", it)).find(|it| !used_lifetime_params.contains(it))
|
||||
}
|
||||
None => Some('a'),
|
||||
None => Some("'a".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_lifetime_param(type_params: ast::GenericParamList, new_lifetime_param: char) {
|
||||
let generic_param =
|
||||
make::generic_param(&format!("'{}", new_lifetime_param), None).clone_for_update();
|
||||
type_params.add_generic_param(generic_param);
|
||||
}
|
||||
|
||||
fn make_ast_lifetime(new_lifetime_param: char) -> ast::Lifetime {
|
||||
make::generic_param(&format!("'{}", new_lifetime_param), None)
|
||||
.syntax()
|
||||
.descendants()
|
||||
.find_map(ast::Lifetime::cast)
|
||||
.unwrap()
|
||||
.map(|it| make::lifetime(&it))
|
||||
}
|
||||
|
||||
enum NeedsLifetime {
|
||||
|
@ -37,12 +37,12 @@ pub(crate) fn replace_impl_trait_with_generic(
|
||||
|
||||
let type_param_name = suggest_name::for_generic_parameter(&impl_trait_type);
|
||||
|
||||
let type_param =
|
||||
make::generic_param(&type_param_name, Some(type_bound_list)).clone_for_update();
|
||||
let type_param = make::type_param(make::name(&type_param_name), Some(type_bound_list))
|
||||
.clone_for_update();
|
||||
let new_ty = make::ty(&type_param_name).clone_for_update();
|
||||
|
||||
ted::replace(impl_trait_type.syntax(), new_ty.syntax());
|
||||
fn_.get_or_create_generic_param_list().add_generic_param(type_param)
|
||||
fn_.get_or_create_generic_param_list().add_generic_param(type_param.into())
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
//! `parse(format!())` we use internally is an implementation detail -- long
|
||||
//! term, it will be replaced with direct tree manipulation.
|
||||
use itertools::Itertools;
|
||||
use stdx::format_to;
|
||||
use stdx::{format_to, never};
|
||||
|
||||
use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken};
|
||||
|
||||
@ -22,6 +22,16 @@ pub fn name_ref(text: &str) -> ast::NameRef {
|
||||
ast_from_text(&format!("fn f() {{ {}{}; }}", raw_ident_esc(text), text))
|
||||
}
|
||||
|
||||
pub fn lifetime(text: &str) -> ast::Lifetime {
|
||||
let mut text = text;
|
||||
let tmp;
|
||||
if never!(!text.starts_with('\'')) {
|
||||
tmp = format!("'{}", text);
|
||||
text = &tmp;
|
||||
}
|
||||
ast_from_text(&format!("fn f<{}>() {{ }}", text))
|
||||
}
|
||||
|
||||
fn raw_ident_esc(ident: &str) -> &'static str {
|
||||
let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some();
|
||||
if is_keyword && !matches!(ident, "self" | "crate" | "super" | "Self") {
|
||||
@ -34,10 +44,13 @@ fn raw_ident_esc(ident: &str) -> &'static str {
|
||||
// FIXME: replace stringly-typed constructor with a family of typed ctors, a-la
|
||||
// `expr_xxx`.
|
||||
pub fn ty(text: &str) -> ast::Type {
|
||||
ast_from_text(&format!("fn f() -> {} {{}}", text))
|
||||
ty_from_text(text)
|
||||
}
|
||||
pub fn ty_unit() -> ast::Type {
|
||||
ty("()")
|
||||
ty_from_text("()")
|
||||
}
|
||||
pub fn ty_bool() -> ast::Type {
|
||||
ty_path(path_unqualified(path_segment(name_ref("bool"))))
|
||||
}
|
||||
pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type {
|
||||
let mut count: usize = 0;
|
||||
@ -46,15 +59,21 @@ pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type {
|
||||
contents.push(',');
|
||||
}
|
||||
|
||||
ty(&format!("({})", contents))
|
||||
ty_from_text(&format!("({})", contents))
|
||||
}
|
||||
// FIXME: handle path to type
|
||||
pub fn ty_generic(name: ast::NameRef, types: impl IntoIterator<Item = ast::Type>) -> ast::Type {
|
||||
let contents = types.into_iter().join(", ");
|
||||
ty(&format!("{}<{}>", name, contents))
|
||||
ty_from_text(&format!("{}<{}>", name, contents))
|
||||
}
|
||||
pub fn ty_ref(target: ast::Type, exclusive: bool) -> ast::Type {
|
||||
ty(&if exclusive { format!("&mut {}", target) } else { format!("&{}", target) })
|
||||
ty_from_text(&if exclusive { format!("&mut {}", target) } else { format!("&{}", target) })
|
||||
}
|
||||
pub fn ty_path(path: ast::Path) -> ast::Type {
|
||||
ty_from_text(&path.to_string())
|
||||
}
|
||||
fn ty_from_text(text: &str) -> ast::Type {
|
||||
ast_from_text(&format!("type _T = {};", text))
|
||||
}
|
||||
|
||||
pub fn assoc_item_list() -> ast::AssocItemList {
|
||||
@ -475,8 +494,8 @@ pub fn param_list(
|
||||
};
|
||||
ast_from_text(&list)
|
||||
}
|
||||
// FIXME: s/&str/ast:Name
|
||||
pub fn generic_param(name: &str, ty: Option<ast::TypeBoundList>) -> ast::GenericParam {
|
||||
|
||||
pub fn type_param(name: ast::Name, ty: Option<ast::TypeBoundList>) -> ast::TypeParam {
|
||||
let bound = match ty {
|
||||
Some(it) => format!(": {}", it),
|
||||
None => String::new(),
|
||||
@ -484,6 +503,10 @@ pub fn generic_param(name: &str, ty: Option<ast::TypeBoundList>) -> ast::Generic
|
||||
ast_from_text(&format!("fn f<{}{}>() {{ }}", name, bound))
|
||||
}
|
||||
|
||||
pub fn lifetime_param(lifetime: ast::Lifetime) -> ast::LifetimeParam {
|
||||
ast_from_text(&format!("fn f<{}>() {{ }}", lifetime))
|
||||
}
|
||||
|
||||
pub fn generic_param_list(
|
||||
pats: impl IntoIterator<Item = ast::GenericParam>,
|
||||
) -> ast::GenericParamList {
|
||||
|
Loading…
Reference in New Issue
Block a user