diff --git a/crates/bin/get-lowering/src/main.rs b/crates/bin/get-lowering/src/main.rs index 4c923569063..db4b611c476 100644 --- a/crates/bin/get-lowering/src/main.rs +++ b/crates/bin/get-lowering/src/main.rs @@ -37,7 +37,7 @@ use itertools::Itertools; fn test_lowering_consistency() { let db_val = RootDatabase::builder() .detect_corelib() - .with_plugin_suite(starknet_plugin_suite()) + .with_default_plugin_suite(starknet_plugin_suite()) .build() .unwrap(); @@ -225,7 +225,7 @@ fn main() -> anyhow::Result<()> { let mut db_val = RootDatabase::builder() .detect_corelib() - .with_plugin_suite(starknet_plugin_suite()) + .with_default_plugin_suite(starknet_plugin_suite()) .build()?; let main_crate_ids = setup_project(&mut db_val, Path::new(&args.path))?; diff --git a/crates/cairo-lang-compiler/src/db.rs b/crates/cairo-lang-compiler/src/db.rs index b276125ae99..ac3ba261dc1 100644 --- a/crates/cairo-lang-compiler/src/db.rs +++ b/crates/cairo-lang-compiler/src/db.rs @@ -2,7 +2,6 @@ use std::sync::Arc; use anyhow::{Result, anyhow, bail}; use cairo_lang_defs::db::{DefsDatabase, DefsGroup, try_ext_as_virtual_impl}; -use cairo_lang_defs::plugin::{InlineMacroExprPlugin, MacroPlugin}; use cairo_lang_filesystem::cfg::CfgSet; use cairo_lang_filesystem::db::{ AsFilesGroupMut, CORELIB_VERSION, ExternalFiles, FilesDatabase, FilesGroup, FilesGroupEx, @@ -14,13 +13,12 @@ use cairo_lang_filesystem::ids::{CrateId, FlagId, VirtualFile}; use cairo_lang_lowering::db::{LoweringDatabase, LoweringGroup, init_lowering_group}; use cairo_lang_parser::db::{ParserDatabase, ParserGroup}; use cairo_lang_project::ProjectConfig; -use cairo_lang_semantic::db::{SemanticDatabase, SemanticGroup}; +use cairo_lang_semantic::db::{PluginSuiteInput, SemanticDatabase, SemanticGroup}; use cairo_lang_semantic::inline_macros::get_default_plugin_suite; -use cairo_lang_semantic::plugin::{AnalyzerPlugin, PluginSuite}; +use cairo_lang_semantic::plugin::PluginSuite; use cairo_lang_sierra_generator::db::SierraGenDatabase; use cairo_lang_syntax::node::db::{SyntaxDatabase, SyntaxGroup}; use cairo_lang_utils::Upcast; -use cairo_lang_utils::ordered_hash_map::OrderedHashMap; use crate::InliningStrategy; use crate::project::update_crate_roots_from_project_config; @@ -49,18 +47,11 @@ impl salsa::ParallelDatabase for RootDatabase { } } impl RootDatabase { - fn new( - plugins: Vec>, - inline_macro_plugins: OrderedHashMap>, - analyzer_plugins: Vec>, - inlining_strategy: InliningStrategy, - ) -> Self { + fn new(default_plugin_suite: PluginSuite, inlining_strategy: InliningStrategy) -> Self { let mut res = Self { storage: Default::default() }; init_files_group(&mut res); init_lowering_group(&mut res, inlining_strategy); - res.set_macro_plugins(plugins); - res.set_inline_macro_plugins(inline_macro_plugins.into()); - res.set_analyzer_plugins(analyzer_plugins); + res.set_default_plugins_from_suite(default_plugin_suite); res } @@ -86,7 +77,7 @@ impl Default for RootDatabase { #[derive(Clone, Debug)] pub struct RootDatabaseBuilder { - plugin_suite: PluginSuite, + default_plugin_suite: PluginSuite, detect_corelib: bool, auto_withdraw_gas: bool, add_redeposit_gas: bool, @@ -98,7 +89,7 @@ pub struct RootDatabaseBuilder { impl RootDatabaseBuilder { fn new() -> Self { Self { - plugin_suite: get_default_plugin_suite(), + default_plugin_suite: get_default_plugin_suite(), detect_corelib: false, auto_withdraw_gas: true, add_redeposit_gas: false, @@ -108,13 +99,13 @@ impl RootDatabaseBuilder { } } - pub fn with_plugin_suite(&mut self, suite: PluginSuite) -> &mut Self { - self.plugin_suite.add(suite); + pub fn with_default_plugin_suite(&mut self, suite: PluginSuite) -> &mut Self { + self.default_plugin_suite.add(suite); self } pub fn clear_plugins(&mut self) -> &mut Self { - self.plugin_suite = get_default_plugin_suite(); + self.default_plugin_suite = get_default_plugin_suite(); self } @@ -153,12 +144,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.plugin_suite.plugins.clone(), - self.plugin_suite.inline_macro_plugins.clone(), - self.plugin_suite.analyzer_plugins.clone(), - self.inlining_strategy, - ); + let mut db = RootDatabase::new(self.default_plugin_suite.clone(), self.inlining_strategy); if let Some(cfg_set) = &self.cfg_set { db.use_cfg(cfg_set); diff --git a/crates/cairo-lang-compiler/src/test.rs b/crates/cairo-lang-compiler/src/test.rs index 2682ec40498..869dbf5a9c9 100644 --- a/crates/cairo-lang-compiler/src/test.rs +++ b/crates/cairo-lang-compiler/src/test.rs @@ -43,7 +43,8 @@ fn can_collect_executables() { "#}; let mut suite = PluginSuite::default(); suite.add_plugin::(); - let mut db = RootDatabase::builder().detect_corelib().with_plugin_suite(suite).build().unwrap(); + let mut db = + RootDatabase::builder().detect_corelib().with_default_plugin_suite(suite).build().unwrap(); let crate_id = setup_test_crate(&db, content); let config = CompilerConfig { replace_ids: true, ..CompilerConfig::default() }; let artefact = compile_prepared_db_program_artifact(&mut db, vec![crate_id], config).unwrap(); diff --git a/crates/cairo-lang-executable/src/compile.rs b/crates/cairo-lang-executable/src/compile.rs index 79d6ba6a31e..2367ff1c604 100644 --- a/crates/cairo-lang-executable/src/compile.rs +++ b/crates/cairo-lang-executable/src/compile.rs @@ -58,7 +58,7 @@ pub fn compile_executable( let mut db = RootDatabase::builder() .skip_auto_withdraw_gas() .detect_corelib() - .with_plugin_suite(executable_plugin_suite()) + .with_default_plugin_suite(executable_plugin_suite()) .build()?; let main_crate_ids = setup_project(&mut db, Path::new(&path))?; diff --git a/crates/cairo-lang-executable/src/test.rs b/crates/cairo-lang-executable/src/test.rs index d280a8184d7..095958ce5eb 100644 --- a/crates/cairo-lang-executable/src/test.rs +++ b/crates/cairo-lang-executable/src/test.rs @@ -18,7 +18,7 @@ pub static SHARED_DB: LazyLock> = LazyLock::new(|| { RootDatabase::builder() .skip_auto_withdraw_gas() .detect_corelib() - .with_plugin_suite(executable_plugin_suite()) + .with_default_plugin_suite(executable_plugin_suite()) .build() .unwrap(), ) diff --git a/crates/cairo-lang-runner/src/profiling_test.rs b/crates/cairo-lang-runner/src/profiling_test.rs index 80b3056423b..763ae836e33 100644 --- a/crates/cairo-lang-runner/src/profiling_test.rs +++ b/crates/cairo-lang-runner/src/profiling_test.rs @@ -42,7 +42,7 @@ pub fn test_profiling( } let db = RootDatabase::builder() - .with_plugin_suite(starknet_plugin_suite()) + .with_default_plugin_suite(starknet_plugin_suite()) .detect_corelib() .build() .unwrap(); diff --git a/crates/cairo-lang-semantic/src/db.rs b/crates/cairo-lang-semantic/src/db.rs index 34625805aa9..ef6526e5e66 100644 --- a/crates/cairo-lang-semantic/src/db.rs +++ b/crates/cairo-lang-semantic/src/db.rs @@ -5,10 +5,10 @@ use cairo_lang_defs::diagnostic_utils::StableLocation; use cairo_lang_defs::ids::{ ConstantId, EnumId, ExternFunctionId, ExternTypeId, FreeFunctionId, FunctionTitleId, FunctionWithBodyId, GenericParamId, GenericTypeId, GlobalUseId, ImplAliasId, ImplConstantDefId, - ImplDefId, ImplFunctionId, ImplImplDefId, ImplItemId, ImplTypeDefId, LanguageElementId, - LookupItemId, ModuleFileId, ModuleId, ModuleItemId, ModuleTypeAliasId, StructId, - TraitConstantId, TraitFunctionId, TraitId, TraitImplId, TraitItemId, TraitTypeId, UseId, - VariantId, + ImplDefId, ImplFunctionId, ImplImplDefId, ImplItemId, ImplTypeDefId, + InlineMacroExprPluginLongId, LanguageElementId, LookupItemId, MacroPluginLongId, ModuleFileId, + ModuleId, ModuleItemId, ModuleTypeAliasId, StructId, TraitConstantId, TraitFunctionId, TraitId, + TraitImplId, TraitItemId, TraitTypeId, UseId, VariantId, }; use cairo_lang_diagnostics::{Diagnostics, DiagnosticsBuilder, Maybe}; use cairo_lang_filesystem::db::{AsFilesGroupMut, FilesGroup}; @@ -38,7 +38,7 @@ use crate::items::trt::{ }; use crate::items::us::{ImportedModules, SemanticUseEx}; use crate::items::visibility::Visibility; -use crate::plugin::AnalyzerPlugin; +use crate::plugin::{AnalyzerPlugin, InternedPluginSuite, PluginSuite}; use crate::resolve::{ResolvedConcreteItem, ResolvedGenericItem, ResolverData}; use crate::substitution::GenericSubstitution; use crate::types::{ImplTypeId, TypeSizeInformation}; @@ -1873,3 +1873,69 @@ pub fn get_resolver_data_options( .flatten() .collect() } + +/// An extension trait for [`SemanticGroup`] to manage plugin setters. +pub trait PluginSuiteInput: SemanticGroup { + /// Interns each plugin from the [`PluginSuite`] into the database. + fn intern_plugin_suite(&mut self, suite: PluginSuite) -> InternedPluginSuite { + let PluginSuite { plugins, inline_macro_plugins, analyzer_plugins } = suite; + + // NOTE: kept for compatibility and testing, removed later in the stack. + self.set_macro_plugins(plugins.clone()); + self.set_inline_macro_plugins(Arc::new(inline_macro_plugins.clone())); + self.set_analyzer_plugins(analyzer_plugins.clone()); + + let macro_plugins = plugins + .into_iter() + .map(|plugin| self.intern_macro_plugin(MacroPluginLongId(plugin))) + .collect::>(); + + let inline_macro_plugins = Arc::new( + inline_macro_plugins + .into_iter() + .map(|(name, plugin)| { + (name, self.intern_inline_macro_plugin(InlineMacroExprPluginLongId(plugin))) + }) + .collect::>(), + ); + + let analyzer_plugins = analyzer_plugins + .into_iter() + .map(|plugin| self.intern_analyzer_plugin(AnalyzerPluginLongId(plugin))) + .collect::>(); + + InternedPluginSuite { macro_plugins, inline_macro_plugins, analyzer_plugins } + } + + /// Sets macro, inline macro and analyzer plugins specified in the [`PluginSuite`] as default + /// for all crates. + /// + /// *Note*: Sets the following Salsa inputs: [`DefsGroup::default_macro_plugins`], + /// [`DefsGroup::default_inline_macro_plugins`], and + /// [`SemanticGroup::default_analyzer_plugins`]. + fn set_default_plugins_from_suite(&mut self, suite: PluginSuite) { + let InternedPluginSuite { macro_plugins, inline_macro_plugins, analyzer_plugins } = + self.intern_plugin_suite(suite); + + self.set_default_macro_plugins(macro_plugins); + self.set_default_inline_macro_plugins(inline_macro_plugins); + self.set_default_analyzer_plugins(analyzer_plugins); + } + + /// Sets macro, inline macro and analyzer plugins present in the [`PluginSuite`] for a crate + /// pointed to by the [`CrateId`], overriding the defaults for that crate. + /// + /// *Note*: Sets the following Salsa inputs: [`DefsGroup::override_crate_macro_plugins`], + /// [`DefsGroup::override_crate_inline_macro_plugins`], and + /// [`SemanticGroup::override_crate_analyzer_plugins`]. + fn set_override_crate_plugins_from_suite(&mut self, crate_id: CrateId, suite: PluginSuite) { + let InternedPluginSuite { macro_plugins, inline_macro_plugins, analyzer_plugins } = + self.intern_plugin_suite(suite); + + self.set_override_crate_macro_plugins(crate_id, macro_plugins); + self.set_override_crate_inline_macro_plugins(crate_id, inline_macro_plugins); + self.set_override_crate_analyzer_plugins(crate_id, analyzer_plugins); + } +} + +impl PluginSuiteInput for T {} diff --git a/crates/cairo-lang-semantic/src/plugin.rs b/crates/cairo-lang-semantic/src/plugin.rs index 922451fe9a6..48aad38f574 100644 --- a/crates/cairo-lang-semantic/src/plugin.rs +++ b/crates/cairo-lang-semantic/src/plugin.rs @@ -1,10 +1,11 @@ use std::sync::Arc; -use cairo_lang_defs::ids::ModuleId; +use cairo_lang_defs::ids::{InlineMacroExprPluginId, MacroPluginId, ModuleId}; use cairo_lang_defs::plugin::{InlineMacroExprPlugin, MacroPlugin, NamedPlugin, PluginDiagnostic}; use cairo_lang_utils::ordered_hash_map::OrderedHashMap; use crate::db::SemanticGroup; +use crate::ids::AnalyzerPluginId; /// A trait for an analyzer plugin: external plugin that generates additional diagnostics for /// modules. @@ -72,3 +73,12 @@ impl PluginSuite { self } } + +/// A helper representation for the plugin IDs obtained from +/// [`crate::db::PluginSuiteInput::intern_plugin_suite`]. +#[derive(Clone, Debug)] +pub struct InternedPluginSuite { + pub macro_plugins: Arc<[MacroPluginId]>, + pub inline_macro_plugins: Arc>, + pub analyzer_plugins: Arc<[AnalyzerPluginId]>, +} diff --git a/crates/cairo-lang-starknet/src/abi_test.rs b/crates/cairo-lang-starknet/src/abi_test.rs index 6c18a9c0d5c..482a3bbc541 100644 --- a/crates/cairo-lang-starknet/src/abi_test.rs +++ b/crates/cairo-lang-starknet/src/abi_test.rs @@ -17,7 +17,7 @@ pub fn test_abi_failure( ) -> TestRunnerResult { let db = &mut RootDatabase::builder() .detect_corelib() - .with_plugin_suite(starknet_plugin_suite()) + .with_default_plugin_suite(starknet_plugin_suite()) .build() .unwrap(); let (_, cairo_code) = get_direct_or_file_content(&inputs["cairo_code"]); @@ -62,7 +62,7 @@ pub fn test_storage_path_check( ) -> TestRunnerResult { let db = &mut RootDatabase::builder() .detect_corelib() - .with_plugin_suite(starknet_plugin_suite()) + .with_default_plugin_suite(starknet_plugin_suite()) .build() .unwrap(); let (_, cairo_code) = get_direct_or_file_content(&inputs["cairo_code"]); diff --git a/crates/cairo-lang-starknet/src/compile.rs b/crates/cairo-lang-starknet/src/compile.rs index 89efc98897c..f61c887588c 100644 --- a/crates/cairo-lang-starknet/src/compile.rs +++ b/crates/cairo-lang-starknet/src/compile.rs @@ -43,7 +43,7 @@ pub fn compile_path( ) -> Result { let mut db = RootDatabase::builder() .detect_corelib() - .with_plugin_suite(starknet_plugin_suite()) + .with_default_plugin_suite(starknet_plugin_suite()) .build()?; let main_crate_ids = setup_project(&mut db, Path::new(&path))?; diff --git a/crates/cairo-lang-starknet/src/contract_test.rs b/crates/cairo-lang-starknet/src/contract_test.rs index df4edfa127f..50501ee1d7b 100644 --- a/crates/cairo-lang-starknet/src/contract_test.rs +++ b/crates/cairo-lang-starknet/src/contract_test.rs @@ -12,7 +12,7 @@ use crate::starknet_plugin_suite; fn test_contract_resolving() { let db = &mut RootDatabase::builder() .detect_corelib() - .with_plugin_suite(starknet_plugin_suite()) + .with_default_plugin_suite(starknet_plugin_suite()) .build() .unwrap(); let crate_id = setup_test_crate(db, indoc! {" diff --git a/crates/cairo-lang-starknet/src/test_utils.rs b/crates/cairo-lang-starknet/src/test_utils.rs index 7f28622d493..14671d215f2 100644 --- a/crates/cairo-lang-starknet/src/test_utils.rs +++ b/crates/cairo-lang-starknet/src/test_utils.rs @@ -29,7 +29,7 @@ pub static SHARED_DB: LazyLock> = LazyLock::new(|| { Mutex::new( RootDatabase::builder() .detect_corelib() - .with_plugin_suite(starknet_plugin_suite()) + .with_default_plugin_suite(starknet_plugin_suite()) .build() .unwrap(), ) @@ -47,7 +47,7 @@ pub static SHARED_DB_WITH_CONTRACTS: LazyLock> = LazyLock::n .with_project_config( ProjectConfig::from_directory(Path::new(CONTRACTS_CRATE_DIR)).unwrap(), ) - .with_plugin_suite(starknet_plugin_suite()) + .with_default_plugin_suite(starknet_plugin_suite()) .build() .unwrap(), ) diff --git a/crates/cairo-lang-test-runner/src/lib.rs b/crates/cairo-lang-test-runner/src/lib.rs index 86574e7e2ed..a7e1c41045b 100644 --- a/crates/cairo-lang-test-runner/src/lib.rs +++ b/crates/cairo-lang-test-runner/src/lib.rs @@ -234,9 +234,9 @@ impl TestCompiler { } b.detect_corelib(); b.with_cfg(CfgSet::from_iter([Cfg::name("test"), Cfg::kv("target", "test")])); - b.with_plugin_suite(test_plugin_suite()); + b.with_default_plugin_suite(test_plugin_suite()); if config.starknet { - b.with_plugin_suite(starknet_plugin_suite()); + b.with_default_plugin_suite(starknet_plugin_suite()); } b.build()? };