Skip to main content

mago_syntax/ast/ast/
terminator.rs

1use serde::Serialize;
2use strum::Display;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::ast::ast::tag::ClosingTag;
8use crate::ast::ast::tag::OpeningTag;
9
10/// A statement terminator.
11///
12/// A PHP statement can be terminated with a semicolon `;` or a closing tag `?>`.
13#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, PartialOrd, Ord, Display)]
14#[serde(tag = "type", content = "value")]
15pub enum Terminator<'arena> {
16    /// A semicolon.
17    Semicolon(Span),
18    /// A closing tag.
19    ClosingTag(ClosingTag),
20    /// A closing tag followed immediately by an opening tag.
21    TagPair(ClosingTag, OpeningTag<'arena>),
22    /// Missing terminator.
23    #[strum(disabled)]
24    Missing(Span),
25}
26
27impl Terminator<'_> {
28    #[must_use]
29    #[inline]
30    pub const fn is_semicolon(&self) -> bool {
31        matches!(self, Terminator::Semicolon(_))
32    }
33
34    #[must_use]
35    #[inline]
36    pub const fn is_closing_tag(&self) -> bool {
37        matches!(self, Terminator::ClosingTag(_))
38    }
39}
40
41impl HasSpan for Terminator<'_> {
42    fn span(&self) -> Span {
43        match self {
44            Terminator::Semicolon(s) => *s,
45            Terminator::ClosingTag(t) => t.span(),
46            Terminator::TagPair(c, o) => c.span().join(o.span()),
47            Terminator::Missing(s) => *s,
48        }
49    }
50}