Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/syntax/src/ast/make.rs')
| -rw-r--r-- | crates/syntax/src/ast/make.rs | 66 |
1 files changed, 54 insertions, 12 deletions
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 2a7b51c3c2..051c583557 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -190,6 +190,7 @@ fn ty_from_text(text: &str) -> ast::Type { } pub fn ty_alias( + attrs: impl IntoIterator<Item = ast::Attr>, ident: &str, generic_param_list: Option<ast::GenericParamList>, type_param_bounds: Option<ast::TypeParam>, @@ -200,6 +201,7 @@ pub fn ty_alias( let assignment_where = assignment_where.flatten(); quote! { TypeAlias { + #(#attrs "\n")* [type] " " Name { [IDENT ident] } #generic_param_list @@ -229,9 +231,24 @@ pub fn ty_fn_ptr<I: Iterator<Item = Param>>( } } -pub fn assoc_item_list( - body: Option<Vec<either::Either<ast::Attr, ast::AssocItem>>>, -) -> ast::AssocItemList { +pub fn item_list(body: Option<Vec<ast::Item>>) -> ast::ItemList { + let is_break_braces = body.is_some(); + let body_newline = if is_break_braces { "\n" } else { "" }; + let body_indent = if is_break_braces { " " } else { "" }; + + let body = match body { + Some(bd) => bd.iter().map(|elem| elem.to_string()).join("\n\n "), + None => String::new(), + }; + ast_from_text(&format!("mod C {{{body_newline}{body_indent}{body}{body_newline}}}")) +} + +pub fn mod_(name: ast::Name, body: Option<ast::ItemList>) -> ast::Module { + let body = body.map_or(";".to_owned(), |body| format!(" {body}")); + ast_from_text(&format!("mod {name}{body}")) +} + +pub fn assoc_item_list(body: Option<Vec<ast::AssocItem>>) -> ast::AssocItemList { let is_break_braces = body.is_some(); let body_newline = if is_break_braces { "\n".to_owned() } else { String::new() }; let body_indent = if is_break_braces { " ".to_owned() } else { String::new() }; @@ -279,12 +296,16 @@ fn merge_where_clause( } pub fn impl_( + attrs: impl IntoIterator<Item = ast::Attr>, generic_params: Option<ast::GenericParamList>, generic_args: Option<ast::GenericArgList>, path_type: ast::Type, where_clause: Option<ast::WhereClause>, body: Option<ast::AssocItemList>, ) -> ast::Impl { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); + let gen_args = generic_args.map_or_else(String::new, |it| it.to_string()); let gen_params = generic_params.map_or_else(String::new, |it| it.to_string()); @@ -297,10 +318,11 @@ pub fn impl_( }; let body = body.map_or_else(|| format!("{{{body_newline}}}"), |it| it.to_string()); - ast_from_text(&format!("impl{gen_params} {path_type}{gen_args}{where_clause}{body}")) + ast_from_text(&format!("{attrs}impl{gen_params} {path_type}{gen_args}{where_clause}{body}")) } pub fn impl_trait( + attrs: impl IntoIterator<Item = ast::Attr>, is_unsafe: bool, trait_gen_params: Option<ast::GenericParamList>, trait_gen_args: Option<ast::GenericArgList>, @@ -313,6 +335,8 @@ pub fn impl_trait( ty_where_clause: Option<ast::WhereClause>, body: Option<ast::AssocItemList>, ) -> ast::Impl { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); let is_unsafe = if is_unsafe { "unsafe " } else { "" }; let trait_gen_args = trait_gen_args.map(|args| args.to_string()).unwrap_or_default(); @@ -336,7 +360,7 @@ pub fn impl_trait( let body = body.map_or_else(|| format!("{{{body_newline}}}"), |it| it.to_string()); ast_from_text(&format!( - "{is_unsafe}impl{gen_params} {is_negative}{path_type}{trait_gen_args} for {ty}{type_gen_args}{where_clause}{body}" + "{attrs}{is_unsafe}impl{gen_params} {is_negative}{path_type}{trait_gen_args} for {ty}{type_gen_args}{where_clause}{body}" )) } @@ -454,12 +478,18 @@ pub fn use_tree_list(use_trees: impl IntoIterator<Item = ast::UseTree>) -> ast:: ast_from_text(&format!("use {{{use_trees}}};")) } -pub fn use_(visibility: Option<ast::Visibility>, use_tree: ast::UseTree) -> ast::Use { +pub fn use_( + attrs: impl IntoIterator<Item = ast::Attr>, + visibility: Option<ast::Visibility>, + use_tree: ast::UseTree, +) -> ast::Use { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); let visibility = match visibility { None => String::new(), Some(it) => format!("{it} "), }; - ast_from_text(&format!("{visibility}use {use_tree};")) + ast_from_text(&format!("{attrs}{visibility}use {use_tree};")) } pub fn record_expr(path: ast::Path, fields: ast::RecordExprFieldList) -> ast::RecordExpr { @@ -948,16 +978,19 @@ pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt { } pub fn item_const( + attrs: impl IntoIterator<Item = ast::Attr>, visibility: Option<ast::Visibility>, name: ast::Name, ty: ast::Type, expr: ast::Expr, ) -> ast::Const { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); let visibility = match visibility { None => String::new(), Some(it) => format!("{it} "), }; - ast_from_text(&format!("{visibility}const {name}: {ty} = {expr};")) + ast_from_text(&format!("{attrs}{visibility}const {name}: {ty} = {expr};")) } pub fn item_static( @@ -1164,6 +1197,7 @@ pub fn variant( } pub fn fn_( + attrs: impl IntoIterator<Item = ast::Attr>, visibility: Option<ast::Visibility>, fn_name: ast::Name, type_params: Option<ast::GenericParamList>, @@ -1176,6 +1210,8 @@ pub fn fn_( is_unsafe: bool, is_gen: bool, ) -> ast::Fn { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); let type_params = match type_params { Some(type_params) => format!("{type_params}"), None => "".into(), @@ -1199,7 +1235,7 @@ pub fn fn_( let gen_literal = if is_gen { "gen " } else { "" }; ast_from_text(&format!( - "{visibility}{const_literal}{async_literal}{gen_literal}{unsafe_literal}fn {fn_name}{type_params}{params} {ret_type}{where_clause}{body}", + "{attrs}{visibility}{const_literal}{async_literal}{gen_literal}{unsafe_literal}fn {fn_name}{type_params}{params} {ret_type}{where_clause}{body}", )) } pub fn struct_( @@ -1208,23 +1244,29 @@ pub fn struct_( generic_param_list: Option<ast::GenericParamList>, field_list: ast::FieldList, ) -> ast::Struct { - let semicolon = if matches!(field_list, ast::FieldList::TupleFieldList(_)) { ";" } else { "" }; + let (semicolon, ws) = + if matches!(field_list, ast::FieldList::TupleFieldList(_)) { (";", "") } else { ("", " ") }; let type_params = generic_param_list.map_or_else(String::new, |it| it.to_string()); let visibility = match visibility { None => String::new(), Some(it) => format!("{it} "), }; - ast_from_text(&format!("{visibility}struct {strukt_name}{type_params}{field_list}{semicolon}",)) + ast_from_text(&format!( + "{visibility}struct {strukt_name}{type_params}{ws}{field_list}{semicolon}" + )) } pub fn enum_( + attrs: impl IntoIterator<Item = ast::Attr>, visibility: Option<ast::Visibility>, enum_name: ast::Name, generic_param_list: Option<ast::GenericParamList>, where_clause: Option<ast::WhereClause>, variant_list: ast::VariantList, ) -> ast::Enum { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); let visibility = match visibility { None => String::new(), Some(it) => format!("{it} "), @@ -1234,7 +1276,7 @@ pub fn enum_( let where_clause = where_clause.map(|it| format!(" {it}")).unwrap_or_default(); ast_from_text(&format!( - "{visibility}enum {enum_name}{generic_params}{where_clause} {variant_list}" + "{attrs}{visibility}enum {enum_name}{generic_params}{where_clause} {variant_list}" )) } |