Skip to content

Commit

Permalink
refactor: move check var around
Browse files Browse the repository at this point in the history
  • Loading branch information
HerringtonDarkholme committed May 1, 2024
1 parent 1e8af4c commit cfe3529
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 38 deletions.
32 changes: 32 additions & 0 deletions crates/config/src/check_var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,45 @@ use crate::fixer::Fixer;
use crate::rule::Rule;
use crate::rule_core::RuleConfigError;
use crate::transform::Transformation;
use crate::{GlobalRules, RuleCore};

use ast_grep_core::language::Language;

use std::collections::{HashMap, HashSet};

type RResult<T> = std::result::Result<T, RuleConfigError>;

pub fn check_rewriters_in_transform<L: Language>(
rule: &RuleCore<L>,
rewriters: &GlobalRules<L>,
) -> Result<(), RuleConfigError> {
let rewriters = rewriters.read();
if let Some(err) = check_one_rewriter_in_rule(rule, &rewriters) {
return Err(err);
}
let error = rewriters
.values()
.find_map(|rewriter| check_one_rewriter_in_rule(rewriter, &rewriters));
if let Some(err) = error {
return Err(err);
}
Ok(())
}

fn check_one_rewriter_in_rule<L: Language>(
rule: &RuleCore<L>,
rewriters: &HashMap<String, RuleCore<L>>,
) -> Option<RuleConfigError> {
let transform = rule.transform.as_ref()?;
let mut used_rewriters = transform
.values()
.flat_map(|trans| trans.used_rewriters().iter());
let undefined_writers = used_rewriters.find(|r| !rewriters.contains_key(*r))?;
Some(RuleConfigError::UndefinedRewriter(
undefined_writers.to_string(),
))
}

pub fn check_vars<'r, L: Language>(
rule: &'r Rule<L>,
constraints: &'r HashMap<String, Rule<L>>,
Expand Down
49 changes: 14 additions & 35 deletions crates/config/src/rule_config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::GlobalRules;

use crate::check_var::check_rewriters_in_transform;
use crate::fixer::Fixer;
use crate::rule::DeserializeEnv;
pub use crate::rule_core::{RuleConfigError, RuleCore, SerializableRuleCore};
Expand Down Expand Up @@ -81,55 +82,33 @@ 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)?;
Ok(rule)
}

fn register_rewriter(
&self,
globals: &GlobalRules<L>,
rewriters: &GlobalRules<L>,
) -> Result<(), RuleConfigError> {
let Some(ser) = &self.rewriters else {
return Ok(rule);
return Ok(());
};
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);
.with_rewriters(rewriters);
let env = self.get_deserialize_env(env)?;
let rewriter = val.core.get_matcher(env)?;
rewriters.insert(&val.id, rewriter).expect("should work");
}
check_rewriters_in_transform(&rule, &rewriters)?;
Ok(rule)
Ok(())
}
}

fn check_rewriters_in_transform<L: Language>(
rule: &RuleCore<L>,
rewriters: &GlobalRules<L>,
) -> Result<(), RuleConfigError> {
let rewriters = rewriters.read();
if let Some(err) = check_one_rewriter_in_rule(rule, &rewriters) {
return Err(err);
}
let error = rewriters
.values()
.find_map(|rewriter| check_one_rewriter_in_rule(rewriter, &rewriters));
if let Some(err) = error {
return Err(err);
}
Ok(())
}

fn check_one_rewriter_in_rule<L: Language>(
rule: &RuleCore<L>,
rewriters: &HashMap<String, RuleCore<L>>,
) -> Option<RuleConfigError> {
let transform = rule.transform.as_ref()?;
let mut used_rewriters = transform
.values()
.flat_map(|trans| trans.used_rewriters().iter());
let undefined_writers = used_rewriters.find(|r| !rewriters.contains_key(*r))?;
Some(RuleConfigError::UndefinedRewriter(
undefined_writers.to_string(),
))
}

impl<L: Language> Deref for SerializableRuleConfig<L> {
type Target = SerializableRuleCore;
fn deref(&self) -> &Self::Target {
Expand Down
7 changes: 4 additions & 3 deletions crates/config/src/rule_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl SerializableRuleCore {
if let Some(utils) = &self.utils {
let env = env
.register_local_utils(utils)
.map_err(RuleConfigError::Rule)?;
.map_err(RuleConfigError::Utils)?;
Ok(env)
} else {
Ok(env)
Expand Down Expand Up @@ -102,7 +102,6 @@ impl SerializableRuleCore {
let constraints = self.get_constraints(env)?;
let transform = self.transform.clone();
let fixer = self.get_fixer(env)?;
check_vars(&rule, &constraints, &transform, &fixer)?;
Ok(
RuleCore::new(rule)
.with_matchers(constraints)
Expand All @@ -114,7 +113,9 @@ impl SerializableRuleCore {

pub fn get_matcher<L: Language>(&self, env: DeserializeEnv<L>) -> RResult<RuleCore<L>> {
let env = self.get_deserialize_env(env)?;
self.get_matcher_from_env(&env)
let ret = self.get_matcher_from_env(&env)?;
check_vars(&ret.rule, &ret.constraints, &ret.transform, &ret.fixer)?;
Ok(ret)
}
}

Expand Down

0 comments on commit cfe3529

Please sign in to comment.