Skip to content

Commit

Permalink
feat: support referencing metavar outside rewriter
Browse files Browse the repository at this point in the history
part of #1072
  • Loading branch information
HerringtonDarkholme committed May 1, 2024
1 parent cfe3529 commit 35de3ef
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
16 changes: 16 additions & 0 deletions crates/config/src/check_var.rs
Expand Up @@ -41,6 +41,22 @@ fn check_one_rewriter_in_rule<L: Language>(
))
}

pub fn check_vars_in_rewriter<'r, L: Language>(
rule: &'r Rule<L>,
constraints: &'r HashMap<String, Rule<L>>,
transform: &'r Option<HashMap<String, Transformation>>,
fixer: &Option<Fixer<L>>,
upper_var: &HashSet<&str>,
) -> RResult<()> {
let vars = check_var_in_constraints(rule, constraints)?;
let mut vars = check_var_in_transform(vars, transform)?;
for v in upper_var {
vars.insert(v);
}
check_var_in_fix(vars, fixer)?;
Ok(())
}

pub fn check_vars<'r, L: Language>(
rule: &'r Rule<L>,
constraints: &'r HashMap<String, Rule<L>>,
Expand Down
8 changes: 5 additions & 3 deletions crates/config/src/rule_config.rs
Expand Up @@ -82,29 +82,31 @@ impl<L: Language> SerializableRuleConfig<L> {
.with_globals(globals)
.with_rewriters(&rewriters);
let rule = self.core.get_matcher(env)?;
self.register_rewriter(globals, &rewriters)?;
check_rewriters_in_transform(&rule, &rewriters)?;
self.register_rewriter(&rule, globals, &rewriters)?;
Ok(rule)
}

fn register_rewriter(
&self,
rule: &RuleCore<L>,
globals: &GlobalRules<L>,
rewriters: &GlobalRules<L>,
) -> Result<(), RuleConfigError> {
let Some(ser) = &self.rewriters else {
return Ok(());
};
let vars = rule.defined_vars();
for val in ser {
// NB should inherit env from matcher to inherit utils
// TODO: optimize duplicate env creation/util registration
let env = DeserializeEnv::new(self.language.clone())
.with_globals(globals)
.with_rewriters(rewriters);
let env = self.get_deserialize_env(env)?;
let rewriter = val.core.get_matcher(env)?;
let rewriter = val.core.get_rewriter(env, &vars)?;
rewriters.insert(&val.id, rewriter).expect("should work");
}
check_rewriters_in_transform(rule, rewriters)?;
Ok(())
}
}
Expand Down
20 changes: 19 additions & 1 deletion crates/config/src/rule_core.rs
@@ -1,4 +1,4 @@
use crate::check_var::check_vars;
use crate::check_var::{check_vars, check_vars_in_rewriter};
use crate::fixer::{Fixer, FixerError, SerializableFixer};
use crate::rule::referent_rule::RuleRegistration;
use crate::rule::Rule;
Expand Down Expand Up @@ -117,6 +117,24 @@ impl SerializableRuleCore {
check_vars(&ret.rule, &ret.constraints, &ret.transform, &ret.fixer)?;
Ok(ret)
}

/// this is needed for checking metavar defined in containing vars
pub(crate) fn get_rewriter<L: Language>(
&self,
env: DeserializeEnv<L>,
upper_vars: &HashSet<&str>,
) -> RResult<RuleCore<L>> {
let env = self.get_deserialize_env(env)?;
let ret = self.get_matcher_from_env(&env)?;
check_vars_in_rewriter(
&ret.rule,
&ret.constraints,
&ret.transform,
&ret.fixer,
upper_vars,
)?;
Ok(ret)
}
}

pub struct RuleCore<L: Language> {
Expand Down

0 comments on commit 35de3ef

Please sign in to comment.