Skip to main content

mago_syntax/ast/ast/
try.rs

1use serde::Serialize;
2
3use mago_span::HasSpan;
4use mago_span::Span;
5
6use crate::ast::ast::block::Block;
7use crate::ast::ast::keyword::Keyword;
8use crate::ast::ast::type_hint::Hint;
9use crate::ast::ast::variable::DirectVariable;
10use crate::ast::sequence::Sequence;
11
12#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
13pub struct Try<'arena> {
14    pub r#try: Keyword<'arena>,
15    pub block: Block<'arena>,
16    pub catch_clauses: Sequence<'arena, TryCatchClause<'arena>>,
17    pub finally_clause: Option<TryFinallyClause<'arena>>,
18}
19
20#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
21pub struct TryCatchClause<'arena> {
22    pub r#catch: Keyword<'arena>,
23    pub left_parenthesis: Span,
24    pub hint: Hint<'arena>,
25    pub variable: Option<DirectVariable<'arena>>,
26    pub right_parenthesis: Span,
27    pub block: Block<'arena>,
28}
29
30#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord)]
31pub struct TryFinallyClause<'arena> {
32    pub r#finally: Keyword<'arena>,
33    pub block: Block<'arena>,
34}
35
36impl HasSpan for Try<'_> {
37    fn span(&self) -> Span {
38        match &self.finally_clause {
39            Some(finally) => Span::between(self.r#try.span(), finally.span()),
40            None => match self.catch_clauses.iter().last() {
41                Some(catch_block) => Span::between(self.r#try.span(), catch_block.span()),
42                None => Span::between(self.r#try.span(), self.block.span()),
43            },
44        }
45    }
46}
47
48impl HasSpan for TryCatchClause<'_> {
49    fn span(&self) -> Span {
50        Span::between(self.r#catch.span(), self.block.span())
51    }
52}
53
54impl HasSpan for TryFinallyClause<'_> {
55    fn span(&self) -> Span {
56        Span::between(self.r#finally.span(), self.block.span())
57    }
58}