From 07cbb7d73deed8dac3eecdbdc7e1eaf6938a6cd6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 27 Aug 2018 12:22:09 +0300 Subject: Support if-let in scopes --- crates/libsyntax2/src/ast/generated.rs | 66 ++++++++++++++++++++--- crates/libsyntax2/src/ast/mod.rs | 12 +++++ crates/libsyntax2/src/grammar.ron | 36 ++++++++++--- crates/libsyntax2/src/grammar/expressions/atom.rs | 4 +- crates/libsyntax2/src/syntax_kinds/generated.rs | 6 ++- 5 files changed, 108 insertions(+), 16 deletions(-) (limited to 'crates/libsyntax2/src') diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs index 1dd161f52..6891e857c 100644 --- a/crates/libsyntax2/src/ast/generated.rs +++ b/crates/libsyntax2/src/ast/generated.rs @@ -141,7 +141,11 @@ impl<'a> AstNode<'a> for BlockExpr<'a> { fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl<'a> BlockExpr<'a> {} +impl<'a> BlockExpr<'a> { + pub fn block(self) -> Option> { + super::child_opt(self) + } +} // BreakExpr #[derive(Debug, Clone, Copy)] @@ -197,6 +201,32 @@ impl<'a> AstNode<'a> for CastExpr<'a> { impl<'a> CastExpr<'a> {} +// Condition +#[derive(Debug, Clone, Copy)] +pub struct Condition<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for Condition<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + CONDITION => Some(Condition { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> Condition<'a> { + pub fn pat(self) -> Option> { + super::child_opt(self) + } + + pub fn expr(self) -> Option> { + super::child_opt(self) + } +} + // ConstDef #[derive(Debug, Clone, Copy)] pub struct ConstDef<'a> { @@ -403,7 +433,11 @@ impl<'a> AstNode<'a> for ExprStmt<'a> { fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl<'a> ExprStmt<'a> {} +impl<'a> ExprStmt<'a> { + pub fn expr(self) -> Option> { + super::child_opt(self) + } +} // FieldExpr #[derive(Debug, Clone, Copy)] @@ -504,7 +538,11 @@ impl<'a> AstNode<'a> for ForExpr<'a> { fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl<'a> ForExpr<'a> {} +impl<'a> ForExpr<'a> { + pub fn body(self) -> Option> { + super::child_opt(self) + } +} // ForType #[derive(Debug, Clone, Copy)] @@ -540,7 +578,11 @@ impl<'a> AstNode<'a> for IfExpr<'a> { fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl<'a> IfExpr<'a> {} +impl<'a> IfExpr<'a> { + pub fn condition(self) -> Option> { + super::child_opt(self) + } +} // ImplItem #[derive(Debug, Clone, Copy)] @@ -674,7 +716,11 @@ impl<'a> AstNode<'a> for LoopExpr<'a> { fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl<'a> LoopExpr<'a> {} +impl<'a> LoopExpr<'a> { + pub fn body(self) -> Option> { + super::child_opt(self) + } +} // MatchArm #[derive(Debug, Clone, Copy)] @@ -1742,5 +1788,13 @@ impl<'a> AstNode<'a> for WhileExpr<'a> { fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl<'a> WhileExpr<'a> {} +impl<'a> WhileExpr<'a> { + pub fn condition(self) -> Option> { + super::child_opt(self) + } + + pub fn body(self) -> Option> { + super::child_opt(self) + } +} diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs index 6217c5b74..2ebee6a4f 100644 --- a/crates/libsyntax2/src/ast/mod.rs +++ b/crates/libsyntax2/src/ast/mod.rs @@ -115,6 +115,18 @@ impl<'a> Module<'a> { } } +impl<'a> IfExpr<'a> { + pub fn then_branch(self) -> Option> { + self.blocks().nth(0) + } + pub fn else_branch(self) -> Option> { + self.blocks().nth(1) + } + fn blocks(self) -> impl Iterator> { + children(self) + } +} + fn child_opt<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> Option { children(parent).next() } diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron index f3c3d3036..c9e128462 100644 --- a/crates/libsyntax2/src/grammar.ron +++ b/crates/libsyntax2/src/grammar.ron @@ -162,9 +162,10 @@ Grammar( "PATH_EXPR", "LAMBDA_EXPR", "IF_EXPR", + "WHILE_EXPR", + "CONDITION", "LOOP_EXPR", "FOR_EXPR", - "WHILE_EXPR", "CONTINUE_EXPR", "BREAK_EXPR", "LABEL", @@ -336,14 +337,27 @@ Grammar( "ParenExpr": (), "PathExpr": (), "LambdaExpr": (), - "IfExpr": (), - "LoopExpr": (), - "ForExpr": (), - "WhileExpr": (), + "IfExpr": ( + options: [ ["condition", "Condition"] ] + ), + "LoopExpr": ( + options: [ ["body", "Block"] ] + ), + "ForExpr": ( + options: [ ["body", "Block"] ] + ), + "WhileExpr": ( + options: [ + ["condition", "Condition"], + ["body", "Block"], + ] + ), "ContinueExpr": (), "BreakExpr": (), "Label": (), - "BlockExpr": (), + "BlockExpr": ( + options: [ ["block", "Block"] ] + ), "ReturnExpr": (), "MatchExpr": (), "MatchArmList": (), @@ -432,11 +446,19 @@ Grammar( "TypeParamList": ( collections: [ ["type_params", "TypeParam" ] ]), "TypeParam": ( traits: ["NameOwner"] ), "WhereClause": (), - "ExprStmt": (), + "ExprStmt": ( + options: [ ["expr", "Expr"] ] + ), "LetStmt": ( options: [ ["pat", "Pat"], ["initializer", "Expr"], ]), + "Condition": ( + options: [ + [ "pat", "Pat" ], + [ "expr", "Expr" ], + ] + ), "Stmt": ( enum: ["ExprStmt", "LetStmt"], ), diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs index d9c3f998a..bb5402af7 100644 --- a/crates/libsyntax2/src/grammar/expressions/atom.rs +++ b/crates/libsyntax2/src/grammar/expressions/atom.rs @@ -237,11 +237,13 @@ fn for_expr(p: &mut Parser, m: Option) -> CompletedMarker { // test cond // fn foo() { if let Some(_) = None {} } fn cond(p: &mut Parser) { + let m = p.start(); if p.eat(LET_KW) { patterns::pattern(p); p.expect(EQ); } - expr_no_struct(p) + expr_no_struct(p); + m.complete(p, CONDITION); } // test match_expr diff --git a/crates/libsyntax2/src/syntax_kinds/generated.rs b/crates/libsyntax2/src/syntax_kinds/generated.rs index 6a24cb19e..0a22b11c2 100644 --- a/crates/libsyntax2/src/syntax_kinds/generated.rs +++ b/crates/libsyntax2/src/syntax_kinds/generated.rs @@ -158,9 +158,10 @@ pub enum SyntaxKind { PATH_EXPR, LAMBDA_EXPR, IF_EXPR, + WHILE_EXPR, + CONDITION, LOOP_EXPR, FOR_EXPR, - WHILE_EXPR, CONTINUE_EXPR, BREAK_EXPR, LABEL, @@ -418,9 +419,10 @@ impl SyntaxKind { PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" }, IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, + WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" }, + CONDITION => &SyntaxInfo { name: "CONDITION" }, LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" }, FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" }, - WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" }, CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" }, BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" }, LABEL => &SyntaxInfo { name: "LABEL" }, -- cgit v1.2.3