From bfe6caa6f83dc70b480572bd93784f5760526bdb Mon Sep 17 00:00:00 2001 From: kevaundray Date: Tue, 28 Nov 2023 00:59:52 +0000 Subject: [PATCH] chore: Pull out aztec macros to their own crate and create an API for them in the compiler frontend (#3578) --- .../workflows/build-aztec-feature-flag.yml | 2 +- .github/workflows/publish-es-packages.yml | 2 +- Cargo.lock | 9 ++ Cargo.toml | 1 + aztec_macros/Cargo.toml | 14 ++ .../src/lib.rs | 126 +++++++++++------- compiler/noirc_driver/Cargo.toml | 5 + compiler/noirc_driver/src/lib.rs | 8 +- compiler/noirc_frontend/Cargo.toml | 3 - .../src/hir/def_collector/dc_crate.rs | 15 ++- .../src/hir/def_collector/errors.rs | 30 ++--- .../noirc_frontend/src/hir/def_map/mod.rs | 34 +++-- compiler/noirc_frontend/src/hir/mod.rs | 3 - compiler/noirc_frontend/src/lib.rs | 43 ++++++ compiler/noirc_frontend/src/tests.rs | 5 + 15 files changed, 206 insertions(+), 94 deletions(-) create mode 100644 aztec_macros/Cargo.toml rename compiler/noirc_frontend/src/hir/aztec_library.rs => aztec_macros/src/lib.rs (90%) diff --git a/.github/workflows/build-aztec-feature-flag.yml b/.github/workflows/build-aztec-feature-flag.yml index 888a88a7f88..bacf74ba7b1 100644 --- a/.github/workflows/build-aztec-feature-flag.yml +++ b/.github/workflows/build-aztec-feature-flag.yml @@ -42,4 +42,4 @@ jobs: save-if: ${{ github.event_name != 'merge_group' }} - name: Build with feature flag - run: cargo build --features="noirc_frontend/aztec" + run: cargo build --features="noirc_driver/aztec" diff --git a/.github/workflows/publish-es-packages.yml b/.github/workflows/publish-es-packages.yml index 2e88ee2b77f..f421672c799 100644 --- a/.github/workflows/publish-es-packages.yml +++ b/.github/workflows/publish-es-packages.yml @@ -33,7 +33,7 @@ jobs: - name: Enable aztec features if: ${{ inputs.npm-tag == 'aztec' }} run: | - echo $'\n'"default = [\"aztec\"]"$'\n' >> compiler/noirc_frontend/Cargo.toml + echo $'\n'"default = [\"aztec\"]"$'\n' >> compiler/noirc_driver/Cargo.toml - name: Build wasm package run: | diff --git a/Cargo.lock b/Cargo.lock index 5e138bf4508..1672ef7dfd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -413,6 +413,14 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "aztec_macros" +version = "0.19.3" +dependencies = [ + "iter-extended", + "noirc_frontend", +] + [[package]] name = "backend-interface" version = "0.11.0" @@ -2608,6 +2616,7 @@ name = "noirc_driver" version = "0.19.4" dependencies = [ "acvm", + "aztec_macros", "build-data", "clap", "fm", diff --git a/Cargo.toml b/Cargo.toml index 3ad0d595023..1a37a4f53e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ + "aztec_macros", "compiler/noirc_evaluator", "compiler/noirc_frontend", "compiler/noirc_errors", diff --git a/aztec_macros/Cargo.toml b/aztec_macros/Cargo.toml new file mode 100644 index 00000000000..04f74d3b022 --- /dev/null +++ b/aztec_macros/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "aztec_macros" +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +repository.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +noirc_frontend.workspace = true +iter-extended.workspace = true diff --git a/compiler/noirc_frontend/src/hir/aztec_library.rs b/aztec_macros/src/lib.rs similarity index 90% rename from compiler/noirc_frontend/src/hir/aztec_library.rs rename to aztec_macros/src/lib.rs index 3b4703dc60f..f55feb9801e 100644 --- a/compiler/noirc_frontend/src/hir/aztec_library.rs +++ b/aztec_macros/src/lib.rs @@ -1,28 +1,59 @@ -use acvm::FieldElement; use iter_extended::vecmap; -use noirc_errors::Span; - -use crate::graph::CrateId; -use crate::hir::def_collector::errors::DefCollectorErrorKind; -use crate::hir_def::expr::{HirExpression, HirLiteral}; -use crate::hir_def::stmt::HirStatement; -use crate::node_interner::{NodeInterner, StructId}; -use crate::parser::SortedModule; -use crate::token::SecondaryAttribute; -use crate::{ - hir::Context, BlockExpression, CallExpression, CastExpression, Distinctness, Expression, - ExpressionKind, FunctionReturnType, Ident, IndexExpression, LetStatement, Literal, - MemberAccessExpression, MethodCallExpression, NoirFunction, Path, PathKind, Pattern, Statement, - UnresolvedType, UnresolvedTypeData, Visibility, -}; -use crate::{ - ForLoopStatement, ForRange, FunctionDefinition, FunctionVisibility, ImportStatement, - NoirStruct, Param, PrefixExpression, Signedness, StatementKind, StructType, Type, TypeImpl, - UnaryOp, + +use noirc_frontend::macros_api::FieldElement; +use noirc_frontend::macros_api::{ + BlockExpression, CallExpression, CastExpression, Distinctness, Expression, ExpressionKind, + ForLoopStatement, ForRange, FunctionDefinition, FunctionReturnType, FunctionVisibility, + HirContext, HirExpression, HirLiteral, HirStatement, Ident, ImportStatement, IndexExpression, + LetStatement, Literal, MemberAccessExpression, MethodCallExpression, NoirFunction, NoirStruct, + Param, Path, PathKind, Pattern, PrefixExpression, SecondaryAttribute, Signedness, Span, + Statement, StatementKind, StructType, Type, TypeImpl, UnaryOp, UnresolvedType, + UnresolvedTypeData, Visibility, }; -use fm::FileId; +use noirc_frontend::macros_api::{CrateId, FileId}; +use noirc_frontend::macros_api::{MacroError, MacroProcessor}; +use noirc_frontend::macros_api::{ModuleDefId, NodeInterner, SortedModule, StructId}; + +pub struct AztecMacro; + +impl MacroProcessor for AztecMacro { + fn process_untyped_ast( + &self, + ast: SortedModule, + crate_id: &CrateId, + context: &HirContext, + ) -> Result { + transform(ast, crate_id, context) + } + + fn process_typed_ast(&self, crate_id: &CrateId, context: &mut HirContext) { + transform_hir(crate_id, context) + } +} + +#[derive(Debug, Clone)] +pub enum AztecMacroError { + // TODO(benesjan): https://github.com/AztecProtocol/aztec-packages/issues/2905 + AztecNotFound, + AztecComputeNoteHashAndNullifierNotFound { span: Span }, +} -use super::def_map::ModuleDefId; +impl From for MacroError { + fn from(err: AztecMacroError) -> Self { + match err { + AztecMacroError::AztecNotFound {} => MacroError { + primary_message: "Aztec dependency not found. Please add aztec as a dependency in your Cargo.toml".to_owned(), + secondary_message: None, + span: None, + }, + AztecMacroError::AztecComputeNoteHashAndNullifierNotFound { span } => MacroError { + primary_message: "compute_note_hash_and_nullifier function not found. Define it in your contract.".to_owned(), + secondary_message: None, + span: Some(span), + }, + } + } +} // // Helper macros for creating noir ast nodes @@ -162,11 +193,11 @@ fn import(path: Path) -> ImportStatement { /// Traverses every function in the ast, calling `transform_function` which /// determines if further processing is required -pub(crate) fn transform( +fn transform( mut ast: SortedModule, crate_id: &CrateId, - context: &Context, -) -> Result { + context: &HirContext, +) -> Result { // Usage -> mut ast -> aztec_library::transform(&mut ast) // Covers all functions in the ast @@ -184,7 +215,7 @@ pub(crate) fn transform( // /// Completes the Hir with data gathered from type resolution -pub(crate) fn transform_hir(crate_id: &CrateId, context: &mut Context) { +fn transform_hir(crate_id: &CrateId, context: &mut HirContext) { transform_events(crate_id, context); } @@ -206,14 +237,14 @@ fn include_relevant_imports(ast: &mut SortedModule) { /// Creates an error alerting the user that they have not downloaded the Aztec-noir library fn check_for_aztec_dependency( crate_id: &CrateId, - context: &Context, -) -> Result<(), (DefCollectorErrorKind, FileId)> { + context: &HirContext, +) -> Result<(), (MacroError, FileId)> { let crate_graph = &context.crate_graph[crate_id]; let has_aztec_dependency = crate_graph.dependencies.iter().any(|dep| dep.as_name() == "aztec"); if has_aztec_dependency { Ok(()) } else { - Err((DefCollectorErrorKind::AztecNotFound {}, crate_graph.root_file_id)) + Err((AztecMacroError::AztecNotFound.into(), crate_graph.root_file_id)) } } @@ -234,10 +265,7 @@ fn check_for_compute_note_hash_and_nullifier_definition(module: &SortedModule) - // Array(Option, Box) contains only fields && match &func.def.parameters[3].typ.typ { UnresolvedTypeData::Array(_, inner_type) => { - match inner_type.typ { - UnresolvedTypeData::FieldElement => true, - _ => false, - } + matches!(inner_type.typ, UnresolvedTypeData::FieldElement) }, _ => false, } @@ -247,10 +275,7 @@ fn check_for_compute_note_hash_and_nullifier_definition(module: &SortedModule) - FunctionReturnType::Ty(unresolved_type) => { match &unresolved_type.typ { UnresolvedTypeData::Array(_, inner_type) => { - match inner_type.typ { - UnresolvedTypeData::FieldElement => true, - _ => false, - } + matches!(inner_type.typ, UnresolvedTypeData::FieldElement) }, _ => false, } @@ -274,19 +299,18 @@ fn is_custom_attribute(attr: &SecondaryAttribute, attribute_name: &str) -> bool fn transform_module( module: &mut SortedModule, crate_id: &CrateId, - context: &Context, -) -> Result { + context: &HirContext, +) -> Result { let mut has_transformed_module = false; // Check for a user defined storage struct - let storage_defined = check_for_storage_definition(&module); + let storage_defined = check_for_storage_definition(module); - if storage_defined && !check_for_compute_note_hash_and_nullifier_definition(&module) { + if storage_defined && !check_for_compute_note_hash_and_nullifier_definition(module) { let crate_graph = &context.crate_graph[crate_id]; return Err(( - DefCollectorErrorKind::AztecComputeNoteHashAndNullifierNotFound { - span: Span::default(), // Add a default span so we know which contract file the error originates from - }, + AztecMacroError::AztecComputeNoteHashAndNullifierNotFound { span: Span::default() } + .into(), crate_graph.root_file_id, )); } @@ -374,7 +398,7 @@ fn transform_unconstrained(func: &mut NoirFunction) { func.def.body.0.insert(0, abstract_storage("Unconstrained", true)); } -fn collect_crate_structs(crate_id: &CrateId, context: &Context) -> Vec { +fn collect_crate_structs(crate_id: &CrateId, context: &HirContext) -> Vec { context .def_map(crate_id) .expect("ICE: Missing crate in def_map") @@ -444,7 +468,7 @@ fn transform_event(struct_id: StructId, interner: &mut NodeInterner) { } } -fn transform_events(crate_id: &CrateId, context: &mut Context) { +fn transform_events(crate_id: &CrateId, context: &mut HirContext) { for struct_id in collect_crate_structs(crate_id, context) { let attributes = context.def_interner.struct_attributes(&struct_id); if attributes.iter().any(|attr| matches!(attr, SecondaryAttribute::Event)) { @@ -514,7 +538,7 @@ fn generate_selector_impl(structure: &NoirStruct) -> TypeImpl { /// fn foo() { /// // ... /// } -pub(crate) fn create_inputs(ty: &str) -> Param { +fn create_inputs(ty: &str) -> Param { let context_ident = ident("inputs"); let context_pattern = Pattern::Identifier(context_ident); let type_path = chained_path!("aztec", "abi", ty); @@ -574,7 +598,7 @@ fn create_context(ty: &str, params: &[Param]) -> Vec { // `hasher.add_multiple({ident}.serialize())` UnresolvedTypeData::Named(..) => add_struct_to_hasher(identifier), UnresolvedTypeData::Array(_, arr_type) => { - add_array_to_hasher(identifier, &arr_type) + add_array_to_hasher(identifier, arr_type) } // `hasher.add({ident})` UnresolvedTypeData::FieldElement => add_field_to_hasher(identifier), @@ -819,7 +843,7 @@ fn make_castable_return_type(expression: Expression) -> Statement { /// fn foo() { /// // ... /// } -pub(crate) fn create_return_type(ty: &str) -> FunctionReturnType { +fn create_return_type(ty: &str) -> FunctionReturnType { let return_path = chained_path!("aztec", "abi", ty); let ty = make_type(UnresolvedTypeData::Named(return_path, vec![])); @@ -844,7 +868,7 @@ pub(crate) fn create_return_type(ty: &str) -> FunctionReturnType { /// fn foo() { /// // ... /// } -pub(crate) fn create_context_finish() -> Statement { +fn create_context_finish() -> Statement { let method_call = method_call( variable("context"), // variable "finish", // method name @@ -875,7 +899,7 @@ fn add_struct_to_hasher(identifier: &Ident) -> Statement { fn create_loop_over(var: Expression, loop_body: Vec) -> Statement { // If this is an array of primitive types (integers / fields) we can add them each to the hasher // casted to a field - let span = var.span.clone(); + let span = var.span; // `array.len()` let end_range_expression = method_call( diff --git a/compiler/noirc_driver/Cargo.toml b/compiler/noirc_driver/Cargo.toml index 09044b39323..c717efed6f5 100644 --- a/compiler/noirc_driver/Cargo.toml +++ b/compiler/noirc_driver/Cargo.toml @@ -21,3 +21,8 @@ iter-extended.workspace = true fm.workspace = true serde.workspace = true fxhash.workspace = true + +aztec_macros ={path = "../../aztec_macros", optional = true} + +[features] +aztec = ["aztec_macros"] \ No newline at end of file diff --git a/compiler/noirc_driver/src/lib.rs b/compiler/noirc_driver/src/lib.rs index 456c2c49609..93ed26fb91a 100644 --- a/compiler/noirc_driver/src/lib.rs +++ b/compiler/noirc_driver/src/lib.rs @@ -13,6 +13,7 @@ use noirc_evaluator::errors::RuntimeError; use noirc_frontend::graph::{CrateId, CrateName}; use noirc_frontend::hir::def_map::{Contract, CrateDefMap}; use noirc_frontend::hir::Context; +use noirc_frontend::macros_api::MacroProcessor; use noirc_frontend::monomorphization::monomorphize; use noirc_frontend::node_interner::FuncId; use serde::{Deserialize, Serialize}; @@ -121,8 +122,13 @@ pub fn check_crate( crate_id: CrateId, deny_warnings: bool, ) -> CompilationResult<()> { + #[cfg(not(feature = "aztec"))] + let macros: Vec<&dyn MacroProcessor> = Vec::new(); + #[cfg(feature = "aztec")] + let macros = vec![&aztec_macros::AztecMacro as &dyn MacroProcessor]; + let mut errors = vec![]; - let diagnostics = CrateDefMap::collect_defs(crate_id, context); + let diagnostics = CrateDefMap::collect_defs(crate_id, context, macros); errors.extend(diagnostics.into_iter().map(|(error, file_id)| { let diagnostic: CustomDiagnostic = error.into(); diagnostic.in_file(file_id) diff --git a/compiler/noirc_frontend/Cargo.toml b/compiler/noirc_frontend/Cargo.toml index 246d6617c94..6f3c35a814a 100644 --- a/compiler/noirc_frontend/Cargo.toml +++ b/compiler/noirc_frontend/Cargo.toml @@ -26,6 +26,3 @@ regex = "1.9.1" [dev-dependencies] strum = "0.24" strum_macros = "0.24" - -[features] -aztec = [] diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index f798dcb64e7..047c53e3206 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -13,6 +13,7 @@ use crate::hir::resolution::{ use crate::hir::type_check::{type_check_func, TypeCheckError, TypeChecker}; use crate::hir::Context; use crate::hir_def::traits::{Trait, TraitConstant, TraitFunction, TraitImpl, TraitType}; +use crate::macros_api::MacroProcessor; use crate::node_interner::{ FuncId, NodeInterner, StmtId, StructId, TraitId, TraitImplId, TypeAliasId, }; @@ -199,6 +200,7 @@ impl DefCollector { context: &mut Context, ast: SortedModule, root_file_id: FileId, + macro_processors: Vec<&dyn MacroProcessor>, ) -> Vec<(CompilationError, FileId)> { let mut errors: Vec<(CompilationError, FileId)> = vec![]; let crate_id = def_map.krate; @@ -211,7 +213,11 @@ impl DefCollector { let crate_graph = &context.crate_graph[crate_id]; for dep in crate_graph.dependencies.clone() { - errors.extend(CrateDefMap::collect_defs(dep.crate_id, context)); + errors.extend(CrateDefMap::collect_defs( + dep.crate_id, + context, + macro_processors.clone(), + )); let dep_def_root = context.def_map(&dep.crate_id).expect("ice: def map was just created").root; @@ -341,10 +347,9 @@ impl DefCollector { errors.extend(resolved_globals.errors); - // We run hir transformations before type checks - #[cfg(feature = "aztec")] - crate::hir::aztec_library::transform_hir(&crate_id, context); - + for macro_processor in macro_processors { + macro_processor.process_typed_ast(&crate_id, context); + } errors.extend(type_check_globals(&mut context.def_interner, resolved_globals.globals)); // Type check all of the functions in the crate diff --git a/compiler/noirc_frontend/src/hir/def_collector/errors.rs b/compiler/noirc_frontend/src/hir/def_collector/errors.rs index edb39fe68d7..2b91c4b36c5 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/errors.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/errors.rs @@ -73,15 +73,16 @@ pub enum DefCollectorErrorKind { "Either the type or the trait must be from the same crate as the trait implementation" )] TraitImplOrphaned { span: Span }, + #[error("macro error : {0:?}")] + MacroError(MacroError), +} - // Aztec feature flag errors - // TODO(benesjan): https://github.com/AztecProtocol/aztec-packages/issues/2905 - #[cfg(feature = "aztec")] - #[error("Aztec dependency not found. Please add aztec as a dependency in your Cargo.toml")] - AztecNotFound {}, - #[cfg(feature = "aztec")] - #[error("compute_note_hash_and_nullifier function not found. Define it in your contract.")] - AztecComputeNoteHashAndNullifierNotFound { span: Span }, +/// An error struct that macro processors can return. +#[derive(Debug, Clone)] +pub struct MacroError { + pub primary_message: String, + pub secondary_message: Option, + pub span: Option, } impl DefCollectorErrorKind { @@ -245,16 +246,9 @@ impl From for Diagnostic { "Either the type or the trait must be from the same crate as the trait implementation".into(), span, ), - #[cfg(feature = "aztec")] - DefCollectorErrorKind::AztecNotFound {} => Diagnostic::from_message( - "Aztec dependency not found. Please add aztec as a dependency in your Cargo.toml", - ), - #[cfg(feature = "aztec")] - DefCollectorErrorKind::AztecComputeNoteHashAndNullifierNotFound {span} => Diagnostic::simple_error( - "compute_note_hash_and_nullifier function not found. Define it in your contract.".into(), - "".into(), - span - ), + DefCollectorErrorKind::MacroError(macro_error) => { + Diagnostic::simple_error(macro_error.primary_message, macro_error.secondary_message.unwrap_or_default(), macro_error.span.unwrap_or_default()) + }, } } } diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs index 345e5447bf5..5f38c80a5fe 100644 --- a/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -1,6 +1,7 @@ use crate::graph::CrateId; use crate::hir::def_collector::dc_crate::{CompilationError, DefCollector}; use crate::hir::Context; +use crate::macros_api::MacroProcessor; use crate::node_interner::{FuncId, NodeInterner, StructId}; use crate::parser::{parse_program, ParsedModule, ParserError}; use crate::token::{FunctionAttribute, SecondaryAttribute, TestScope}; @@ -17,6 +18,8 @@ pub use module_data::*; mod namespace; pub use namespace::*; +use super::def_collector::errors::DefCollectorErrorKind; + /// The name that is used for a non-contract program's entry-point function. pub const MAIN_FUNCTION: &str = "main"; @@ -69,6 +72,7 @@ impl CrateDefMap { pub fn collect_defs( crate_id: CrateId, context: &mut Context, + macro_processors: Vec<&dyn MacroProcessor>, ) -> Vec<(CompilationError, FileId)> { // Check if this Crate has already been compiled // XXX: There is probably a better alternative for this. @@ -83,16 +87,18 @@ impl CrateDefMap { // First parse the root file. let root_file_id = context.crate_graph[crate_id].root_file_id; let (ast, parsing_errors) = parse_file(&context.file_manager, root_file_id); - let ast = ast.into_sorted(); - - #[cfg(feature = "aztec")] - let ast = match super::aztec_library::transform(ast, &crate_id, context) { - Ok(ast) => ast, - Err((error, file_id)) => { - errors.push((error.into(), file_id)); - return errors; - } - }; + let mut ast = ast.into_sorted(); + + for macro_processor in ¯o_processors { + ast = match macro_processor.process_untyped_ast(ast, &crate_id, context) { + Ok(ast) => ast, + Err((error, file_id)) => { + let def_error = DefCollectorErrorKind::MacroError(error); + errors.push((def_error.into(), file_id)); + return errors; + } + }; + } // Allocate a default Module for the root, giving it a ModuleId let mut modules: Arena = Arena::default(); @@ -107,7 +113,13 @@ impl CrateDefMap { }; // Now we want to populate the CrateDefMap using the DefCollector - errors.extend(DefCollector::collect(def_map, context, ast, root_file_id)); + errors.extend(DefCollector::collect( + def_map, + context, + ast, + root_file_id, + macro_processors.clone(), + )); errors.extend( parsing_errors.iter().map(|e| (e.clone().into(), root_file_id)).collect::>(), diff --git a/compiler/noirc_frontend/src/hir/mod.rs b/compiler/noirc_frontend/src/hir/mod.rs index 789a59e276f..154b695d552 100644 --- a/compiler/noirc_frontend/src/hir/mod.rs +++ b/compiler/noirc_frontend/src/hir/mod.rs @@ -4,9 +4,6 @@ pub mod resolution; pub mod scope; pub mod type_check; -#[cfg(feature = "aztec")] -pub(crate) mod aztec_library; - use crate::graph::{CrateGraph, CrateId}; use crate::hir_def::function::FuncMeta; use crate::node_interner::{FuncId, NodeInterner, StructId}; diff --git a/compiler/noirc_frontend/src/lib.rs b/compiler/noirc_frontend/src/lib.rs index 74057240de1..77107d3e7db 100644 --- a/compiler/noirc_frontend/src/lib.rs +++ b/compiler/noirc_frontend/src/lib.rs @@ -34,3 +34,46 @@ pub use hir_def::types::*; // Unit tests that involve all modules pub mod tests; + +// API for experimental macros feature +pub mod macros_api { + + pub use acvm::FieldElement; + pub use fm::FileId; + pub use noirc_errors::Span; + + pub use crate::graph::CrateId; + pub use crate::hir::def_collector::errors::MacroError; + pub use crate::hir_def::expr::{HirExpression, HirLiteral}; + pub use crate::hir_def::stmt::HirStatement; + pub use crate::node_interner::{NodeInterner, StructId}; + pub use crate::parser::SortedModule; + pub use crate::token::SecondaryAttribute; + + pub use crate::hir::def_map::ModuleDefId; + pub use crate::{ + hir::Context as HirContext, BlockExpression, CallExpression, CastExpression, Distinctness, + Expression, ExpressionKind, FunctionReturnType, Ident, IndexExpression, LetStatement, + Literal, MemberAccessExpression, MethodCallExpression, NoirFunction, Path, PathKind, + Pattern, Statement, UnresolvedType, UnresolvedTypeData, Visibility, + }; + pub use crate::{ + ForLoopStatement, ForRange, FunctionDefinition, FunctionVisibility, ImportStatement, + NoirStruct, Param, PrefixExpression, Signedness, StatementKind, StructType, Type, TypeImpl, + UnaryOp, + }; + + /// Methods to process the AST before and after type checking + pub trait MacroProcessor { + /// Function to manipulate the AST before type checking has been completed. + fn process_untyped_ast( + &self, + ast: SortedModule, + crate_id: &CrateId, + context: &HirContext, + ) -> Result; + /// Function to manipulate the AST after type checking has been completed. + /// The AST after type checking has been done is called the HIR. + fn process_typed_ast(&self, crate_id: &CrateId, context: &mut HirContext); + } +} diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index 6a1cf80accd..13ce71c4616 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -18,6 +18,7 @@ mod test { use crate::hir::resolution::import::PathResolutionError; use crate::hir::type_check::TypeCheckError; use crate::hir::Context; + use crate::macros_api::MacroProcessor; use crate::node_interner::{NodeInterner, StmtId}; use crate::graph::CrateGraph; @@ -79,12 +80,16 @@ mod test { krate: root_crate_id, extern_prelude: BTreeMap::new(), }; + + let empty_macro_processors: Vec<&dyn MacroProcessor> = Vec::new(); + // Now we want to populate the CrateDefMap using the DefCollector errors.extend(DefCollector::collect( def_map, &mut context, program.clone().into_sorted(), root_file_id, + empty_macro_processors, )); } (program, context, errors)