diff options
Diffstat (limited to 'crates/syntax')
-rw-r--r-- | crates/syntax/src/ast/make.rs | 39 |
1 files changed, 31 insertions, 8 deletions
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 @@ | |||
10 | //! `parse(format!())` we use internally is an implementation detail -- long | 10 | //! `parse(format!())` we use internally is an implementation detail -- long |
11 | //! term, it will be replaced with direct tree manipulation. | 11 | //! term, it will be replaced with direct tree manipulation. |
12 | use itertools::Itertools; | 12 | use itertools::Itertools; |
13 | use stdx::format_to; | 13 | use stdx::{format_to, never}; |
14 | 14 | ||
15 | use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken}; | 15 | use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken}; |
16 | 16 | ||
@@ -22,6 +22,16 @@ pub fn name_ref(text: &str) -> ast::NameRef { | |||
22 | ast_from_text(&format!("fn f() {{ {}{}; }}", raw_ident_esc(text), text)) | 22 | ast_from_text(&format!("fn f() {{ {}{}; }}", raw_ident_esc(text), text)) |
23 | } | 23 | } |
24 | 24 | ||
25 | pub fn lifetime(text: &str) -> ast::Lifetime { | ||
26 | let mut text = text; | ||
27 | let tmp; | ||
28 | if never!(!text.starts_with('\'')) { | ||
29 | tmp = format!("'{}", text); | ||
30 | text = &tmp; | ||
31 | } | ||
32 | ast_from_text(&format!("fn f<{}>() {{ }}", text)) | ||
33 | } | ||
34 | |||
25 | fn raw_ident_esc(ident: &str) -> &'static str { | 35 | fn raw_ident_esc(ident: &str) -> &'static str { |
26 | let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some(); | 36 | let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some(); |
27 | if is_keyword && !matches!(ident, "self" | "crate" | "super" | "Self") { | 37 | if is_keyword && !matches!(ident, "self" | "crate" | "super" | "Self") { |
@@ -34,10 +44,13 @@ fn raw_ident_esc(ident: &str) -> &'static str { | |||
34 | // FIXME: replace stringly-typed constructor with a family of typed ctors, a-la | 44 | // FIXME: replace stringly-typed constructor with a family of typed ctors, a-la |
35 | // `expr_xxx`. | 45 | // `expr_xxx`. |
36 | pub fn ty(text: &str) -> ast::Type { | 46 | pub fn ty(text: &str) -> ast::Type { |
37 | ast_from_text(&format!("fn f() -> {} {{}}", text)) | 47 | ty_from_text(text) |
38 | } | 48 | } |
39 | pub fn ty_unit() -> ast::Type { | 49 | pub fn ty_unit() -> ast::Type { |
40 | ty("()") | 50 | ty_from_text("()") |
51 | } | ||
52 | pub fn ty_bool() -> ast::Type { | ||
53 | ty_path(path_unqualified(path_segment(name_ref("bool")))) | ||
41 | } | 54 | } |
42 | pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type { | 55 | pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type { |
43 | let mut count: usize = 0; | 56 | let mut count: usize = 0; |
@@ -46,15 +59,21 @@ pub fn ty_tuple(types: impl IntoIterator<Item = ast::Type>) -> ast::Type { | |||
46 | contents.push(','); | 59 | contents.push(','); |
47 | } | 60 | } |
48 | 61 | ||
49 | ty(&format!("({})", contents)) | 62 | ty_from_text(&format!("({})", contents)) |
50 | } | 63 | } |
51 | // FIXME: handle path to type | 64 | // FIXME: handle path to type |
52 | pub fn ty_generic(name: ast::NameRef, types: impl IntoIterator<Item = ast::Type>) -> ast::Type { | 65 | pub fn ty_generic(name: ast::NameRef, types: impl IntoIterator<Item = ast::Type>) -> ast::Type { |
53 | let contents = types.into_iter().join(", "); | 66 | let contents = types.into_iter().join(", "); |
54 | ty(&format!("{}<{}>", name, contents)) | 67 | ty_from_text(&format!("{}<{}>", name, contents)) |
55 | } | 68 | } |
56 | pub fn ty_ref(target: ast::Type, exclusive: bool) -> ast::Type { | 69 | pub fn ty_ref(target: ast::Type, exclusive: bool) -> ast::Type { |
57 | ty(&if exclusive { format!("&mut {}", target) } else { format!("&{}", target) }) | 70 | ty_from_text(&if exclusive { format!("&mut {}", target) } else { format!("&{}", target) }) |
71 | } | ||
72 | pub fn ty_path(path: ast::Path) -> ast::Type { | ||
73 | ty_from_text(&path.to_string()) | ||
74 | } | ||
75 | fn ty_from_text(text: &str) -> ast::Type { | ||
76 | ast_from_text(&format!("type _T = {};", text)) | ||
58 | } | 77 | } |
59 | 78 | ||
60 | pub fn assoc_item_list() -> ast::AssocItemList { | 79 | pub fn assoc_item_list() -> ast::AssocItemList { |
@@ -475,8 +494,8 @@ pub fn param_list( | |||
475 | }; | 494 | }; |
476 | ast_from_text(&list) | 495 | ast_from_text(&list) |
477 | } | 496 | } |
478 | // FIXME: s/&str/ast:Name | 497 | |
479 | pub fn generic_param(name: &str, ty: Option<ast::TypeBoundList>) -> ast::GenericParam { | 498 | pub fn type_param(name: ast::Name, ty: Option<ast::TypeBoundList>) -> ast::TypeParam { |
480 | let bound = match ty { | 499 | let bound = match ty { |
481 | Some(it) => format!(": {}", it), | 500 | Some(it) => format!(": {}", it), |
482 | None => String::new(), | 501 | None => String::new(), |
@@ -484,6 +503,10 @@ pub fn generic_param(name: &str, ty: Option<ast::TypeBoundList>) -> ast::Generic | |||
484 | ast_from_text(&format!("fn f<{}{}>() {{ }}", name, bound)) | 503 | ast_from_text(&format!("fn f<{}{}>() {{ }}", name, bound)) |
485 | } | 504 | } |
486 | 505 | ||
506 | pub fn lifetime_param(lifetime: ast::Lifetime) -> ast::LifetimeParam { | ||
507 | ast_from_text(&format!("fn f<{}>() {{ }}", lifetime)) | ||
508 | } | ||
509 | |||
487 | pub fn generic_param_list( | 510 | pub fn generic_param_list( |
488 | pats: impl IntoIterator<Item = ast::GenericParam>, | 511 | pats: impl IntoIterator<Item = ast::GenericParam>, |
489 | ) -> ast::GenericParamList { | 512 | ) -> ast::GenericParamList { |