use crate::transpiler::errors::check::Check;
use crate::transpiler::errors::duplicate_refs::DuplicateRefs;
use crate::transpiler::errors::invalid_application_ref::InvalidApplicationRef;
use crate::transpiler::fsl_transpiler::Fslt;
use serde_json::{json, Value};
pub struct ErrAst {
pub base: Fslt,
pub checks: Vec<Box<dyn Check>>,
}
impl ErrAst {
pub fn default(base: Fslt) -> ErrAst {
ErrAst {
base,
checks: vec![
Box::new(DuplicateRefs {}),
Box::new(InvalidApplicationRef {}),
],
}
}
pub fn new(base: Fslt, checks: Vec<Box<dyn Check>>) -> ErrAst {
ErrAst { base, checks }
}
pub fn decorate(&self) -> Value {
let ast = self.base.out();
let mut aggregated = Vec::new();
self.checks.iter().for_each(|c| {
let errors = c.inspect(&ast);
for err in errors {
aggregated.push(err);
}
});
json!(
{
"program": ast["program"],
"errors": aggregated
}
)
}
}
#[cfg(test)]
mod tests {
use crate::sample_program::sample_program;
use crate::transpiler::errors::duplicate_refs::DuplicateRefs;
use crate::transpiler::errors::err_ast::ErrAst;
use crate::transpiler::errors::invalid_application_ref::InvalidApplicationRef;
use crate::transpiler::fsl_transpiler::Fslt;
use anyhow::Result;
use hamcrest::{equal_to, is, HamcrestMatcher};
#[test]
fn adds_error_for_duplicate_refs() -> Result<()> {
let transpiler =
Fslt::program(sample_program("errors/duplicate-refs.fsl"));
let decorated =
ErrAst::new(transpiler, vec![Box::new(DuplicateRefs {})])
.decorate();
let errors = decorated["errors"]
.as_array()
.expect("failed to get errors");
assert_that!(errors.is_empty(), is(equal_to(false)));
Ok(())
}
#[test]
fn adds_error_for_invalid_application_ref() -> Result<()> {
let transpiler =
Fslt::program(sample_program("errors/invalid-application-ref.fsl"));
let decorated =
ErrAst::new(transpiler, vec![Box::new(InvalidApplicationRef {})])
.decorate();
let errors = decorated["errors"]
.as_array()
.expect("failed to get errors");
assert_that!(errors.is_empty(), is(equal_to(false)));
Ok(())
}
#[test]
fn composes_errors() -> Result<()> {
let transpiler =
Fslt::program(sample_program("errors/duplicate-invalid.fsl"));
let decorated = ErrAst::default(transpiler).decorate();
let errors = decorated["errors"]
.as_array()
.expect("failed to get errors");
assert_that!(errors.len(), is(equal_to(2)));
Ok(())
}
}