mago_syntax/ast/ast/
try.rs1use 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}