aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/ast/make.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/ast/make.rs')
-rw-r--r--crates/ra_syntax/src/ast/make.rs55
1 files changed, 27 insertions, 28 deletions
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
index 492088353..da0eb0926 100644
--- a/crates/ra_syntax/src/ast/make.rs
+++ b/crates/ra_syntax/src/ast/make.rs
@@ -1,5 +1,9 @@
1//! This module contains free-standing functions for creating AST fragments out 1//! This module contains free-standing functions for creating AST fragments out
2//! of smaller pieces. 2//! of smaller pieces.
3//!
4//! Note that all functions here intended to be stupid constructors, which just
5//! assemble a finish node from immediate children. If you want to do something
6//! smarter than that, it probably doesn't belong in this module.
3use itertools::Itertools; 7use itertools::Itertools;
4use stdx::format_to; 8use stdx::format_to;
5 9
@@ -13,6 +17,10 @@ pub fn name_ref(text: &str) -> ast::NameRef {
13 ast_from_text(&format!("fn f() {{ {}; }}", text)) 17 ast_from_text(&format!("fn f() {{ {}; }}", text))
14} 18}
15 19
20pub fn type_ref(text: &str) -> ast::TypeRef {
21 ast_from_text(&format!("impl {} for D {{}};", text))
22}
23
16pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment { 24pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment {
17 ast_from_text(&format!("use {};", name_ref)) 25 ast_from_text(&format!("use {};", name_ref))
18} 26}
@@ -82,14 +90,6 @@ pub fn block_expr(
82 ast_from_text(&format!("fn f() {}", buf)) 90 ast_from_text(&format!("fn f() {}", buf))
83} 91}
84 92
85pub fn block_from_expr(e: ast::Expr) -> ast::Block {
86 return from_text(&format!("{{ {} }}", e));
87
88 fn from_text(text: &str) -> ast::Block {
89 ast_from_text(&format!("fn f() {}", text))
90 }
91}
92
93pub fn expr_unit() -> ast::Expr { 93pub fn expr_unit() -> ast::Expr {
94 expr_from_text("()") 94 expr_from_text("()")
95} 95}
@@ -99,6 +99,9 @@ pub fn expr_empty_block() -> ast::Expr {
99pub fn expr_unimplemented() -> ast::Expr { 99pub fn expr_unimplemented() -> ast::Expr {
100 expr_from_text("unimplemented!()") 100 expr_from_text("unimplemented!()")
101} 101}
102pub fn expr_unreachable() -> ast::Expr {
103 expr_from_text("unreachable!()")
104}
102pub fn expr_todo() -> ast::Expr { 105pub fn expr_todo() -> ast::Expr {
103 expr_from_text("todo!()") 106 expr_from_text("todo!()")
104} 107}
@@ -268,10 +271,6 @@ pub fn token(kind: SyntaxKind) -> SyntaxToken {
268 .unwrap_or_else(|| panic!("unhandled token: {:?}", kind)) 271 .unwrap_or_else(|| panic!("unhandled token: {:?}", kind))
269} 272}
270 273
271pub fn unreachable_macro_call() -> ast::MacroCall {
272 ast_from_text(&format!("unreachable!()"))
273}
274
275pub fn param(name: String, ty: String) -> ast::Param { 274pub fn param(name: String, ty: String) -> ast::Param {
276 ast_from_text(&format!("fn f({}: {}) {{ }}", name, ty)) 275 ast_from_text(&format!("fn f({}: {}) {{ }}", name, ty))
277} 276}
@@ -281,7 +280,12 @@ pub fn param_list(pats: impl IntoIterator<Item = ast::Param>) -> ast::ParamList
281 ast_from_text(&format!("fn f({}) {{ }}", args)) 280 ast_from_text(&format!("fn f({}) {{ }}", args))
282} 281}
283 282
283pub fn visibility_pub_crate() -> ast::Visibility {
284 ast_from_text("pub(crate) struct S")
285}
286
284pub fn fn_def( 287pub fn fn_def(
288 visibility: Option<ast::Visibility>,
285 fn_name: ast::Name, 289 fn_name: ast::Name,
286 type_params: Option<ast::TypeParamList>, 290 type_params: Option<ast::TypeParamList>,
287 params: ast::ParamList, 291 params: ast::ParamList,
@@ -289,26 +293,21 @@ pub fn fn_def(
289) -> ast::FnDef { 293) -> ast::FnDef {
290 let type_params = 294 let type_params =
291 if let Some(type_params) = type_params { format!("<{}>", type_params) } else { "".into() }; 295 if let Some(type_params) = type_params { format!("<{}>", type_params) } else { "".into() };
292 ast_from_text(&format!("fn {}{}{} {}", fn_name, type_params, params, body)) 296 let visibility = match visibility {
293} 297 None => String::new(),
294 298 Some(it) => format!("{} ", it),
295pub fn add_leading_newlines(amount_of_newlines: usize, t: impl AstNode) -> ast::SourceFile { 299 };
296 let newlines = "\n".repeat(amount_of_newlines); 300 ast_from_text(&format!("{}fn {}{}{} {}", visibility, fn_name, type_params, params, body))
297 ast_from_text(&format!("{}{}", newlines, t.syntax()))
298}
299
300pub fn add_trailing_newlines(amount_of_newlines: usize, t: impl AstNode) -> ast::SourceFile {
301 let newlines = "\n".repeat(amount_of_newlines);
302 ast_from_text(&format!("{}{}", t.syntax(), newlines))
303}
304
305pub fn add_pub_crate_modifier(fn_def: ast::FnDef) -> ast::FnDef {
306 ast_from_text(&format!("pub(crate) {}", fn_def))
307} 301}
308 302
309fn ast_from_text<N: AstNode>(text: &str) -> N { 303fn ast_from_text<N: AstNode>(text: &str) -> N {
310 let parse = SourceFile::parse(text); 304 let parse = SourceFile::parse(text);
311 let node = parse.tree().syntax().descendants().find_map(N::cast).unwrap(); 305 let node = match parse.tree().syntax().descendants().find_map(N::cast) {
306 Some(it) => it,
307 None => {
308 panic!("Failed to make ast node `{}` from text {}", std::any::type_name::<N>(), text)
309 }
310 };
312 let node = node.syntax().clone(); 311 let node = node.syntax().clone();
313 let node = unroot(node); 312 let node = unroot(node);
314 let node = N::cast(node).unwrap(); 313 let node = N::cast(node).unwrap();