expand_expr visitors now don't depend on each other.

This commit is contained in:
Filipe Rodrigues 2022-09-19 02:00:16 +01:00
parent 9ac00b7304
commit f25a24fce7
3 changed files with 45 additions and 26 deletions

View File

@ -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<Option<Rule<String>>, 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));
}

View File

@ -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<String, Expr>,
/// Rule aliases
rule_aliases: &'rule HashMap<String, Expr>,
@ -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<String, Expr>) -> Self {
pub fn new(global_aliases: &'global HashMap<String, Expr>, rule_aliases: &'rule HashMap<String, Expr>) -> 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<Expr> {
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<String, Expr>,
/// Patterns
pats: &'pats HashMap<String, String>,
/// Rule aliases
rule_aliases: &'rule HashMap<String, Expr>,
/// Rule patterns
rule_pats: &'pats HashMap<String, String>,
}
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<String, String>) -> Self {
pub fn new(
global_aliases: &'global HashMap<String, Expr>,
rule_aliases: &'rule HashMap<String, Expr>,
rule_pats: &'pats HashMap<String, String>,
) -> 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<Expr> {
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<String> {
match self.pats.get(pat_name).cloned() {
match self.rule_pats.get(pat_name).cloned() {
Some(value) => FlowControl::ExpandTo(value),
None => FlowControl::Error,
}

View File

@ -10,12 +10,16 @@ use {
/// Expands a rule of all it's aliases and patterns
pub fn expand_rule(
rule: &Rule<Expr>,
rule_output_expr_visitor: expand_expr::RuleOutputVisitor,
pats: &HashMap<String, String>,
global_aliases: &HashMap<String, Expr>,
rule_aliases: &HashMap<String, Expr>,
rule_pats: &HashMap<String, String>,
) -> Result<Rule<String>, anyhow::Error> {
// Helper function to expand an expression
let expand_expr = for<'a> move |expr: &'a Expr| -> anyhow::Result<String> {
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