diff options
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r-- | crates/ra_syntax/src/ast/expr_extensions.rs | 26 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/traits.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 3 | ||||
-rw-r--r-- | crates/ra_syntax/src/validation.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/validation/block.rs | 20 |
7 files changed, 41 insertions, 20 deletions
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs index d7ea4354d..25dbd0bed 100644 --- a/crates/ra_syntax/src/ast/expr_extensions.rs +++ b/crates/ra_syntax/src/ast/expr_extensions.rs | |||
@@ -9,12 +9,12 @@ use crate::{ | |||
9 | 9 | ||
10 | #[derive(Debug, Clone, PartialEq, Eq)] | 10 | #[derive(Debug, Clone, PartialEq, Eq)] |
11 | pub enum ElseBranch { | 11 | pub enum ElseBranch { |
12 | Block(ast::Block), | 12 | Block(ast::BlockExpr), |
13 | IfExpr(ast::IfExpr), | 13 | IfExpr(ast::IfExpr), |
14 | } | 14 | } |
15 | 15 | ||
16 | impl ast::IfExpr { | 16 | impl ast::IfExpr { |
17 | pub fn then_branch(&self) -> Option<ast::Block> { | 17 | pub fn then_branch(&self) -> Option<ast::BlockExpr> { |
18 | self.blocks().nth(0) | 18 | self.blocks().nth(0) |
19 | } | 19 | } |
20 | pub fn else_branch(&self) -> Option<ElseBranch> { | 20 | pub fn else_branch(&self) -> Option<ElseBranch> { |
@@ -28,7 +28,7 @@ impl ast::IfExpr { | |||
28 | Some(res) | 28 | Some(res) |
29 | } | 29 | } |
30 | 30 | ||
31 | fn blocks(&self) -> AstChildren<ast::Block> { | 31 | fn blocks(&self) -> AstChildren<ast::BlockExpr> { |
32 | children(self) | 32 | children(self) |
33 | } | 33 | } |
34 | } | 34 | } |
@@ -289,6 +289,26 @@ impl ast::Literal { | |||
289 | } | 289 | } |
290 | } | 290 | } |
291 | 291 | ||
292 | impl ast::BlockExpr { | ||
293 | /// false if the block is an intrinsic part of the syntax and can't be | ||
294 | /// replaced with arbitrary expression. | ||
295 | /// | ||
296 | /// ```not_rust | ||
297 | /// fn foo() { not_stand_alone } | ||
298 | /// const FOO: () = { stand_alone }; | ||
299 | /// ``` | ||
300 | pub fn is_standalone(&self) -> bool { | ||
301 | let kind = match self.syntax().parent() { | ||
302 | None => return true, | ||
303 | Some(it) => it.kind(), | ||
304 | }; | ||
305 | match kind { | ||
306 | FN_DEF | MATCH_ARM | IF_EXPR | WHILE_EXPR | LOOP_EXPR | TRY_BLOCK_EXPR => false, | ||
307 | _ => true, | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | |||
292 | #[test] | 312 | #[test] |
293 | fn test_literal_with_attr() { | 313 | fn test_literal_with_attr() { |
294 | let parse = ast::SourceFile::parse(r#"const _: &str = { #[attr] "Hello" };"#); | 314 | let parse = ast::SourceFile::parse(r#"const _: &str = { #[attr] "Hello" };"#); |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 7f91417c5..e2a92ae60 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -1003,7 +1003,7 @@ impl FnDef { | |||
1003 | pub fn param_list(&self) -> Option<ParamList> { | 1003 | pub fn param_list(&self) -> Option<ParamList> { |
1004 | AstChildren::new(&self.syntax).next() | 1004 | AstChildren::new(&self.syntax).next() |
1005 | } | 1005 | } |
1006 | pub fn body(&self) -> Option<Block> { | 1006 | pub fn body(&self) -> Option<BlockExpr> { |
1007 | AstChildren::new(&self.syntax).next() | 1007 | AstChildren::new(&self.syntax).next() |
1008 | } | 1008 | } |
1009 | pub fn ret_type(&self) -> Option<RetType> { | 1009 | pub fn ret_type(&self) -> Option<RetType> { |
@@ -3135,7 +3135,7 @@ impl AstNode for TryBlockExpr { | |||
3135 | } | 3135 | } |
3136 | } | 3136 | } |
3137 | impl TryBlockExpr { | 3137 | impl TryBlockExpr { |
3138 | pub fn block(&self) -> Option<Block> { | 3138 | pub fn body(&self) -> Option<BlockExpr> { |
3139 | AstChildren::new(&self.syntax).next() | 3139 | AstChildren::new(&self.syntax).next() |
3140 | } | 3140 | } |
3141 | } | 3141 | } |
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs index 20c251fba..c3e676d4c 100644 --- a/crates/ra_syntax/src/ast/traits.rs +++ b/crates/ra_syntax/src/ast/traits.rs | |||
@@ -28,7 +28,7 @@ pub trait VisibilityOwner: AstNode { | |||
28 | } | 28 | } |
29 | 29 | ||
30 | pub trait LoopBodyOwner: AstNode { | 30 | pub trait LoopBodyOwner: AstNode { |
31 | fn loop_body(&self) -> Option<ast::Block> { | 31 | fn loop_body(&self) -> Option<ast::BlockExpr> { |
32 | child_opt(self) | 32 | child_opt(self) |
33 | } | 33 | } |
34 | } | 34 | } |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 9f17a10ed..c14ee0e85 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -275,7 +275,7 @@ Grammar( | |||
275 | "AttrsOwner", | 275 | "AttrsOwner", |
276 | "DocCommentsOwner" | 276 | "DocCommentsOwner" |
277 | ], | 277 | ], |
278 | options: [ "ParamList", ["body", "Block"], "RetType" ], | 278 | options: [ "ParamList", ["body", "BlockExpr"], "RetType" ], |
279 | ), | 279 | ), |
280 | "RetType": (options: ["TypeRef"]), | 280 | "RetType": (options: ["TypeRef"]), |
281 | "StructDef": ( | 281 | "StructDef": ( |
@@ -426,7 +426,7 @@ Grammar( | |||
426 | traits: ["LoopBodyOwner"], | 426 | traits: ["LoopBodyOwner"], |
427 | ), | 427 | ), |
428 | "TryBlockExpr": ( | 428 | "TryBlockExpr": ( |
429 | options: ["Block"], | 429 | options: [["body", "BlockExpr"]], |
430 | ), | 430 | ), |
431 | "ForExpr": ( | 431 | "ForExpr": ( |
432 | traits: ["LoopBodyOwner"], | 432 | traits: ["LoopBodyOwner"], |
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 2bced1867..edb6076bb 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -203,7 +203,8 @@ fn api_walkthrough() { | |||
203 | assert_eq!(name.text(), "foo"); | 203 | assert_eq!(name.text(), "foo"); |
204 | 204 | ||
205 | // Let's get the `1 + 1` expression! | 205 | // Let's get the `1 + 1` expression! |
206 | let block: ast::Block = func.body().unwrap(); | 206 | let body: ast::BlockExpr = func.body().unwrap(); |
207 | let block = body.block().unwrap(); | ||
207 | let expr: ast::Expr = block.expr().unwrap(); | 208 | let expr: ast::Expr = block.expr().unwrap(); |
208 | 209 | ||
209 | // Enums are used to group related ast nodes together, and can be used for | 210 | // Enums are used to group related ast nodes together, and can be used for |
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index ee8797410..16824f3c4 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs | |||
@@ -97,7 +97,7 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> { | |||
97 | for node in root.descendants() { | 97 | for node in root.descendants() { |
98 | let _ = visitor_ctx(&mut errors) | 98 | let _ = visitor_ctx(&mut errors) |
99 | .visit::<ast::Literal, _>(validate_literal) | 99 | .visit::<ast::Literal, _>(validate_literal) |
100 | .visit::<ast::Block, _>(block::validate_block_node) | 100 | .visit::<ast::BlockExpr, _>(block::validate_block_expr) |
101 | .visit::<ast::FieldExpr, _>(|it, errors| validate_numeric_name(it.name_ref(), errors)) | 101 | .visit::<ast::FieldExpr, _>(|it, errors| validate_numeric_name(it.name_ref(), errors)) |
102 | .visit::<ast::RecordField, _>(|it, errors| validate_numeric_name(it.name_ref(), errors)) | 102 | .visit::<ast::RecordField, _>(|it, errors| validate_numeric_name(it.name_ref(), errors)) |
103 | .accept(&node); | 103 | .accept(&node); |
diff --git a/crates/ra_syntax/src/validation/block.rs b/crates/ra_syntax/src/validation/block.rs index c5588658d..3c9e96eb3 100644 --- a/crates/ra_syntax/src/validation/block.rs +++ b/crates/ra_syntax/src/validation/block.rs | |||
@@ -5,18 +5,18 @@ use crate::{ | |||
5 | SyntaxKind::*, | 5 | SyntaxKind::*, |
6 | }; | 6 | }; |
7 | 7 | ||
8 | pub(crate) fn validate_block_node(node: ast::Block, errors: &mut Vec<SyntaxError>) { | 8 | pub(crate) fn validate_block_expr(expr: ast::BlockExpr, errors: &mut Vec<SyntaxError>) { |
9 | if let Some(parent) = node.syntax().parent() { | 9 | if let Some(parent) = expr.syntax().parent() { |
10 | match parent.kind() { | 10 | match parent.kind() { |
11 | FN_DEF => return, | 11 | FN_DEF | EXPR_STMT | BLOCK => return, |
12 | BLOCK_EXPR => match parent.parent().map(|v| v.kind()) { | ||
13 | Some(EXPR_STMT) | Some(BLOCK) => return, | ||
14 | _ => {} | ||
15 | }, | ||
16 | _ => {} | 12 | _ => {} |
17 | } | 13 | } |
18 | } | 14 | } |
19 | errors.extend( | 15 | if let Some(block) = expr.block() { |
20 | node.attrs().map(|attr| SyntaxError::new(InvalidBlockAttr, attr.syntax().text_range())), | 16 | errors.extend( |
21 | ) | 17 | block |
18 | .attrs() | ||
19 | .map(|attr| SyntaxError::new(InvalidBlockAttr, attr.syntax().text_range())), | ||
20 | ) | ||
21 | } | ||
22 | } | 22 | } |