Borrow Ast in Analyser (#1527)

This commit is contained in:
Greg Shuflin 2023-01-24 20:06:33 -08:00 committed by GitHub
parent 70dcc7f528
commit 6ab6588549
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 18 deletions

View File

@ -4,40 +4,39 @@ const VALID_ALIAS_ATTRIBUTES: [Attribute; 1] = [Attribute::Private];
#[derive(Default)] #[derive(Default)]
pub(crate) struct Analyzer<'src> { pub(crate) struct Analyzer<'src> {
recipes: Table<'src, UnresolvedRecipe<'src>>,
assignments: Table<'src, Assignment<'src>>, assignments: Table<'src, Assignment<'src>>,
aliases: Table<'src, Alias<'src, Name<'src>>>, aliases: Table<'src, Alias<'src, Name<'src>>>,
sets: Table<'src, Set<'src>>, sets: Table<'src, Set<'src>>,
} }
impl<'src> Analyzer<'src> { impl<'src> Analyzer<'src> {
pub(crate) fn analyze(ast: Ast<'src>) -> CompileResult<'src, Justfile> { pub(crate) fn analyze(ast: &Ast<'src>) -> CompileResult<'src, Justfile<'src>> {
Analyzer::default().justfile(ast) Analyzer::default().justfile(ast)
} }
pub(crate) fn justfile(mut self, ast: Ast<'src>) -> CompileResult<'src, Justfile<'src>> { fn justfile(mut self, ast: &Ast<'src>) -> CompileResult<'src, Justfile<'src>> {
let mut recipes = Vec::new(); let mut recipes = Vec::new();
for item in ast.items { for item in &ast.items {
match item { match item {
Item::Alias(alias) => { Item::Alias(alias) => {
self.analyze_alias(&alias)?; self.analyze_alias(alias)?;
self.aliases.insert(alias); self.aliases.insert(alias.clone());
} }
Item::Assignment(assignment) => { Item::Assignment(assignment) => {
self.analyze_assignment(&assignment)?; self.analyze_assignment(assignment)?;
self.assignments.insert(assignment); self.assignments.insert(assignment.clone());
} }
Item::Comment(_) => (), Item::Comment(_) => (),
Item::Recipe(recipe) => { Item::Recipe(recipe) => {
if recipe.enabled() { if recipe.enabled() {
Self::analyze_recipe(&recipe)?; Self::analyze_recipe(recipe)?;
recipes.push(recipe); recipes.push(recipe);
} }
} }
Item::Set(set) => { Item::Set(set) => {
self.analyze_set(&set)?; self.analyze_set(set)?;
self.sets.insert(set); self.sets.insert(set.clone());
} }
} }
} }
@ -81,10 +80,12 @@ impl<'src> Analyzer<'src> {
let assignments = self.assignments; let assignments = self.assignments;
let mut recipe_table: Table<'src, UnresolvedRecipe<'src>> = Default::default();
AssignmentResolver::resolve_assignments(&assignments)?; AssignmentResolver::resolve_assignments(&assignments)?;
for recipe in recipes { for recipe in recipes {
if let Some(original) = self.recipes.get(recipe.name.lexeme()) { if let Some(original) = recipe_table.get(recipe.name.lexeme()) {
if !settings.allow_duplicate_recipes { if !settings.allow_duplicate_recipes {
return Err(recipe.name.token().error(DuplicateRecipe { return Err(recipe.name.token().error(DuplicateRecipe {
recipe: original.name(), recipe: original.name(),
@ -92,10 +93,10 @@ impl<'src> Analyzer<'src> {
})); }));
} }
} }
self.recipes.insert(recipe); recipe_table.insert(recipe.clone());
} }
let recipes = RecipeResolver::resolve_recipes(self.recipes, &assignments)?; let recipes = RecipeResolver::resolve_recipes(recipe_table, &assignments)?;
let mut aliases = Table::new(); let mut aliases = Table::new();
while let Some(alias) = self.aliases.pop() { while let Some(alias) = self.aliases.pop() {
@ -103,7 +104,7 @@ impl<'src> Analyzer<'src> {
} }
Ok(Justfile { Ok(Justfile {
warnings: ast.warnings, warnings: ast.warnings.clone(),
first: recipes first: recipes
.values() .values()
.fold(None, |accumulator, next| match accumulator { .fold(None, |accumulator, next| match accumulator {

View File

@ -8,6 +8,6 @@ impl Compiler {
let ast = Parser::parse(&tokens)?; let ast = Parser::parse(&tokens)?;
Analyzer::analyze(ast) Analyzer::analyze(&ast)
} }
} }

View File

@ -181,7 +181,7 @@ impl Subcommand {
let tokens = Lexer::lex(src)?; let tokens = Lexer::lex(src)?;
let ast = Parser::parse(&tokens)?; let ast = Parser::parse(&tokens)?;
let justfile = Analyzer::analyze(ast.clone())?; let justfile = Analyzer::analyze(&ast)?;
if config.verbosity.loud() { if config.verbosity.loud() {
for warning in &justfile.warnings { for warning in &justfile.warnings {

View File

@ -64,7 +64,7 @@ pub(crate) fn analysis_error(
let ast = Parser::parse(&tokens).expect("Parsing failed in analysis test..."); let ast = Parser::parse(&tokens).expect("Parsing failed in analysis test...");
match Analyzer::analyze(ast) { match Analyzer::analyze(&ast) {
Ok(_) => panic!("Analysis unexpectedly succeeded"), Ok(_) => panic!("Analysis unexpectedly succeeded"),
Err(have) => { Err(have) => {
let want = CompileError { let want = CompileError {