Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrated the compiler to per-crate plugin queries #6843

Open
wants to merge 1 commit into
base: spr/main/ffce04df
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions crates/cairo-lang-compiler/src/db.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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::db::{DefsDatabase, DefsGroup, init_defs_group, try_ext_as_virtual_impl};
use cairo_lang_filesystem::cfg::CfgSet;
use cairo_lang_filesystem::db::{
AsFilesGroupMut, CORELIB_VERSION, ExternalFiles, FilesDatabase, FilesGroup, FilesGroupEx,
Expand All @@ -13,7 +13,9 @@ 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::{PluginSuiteInput, SemanticDatabase, SemanticGroup};
use cairo_lang_semantic::db::{
PluginSuiteInput, SemanticDatabase, SemanticGroup, init_semantic_group,
};
use cairo_lang_semantic::inline_macros::get_default_plugin_suite;
use cairo_lang_semantic::plugin::PluginSuite;
use cairo_lang_sierra_generator::db::SierraGenDatabase;
Expand Down Expand Up @@ -51,6 +53,8 @@ impl RootDatabase {
let mut res = Self { storage: Default::default() };
init_files_group(&mut res);
init_lowering_group(&mut res, inlining_strategy);
init_defs_group(&mut res);
init_semantic_group(&mut res);

let suite = res.intern_plugin_suite(default_plugin_suite);
res.set_default_plugins_from_suite(suite);
Expand Down
52 changes: 31 additions & 21 deletions crates/cairo-lang-defs/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ use itertools::{Itertools, chain};
use salsa::InternKey;

use crate::ids::*;
use crate::plugin::{
DynGeneratedFileAuxData, InlineMacroExprPlugin, MacroPlugin, MacroPluginMetadata,
PluginDiagnostic,
};
use crate::plugin::{DynGeneratedFileAuxData, MacroPlugin, MacroPluginMetadata, PluginDiagnostic};

/// Salsa database interface.
/// See [`super::ids`] for further details.
Expand Down Expand Up @@ -95,10 +92,6 @@ pub trait DefsGroup:

// Plugins.
// ========
#[salsa::input]
fn macro_plugins(&self) -> Vec<Arc<dyn MacroPlugin>>; // TODO: Delete in favour or [`default_macro_plugins`]
#[salsa::input] // TODO: Delete in favour or [`default_inline_macro_plugins`]
fn inline_macro_plugins(&self) -> Arc<OrderedHashMap<String, Arc<dyn InlineMacroExprPlugin>>>;

#[salsa::input]
fn default_macro_plugins(&self) -> Arc<[MacroPluginId]>;
Expand Down Expand Up @@ -140,19 +133,19 @@ pub trait DefsGroup:

/// Returns the set of attributes allowed anywhere.
/// An attribute on any item that is not in this set will be handled as an unknown attribute.
fn allowed_attributes(&self) -> Arc<OrderedHashSet<String>>;
fn allowed_attributes(&self, crate_id: CrateId) -> Arc<OrderedHashSet<String>>;

/// Returns the set of attributes allowed on statements.
/// An attribute on a statement that is not in this set will be handled as an unknown attribute.
fn allowed_statement_attributes(&self) -> Arc<OrderedHashSet<String>>;

/// Returns the set of `derive` that were declared as by a plugin.
/// A derive that is not in this set will be handled as an unknown derive.
fn declared_derives(&self) -> Arc<OrderedHashSet<String>>;
fn declared_derives(&self, crate_id: CrateId) -> Arc<OrderedHashSet<String>>;

/// Returns the set of attributes that were declared as phantom type attributes by a plugin,
/// i.e. a type marked with this attribute is considered a phantom type.
fn declared_phantom_type_attributes(&self) -> Arc<OrderedHashSet<String>>;
fn declared_phantom_type_attributes(&self, crate_id: CrateId) -> Arc<OrderedHashSet<String>>;

/// Checks whether the submodule is defined as inline.
fn is_submodule_inline(&self, submodule_id: SubmoduleId) -> Maybe<bool>;
Expand Down Expand Up @@ -322,7 +315,7 @@ fn crate_inline_macro_plugins(
.unwrap_or_else(|| db.default_inline_macro_plugins())
}

fn allowed_attributes(db: &dyn DefsGroup) -> Arc<OrderedHashSet<String>> {
fn allowed_attributes(db: &dyn DefsGroup, crate_id: CrateId) -> Arc<OrderedHashSet<String>> {
let base_attrs = [
INLINE_ATTR,
MUST_USE_ATTR,
Expand All @@ -337,9 +330,14 @@ fn allowed_attributes(db: &dyn DefsGroup) -> Arc<OrderedHashSet<String>> {
// TODO(orizi): Remove this once `starknet` is removed from corelib.
STARKNET_INTERFACE_ATTR,
];

let crate_plugins = db.crate_macro_plugins(crate_id);

Arc::new(OrderedHashSet::from_iter(chain!(
base_attrs.map(|attr| attr.into()),
db.macro_plugins().into_iter().flat_map(|plugin| plugin.declared_attributes())
crate_plugins
.iter()
.flat_map(|plugin| db.lookup_intern_macro_plugin(*plugin).declared_attributes())
)))
}

Expand All @@ -348,16 +346,25 @@ fn allowed_statement_attributes(_db: &dyn DefsGroup) -> Arc<OrderedHashSet<Strin
Arc::new(OrderedHashSet::from_iter(all_attributes.map(|attr| attr.into())))
}

fn declared_derives(db: &dyn DefsGroup) -> Arc<OrderedHashSet<String>> {
fn declared_derives(db: &dyn DefsGroup, crate_id: CrateId) -> Arc<OrderedHashSet<String>> {
Arc::new(OrderedHashSet::from_iter(
db.macro_plugins().into_iter().flat_map(|plugin| plugin.declared_derives()),
db.crate_macro_plugins(crate_id)
.iter()
.flat_map(|plugin| db.lookup_intern_macro_plugin(*plugin).declared_derives()),
))
}

fn declared_phantom_type_attributes(db: &dyn DefsGroup) -> Arc<OrderedHashSet<String>> {
fn declared_phantom_type_attributes(
db: &dyn DefsGroup,
crate_id: CrateId,
) -> Arc<OrderedHashSet<String>> {
let crate_plugins = db.crate_macro_plugins(crate_id);

Arc::new(OrderedHashSet::from_iter(chain!(
[PHANTOM_ATTR.into()],
db.macro_plugins().into_iter().flat_map(|plugin| plugin.phantom_type_attributes())
crate_plugins
.iter()
.flat_map(|plugin| db.lookup_intern_macro_plugin(*plugin).phantom_type_attributes())
)))
}

Expand Down Expand Up @@ -707,11 +714,12 @@ fn priv_module_sub_files(
}
.unwrap_or_else(|| file_syntax.items(syntax_db));

let allowed_attributes = db.allowed_attributes();
let crate_id = module_id.owning_crate(db);

let allowed_attributes = db.allowed_attributes(crate_id);
// TODO(orizi): Actually extract the allowed features per module.
let allowed_features = Default::default();

let crate_id = module_id.owning_crate(db);
let cfg_set = db
.crate_config(crate_id)
.and_then(|cfg| cfg.settings.cfg_set.map(Arc::new))
Expand All @@ -722,7 +730,7 @@ fn priv_module_sub_files(
.unwrap_or_default();
let metadata = MacroPluginMetadata {
cfg_set: &cfg_set,
declared_derives: &db.declared_derives(),
declared_derives: &db.declared_derives(crate_id),
allowed_features: &allowed_features,
edition,
};
Expand All @@ -737,7 +745,9 @@ fn priv_module_sub_files(
// Iterate the plugins by their order. The first one to change something (either
// generate new code, remove the original code, or both), breaks the loop. If more
// plugins might have act on the item, they can do it on the generated code.
for plugin in db.macro_plugins() {
for plugin_id in db.crate_macro_plugins(crate_id).iter() {
let plugin = db.lookup_intern_macro_plugin(*plugin_id);

let result = plugin.generate_code(db.upcast(), item_ast.clone(), &metadata);
plugin_diagnostics.extend(result.diagnostics);
if result.remove_original_item {
Expand Down
17 changes: 9 additions & 8 deletions crates/cairo-lang-defs/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
use cairo_lang_utils::{Intern, LookupIntern, Upcast, extract_matches, try_extract_matches};
use indoc::indoc;

use crate::db::{DefsDatabase, DefsGroup, try_ext_as_virtual_impl};
use crate::db::{DefsDatabase, DefsGroup, init_defs_group, try_ext_as_virtual_impl};
use crate::ids::{
FileIndex, GenericParamLongId, ModuleFileId, ModuleId, ModuleItemId, NamedLanguageElementId,
SubmoduleLongId,
FileIndex, GenericParamLongId, MacroPluginLongId, ModuleFileId, ModuleId, ModuleItemId,
NamedLanguageElementId, SubmoduleLongId,
};
use crate::plugin::{
MacroPlugin, MacroPluginMetadata, PluginDiagnostic, PluginGeneratedFile, PluginResult,
Expand All @@ -40,11 +40,12 @@ impl Default for DatabaseForTesting {
fn default() -> Self {
let mut res = Self { storage: Default::default() };
init_files_group(&mut res);
res.set_macro_plugins(vec![
Arc::new(FooToBarPlugin),
Arc::new(RemoveOrigPlugin),
Arc::new(DummyPlugin),
]);
init_defs_group(&mut res);
res.set_default_macro_plugins(Arc::new([
res.intern_macro_plugin(MacroPluginLongId(Arc::new(FooToBarPlugin))),
res.intern_macro_plugin(MacroPluginLongId(Arc::new(RemoveOrigPlugin))),
res.intern_macro_plugin(MacroPluginLongId(Arc::new(DummyPlugin))),
]));
res
}
}
Expand Down
14 changes: 11 additions & 3 deletions crates/cairo-lang-doc/src/tests/test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::{Result, anyhow};
use cairo_lang_defs::db::{DefsDatabase, DefsGroup};
use cairo_lang_defs::db::{DefsDatabase, DefsGroup, init_defs_group};
use cairo_lang_defs::ids::ModuleId;
use cairo_lang_filesystem::db::{
AsFilesGroupMut, CrateConfiguration, ExternalFiles, FilesDatabase, FilesGroup, FilesGroupEx,
Expand All @@ -8,7 +8,10 @@ use cairo_lang_filesystem::db::{
use cairo_lang_filesystem::detect::detect_corelib;
use cairo_lang_filesystem::ids::{CrateId, Directory, FileLongId};
use cairo_lang_parser::db::{ParserDatabase, ParserGroup};
use cairo_lang_semantic::db::{SemanticDatabase, SemanticGroup};
use cairo_lang_semantic::db::{
PluginSuiteInput, SemanticDatabase, SemanticGroup, init_semantic_group,
};
use cairo_lang_semantic::plugin::PluginSuite;
use cairo_lang_syntax::node::db::{SyntaxDatabase, SyntaxGroup};
use cairo_lang_utils::{Intern, Upcast};

Expand All @@ -33,7 +36,12 @@ impl Default for TestDatabase {
fn default() -> Self {
let mut res = Self { storage: Default::default() };
init_files_group(&mut res);
res.set_macro_plugins(vec![]);
init_defs_group(&mut res);
init_semantic_group(&mut res);

let plugin_suite = res.intern_plugin_suite(PluginSuite::default());
res.set_default_plugins_from_suite(plugin_suite);

res
}
}
Expand Down
15 changes: 9 additions & 6 deletions crates/cairo-lang-lowering/src/test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use std::sync::{LazyLock, Mutex};

use cairo_lang_defs::db::{DefsDatabase, DefsGroup, try_ext_as_virtual_impl};
use cairo_lang_defs::db::{DefsDatabase, DefsGroup, init_defs_group, try_ext_as_virtual_impl};
use cairo_lang_filesystem::db::{
AsFilesGroupMut, ExternalFiles, FilesDatabase, FilesGroup, init_dev_corelib, init_files_group,
};
use cairo_lang_filesystem::detect::detect_corelib;
use cairo_lang_filesystem::ids::VirtualFile;
use cairo_lang_parser::db::{ParserDatabase, ParserGroup};
use cairo_lang_semantic::db::{SemanticDatabase, SemanticGroup};
use cairo_lang_semantic::db::{
PluginSuiteInput, SemanticDatabase, SemanticGroup, init_semantic_group,
};
use cairo_lang_semantic::inline_macros::get_default_plugin_suite;
use cairo_lang_syntax::node::db::{SyntaxDatabase, SyntaxGroup};
use cairo_lang_utils::Upcast;
Expand Down Expand Up @@ -41,10 +43,11 @@ impl LoweringDatabaseForTesting {
pub fn new() -> Self {
let mut res = LoweringDatabaseForTesting { storage: Default::default() };
init_files_group(&mut res);
let suite = get_default_plugin_suite();
res.set_macro_plugins(suite.plugins);
res.set_inline_macro_plugins(suite.inline_macro_plugins.into());
res.set_analyzer_plugins(suite.analyzer_plugins);
init_defs_group(&mut res);
init_semantic_group(&mut res);

let suite = res.intern_plugin_suite(get_default_plugin_suite());
res.set_default_plugins_from_suite(suite);

let corelib_path = detect_corelib().expect("Corelib not found in default location.");
init_dev_corelib(&mut res, corelib_path);
Expand Down
25 changes: 19 additions & 6 deletions crates/cairo-lang-plugins/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::default::Default;
use std::sync::Arc;

use cairo_lang_defs::db::{DefsDatabase, DefsGroup, try_ext_as_virtual_impl};
use cairo_lang_defs::ids::ModuleId;
use cairo_lang_defs::db::{DefsDatabase, DefsGroup, init_defs_group, try_ext_as_virtual_impl};
use cairo_lang_defs::ids::{MacroPluginLongId, ModuleId};
use cairo_lang_defs::plugin::{
MacroPlugin, MacroPluginMetadata, PluginDiagnostic, PluginGeneratedFile, PluginResult,
};
Expand All @@ -23,6 +23,7 @@ use cairo_lang_test_utils::parse_test_file::TestRunnerResult;
use cairo_lang_test_utils::verify_diagnostics_expectation;
use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
use cairo_lang_utils::{Intern, Upcast};
use itertools::chain;

use crate::get_base_plugins;
use crate::test_utils::expand_module_text;
Expand Down Expand Up @@ -64,7 +65,13 @@ impl Default for DatabaseForTesting {
fn default() -> Self {
let mut res = Self { storage: Default::default() };
init_files_group(&mut res);
res.set_macro_plugins(get_base_plugins());
init_defs_group(&mut res);
res.set_default_macro_plugins(
get_base_plugins()
.into_iter()
.map(|plugin| res.intern_macro_plugin(MacroPluginLongId(plugin)))
.collect(),
);
res
}
}
Expand Down Expand Up @@ -112,9 +119,15 @@ pub fn test_expand_plugin_inner(
extra_plugins: &[Arc<dyn MacroPlugin>],
) -> TestRunnerResult {
let db = &mut DatabaseForTesting::default();
let mut plugins = db.macro_plugins();
plugins.extend_from_slice(extra_plugins);
db.set_macro_plugins(plugins);

let extra_plugins = extra_plugins
.iter()
.cloned()
.map(|plugin| db.intern_macro_plugin(MacroPluginLongId(plugin)));

let default_plugins = db.default_macro_plugins();
let plugins = chain!(default_plugins.iter().cloned(), extra_plugins).collect::<Arc<[_]>>();
db.set_default_macro_plugins(plugins);

let cfg_set: Option<CfgSet> =
inputs.get("cfg").map(|s| serde_json::from_str(s.as_str()).unwrap());
Expand Down
Loading
Loading