use serde::Deserialize;
use serde::Serialize;
use mago_ast::Program;
use mago_interner::ThreadedInterner;
use mago_names::Names;
use mago_parser::error::ParseError;
use mago_php_version::PHPVersion;
use mago_reflection::CodebaseReflection;
use mago_reporting::IssueCollection;
use mago_source::Source;
use mago_source::SourceCategory;
use crate::internal;
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Module {
pub source: Source,
pub names: Names,
pub parse_error: Option<ParseError>,
pub reflection: Option<CodebaseReflection>,
pub issues: IssueCollection,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
pub struct ModuleBuildOptions {
pub reflect: bool,
pub validate: bool,
}
impl Module {
#[inline(always)]
pub fn build(
interner: &ThreadedInterner,
version: PHPVersion,
source: Source,
options: ModuleBuildOptions,
) -> Self {
let (module, _) = Self::build_with_ast(interner, version, source, options);
module
}
#[inline(always)]
pub fn build_with_ast(
interner: &ThreadedInterner,
version: PHPVersion,
source: Source,
options: ModuleBuildOptions,
) -> (Self, Program) {
let (program, parse_error) = mago_parser::parse_source(interner, &source);
let names = Names::resolve(interner, &program);
let (reflection, issues) = internal::build(interner, version, &source, &program, &names, options);
let module = Self { source, parse_error, names, reflection, issues };
(module, program)
}
pub fn parse(&self, interner: &ThreadedInterner) -> Program {
mago_parser::parse_source(interner, &self.source).0
}
#[inline]
pub const fn category(&self) -> SourceCategory {
self.source.identifier.category()
}
}
impl ModuleBuildOptions {
#[inline(always)]
pub const fn new(reflect: bool, validate: bool) -> Self {
Self { reflect, validate }
}
#[inline(always)]
pub const fn reflection() -> Self {
Self { reflect: true, validate: false }
}
#[inline(always)]
pub const fn validation() -> Self {
Self { reflect: false, validate: true }
}
}
impl Default for ModuleBuildOptions {
fn default() -> Self {
Self::new(true, true)
}
}