From 4f2134cc33f07c09fe166cec42971828843bc0ef Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 2 May 2020 01:18:19 +0200 Subject: Introduce EffectExpr --- crates/ra_syntax/src/ast.rs | 2 +- crates/ra_syntax/src/ast/edit.rs | 2 +- crates/ra_syntax/src/ast/expr_extensions.rs | 40 ++++++++++++---- crates/ra_syntax/src/ast/generated/nodes.rs | 74 ++++++++++------------------- crates/ra_syntax/src/ast/make.rs | 4 +- crates/ra_syntax/src/lib.rs | 7 ++- crates/ra_syntax/src/validation/block.rs | 20 ++++---- 7 files changed, 73 insertions(+), 76 deletions(-) (limited to 'crates/ra_syntax/src') diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index a716e525b..1876afe95 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -16,7 +16,7 @@ use crate::{ }; pub use self::{ - expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp}, + expr_extensions::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp}, extensions::{ AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind, TypeBoundKind, VisibilityKind, diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs index 26e4576ff..c507dc683 100644 --- a/crates/ra_syntax/src/ast/edit.rs +++ b/crates/ra_syntax/src/ast/edit.rs @@ -28,7 +28,7 @@ impl ast::BinExpr { impl ast::FnDef { #[must_use] - pub fn with_body(&self, body: ast::Block) -> ast::FnDef { + pub fn with_body(&self, body: ast::BlockExpr) -> ast::FnDef { let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new(); let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() { old_body.syntax().clone().into() diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs index ecf74fd36..7ee36e60c 100644 --- a/crates/ra_syntax/src/ast/expr_extensions.rs +++ b/crates/ra_syntax/src/ast/expr_extensions.rs @@ -16,7 +16,7 @@ impl ast::Expr { | ast::Expr::WhileExpr(_) | ast::Expr::BlockExpr(_) | ast::Expr::MatchExpr(_) - | ast::Expr::TryBlockExpr(_) => true, + | ast::Expr::EffectExpr(_) => true, _ => false, } } @@ -359,6 +359,33 @@ impl ast::Literal { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Effect { + Async(SyntaxToken), + Unsafe(SyntaxToken), + Try(SyntaxToken), + // Very much not an effect, but we stuff it into this node anyway + Label(ast::Label), +} + +impl ast::EffectExpr { + pub fn effect(&self) -> Effect { + if let Some(token) = self.async_token() { + return Effect::Async(token); + } + if let Some(token) = self.unsafe_token() { + return Effect::Unsafe(token); + } + if let Some(token) = self.try_token() { + return Effect::Try(token); + } + if let Some(label) = self.label() { + return Effect::Label(label); + } + unreachable!("ast::EffectExpr without Effect") + } +} + impl ast::BlockExpr { /// false if the block is an intrinsic part of the syntax and can't be /// replaced with arbitrary expression. @@ -368,15 +395,12 @@ impl ast::BlockExpr { /// const FOO: () = { stand_alone }; /// ``` pub fn is_standalone(&self) -> bool { - if self.unsafe_token().is_some() || self.async_token().is_some() { - return false; - } - let kind = match self.syntax().parent() { + let parent = match self.syntax().parent() { + Some(it) => it, None => return true, - Some(it) => it.kind(), }; - match kind { - FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR | TRY_BLOCK_EXPR => false, + match parent.kind() { + FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR | EFFECT_EXPR => false, _ => true, } } diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs index 2096f12f1..5e844d5ae 100644 --- a/crates/ra_syntax/src/ast/generated/nodes.rs +++ b/crates/ra_syntax/src/ast/generated/nodes.rs @@ -476,13 +476,16 @@ impl LoopExpr { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TryBlockExpr { +pub struct EffectExpr { pub(crate) syntax: SyntaxNode, } -impl ast::AttrsOwner for TryBlockExpr {} -impl TryBlockExpr { +impl ast::AttrsOwner for EffectExpr {} +impl EffectExpr { + pub fn label(&self) -> Option