compose_syntax/ast/
statement.rs

1use crate::ast::{Assignment, AstNode, Expr, LetBinding};
2use crate::ast::macros::node;
3use crate::ast::module::ModuleImport;
4use crate::kind::SyntaxKind;
5use crate::SyntaxNode;
6
7#[derive(Debug, Clone, Copy)]
8pub enum Statement<'a> {
9    Expr(Expr<'a>),
10    Let(LetBinding<'a>),
11    Assign(Assignment<'a>),
12    Break(BreakStatement<'a>),
13    Return(ReturnStatement<'a>),
14    Continue(Continue<'a>),
15    ModuleImport(ModuleImport<'a>)
16}
17
18impl<'a> AstNode<'a> for Statement<'a> {
19    fn from_untyped(node: &'a SyntaxNode) -> Option<Self> {
20        match node.kind() {
21            SyntaxKind::LetBinding => Some(Statement::Let(LetBinding::from_untyped(node)?)),
22            SyntaxKind::Assignment => {
23                Some(Statement::Assign(Assignment::from_untyped(node)?))
24            }
25            SyntaxKind::BreakStatement => Some(Statement::Break(BreakStatement::from_untyped(node)?)),
26            SyntaxKind::ReturnStatement => Some(Statement::Return(ReturnStatement::from_untyped(node)?)),
27            SyntaxKind::Continue => Some(Statement::Continue(Continue::from_untyped(node)?)),
28            SyntaxKind::ModuleImport => Some(Statement::ModuleImport(ModuleImport::from_untyped(node)?)),
29            _ => Expr::from_untyped(node).map(Statement::Expr),
30        }
31    }
32
33    fn to_untyped(&self) -> &'a SyntaxNode {
34        match self {
35            Statement::Expr(expr) => expr.to_untyped(),
36            Statement::Let(let_binding) => let_binding.to_untyped(),
37            Statement::Assign(assign_statement) => assign_statement.to_untyped(),
38            Statement::Break(break_statement) => break_statement.to_untyped(),
39            Statement::Return(return_statement) => return_statement.to_untyped(),
40            Statement::Continue(continue_statement) => continue_statement.to_untyped(),
41            Statement::ModuleImport(import) => import.to_untyped(),
42        }
43    }
44}
45
46node! {
47    struct BreakStatement
48}
49
50impl<'a> BreakStatement<'a> {
51    pub fn value(self) -> Option<Expr<'a>> {
52        self.0.children().find_map(SyntaxNode::cast)
53    }
54}
55
56node! {
57    struct ReturnStatement
58}
59
60impl<'a> ReturnStatement<'a> {
61    pub fn value(self) -> Option<Expr<'a>> {
62        self.0.children().find_map(SyntaxNode::cast)
63    }
64}
65
66node! {
67    struct Continue
68}