aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/ast/expr_extensions.rs26
-rw-r--r--crates/ra_syntax/src/ast/generated.rs9
-rw-r--r--crates/ra_syntax/src/ast/traits.rs8
-rw-r--r--crates/ra_syntax/src/grammar.ron4
-rw-r--r--crates/ra_syntax/src/lib.rs3
-rw-r--r--crates/ra_syntax/src/validation.rs2
-rw-r--r--crates/ra_syntax/src/validation/block.rs20
7 files changed, 45 insertions, 27 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)]
11pub enum ElseBranch { 11pub enum ElseBranch {
12 Block(ast::Block), 12 Block(ast::BlockExpr),
13 IfExpr(ast::IfExpr), 13 IfExpr(ast::IfExpr),
14} 14}
15 15
16impl ast::IfExpr { 16impl 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
292impl 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]
293fn test_literal_with_attr() { 313fn 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 d161470e7..bcf753f78 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -1004,7 +1004,7 @@ impl FnDef {
1004 pub fn param_list(&self) -> Option<ParamList> { 1004 pub fn param_list(&self) -> Option<ParamList> {
1005 AstChildren::new(&self.syntax).next() 1005 AstChildren::new(&self.syntax).next()
1006 } 1006 }
1007 pub fn body(&self) -> Option<Block> { 1007 pub fn body(&self) -> Option<BlockExpr> {
1008 AstChildren::new(&self.syntax).next() 1008 AstChildren::new(&self.syntax).next()
1009 } 1009 }
1010 pub fn ret_type(&self) -> Option<RetType> { 1010 pub fn ret_type(&self) -> Option<RetType> {
@@ -3135,8 +3135,11 @@ impl AstNode for TryBlockExpr {
3135 &self.syntax 3135 &self.syntax
3136 } 3136 }
3137} 3137}
3138impl ast::TryBlockBodyOwner for TryBlockExpr {} 3138impl TryBlockExpr {
3139impl TryBlockExpr {} 3139 pub fn body(&self) -> Option<BlockExpr> {
3140 AstChildren::new(&self.syntax).next()
3141 }
3142}
3140#[derive(Debug, Clone, PartialEq, Eq, Hash)] 3143#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3141pub struct TryExpr { 3144pub struct TryExpr {
3142 pub(crate) syntax: SyntaxNode, 3145 pub(crate) syntax: SyntaxNode,
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
index 1b9a2b20c..c3e676d4c 100644
--- a/crates/ra_syntax/src/ast/traits.rs
+++ b/crates/ra_syntax/src/ast/traits.rs
@@ -28,13 +28,7 @@ pub trait VisibilityOwner: AstNode {
28} 28}
29 29
30pub trait LoopBodyOwner: AstNode { 30pub trait LoopBodyOwner: AstNode {
31 fn loop_body(&self) -> Option<ast::Block> { 31 fn loop_body(&self) -> Option<ast::BlockExpr> {
32 child_opt(self)
33 }
34}
35
36pub trait TryBlockBodyOwner: AstNode {
37 fn try_body(&self) -> Option<ast::Block> {
38 child_opt(self) 32 child_opt(self)
39 } 33 }
40} 34}
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index a07293a46..3e6c2d3f3 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 traits: ["TryBlockBodyOwner"], 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
8pub(crate) fn validate_block_node(node: ast::Block, errors: &mut Vec<SyntaxError>) { 8pub(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}