From 680a0d54e4d2d474ae41f4f4a95c749495a02883 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 9 May 2021 19:11:42 +0300 Subject: internal: fix make API --- .../ide_assists/src/handlers/extract_function.rs | 2 +- .../src/handlers/introduce_named_lifetime.rs | 46 +++++++--------------- .../handlers/replace_impl_trait_with_generic.rs | 6 +-- crates/syntax/src/ast/make.rs | 39 ++++++++++++++---- 4 files changed, 49 insertions(+), 44 deletions(-) diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs index 4116985ae..494ef4621 100644 --- a/crates/ide_assists/src/handlers/extract_function.rs +++ b/crates/ide_assists/src/handlers/extract_function.rs @@ -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) diff --git a/crates/ide_assists/src/handlers/introduce_named_lifetime.rs b/crates/ide_assists/src/handlers/introduce_named_lifetime.rs index cb71ca8bd..68bc15120 100644 --- a/crates/ide_assists/src/handlers/introduce_named_lifetime.rs +++ b/crates/ide_assists/src/handlers/introduce_named_lifetime.rs @@ -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, -) -> Option { +) -> Option { 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 { diff --git a/crates/ide_assists/src/handlers/replace_impl_trait_with_generic.rs b/crates/ide_assists/src/handlers/replace_impl_trait_with_generic.rs index 16cae0281..15420aedf 100644 --- a/crates/ide_assists/src/handlers/replace_impl_trait_with_generic.rs +++ b/crates/ide_assists/src/handlers/replace_impl_trait_with_generic.rs @@ -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()) }, ) } diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 2289d8f3e..c39e248ce 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -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) -> ast::Type { let mut count: usize = 0; @@ -46,15 +59,21 @@ pub fn ty_tuple(types: impl IntoIterator) -> 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) -> 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::GenericParam { + +pub fn type_param(name: ast::Name, ty: Option) -> 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::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, ) -> ast::GenericParamList { -- cgit v1.2.3