Skip to content

Commit

Permalink
Reform scope and binding (#556)
Browse files Browse the repository at this point in the history
Clean up scope handling by introducing `Binding` and `Scope` objects.
  • Loading branch information
casey authored Dec 7, 2019
1 parent d0e813c commit 2d3134a
Show file tree
Hide file tree
Showing 21 changed files with 543 additions and 438 deletions.
16 changes: 1 addition & 15 deletions src/assignment.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,4 @@
use crate::common::*;

/// An assignment, e.g `foo := bar`
#[derive(Debug, PartialEq)]
pub(crate) struct Assignment<'src> {
/// Assignment was prefixed by the `export` keyword
pub(crate) export: bool,
/// Left-hand side of the assignment
pub(crate) name: Name<'src>,
/// Right-hand side of the assignment
pub(crate) expression: Expression<'src>,
}

impl<'src> Keyed<'src> for Assignment<'src> {
fn key(&self) -> &'src str {
self.name.lexeme()
}
}
pub(crate) type Assignment<'src> = Binding<'src, Expression<'src>>;
231 changes: 0 additions & 231 deletions src/assignment_evaluator.rs

This file was deleted.

22 changes: 11 additions & 11 deletions src/assignment_resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ use crate::common::*;

use CompilationErrorKind::*;

pub(crate) struct AssignmentResolver<'a: 'b, 'b> {
assignments: &'b Table<'a, Assignment<'a>>,
stack: Vec<&'a str>,
seen: BTreeSet<&'a str>,
evaluated: BTreeSet<&'a str>,
pub(crate) struct AssignmentResolver<'src: 'run, 'run> {
assignments: &'run Table<'src, Assignment<'src>>,
stack: Vec<&'src str>,
seen: BTreeSet<&'src str>,
evaluated: BTreeSet<&'src str>,
}

impl<'a: 'b, 'b> AssignmentResolver<'a, 'b> {
impl<'src: 'run, 'run> AssignmentResolver<'src, 'run> {
pub(crate) fn resolve_assignments(
assignments: &Table<'a, Assignment<'a>>,
) -> CompilationResult<'a, ()> {
assignments: &Table<'src, Assignment<'src>>,
) -> CompilationResult<'src, ()> {
let mut resolver = AssignmentResolver {
stack: empty(),
seen: empty(),
Expand All @@ -27,7 +27,7 @@ impl<'a: 'b, 'b> AssignmentResolver<'a, 'b> {
Ok(())
}

fn resolve_assignment(&mut self, name: &'a str) -> CompilationResult<'a, ()> {
fn resolve_assignment(&mut self, name: &'src str) -> CompilationResult<'src, ()> {
if self.evaluated.contains(name) {
return Ok(());
}
Expand All @@ -36,7 +36,7 @@ impl<'a: 'b, 'b> AssignmentResolver<'a, 'b> {
self.stack.push(name);

if let Some(assignment) = self.assignments.get(name) {
self.resolve_expression(&assignment.expression)?;
self.resolve_expression(&assignment.value)?;
self.evaluated.insert(name);
} else {
let message = format!("attempted to resolve unknown assignment `{}`", name);
Expand All @@ -56,7 +56,7 @@ impl<'a: 'b, 'b> AssignmentResolver<'a, 'b> {
Ok(())
}

fn resolve_expression(&mut self, expression: &Expression<'a>) -> CompilationResult<'a, ()> {
fn resolve_expression(&mut self, expression: &Expression<'src>) -> CompilationResult<'src, ()> {
match expression {
Expression::Variable { name } => {
let variable = name.lexeme();
Expand Down
18 changes: 18 additions & 0 deletions src/binding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use crate::common::*;

/// A binding of `name` to `value`
#[derive(Debug, PartialEq)]
pub(crate) struct Binding<'src, V = String> {
/// Export binding as an environment variable to child processes
pub(crate) export: bool,
/// Binding name
pub(crate) name: Name<'src>,
/// Binding value
pub(crate) value: V,
}

impl<'src, V> Keyed<'src> for Binding<'src, V> {
fn key(&self) -> &'src str {
self.name.lexeme()
}
}
32 changes: 17 additions & 15 deletions src/command_ext.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
use crate::common::*;

pub(crate) trait CommandExt {
fn export_environment_variables<'a>(
&mut self,
scope: &BTreeMap<&'a str, (bool, String)>,
dotenv: &BTreeMap<String, String>,
) -> RunResult<'a, ()>;
fn export(&mut self, dotenv: &BTreeMap<String, String>, scope: &Scope);

fn export_scope(&mut self, scope: &Scope);
}

impl CommandExt for Command {
fn export_environment_variables<'a>(
&mut self,
scope: &BTreeMap<&'a str, (bool, String)>,
dotenv: &BTreeMap<String, String>,
) -> RunResult<'a, ()> {
fn export(&mut self, dotenv: &BTreeMap<String, String>, scope: &Scope) {
for (name, value) in dotenv {
self.env(name, value);
}

for (name, (export, value)) in scope {
if *export {
self.env(name, value);
}
if let Some(parent) = scope.parent() {
self.export_scope(parent);
}
}

Ok(())
fn export_scope(&mut self, scope: &Scope) {
if let Some(parent) = scope.parent() {
self.export_scope(parent);
}

for binding in scope.bindings() {
if binding.export {
self.env(binding.name.lexeme(), &binding.value);
}
}
}
}
16 changes: 8 additions & 8 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,16 @@ pub(crate) use crate::{
// structs and enums
pub(crate) use crate::{
alias::Alias, analyzer::Analyzer, assignment::Assignment,
assignment_evaluator::AssignmentEvaluator, assignment_resolver::AssignmentResolver, color::Color,
assignment_resolver::AssignmentResolver, binding::Binding, color::Color,
compilation_error::CompilationError, compilation_error_kind::CompilationErrorKind,
compiler::Compiler, config::Config, config_error::ConfigError, count::Count,
dependency::Dependency, enclosure::Enclosure, expression::Expression, fragment::Fragment,
function::Function, function_context::FunctionContext, interrupt_guard::InterruptGuard,
interrupt_handler::InterruptHandler, item::Item, justfile::Justfile, lexer::Lexer, line::Line,
list::List, load_error::LoadError, module::Module, name::Name, output_error::OutputError,
parameter::Parameter, parser::Parser, platform::Platform, position::Position,
positional::Positional, recipe::Recipe, recipe_context::RecipeContext,
recipe_resolver::RecipeResolver, runtime_error::RuntimeError, search::Search,
dependency::Dependency, enclosure::Enclosure, evaluator::Evaluator, expression::Expression,
fragment::Fragment, function::Function, function_context::FunctionContext,
interrupt_guard::InterruptGuard, interrupt_handler::InterruptHandler, item::Item,
justfile::Justfile, lexer::Lexer, line::Line, list::List, load_error::LoadError, module::Module,
name::Name, output_error::OutputError, parameter::Parameter, parser::Parser, platform::Platform,
position::Position, positional::Positional, recipe::Recipe, recipe_context::RecipeContext,
recipe_resolver::RecipeResolver, runtime_error::RuntimeError, scope::Scope, search::Search,
search_config::SearchConfig, search_error::SearchError, set::Set, setting::Setting,
settings::Settings, shebang::Shebang, show_whitespace::ShowWhitespace, state::State,
string_literal::StringLiteral, subcommand::Subcommand, table::Table, thunk::Thunk, token::Token,
Expand Down
Loading

0 comments on commit 2d3134a

Please sign in to comment.