Skip constant evaluation on fatal parser error

Replaces the previous "sloppy" system which would still generate up to
one 'undefined var' error for variable assignments whose declarations
were lost, and did not protect against variable references in values.

Fixes #110.
This commit is contained in:
Tad Hardesty 2019-11-06 20:23:38 -08:00
parent 424731084e
commit ccd81ada75
3 changed files with 11 additions and 19 deletions

View file

@ -380,9 +380,7 @@ pub fn preprocessor_evaluate(location: Location, expr: Expression, defines: &Def
}
/// Evaluate all the type-level variables in an object tree into constants.
pub(crate) fn evaluate_all(context: &Context, tree: &mut ObjectTree, sloppy: bool) {
let mut been_sloppy = false;
pub(crate) fn evaluate_all(context: &Context, tree: &mut ObjectTree) {
for ty in tree.graph.node_indices() {
let keys: Vec<String> = tree.graph.node_weight(ty).unwrap().vars.keys().cloned().collect();
for key in keys {
@ -401,23 +399,12 @@ pub(crate) fn evaluate_all(context: &Context, tree: &mut ObjectTree, sloppy: boo
Err(err) => context.register_error(err),
Ok(ConstLookup::Found(_, _)) => {}
Ok(ConstLookup::Continue(_)) => {
let extra = if sloppy {
if been_sloppy {
continue;
}
been_sloppy = true;
"\nignoring further errors of this type due to earlier parse failures"
} else {
""
};
context.register_error(DMError::new(
tree.graph.node_weight(ty).unwrap().vars[&key].value.location,
format!(
"undefined var '{}' on type '{}'{}",
"undefined var '{}' on type '{}'",
key,
tree.graph.node_weight(ty).unwrap().path,
extra
),
));
}

View file

@ -696,9 +696,11 @@ impl ObjectTree {
// ------------------------------------------------------------------------
// Finalization
pub(crate) fn finalize(&mut self, context: &Context, sloppy: bool) {
pub(crate) fn finalize(&mut self, context: &Context, parser_fatal_errored: bool) {
self.assign_parent_types(context);
super::constants::evaluate_all(context, self, sloppy);
if !parser_fatal_errored {
super::constants::evaluate_all(context, self);
}
}
fn assign_parent_types(&mut self, context: &Context) {

View file

@ -337,6 +337,7 @@ pub struct Parser<'ctx, 'an, I> {
context: &'ctx Context,
annotations: Option<&'an mut AnnotationTree>,
tree: ObjectTree,
fatal_errored: bool,
input: I,
eof: bool,
@ -370,6 +371,7 @@ where
context,
annotations: None,
tree: ObjectTree::default(),
fatal_errored: false,
input,
eof: false,
@ -414,6 +416,8 @@ where
let loc = e.location();
e = e.set_severity(Severity::Error);
e.add_note(loc, "fatal error: the parser cannot continue");
e.add_note(loc, "constant evaluation will be skipped");
self.fatal_errored = true;
self.context.register_error(e);
}
}
@ -433,8 +437,7 @@ where
);
}
let sloppy = self.context.errors().iter().any(|p| p.severity() == Severity::Error);
self.tree.finalize(self.context, sloppy);
self.tree.finalize(self.context, self.fatal_errored);
self.tree
}