diff options
author | Aleksey Kladov <[email protected]> | 2019-11-13 08:40:51 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-11-13 08:54:21 +0000 |
commit | e177c65e36f432821087b215b83c2dad1c97f478 (patch) | |
tree | 1f49b178983c1c409de123af8f09d07363aa040a /crates/ra_syntax/src/ast | |
parent | 2a69d584d6afc842d6dc8503f3fd3a0a691ea385 (diff) |
Use strongly-typed ast building for early-return assist
Diffstat (limited to 'crates/ra_syntax/src/ast')
-rw-r--r-- | crates/ra_syntax/src/ast/make.rs | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs index 95062ef6c..6c903ca64 100644 --- a/crates/ra_syntax/src/ast/make.rs +++ b/crates/ra_syntax/src/ast/make.rs | |||
@@ -4,6 +4,10 @@ use itertools::Itertools; | |||
4 | 4 | ||
5 | use crate::{ast, AstNode, SourceFile}; | 5 | use crate::{ast, AstNode, SourceFile}; |
6 | 6 | ||
7 | pub fn name(text: &str) -> ast::Name { | ||
8 | ast_from_text(&format!("mod {};", text)) | ||
9 | } | ||
10 | |||
7 | pub fn name_ref(text: &str) -> ast::NameRef { | 11 | pub fn name_ref(text: &str) -> ast::NameRef { |
8 | ast_from_text(&format!("fn f() {{ {}; }}", text)) | 12 | ast_from_text(&format!("fn f() {{ {}; }}", text)) |
9 | } | 13 | } |
@@ -43,6 +47,21 @@ pub fn expr_unit() -> ast::Expr { | |||
43 | pub fn expr_unimplemented() -> ast::Expr { | 47 | pub fn expr_unimplemented() -> ast::Expr { |
44 | expr_from_text("unimplemented!()") | 48 | expr_from_text("unimplemented!()") |
45 | } | 49 | } |
50 | pub fn expr_path(path: ast::Path) -> ast::Expr { | ||
51 | expr_from_text(&path.syntax().to_string()) | ||
52 | } | ||
53 | pub fn expr_continue() -> ast::Expr { | ||
54 | expr_from_text("continue") | ||
55 | } | ||
56 | pub fn expr_break() -> ast::Expr { | ||
57 | expr_from_text("break") | ||
58 | } | ||
59 | pub fn expr_return() -> ast::Expr { | ||
60 | expr_from_text("return") | ||
61 | } | ||
62 | pub fn expr_match(expr: ast::Expr, match_arm_list: ast::MatchArmList) -> ast::Expr { | ||
63 | expr_from_text(&format!("match {} {}", expr.syntax(), match_arm_list.syntax())) | ||
64 | } | ||
46 | fn expr_from_text(text: &str) -> ast::Expr { | 65 | fn expr_from_text(text: &str) -> ast::Expr { |
47 | ast_from_text(&format!("const C: () = {};", text)) | 66 | ast_from_text(&format!("const C: () = {};", text)) |
48 | } | 67 | } |
@@ -92,8 +111,8 @@ pub fn path_pat(path: ast::Path) -> ast::PathPat { | |||
92 | } | 111 | } |
93 | } | 112 | } |
94 | 113 | ||
95 | pub fn match_arm(pats: impl Iterator<Item = ast::Pat>, expr: ast::Expr) -> ast::MatchArm { | 114 | pub fn match_arm(pats: impl IntoIterator<Item = ast::Pat>, expr: ast::Expr) -> ast::MatchArm { |
96 | let pats_str = pats.map(|p| p.syntax().to_string()).join(" | "); | 115 | let pats_str = pats.into_iter().map(|p| p.syntax().to_string()).join(" | "); |
97 | return from_text(&format!("{} => {}", pats_str, expr.syntax())); | 116 | return from_text(&format!("{} => {}", pats_str, expr.syntax())); |
98 | 117 | ||
99 | fn from_text(text: &str) -> ast::MatchArm { | 118 | fn from_text(text: &str) -> ast::MatchArm { |
@@ -101,8 +120,8 @@ pub fn match_arm(pats: impl Iterator<Item = ast::Pat>, expr: ast::Expr) -> ast:: | |||
101 | } | 120 | } |
102 | } | 121 | } |
103 | 122 | ||
104 | pub fn match_arm_list(arms: impl Iterator<Item = ast::MatchArm>) -> ast::MatchArmList { | 123 | pub fn match_arm_list(arms: impl IntoIterator<Item = ast::MatchArm>) -> ast::MatchArmList { |
105 | let arms_str = arms.map(|arm| format!("\n {}", arm.syntax())).join(","); | 124 | let arms_str = arms.into_iter().map(|arm| format!("\n {}", arm.syntax())).join(","); |
106 | return from_text(&format!("{},\n", arms_str)); | 125 | return from_text(&format!("{},\n", arms_str)); |
107 | 126 | ||
108 | fn from_text(text: &str) -> ast::MatchArmList { | 127 | fn from_text(text: &str) -> ast::MatchArmList { |
@@ -110,23 +129,6 @@ pub fn match_arm_list(arms: impl Iterator<Item = ast::MatchArm>) -> ast::MatchAr | |||
110 | } | 129 | } |
111 | } | 130 | } |
112 | 131 | ||
113 | pub fn let_match_early(expr: ast::Expr, path: &str, early_expression: &str) -> ast::LetStmt { | ||
114 | return from_text(&format!( | ||
115 | r#"let {} = match {} {{ | ||
116 | {}(it) => it, | ||
117 | None => {}, | ||
118 | }};"#, | ||
119 | expr.syntax().text(), | ||
120 | expr.syntax().text(), | ||
121 | path, | ||
122 | early_expression | ||
123 | )); | ||
124 | |||
125 | fn from_text(text: &str) -> ast::LetStmt { | ||
126 | ast_from_text(&format!("fn f() {{ {} }}", text)) | ||
127 | } | ||
128 | } | ||
129 | |||
130 | pub fn where_pred(path: ast::Path, bounds: impl Iterator<Item = ast::TypeBound>) -> ast::WherePred { | 132 | pub fn where_pred(path: ast::Path, bounds: impl Iterator<Item = ast::TypeBound>) -> ast::WherePred { |
131 | let bounds = bounds.map(|b| b.syntax().to_string()).join(" + "); | 133 | let bounds = bounds.map(|b| b.syntax().to_string()).join(" + "); |
132 | return from_text(&format!("{}: {}", path.syntax(), bounds)); | 134 | return from_text(&format!("{}: {}", path.syntax(), bounds)); |
@@ -153,6 +155,14 @@ pub fn if_expression(condition: &ast::Expr, statement: &str) -> ast::IfExpr { | |||
153 | )) | 155 | )) |
154 | } | 156 | } |
155 | 157 | ||
158 | pub fn let_stmt(pattern: ast::Pat, initializer: Option<ast::Expr>) -> ast::LetStmt { | ||
159 | let text = match initializer { | ||
160 | Some(it) => format!("let {} = {};", pattern.syntax(), it.syntax()), | ||
161 | None => format!("let {};", pattern.syntax()), | ||
162 | }; | ||
163 | ast_from_text(&format!("fn f() {{ {} }}", text)) | ||
164 | } | ||
165 | |||
156 | fn ast_from_text<N: AstNode>(text: &str) -> N { | 166 | fn ast_from_text<N: AstNode>(text: &str) -> N { |
157 | let parse = SourceFile::parse(text); | 167 | let parse = SourceFile::parse(text); |
158 | let res = parse.tree().syntax().descendants().find_map(N::cast).unwrap(); | 168 | let res = parse.tree().syntax().descendants().find_map(N::cast).unwrap(); |