From 44ff5623f49dfaad9b455bd2d244b52231c37e51 Mon Sep 17 00:00:00 2001 From: Ori Ziv Date: Wed, 9 Aug 2023 15:36:33 +0300 Subject: [PATCH] Made inline macros pluginable. commit-id:3784e194 --- crates/cairo-lang-compiler/src/db.rs | 23 ++++++++++++++--- crates/cairo-lang-defs/src/db.rs | 6 ++++- crates/cairo-lang-defs/src/plugin.rs | 2 +- crates/cairo-lang-lowering/src/test_utils.rs | 2 ++ .../cairo-lang-semantic/src/expr/compute.rs | 3 +-- .../src/inline_macros/array.rs | 4 +-- .../src/inline_macros/consteval_int.rs | 4 +-- .../src/inline_macros/mod.rs | 25 +++++++++++-------- crates/cairo-lang-semantic/src/lib.rs | 2 +- crates/cairo-lang-semantic/src/test_utils.rs | 2 ++ .../src/test_utils.rs | 2 ++ 11 files changed, 52 insertions(+), 23 deletions(-) diff --git a/crates/cairo-lang-compiler/src/db.rs b/crates/cairo-lang-compiler/src/db.rs index 3eb4a8a5f43..33118e29693 100644 --- a/crates/cairo-lang-compiler/src/db.rs +++ b/crates/cairo-lang-compiler/src/db.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use anyhow::{anyhow, Result}; use cairo_lang_defs::db::{DefsDatabase, DefsGroup}; -use cairo_lang_defs::plugin::MacroPlugin; +use cairo_lang_defs::plugin::{InlineMacroExprPlugin, MacroPlugin}; use cairo_lang_filesystem::cfg::CfgSet; use cairo_lang_filesystem::db::{ init_dev_corelib, init_files_group, AsFilesGroupMut, FilesDatabase, FilesGroup, FilesGroupEx, @@ -15,8 +15,10 @@ use cairo_lang_parser::db::ParserDatabase; use cairo_lang_plugins::get_default_plugins; use cairo_lang_project::ProjectConfig; use cairo_lang_semantic::db::{SemanticDatabase, SemanticGroup}; +use cairo_lang_semantic::inline_macros::get_default_inline_macro_plugins; use cairo_lang_sierra_generator::db::SierraGenDatabase; use cairo_lang_syntax::node::db::{SyntaxDatabase, SyntaxGroup}; +use cairo_lang_utils::ordered_hash_map::OrderedHashMap; use cairo_lang_utils::Upcast; use crate::project::update_crate_roots_from_project_config; @@ -40,10 +42,14 @@ impl salsa::ParallelDatabase for RootDatabase { } } impl RootDatabase { - fn new(plugins: Vec>) -> Self { + fn new( + plugins: Vec>, + inline_macro_plugins: OrderedHashMap>, + ) -> Self { let mut res = Self { storage: Default::default() }; init_files_group(&mut res); res.set_macro_plugins(plugins); + res.set_inline_macro_plugins(inline_macro_plugins.into()); res } @@ -70,6 +76,7 @@ impl Default for RootDatabase { #[derive(Clone, Debug)] pub struct RootDatabaseBuilder { plugins: Vec>, + inline_macro_plugins: OrderedHashMap>, detect_corelib: bool, project_config: Option>, cfg_set: Option, @@ -79,6 +86,7 @@ impl RootDatabaseBuilder { fn new() -> Self { Self { plugins: get_default_plugins(), + inline_macro_plugins: get_default_inline_macro_plugins(), detect_corelib: false, project_config: None, cfg_set: None, @@ -90,6 +98,15 @@ impl RootDatabaseBuilder { self } + pub fn with_inline_macro_plugin( + &mut self, + name: String, + plugin: Arc, + ) -> &mut Self { + self.inline_macro_plugins.insert(name, plugin); + self + } + pub fn clear_plugins(&mut self) -> &mut Self { self.plugins.clear(); self @@ -115,7 +132,7 @@ impl RootDatabaseBuilder { // Errors if something is not OK are very subtle, mostly this results in missing // identifier diagnostics, or panics regarding lack of corelib items. - let mut db = RootDatabase::new(self.plugins.clone()); + let mut db = RootDatabase::new(self.plugins.clone(), self.inline_macro_plugins.clone()); if let Some(cfg_set) = &self.cfg_set { db.use_cfg(cfg_set); diff --git a/crates/cairo-lang-defs/src/db.rs b/crates/cairo-lang-defs/src/db.rs index cf78f383faa..ba81032ba86 100644 --- a/crates/cairo-lang-defs/src/db.rs +++ b/crates/cairo-lang-defs/src/db.rs @@ -14,7 +14,9 @@ use cairo_lang_utils::Upcast; use crate::ids::*; use crate::patcher::Patches; -use crate::plugin::{DynGeneratedFileAuxData, MacroPlugin, PluginDiagnostic}; +use crate::plugin::{ + DynGeneratedFileAuxData, InlineMacroExprPlugin, MacroPlugin, PluginDiagnostic, +}; /// Salsa database interface. /// See [`super::ids`] for further details. @@ -65,6 +67,8 @@ pub trait DefsGroup: // ======== #[salsa::input] fn macro_plugins(&self) -> Vec>; + #[salsa::input] + fn inline_macro_plugins(&self) -> Arc>>; // Module to syntax. /// Gets the main file of the module. diff --git a/crates/cairo-lang-defs/src/plugin.rs b/crates/cairo-lang-defs/src/plugin.rs index 5d852af3be7..da583ca1050 100644 --- a/crates/cairo-lang-defs/src/plugin.rs +++ b/crates/cairo-lang-defs/src/plugin.rs @@ -83,7 +83,7 @@ pub struct InlinePluginResult { pub diagnostics: Vec, } -pub trait InlineMacroPlugin: std::fmt::Debug + Sync + Send { +pub trait InlineMacroExprPlugin: std::fmt::Debug + Sync + Send { /// Generates code for an item. If no code should be generated returns None. /// Otherwise, returns (virtual_module_name, module_content), and a virtual submodule /// with that name and content should be created. diff --git a/crates/cairo-lang-lowering/src/test_utils.rs b/crates/cairo-lang-lowering/src/test_utils.rs index d2a596f4048..a2413dd670e 100644 --- a/crates/cairo-lang-lowering/src/test_utils.rs +++ b/crates/cairo-lang-lowering/src/test_utils.rs @@ -8,6 +8,7 @@ use cairo_lang_filesystem::detect::detect_corelib; use cairo_lang_parser::db::ParserDatabase; use cairo_lang_plugins::get_default_plugins; use cairo_lang_semantic::db::{SemanticDatabase, SemanticGroup}; +use cairo_lang_semantic::inline_macros::get_default_inline_macro_plugins; use cairo_lang_syntax::node::db::{SyntaxDatabase, SyntaxGroup}; use cairo_lang_utils::Upcast; use once_cell::sync::Lazy; @@ -41,6 +42,7 @@ pub static SHARED_DB: Lazy> = Lazy::new(|| { let mut res = LoweringDatabaseForTesting { storage: Default::default() }; init_files_group(&mut res); res.set_macro_plugins(get_default_plugins()); + res.set_inline_macro_plugins(get_default_inline_macro_plugins().into()); let corelib_path = detect_corelib().expect("Corelib not found in default location."); init_dev_corelib(&mut res, corelib_path); Mutex::new(res) diff --git a/crates/cairo-lang-semantic/src/expr/compute.rs b/crates/cairo-lang-semantic/src/expr/compute.rs index 6c42536e63a..33ee5516200 100644 --- a/crates/cairo-lang-semantic/src/expr/compute.rs +++ b/crates/cairo-lang-semantic/src/expr/compute.rs @@ -47,7 +47,6 @@ use crate::diagnostic::SemanticDiagnosticKind::{self, *}; use crate::diagnostic::{ ElementKind, NotFoundItemType, SemanticDiagnostics, UnsupportedOutsideOfFunctionFeatureName, }; -use crate::inline_macros::get_inline_macro_plugin; use crate::items::enm::SemanticEnumEx; use crate::items::imp::{filter_candidate_traits, infer_impl_by_self}; use crate::items::modifiers::compute_mutability; @@ -284,7 +283,7 @@ fn compute_expr_inline_macro_semantic( let syntax_db = ctx.db.upcast(); let macro_name = syntax.path(syntax_db).as_syntax_node().get_text(syntax_db).trim().to_string(); - let Some(macro_plugin) = get_inline_macro_plugin(¯o_name) else { + let Some(macro_plugin) = ctx.db.inline_macro_plugins().get(¯o_name).cloned() else { return Err(ctx .diagnostics .report(syntax, InlineMacroNotFound { macro_name: macro_name.into() })); diff --git a/crates/cairo-lang-semantic/src/inline_macros/array.rs b/crates/cairo-lang-semantic/src/inline_macros/array.rs index 92ad428364d..28e4f893064 100644 --- a/crates/cairo-lang-semantic/src/inline_macros/array.rs +++ b/crates/cairo-lang-semantic/src/inline_macros/array.rs @@ -1,4 +1,4 @@ -use cairo_lang_defs::plugin::{InlineMacroPlugin, InlinePluginResult}; +use cairo_lang_defs::plugin::{InlineMacroExprPlugin, InlinePluginResult}; use cairo_lang_syntax::node::db::SyntaxGroup; use cairo_lang_syntax::node::{ast, TypedSyntaxNode}; @@ -6,7 +6,7 @@ use super::unsupported_bracket_diagnostic; #[derive(Debug)] pub struct ArrayMacro; -impl InlineMacroPlugin for ArrayMacro { +impl InlineMacroExprPlugin for ArrayMacro { fn generate_code( &self, db: &dyn SyntaxGroup, diff --git a/crates/cairo-lang-semantic/src/inline_macros/consteval_int.rs b/crates/cairo-lang-semantic/src/inline_macros/consteval_int.rs index 3fecc7906a4..03011b47795 100644 --- a/crates/cairo-lang-semantic/src/inline_macros/consteval_int.rs +++ b/crates/cairo-lang-semantic/src/inline_macros/consteval_int.rs @@ -1,4 +1,4 @@ -use cairo_lang_defs::plugin::{InlineMacroPlugin, InlinePluginResult, PluginDiagnostic}; +use cairo_lang_defs::plugin::{InlineMacroExprPlugin, InlinePluginResult, PluginDiagnostic}; use cairo_lang_syntax::node::db::SyntaxGroup; use cairo_lang_syntax::node::{ast, TypedSyntaxNode}; use num_bigint::BigInt; @@ -8,7 +8,7 @@ use super::unsupported_bracket_diagnostic; #[derive(Debug)] pub struct ConstevalIntMacro; -impl InlineMacroPlugin for ConstevalIntMacro { +impl InlineMacroExprPlugin for ConstevalIntMacro { fn generate_code( &self, db: &dyn SyntaxGroup, diff --git a/crates/cairo-lang-semantic/src/inline_macros/mod.rs b/crates/cairo-lang-semantic/src/inline_macros/mod.rs index 0f8c3385c03..b78071fe8a9 100644 --- a/crates/cairo-lang-semantic/src/inline_macros/mod.rs +++ b/crates/cairo-lang-semantic/src/inline_macros/mod.rs @@ -1,24 +1,27 @@ -pub mod array; -pub mod consteval_int; +mod array; +mod consteval_int; -use cairo_lang_defs::plugin::{InlineMacroPlugin, InlinePluginResult, PluginDiagnostic}; +use std::sync::Arc; + +use cairo_lang_defs::plugin::{InlineMacroExprPlugin, InlinePluginResult, PluginDiagnostic}; use cairo_lang_syntax::node::ast::{self}; use cairo_lang_syntax::node::db::SyntaxGroup; use cairo_lang_syntax::node::TypedSyntaxNode; +use cairo_lang_utils::ordered_hash_map::OrderedHashMap; use super::inline_macros::array::ArrayMacro; use super::inline_macros::consteval_int::ConstevalIntMacro; -/// Returns the inline macro plugin for the given macro name, or None if no such plugin exists. -pub fn get_inline_macro_plugin(macro_name: &str) -> Option> { - match macro_name { - "array" => Some(Box::new(ArrayMacro)), - "consteval_int" => Some(Box::new(ConstevalIntMacro)), - _ => None, - } +/// Gets the default plugins to load into the Cairo compiler. +pub fn get_default_inline_macro_plugins() -> OrderedHashMap> +{ + let mut res = OrderedHashMap::>::default(); + res.insert("array".to_string(), Arc::new(ArrayMacro)); + res.insert("consteval_int".to_string(), Arc::new(ConstevalIntMacro)); + res } -pub fn unsupported_bracket_diagnostic( +fn unsupported_bracket_diagnostic( db: &dyn SyntaxGroup, macro_ast: &ast::ExprInlineMacro, ) -> InlinePluginResult { diff --git a/crates/cairo-lang-semantic/src/lib.rs b/crates/cairo-lang-semantic/src/lib.rs index 9afefec56f2..177c4734663 100644 --- a/crates/cairo-lang-semantic/src/lib.rs +++ b/crates/cairo-lang-semantic/src/lib.rs @@ -6,7 +6,7 @@ pub mod corelib; pub mod db; pub mod diagnostic; pub mod expr; -mod inline_macros; +pub mod inline_macros; pub mod items; pub mod literals; pub mod lookup_item; diff --git a/crates/cairo-lang-semantic/src/test_utils.rs b/crates/cairo-lang-semantic/src/test_utils.rs index e425458c54d..d4213629fc0 100644 --- a/crates/cairo-lang-semantic/src/test_utils.rs +++ b/crates/cairo-lang-semantic/src/test_utils.rs @@ -19,6 +19,7 @@ use cairo_lang_utils::{extract_matches, OptionFrom, Upcast}; use once_cell::sync::Lazy; use crate::db::{SemanticDatabase, SemanticGroup}; +use crate::inline_macros::get_default_inline_macro_plugins; use crate::items::functions::GenericFunctionId; use crate::{semantic, ConcreteFunctionWithBodyId, SemanticDiagnostic}; @@ -37,6 +38,7 @@ impl SemanticDatabaseForTesting { let mut res = SemanticDatabaseForTesting { storage: Default::default() }; init_files_group(&mut res); res.set_macro_plugins(get_default_plugins()); + res.set_inline_macro_plugins(get_default_inline_macro_plugins().into()); let corelib_path = detect_corelib().expect("Corelib not found in default location."); init_dev_corelib(&mut res, corelib_path); res diff --git a/crates/cairo-lang-sierra-generator/src/test_utils.rs b/crates/cairo-lang-sierra-generator/src/test_utils.rs index 584d6d202d8..f5161ebdea6 100644 --- a/crates/cairo-lang-sierra-generator/src/test_utils.rs +++ b/crates/cairo-lang-sierra-generator/src/test_utils.rs @@ -20,6 +20,7 @@ use cairo_lang_utils::{Upcast, UpcastMut}; use defs::ids::FreeFunctionId; use lowering::ids::ConcreteFunctionWithBodyLongId; use once_cell::sync::Lazy; +use semantic::inline_macros::get_default_inline_macro_plugins; use {cairo_lang_defs as defs, cairo_lang_lowering as lowering, cairo_lang_semantic as semantic}; use crate::db::{SierraGenDatabase, SierraGenGroup}; @@ -59,6 +60,7 @@ impl SierraGenDatabaseForTesting { let mut res = SierraGenDatabaseForTesting { storage: Default::default() }; init_files_group(&mut res); res.set_macro_plugins(get_default_plugins()); + res.set_inline_macro_plugins(get_default_inline_macro_plugins().into()); let corelib_path = detect_corelib().expect("Corelib not found in default location."); init_dev_corelib(&mut res, corelib_path); res