diff --git a/src/analyzer.rs b/src/analyzer.rs index 172b5b2..6899796 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -41,48 +41,11 @@ impl<'src> Analyzer<'src> { } } - let mut settings = Settings::default(); - - for (_, set) in self.sets { - match set.value { - Setting::AllowDuplicateRecipes(allow_duplicate_recipes) => { - settings.allow_duplicate_recipes = allow_duplicate_recipes; - } - Setting::DotenvLoad(dotenv_load) => { - settings.dotenv_load = Some(dotenv_load); - } - Setting::Export(export) => { - settings.export = export; - } - Setting::Fallback(fallback) => { - settings.fallback = fallback; - } - Setting::IgnoreComments(ignore_comments) => { - settings.ignore_comments = ignore_comments; - } - Setting::PositionalArguments(positional_arguments) => { - settings.positional_arguments = positional_arguments; - } - Setting::Shell(shell) => { - settings.shell = Some(shell); - } - Setting::WindowsPowerShell(windows_powershell) => { - settings.windows_powershell = windows_powershell; - } - Setting::WindowsShell(windows_shell) => { - settings.windows_shell = Some(windows_shell); - } - Setting::Tempdir(tempdir) => { - settings.tempdir = Some(tempdir); - } - } - } - - let assignments = self.assignments; + let settings = Settings::from_setting_iter(self.sets.into_iter().map(|(_, set)| set.value)); let mut recipe_table: Table<'src, UnresolvedRecipe<'src>> = Default::default(); - AssignmentResolver::resolve_assignments(&assignments)?; + AssignmentResolver::resolve_assignments(&self.assignments)?; for recipe in recipes { if let Some(original) = recipe_table.get(recipe.name.lexeme()) { @@ -96,7 +59,7 @@ impl<'src> Analyzer<'src> { recipe_table.insert(recipe.clone()); } - let recipes = RecipeResolver::resolve_recipes(recipe_table, &assignments)?; + let recipes = RecipeResolver::resolve_recipes(recipe_table, &self.assignments)?; let mut aliases = Table::new(); while let Some(alias) = self.aliases.pop() { @@ -116,7 +79,7 @@ impl<'src> Analyzer<'src> { }), }), aliases, - assignments, + assignments: self.assignments, recipes, settings, }) diff --git a/src/compiler.rs b/src/compiler.rs index cd944a7..999feea 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -3,11 +3,11 @@ use super::*; pub(crate) struct Compiler; impl Compiler { - pub(crate) fn compile(src: &str) -> CompileResult { + pub(crate) fn compile(src: &str) -> CompileResult<(Ast, Justfile)> { let tokens = Lexer::lex(src)?; - let ast = Parser::parse(&tokens)?; + let justfile = Analyzer::analyze(&ast)?; - Analyzer::analyze(&ast) + Ok((ast, justfile)) } } diff --git a/src/lib.rs b/src/lib.rs index 2b44126..c69bfb6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,7 @@ pub(crate) use { alias::Alias, analyzer::Analyzer, assignment::Assignment, assignment_resolver::AssignmentResolver, ast::Ast, attribute::Attribute, binding::Binding, color::Color, color_display::ColorDisplay, command_ext::CommandExt, - compile_error::CompileError, compile_error_kind::CompileErrorKind, + compile_error::CompileError, compile_error_kind::CompileErrorKind, compiler::Compiler, conditional_operator::ConditionalOperator, config::Config, config_error::ConfigError, count::Count, delimiter::Delimiter, dependency::Dependency, dump_format::DumpFormat, enclosure::Enclosure, error::Error, evaluator::Evaluator, expression::Expression, diff --git a/src/settings.rs b/src/settings.rs index 5c3cc10..8a7d919 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -20,6 +20,47 @@ pub(crate) struct Settings<'src> { } impl<'src> Settings<'src> { + pub(crate) fn from_setting_iter(iter: impl Iterator>) -> Self { + let mut settings = Self::default(); + + for set in iter { + match set { + Setting::AllowDuplicateRecipes(allow_duplicate_recipes) => { + settings.allow_duplicate_recipes = allow_duplicate_recipes; + } + Setting::DotenvLoad(dotenv_load) => { + settings.dotenv_load = Some(dotenv_load); + } + Setting::Export(export) => { + settings.export = export; + } + Setting::Fallback(fallback) => { + settings.fallback = fallback; + } + Setting::IgnoreComments(ignore_comments) => { + settings.ignore_comments = ignore_comments; + } + Setting::PositionalArguments(positional_arguments) => { + settings.positional_arguments = positional_arguments; + } + Setting::Shell(shell) => { + settings.shell = Some(shell); + } + Setting::WindowsPowerShell(windows_powershell) => { + settings.windows_powershell = windows_powershell; + } + Setting::WindowsShell(windows_shell) => { + settings.windows_shell = Some(windows_shell); + } + Setting::Tempdir(tempdir) => { + settings.tempdir = Some(tempdir); + } + } + } + + settings + } + pub(crate) fn shell_command(&self, config: &Config) -> Command { let (command, args) = self.shell(config); diff --git a/src/subcommand.rs b/src/subcommand.rs index 0dbaaed..0a57c49 100644 --- a/src/subcommand.rs +++ b/src/subcommand.rs @@ -179,9 +179,7 @@ impl Subcommand { ) -> Result<(&'src str, Ast<'src>, Justfile<'src>), Error<'src>> { let src = loader.load(&search.justfile)?; - let tokens = Lexer::lex(src)?; - let ast = Parser::parse(&tokens)?; - let justfile = Analyzer::analyze(&ast)?; + let (ast, justfile) = Compiler::compile(src)?; if config.verbosity.loud() { for warning in &justfile.warnings { diff --git a/src/summary.rs b/src/summary.rs index f1415f9..091e08b 100644 --- a/src/summary.rs +++ b/src/summary.rs @@ -29,7 +29,7 @@ pub fn summary(path: &Path) -> Result, io::Error> { let text = fs::read_to_string(path)?; match Compiler::compile(&text) { - Ok(justfile) => Ok(Ok(Summary::new(justfile))), + Ok((_, justfile)) => Ok(Ok(Summary::new(justfile))), Err(compilation_error) => Ok(Err(compilation_error.to_string())), } } diff --git a/src/testing.rs b/src/testing.rs index 1e42085..4f3a913 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -2,7 +2,7 @@ use {super::*, crate::compiler::Compiler, pretty_assertions::assert_eq}; pub(crate) fn compile(text: &str) -> Justfile { match Compiler::compile(text) { - Ok(justfile) => justfile, + Ok((_, justfile)) => justfile, Err(error) => panic!("Expected successful compilation but got error:\n {error}"), } } @@ -99,6 +99,7 @@ macro_rules! run_error { if let Subcommand::Run{ overrides, arguments } = &config.subcommand { match $crate::compiler::Compiler::compile(&$crate::unindent::unindent($src)) .expect("Expected successful compilation") + .1 .run( &config, &search,