diff --git a/src/build.rs b/src/build.rs index 3ff45a0..09718e4 100644 --- a/src/build.rs +++ b/src/build.rs @@ -135,9 +135,7 @@ impl Builder { .rules .get(rule) .with_context(|| format!("Unknown rule {rule:?}"))?; - let global_expr_visitor = expand_expr::GlobalVisitor::new(&rules.aliases); - let rule_output_expr_visitor = expand_expr::RuleOutputVisitor::new(global_expr_visitor, &rule.aliases); - self::expand_rule(rule, rule_output_expr_visitor, pats) + self::expand_rule(rule, &rules.aliases, &rule.aliases, pats) .with_context(|| format!("Unable to expand rule {:?}", rule.name))? }, }; @@ -498,20 +496,20 @@ fn file_modified_time(metadata: fs::Metadata) -> SystemTime { // TODO: Not make this `O(N)` for the number of rules. pub fn find_rule_for_file(file: &str, rules: &Rules) -> Result>, anyhow::Error> { for rule in rules.rules.values() { - let global_expr_visitor = expand_expr::GlobalVisitor::new(&rules.aliases); - let mut rule_output_expr_visitor = expand_expr::RuleOutputVisitor::new(global_expr_visitor, &rule.aliases); - for output in &rule.output { // Expand all expressions in the output file // Note: This doesn't expand patterns, so we can match those later let output = output.file(); - let file_cmpts = self::expand_expr(output, &mut rule_output_expr_visitor)?; + let file_cmpts = self::expand_expr( + output, + &mut expand_expr::RuleOutputVisitor::new(&rules.aliases, &rule.aliases), + )?; // Then try to match the output file to the file we need to create - if let Some(pats) = self::match_expr(&file_cmpts, file) + if let Some(rule_pats) = self::match_expr(&file_cmpts, file) .with_context(|| format!("Unable to match expression inside rule {:?}", rule.name))? { - let rule = self::expand_rule(rule, rule_output_expr_visitor, &pats) + let rule = self::expand_rule(rule, &rules.aliases, &rule.aliases, &rule_pats) .with_context(|| format!("Unable to expand rule {:?}", rule.name))?; return Ok(Some(rule)); } diff --git a/src/build/expand_expr.rs b/src/build/expand_expr.rs index 098368b..baca7e6 100644 --- a/src/build/expand_expr.rs +++ b/src/build/expand_expr.rs @@ -173,8 +173,8 @@ impl<'global> Visitor for GlobalVisitor<'global> { /// Keeps any patterns. #[derive(Clone, Copy, Debug)] pub struct RuleOutputVisitor<'global, 'rule> { - /// Global visitor - global_visitor: GlobalVisitor<'global>, + /// Global aliases + global_aliases: &'global HashMap, /// Rule aliases rule_aliases: &'rule HashMap, @@ -182,9 +182,9 @@ pub struct RuleOutputVisitor<'global, 'rule> { impl<'global, 'rule> RuleOutputVisitor<'global, 'rule> { /// Creates a new rule output expression visitor - pub fn new(global_visitor: GlobalVisitor<'global>, rule_aliases: &'rule HashMap) -> Self { + pub fn new(global_aliases: &'global HashMap, rule_aliases: &'rule HashMap) -> Self { Self { - global_visitor, + global_aliases, rule_aliases, } } @@ -194,7 +194,10 @@ impl<'global, 'rule> Visitor for RuleOutputVisitor<'global, 'rule> { fn visit_alias(&mut self, alias_name: &str) -> FlowControl { match self.rule_aliases.get(alias_name).cloned() { Some(expr) => FlowControl::ExpandTo(expr), - None => self.global_visitor.visit_alias(alias_name), + None => match self.global_aliases.get(alias_name).cloned() { + Some(expr) => FlowControl::ExpandTo(expr), + None => FlowControl::Error, + }, } } @@ -209,30 +212,44 @@ impl<'global, 'rule> Visitor for RuleOutputVisitor<'global, 'rule> { /// Expands any defined patterns, errors on undefined #[derive(Clone, Copy, Debug)] pub struct RuleVisitor<'global, 'rule, 'pats> { - /// Rule output visitor - rule_output_visitor: RuleOutputVisitor<'global, 'rule>, + /// Global aliases + global_aliases: &'global HashMap, - /// Patterns - pats: &'pats HashMap, + /// Rule aliases + rule_aliases: &'rule HashMap, + + /// Rule patterns + rule_pats: &'pats HashMap, } impl<'global, 'rule, 'pats> RuleVisitor<'global, 'rule, 'pats> { /// Creates a new rule visitor - pub fn new(rule_output_visitor: RuleOutputVisitor<'global, 'rule>, pats: &'pats HashMap) -> Self { + pub fn new( + global_aliases: &'global HashMap, + rule_aliases: &'rule HashMap, + rule_pats: &'pats HashMap, + ) -> Self { Self { - rule_output_visitor, - pats, + global_aliases, + rule_aliases, + rule_pats, } } } impl<'global, 'rule, 'pats> Visitor for RuleVisitor<'global, 'rule, 'pats> { fn visit_alias(&mut self, alias_name: &str) -> FlowControl { - self.rule_output_visitor.visit_alias(alias_name) + match self.rule_aliases.get(alias_name).cloned() { + Some(expr) => FlowControl::ExpandTo(expr), + None => match self.global_aliases.get(alias_name).cloned() { + Some(expr) => FlowControl::ExpandTo(expr), + None => FlowControl::Error, + }, + } } fn visit_pat(&mut self, pat_name: &str) -> FlowControl { - match self.pats.get(pat_name).cloned() { + match self.rule_pats.get(pat_name).cloned() { Some(value) => FlowControl::ExpandTo(value), None => FlowControl::Error, } diff --git a/src/build/expand_rule.rs b/src/build/expand_rule.rs index c32d12e..1102a90 100644 --- a/src/build/expand_rule.rs +++ b/src/build/expand_rule.rs @@ -10,12 +10,16 @@ use { /// Expands a rule of all it's aliases and patterns pub fn expand_rule( rule: &Rule, - rule_output_expr_visitor: expand_expr::RuleOutputVisitor, - pats: &HashMap, + global_aliases: &HashMap, + rule_aliases: &HashMap, + rule_pats: &HashMap, ) -> Result, anyhow::Error> { // Helper function to expand an expression let expand_expr = for<'a> move |expr: &'a Expr| -> anyhow::Result { - self::expand_expr_string(expr, &mut expand_expr::RuleVisitor::new(rule_output_expr_visitor, pats)) + self::expand_expr_string( + expr, + &mut expand_expr::RuleVisitor::new(global_aliases, rule_aliases, rule_pats), + ) }; // Helper function to expand items