diff options
author | Kevin DeLorey <[email protected]> | 2020-02-09 16:25:47 +0000 |
---|---|---|
committer | Kevin DeLorey <[email protected]> | 2020-02-09 16:37:43 +0000 |
commit | a957c473fdb79880c39b73dc9e0c923093cf16ac (patch) | |
tree | f998b548f530ce604651e0e6af314ed2ec74b3b5 /crates/ra_syntax/src/ast | |
parent | 22caf982b99c54058e2e9200aeea0e61cada284a (diff) | |
parent | 1b9b13b4b4a75b5531c3f046ce6bf72d681f2732 (diff) |
Merge branch 'master' into kdelorey/complete-trait-impl
Diffstat (limited to 'crates/ra_syntax/src/ast')
-rw-r--r-- | crates/ra_syntax/src/ast/expr_extensions.rs | 15 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/make.rs | 61 |
3 files changed, 63 insertions, 15 deletions
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs index 539759450..2e50a095c 100644 --- a/crates/ra_syntax/src/ast/expr_extensions.rs +++ b/crates/ra_syntax/src/ast/expr_extensions.rs | |||
@@ -7,6 +7,21 @@ use crate::{ | |||
7 | SyntaxToken, T, | 7 | SyntaxToken, T, |
8 | }; | 8 | }; |
9 | 9 | ||
10 | impl ast::Expr { | ||
11 | pub fn is_block_like(&self) -> bool { | ||
12 | match self { | ||
13 | ast::Expr::IfExpr(_) | ||
14 | | ast::Expr::LoopExpr(_) | ||
15 | | ast::Expr::ForExpr(_) | ||
16 | | ast::Expr::WhileExpr(_) | ||
17 | | ast::Expr::BlockExpr(_) | ||
18 | | ast::Expr::MatchExpr(_) | ||
19 | | ast::Expr::TryBlockExpr(_) => true, | ||
20 | _ => false, | ||
21 | } | ||
22 | } | ||
23 | } | ||
24 | |||
10 | #[derive(Debug, Clone, PartialEq, Eq)] | 25 | #[derive(Debug, Clone, PartialEq, Eq)] |
11 | pub enum ElseBranch { | 26 | pub enum ElseBranch { |
12 | Block(ast::BlockExpr), | 27 | Block(ast::BlockExpr), |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 33d5578e7..435135f92 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | //! Generated file, do not edit by hand, see `crate/ra_tools/src/codegen` | 1 | //! Generated file, do not edit by hand, see `xtask/src/codegen` |
2 | 2 | ||
3 | use crate::{ | 3 | use crate::{ |
4 | ast::{self, AstChildren, AstNode}, | 4 | ast::{self, AstChildren, AstNode}, |
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs index 36e648180..862eb1172 100644 --- a/crates/ra_syntax/src/ast/make.rs +++ b/crates/ra_syntax/src/ast/make.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | //! of smaller pieces. | 2 | //! of smaller pieces. |
3 | use itertools::Itertools; | 3 | use itertools::Itertools; |
4 | 4 | ||
5 | use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxToken}; | 5 | use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken}; |
6 | 6 | ||
7 | pub fn name(text: &str) -> ast::Name { | 7 | pub fn name(text: &str) -> ast::Name { |
8 | ast_from_text(&format!("mod {};", text)) | 8 | ast_from_text(&format!("mod {};", text)) |
@@ -33,6 +33,21 @@ pub fn record_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordF | |||
33 | } | 33 | } |
34 | } | 34 | } |
35 | 35 | ||
36 | pub fn block_expr( | ||
37 | stmts: impl IntoIterator<Item = ast::Stmt>, | ||
38 | tail_expr: Option<ast::Expr>, | ||
39 | ) -> ast::BlockExpr { | ||
40 | let mut text = "{\n".to_string(); | ||
41 | for stmt in stmts.into_iter() { | ||
42 | text += &format!(" {}\n", stmt.syntax()); | ||
43 | } | ||
44 | if let Some(tail_expr) = tail_expr { | ||
45 | text += &format!(" {}\n", tail_expr.syntax()) | ||
46 | } | ||
47 | text += "}"; | ||
48 | ast_from_text(&format!("fn f() {}", text)) | ||
49 | } | ||
50 | |||
36 | pub fn block_from_expr(e: ast::Expr) -> ast::Block { | 51 | pub fn block_from_expr(e: ast::Expr) -> ast::Block { |
37 | return from_text(&format!("{{ {} }}", e.syntax())); | 52 | return from_text(&format!("{{ {} }}", e.syntax())); |
38 | 53 | ||
@@ -62,6 +77,13 @@ pub fn expr_return() -> ast::Expr { | |||
62 | pub fn expr_match(expr: ast::Expr, match_arm_list: ast::MatchArmList) -> ast::Expr { | 77 | 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())) | 78 | expr_from_text(&format!("match {} {}", expr.syntax(), match_arm_list.syntax())) |
64 | } | 79 | } |
80 | pub fn expr_if(condition: ast::Expr, then_branch: ast::BlockExpr) -> ast::Expr { | ||
81 | expr_from_text(&format!("if {} {}", condition.syntax(), then_branch.syntax())) | ||
82 | } | ||
83 | pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr { | ||
84 | let token = token(op); | ||
85 | expr_from_text(&format!("{}{}", token, expr.syntax())) | ||
86 | } | ||
65 | fn expr_from_text(text: &str) -> ast::Expr { | 87 | fn expr_from_text(text: &str) -> ast::Expr { |
66 | ast_from_text(&format!("const C: () = {};", text)) | 88 | ast_from_text(&format!("const C: () = {};", text)) |
67 | } | 89 | } |
@@ -122,11 +144,18 @@ pub fn match_arm(pats: impl IntoIterator<Item = ast::Pat>, expr: ast::Expr) -> a | |||
122 | } | 144 | } |
123 | 145 | ||
124 | pub fn match_arm_list(arms: impl IntoIterator<Item = ast::MatchArm>) -> ast::MatchArmList { | 146 | pub fn match_arm_list(arms: impl IntoIterator<Item = ast::MatchArm>) -> ast::MatchArmList { |
125 | let arms_str = arms.into_iter().map(|arm| format!("\n {}", arm.syntax())).join(","); | 147 | let arms_str = arms |
126 | return from_text(&format!("{},\n", arms_str)); | 148 | .into_iter() |
149 | .map(|arm| { | ||
150 | let needs_comma = arm.expr().map_or(true, |it| !it.is_block_like()); | ||
151 | let comma = if needs_comma { "," } else { "" }; | ||
152 | format!(" {}{}\n", arm.syntax(), comma) | ||
153 | }) | ||
154 | .collect::<String>(); | ||
155 | return from_text(&format!("{}", arms_str)); | ||
127 | 156 | ||
128 | fn from_text(text: &str) -> ast::MatchArmList { | 157 | fn from_text(text: &str) -> ast::MatchArmList { |
129 | ast_from_text(&format!("fn f() {{ match () {{{}}} }}", text)) | 158 | ast_from_text(&format!("fn f() {{ match () {{\n{}}} }}", text)) |
130 | } | 159 | } |
131 | } | 160 | } |
132 | 161 | ||
@@ -151,14 +180,6 @@ pub fn where_clause(preds: impl IntoIterator<Item = ast::WherePred>) -> ast::Whe | |||
151 | } | 180 | } |
152 | } | 181 | } |
153 | 182 | ||
154 | pub fn if_expression(condition: &ast::Expr, statement: &str) -> ast::IfExpr { | ||
155 | ast_from_text(&format!( | ||
156 | "fn f() {{ if !{} {{\n {}\n}}\n}}", | ||
157 | condition.syntax().text(), | ||
158 | statement | ||
159 | )) | ||
160 | } | ||
161 | |||
162 | pub fn let_stmt(pattern: ast::Pat, initializer: Option<ast::Expr>) -> ast::LetStmt { | 183 | pub fn let_stmt(pattern: ast::Pat, initializer: Option<ast::Expr>) -> ast::LetStmt { |
163 | let text = match initializer { | 184 | let text = match initializer { |
164 | Some(it) => format!("let {} = {};", pattern.syntax(), it.syntax()), | 185 | Some(it) => format!("let {} = {};", pattern.syntax(), it.syntax()), |
@@ -166,6 +187,9 @@ pub fn let_stmt(pattern: ast::Pat, initializer: Option<ast::Expr>) -> ast::LetSt | |||
166 | }; | 187 | }; |
167 | ast_from_text(&format!("fn f() {{ {} }}", text)) | 188 | ast_from_text(&format!("fn f() {{ {} }}", text)) |
168 | } | 189 | } |
190 | pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt { | ||
191 | ast_from_text(&format!("fn f() {{ {}; }}", expr.syntax())) | ||
192 | } | ||
169 | 193 | ||
170 | pub fn token(kind: SyntaxKind) -> SyntaxToken { | 194 | pub fn token(kind: SyntaxKind) -> SyntaxToken { |
171 | tokens::SOURCE_FILE | 195 | tokens::SOURCE_FILE |
@@ -179,7 +203,16 @@ pub fn token(kind: SyntaxKind) -> SyntaxToken { | |||
179 | 203 | ||
180 | fn ast_from_text<N: AstNode>(text: &str) -> N { | 204 | fn ast_from_text<N: AstNode>(text: &str) -> N { |
181 | let parse = SourceFile::parse(text); | 205 | let parse = SourceFile::parse(text); |
182 | parse.tree().syntax().descendants().find_map(N::cast).unwrap() | 206 | let node = parse.tree().syntax().descendants().find_map(N::cast).unwrap(); |
207 | let node = node.syntax().clone(); | ||
208 | let node = unroot(node); | ||
209 | let node = N::cast(node).unwrap(); | ||
210 | assert_eq!(node.syntax().text_range().start(), 0.into()); | ||
211 | node | ||
212 | } | ||
213 | |||
214 | fn unroot(n: SyntaxNode) -> SyntaxNode { | ||
215 | SyntaxNode::new_root(n.green().clone()) | ||
183 | } | 216 | } |
184 | 217 | ||
185 | pub mod tokens { | 218 | pub mod tokens { |
@@ -187,7 +220,7 @@ pub mod tokens { | |||
187 | use once_cell::sync::Lazy; | 220 | use once_cell::sync::Lazy; |
188 | 221 | ||
189 | pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> = | 222 | pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> = |
190 | Lazy::new(|| SourceFile::parse("const C: <()>::Item = (1 != 1, 2 == 2)\n;")); | 223 | Lazy::new(|| SourceFile::parse("const C: <()>::Item = (1 != 1, 2 == 2, !true)\n;")); |
191 | 224 | ||
192 | pub fn comma() -> SyntaxToken { | 225 | pub fn comma() -> SyntaxToken { |
193 | SOURCE_FILE | 226 | SOURCE_FILE |