use alloc::{boxed::Box, sync::Arc, vec::Vec};
use miden_debug_types::{DefaultSourceManager, SourceFile, SourceManager};
use miden_utils_diagnostics::{
Report,
reporting::{ReportHandlerOpts, set_hook},
};
#[cfg(feature = "std")]
use crate::diagnostics::reporting::set_panic_hook;
use crate::{
Parse, ParseOptions, Path,
ast::{Form, Module, ModuleKind},
};
pub struct SyntaxTestContext {
source_manager: Arc<dyn SourceManager>,
warnings_as_errors: bool,
}
impl Default for SyntaxTestContext {
fn default() -> Self {
Self::new()
}
}
impl SyntaxTestContext {
pub fn new() -> Self {
#[cfg(feature = "logging")]
{
let _ = env_logger::Builder::from_env("MIDEN_LOG").format_timestamp(None).try_init();
}
#[cfg(feature = "std")]
{
let result = set_hook(Box::new(|_| Box::new(ReportHandlerOpts::new().build())));
#[cfg(feature = "std")]
if result.is_ok() {
set_panic_hook();
}
}
#[cfg(not(feature = "std"))]
{
let _ = set_hook(Box::new(|_| Box::new(ReportHandlerOpts::new().build())));
}
let source_manager = Arc::new(DefaultSourceManager::default());
Self {
source_manager,
warnings_as_errors: false,
}
}
pub fn with_warnings_as_errors(mut self, yes: bool) -> Self {
self.warnings_as_errors = yes;
self
}
#[inline(always)]
pub fn source_manager(&self) -> Arc<dyn SourceManager> {
self.source_manager.clone()
}
#[track_caller]
pub fn parse_forms(&self, source: Arc<SourceFile>) -> Result<Vec<Form>, Report> {
crate::parser::parse_forms(source.clone())
.map_err(|err| Report::new(err).with_source_code(source))
}
#[track_caller]
pub fn parse_program(&self, source: impl Parse) -> Result<Box<Module>, Report> {
source.parse_with_options(
self.source_manager.clone(),
ParseOptions {
warnings_as_errors: self.warnings_as_errors,
..Default::default()
},
)
}
#[track_caller]
pub fn parse_kernel(&self, source: impl Parse) -> Result<Box<Module>, Report> {
source.parse_with_options(
self.source_manager.clone(),
ParseOptions {
warnings_as_errors: self.warnings_as_errors,
..ParseOptions::for_kernel()
},
)
}
#[track_caller]
pub fn parse_module(&self, source: impl Parse) -> Result<Box<Module>, Report> {
source.parse_with_options(
self.source_manager.clone(),
ParseOptions {
warnings_as_errors: self.warnings_as_errors,
..ParseOptions::for_library()
},
)
}
#[track_caller]
pub fn parse_module_with_path(
&self,
path: impl AsRef<Path>,
source: impl Parse,
) -> Result<Box<Module>, Report> {
source.parse_with_options(
self.source_manager.clone(),
ParseOptions {
warnings_as_errors: self.warnings_as_errors,
..ParseOptions::new(ModuleKind::Library, path)
},
)
}
}