Refactor evaluators and resolvers into common form (#258)

This commit is contained in:
Casey Rodarmor 2017-11-18 01:18:04 -08:00 committed by GitHub
parent bc79d16eac
commit 28a57d9828
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 111 additions and 112 deletions

View File

@ -2,13 +2,25 @@ use common::*;
use brev; use brev;
pub fn evaluate_assignments<'a>( pub struct AssignmentEvaluator<'a: 'b, 'b> {
pub assignments: &'b Map<&'a str, Expression<'a>>,
pub evaluated: Map<&'a str, String>,
pub exports: &'b Set<&'a str>,
pub overrides: &'b Map<&'b str, &'b str>,
pub quiet: bool,
pub scope: &'b Map<&'a str, String>,
pub shell: &'b str,
pub dry_run: bool,
}
impl<'a, 'b> AssignmentEvaluator<'a, 'b> {
pub fn evaluate_assignments(
assignments: &Map<&'a str, Expression<'a>>, assignments: &Map<&'a str, Expression<'a>>,
overrides: &Map<&str, &str>, overrides: &Map<&str, &str>,
quiet: bool, quiet: bool,
shell: &'a str, shell: &'a str,
dry_run: bool, dry_run: bool,
) -> RunResult<'a, Map<&'a str, String>> { ) -> RunResult<'a, Map<&'a str, String>> {
let mut evaluator = AssignmentEvaluator { let mut evaluator = AssignmentEvaluator {
assignments: assignments, assignments: assignments,
evaluated: empty(), evaluated: empty(),
@ -25,20 +37,8 @@ pub fn evaluate_assignments<'a>(
} }
Ok(evaluator.evaluated) Ok(evaluator.evaluated)
} }
pub struct AssignmentEvaluator<'a: 'b, 'b> {
pub assignments: &'b Map<&'a str, Expression<'a>>,
pub evaluated: Map<&'a str, String>,
pub exports: &'b Set<&'a str>,
pub overrides: &'b Map<&'b str, &'b str>,
pub quiet: bool,
pub scope: &'b Map<&'a str, String>,
pub shell: &'b str,
pub dry_run: bool,
}
impl<'a, 'b> AssignmentEvaluator<'a, 'b> {
pub fn evaluate_line( pub fn evaluate_line(
&mut self, &mut self,
line: &[Fragment<'a>], line: &[Fragment<'a>],

View File

@ -2,10 +2,19 @@ use common::*;
use CompilationErrorKind::*; use CompilationErrorKind::*;
pub fn resolve_assignments<'a>( pub struct AssignmentResolver<'a: 'b, 'b> {
assignments: &'b Map<&'a str, Expression<'a>>,
assignment_tokens: &'b Map<&'a str, Token<'a>>,
stack: Vec<&'a str>,
seen: Set<&'a str>,
evaluated: Set<&'a str>,
}
impl<'a: 'b, 'b> AssignmentResolver<'a, 'b> {
pub fn resolve_assignments(
assignments: &Map<&'a str, Expression<'a>>, assignments: &Map<&'a str, Expression<'a>>,
assignment_tokens: &Map<&'a str, Token<'a>>, assignment_tokens: &Map<&'a str, Token<'a>>,
) -> CompilationResult<'a, ()> { ) -> CompilationResult<'a, ()> {
let mut resolver = AssignmentResolver { let mut resolver = AssignmentResolver {
assignments: assignments, assignments: assignments,
@ -20,17 +29,8 @@ pub fn resolve_assignments<'a>(
} }
Ok(()) Ok(())
} }
struct AssignmentResolver<'a: 'b, 'b> {
assignments: &'b Map<&'a str, Expression<'a>>,
assignment_tokens: &'b Map<&'a str, Token<'a>>,
stack: Vec<&'a str>,
seen: Set<&'a str>,
evaluated: Set<&'a str>,
}
impl<'a: 'b, 'b> AssignmentResolver<'a, 'b> {
fn resolve_assignment(&mut self, name: &'a str) -> CompilationResult<'a, ()> { fn resolve_assignment(&mut self, name: &'a str) -> CompilationResult<'a, ()> {
if self.evaluated.contains(name) { if self.evaluated.contains(name) {
return Ok(()); return Ok(());

View File

@ -1,8 +1,6 @@
use common::*; use common::*;
use edit_distance::edit_distance; use edit_distance::edit_distance;
use assignment_evaluator::evaluate_assignments;
use range_ext::RangeExt;
pub struct Justfile<'a> { pub struct Justfile<'a> {
pub recipes: Map<&'a str, Recipe<'a>>, pub recipes: Map<&'a str, Recipe<'a>>,
@ -55,7 +53,7 @@ impl<'a, 'b> Justfile<'a> where 'a: 'b {
return Err(RuntimeError::UnknownOverrides{overrides: unknown_overrides}); return Err(RuntimeError::UnknownOverrides{overrides: unknown_overrides});
} }
let scope = evaluate_assignments( let scope = AssignmentEvaluator::evaluate_assignments(
&self.assignments, &self.assignments,
&configuration.overrides, &configuration.overrides,
configuration.quiet, configuration.quiet,

View File

@ -53,6 +53,7 @@ mod common {
pub use tempdir::TempDir; pub use tempdir::TempDir;
pub use assignment_evaluator::AssignmentEvaluator; pub use assignment_evaluator::AssignmentEvaluator;
pub use assignment_resolver::AssignmentResolver;
pub use command_ext::CommandExt; pub use command_ext::CommandExt;
pub use compilation_error::{CompilationError, CompilationErrorKind, CompilationResult}; pub use compilation_error::{CompilationError, CompilationErrorKind, CompilationResult};
pub use configuration::Configuration; pub use configuration::Configuration;
@ -63,7 +64,9 @@ mod common {
pub use misc::{default, empty}; pub use misc::{default, empty};
pub use parameter::Parameter; pub use parameter::Parameter;
pub use parser::Parser; pub use parser::Parser;
pub use range_ext::RangeExt;
pub use recipe::Recipe; pub use recipe::Recipe;
pub use recipe_resolver::RecipeResolver;
pub use runtime_error::{RuntimeError, RunResult}; pub use runtime_error::{RuntimeError, RunResult};
pub use shebang::Shebang; pub use shebang::Shebang;
pub use token::{Token, TokenKind}; pub use token::{Token, TokenKind};

View File

@ -3,8 +3,6 @@ use common::*;
use itertools; use itertools;
use TokenKind::*; use TokenKind::*;
use CompilationErrorKind::*; use CompilationErrorKind::*;
use recipe_resolver::resolve_recipes;
use assignment_resolver::resolve_assignments;
pub struct Parser<'a> { pub struct Parser<'a> {
text: &'a str, text: &'a str,
@ -350,7 +348,7 @@ impl<'a> Parser<'a> {
})) }))
} }
resolve_recipes(&self.recipes, &self.assignments, self.text)?; RecipeResolver::resolve_recipes(&self.recipes, &self.assignments, self.text)?;
for recipe in self.recipes.values() { for recipe in self.recipes.values() {
for parameter in &recipe.parameters { for parameter in &recipe.parameters {
@ -371,7 +369,7 @@ impl<'a> Parser<'a> {
} }
} }
resolve_assignments(&self.assignments, &self.assignment_tokens)?; AssignmentResolver::resolve_assignments(&self.assignments, &self.assignment_tokens)?;
Ok(Justfile { Ok(Justfile {
recipes: self.recipes, recipes: self.recipes,

View File

@ -2,11 +2,19 @@ use common::*;
use CompilationErrorKind::*; use CompilationErrorKind::*;
pub fn resolve_recipes<'a>( pub struct RecipeResolver<'a: 'b, 'b> {
stack: Vec<&'a str>,
seen: Set<&'a str>,
resolved: Set<&'a str>,
recipes: &'b Map<&'a str, Recipe<'a>>,
}
impl<'a, 'b> RecipeResolver<'a, 'b> {
pub fn resolve_recipes(
recipes: &Map<&'a str, Recipe<'a>>, recipes: &Map<&'a str, Recipe<'a>>,
assignments: &Map<&'a str, Expression<'a>>, assignments: &Map<&'a str, Expression<'a>>,
text: &'a str, text: &'a str,
) -> CompilationResult<'a, ()> { ) -> CompilationResult<'a, ()> {
let mut resolver = RecipeResolver { let mut resolver = RecipeResolver {
seen: empty(), seen: empty(),
stack: empty(), stack: empty(),
@ -15,7 +23,7 @@ pub fn resolve_recipes<'a>(
}; };
for recipe in recipes.values() { for recipe in recipes.values() {
resolver.resolve(recipe)?; resolver.resolve_recipe(recipe)?;
resolver.seen = empty(); resolver.seen = empty();
} }
@ -56,17 +64,9 @@ pub fn resolve_recipes<'a>(
} }
Ok(()) Ok(())
} }
struct RecipeResolver<'a: 'b, 'b> { fn resolve_recipe(&mut self, recipe: &Recipe<'a>) -> CompilationResult<'a, ()> {
stack: Vec<&'a str>,
seen: Set<&'a str>,
resolved: Set<&'a str>,
recipes: &'b Map<&'a str, Recipe<'a>>,
}
impl<'a, 'b> RecipeResolver<'a, 'b> {
fn resolve(&mut self, recipe: &Recipe<'a>) -> CompilationResult<'a, ()> {
if self.resolved.contains(recipe.name) { if self.resolved.contains(recipe.name) {
return Ok(()) return Ok(())
} }
@ -85,7 +85,7 @@ impl<'a, 'b> RecipeResolver<'a, 'b> {
.cloned().collect() .cloned().collect()
})); }));
} }
self.resolve(dependency)?; self.resolve_recipe(dependency)?;
}, },
None => return Err(dependency_token.error(UnknownDependency { None => return Err(dependency_token.error(UnknownDependency {
recipe: recipe.name, recipe: recipe.name,