1#![expect(clippy::module_inception)]
2
3use std::fmt::Debug;
4
5use serde::Deserialize;
6use serde::Serialize;
7
8use mago_source::SourceIdentifier;
9use mago_span::HasSpan;
10use mago_span::Position;
11use mago_span::Span;
12
13pub use crate::ast::ast::*;
14pub use crate::ast::node::*;
15pub use crate::ast::sequence::Sequence;
16pub use crate::ast::trivia::Trivia;
17pub use crate::ast::trivia::TriviaKind;
18
19pub mod ast;
20pub mod node;
21pub mod sequence;
22pub mod trivia;
23
24#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
25pub struct Program {
26 pub source: SourceIdentifier,
27 pub trivia: Sequence<Trivia>,
28 pub statements: Sequence<Statement>,
29}
30
31impl Program {
32 pub fn has_script(&self) -> bool {
33 for statement in self.statements.iter() {
34 if !matches!(statement, Statement::Inline(_)) {
35 return true;
36 }
37 }
38
39 false
40 }
41}
42
43impl HasSpan for Program {
44 fn span(&self) -> Span {
45 let start =
46 self.statements.first().map(|stmt| stmt.span().start).unwrap_or_else(|| Position::start_of(self.source));
47
48 let end = self.statements.last().map(|stmt| stmt.span().end).unwrap_or_else(|| Position::start_of(self.source));
49
50 Span::new(start, end)
51 }
52}