Borrow Ast in Analyser (#1527)
This commit is contained in:
parent
70dcc7f528
commit
6ab6588549
@ -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 {
|
||||||
|
@ -8,6 +8,6 @@ impl Compiler {
|
|||||||
|
|
||||||
let ast = Parser::parse(&tokens)?;
|
let ast = Parser::parse(&tokens)?;
|
||||||
|
|
||||||
Analyzer::analyze(ast)
|
Analyzer::analyze(&ast)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user