Skip to content

Commit

Permalink
Introduced queries for crate plugins in DefsGroup and SemanticGroup
Browse files Browse the repository at this point in the history
commit-id:5dc187d6
  • Loading branch information
integraledelebesgue committed Dec 12, 2024
1 parent 55d2e0d commit 445d1b6
Show file tree
Hide file tree
Showing 12 changed files with 318 additions and 16 deletions.
6 changes: 4 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_defs::plugin::{InlineMacroExprPlugin, MacroPlugin};
use cairo_lang_filesystem::cfg::CfgSet;
use cairo_lang_filesystem::db::{
Expand All @@ -14,7 +14,7 @@ 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::{SemanticDatabase, SemanticGroup, init_semantic_group};
use cairo_lang_semantic::inline_macros::get_default_plugin_suite;
use cairo_lang_semantic::plugin::{AnalyzerPlugin, PluginSuite};
use cairo_lang_sierra_generator::db::SierraGenDatabase;
Expand Down Expand Up @@ -58,6 +58,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);
res.set_macro_plugins(plugins);
res.set_inline_macro_plugins(inline_macro_plugins.into());
res.set_analyzer_plugins(analyzer_plugins);
Expand Down
95 changes: 93 additions & 2 deletions crates/cairo-lang-defs/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,48 @@ pub trait DefsGroup:
// Plugins.
// ========
#[salsa::input]
fn macro_plugins(&self) -> Vec<Arc<dyn MacroPlugin>>;
#[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]>;

#[salsa::input]
fn macro_plugin_overrides(&self) -> Arc<OrderedHashMap<CrateId, Arc<[MacroPluginId]>>>;

#[salsa::interned]
fn intern_macro_plugin(&self, plugin: MacroPluginLongId) -> MacroPluginId;

/// Returns [`MacroPluginId`]s of the plugins set for the crate with [`CrateId`].
/// Provides an override if it has been set with
/// [`DefsGroup::set_override_crate_macro_plugins`] or the default
/// ([`DefsGroup::default_macro_plugins`]) otherwise.
fn crate_macro_plugins(&self, crate_id: CrateId) -> Arc<[MacroPluginId]>;

#[salsa::input]
fn default_inline_macro_plugins(&self) -> Arc<OrderedHashMap<String, InlineMacroExprPluginId>>;

#[salsa::input]
fn inline_macro_plugin_overrides(
&self,
) -> Arc<OrderedHashMap<CrateId, Arc<OrderedHashMap<String, InlineMacroExprPluginId>>>>;

#[salsa::interned]
fn intern_inline_macro_plugin(
&self,
plugin: InlineMacroExprPluginLongId,
) -> InlineMacroExprPluginId;

/// Returns [`InlineMacroExprPluginId`]s of the plugins set for the crate with [`CrateId`].
/// Provides an override if it has been set with
/// [`DefsGroup::set_override_crate_inline_macro_plugins`] or the default
/// ([`DefsGroup::default_inline_macro_plugins`]) otherwise.
fn crate_inline_macro_plugins(
&self,
crate_id: CrateId,
) -> Arc<OrderedHashMap<String, InlineMacroExprPluginId>>;

/// 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>>;
Expand Down Expand Up @@ -261,6 +299,29 @@ pub trait DefsGroup:
) -> Maybe<Arc<PluginFileDiagnosticNotes>>;
}

/// Initializes the [`DefsGroup`] database to a proper state.
pub fn init_defs_group(db: &mut dyn DefsGroup) {
db.set_macro_plugin_overrides(Arc::new(OrderedHashMap::default()));
db.set_inline_macro_plugin_overrides(Arc::new(OrderedHashMap::default()));
}

fn crate_macro_plugins(db: &dyn DefsGroup, crate_id: CrateId) -> Arc<[MacroPluginId]> {
db.macro_plugin_overrides()
.get(&crate_id)
.cloned()
.unwrap_or_else(|| db.default_macro_plugins())
}

fn crate_inline_macro_plugins(
db: &dyn DefsGroup,
crate_id: CrateId,
) -> Arc<OrderedHashMap<String, InlineMacroExprPluginId>> {
db.inline_macro_plugin_overrides()
.get(&crate_id)
.cloned()
.unwrap_or_else(|| db.default_inline_macro_plugins())
}

fn allowed_attributes(db: &dyn DefsGroup) -> Arc<OrderedHashSet<String>> {
let base_attrs = [
INLINE_ATTR,
Expand Down Expand Up @@ -1145,3 +1206,33 @@ fn module_item_name_stable_ptr(
}
})
}

pub trait DefsGroupEx: DefsGroup {
/// Overrides the default macro plugins available for [`CrateId`] with `plugins`.
///
/// *Note*: Sets the following Salsa input: `DefsGroup::macro_plugin_overrides`.
fn set_override_crate_macro_plugins(
&mut self,
crate_id: CrateId,
plugins: Arc<[MacroPluginId]>,
) {
let mut overrides = self.macro_plugin_overrides().as_ref().clone();
overrides.insert(crate_id, plugins);
self.set_macro_plugin_overrides(Arc::new(overrides));
}

/// Overrides the default inline macro plugins available for [`CrateId`] with `plugins`.
///
/// *Note*: Sets the following Salsa input: `DefsGroup::inline_macro_plugin_overrides`.
fn set_override_crate_inline_macro_plugins(
&mut self,
crate_id: CrateId,
plugins: Arc<OrderedHashMap<String, InlineMacroExprPluginId>>,
) {
let mut overrides = self.inline_macro_plugin_overrides().as_ref().clone();
overrides.insert(crate_id, plugins);
self.set_inline_macro_plugin_overrides(Arc::new(overrides));
}
}

impl<T: DefsGroup + ?Sized> DefsGroupEx for T {}
102 changes: 102 additions & 0 deletions crates/cairo-lang-defs/src/ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
//
// Call sites, variable usages, assignments, etc. are NOT definitions.

use std::hash::{Hash, Hasher};
use std::sync::Arc;

use cairo_lang_debug::debug::DebugWithDb;
use cairo_lang_diagnostics::Maybe;
pub use cairo_lang_filesystem::ids::UnstableSalsaId;
Expand All @@ -37,6 +40,7 @@ use smol_str::SmolStr;

use crate::db::DefsGroup;
use crate::diagnostic_utils::StableLocation;
use crate::plugin::{InlineMacroExprPlugin, MacroPlugin};

// A trait for an id for a language element.
pub trait LanguageElementId {
Expand Down Expand Up @@ -321,6 +325,104 @@ define_short_id!(
intern_plugin_generated_file
);

/// An ID allowing for interning the [`MacroPlugin`] into Salsa database.
#[derive(Clone, Debug)]
pub struct MacroPluginLongId(pub Arc<dyn MacroPlugin>);

impl MacroPlugin for MacroPluginLongId {
fn generate_code(
&self,
db: &dyn SyntaxGroup,
item_ast: ast::ModuleItem,
metadata: &crate::plugin::MacroPluginMetadata<'_>,
) -> crate::plugin::PluginResult {
self.0.generate_code(db, item_ast, metadata)
}

fn declared_attributes(&self) -> Vec<String> {
self.0.declared_attributes()
}

fn declared_derives(&self) -> Vec<String> {
self.0.declared_derives()
}

fn executable_attributes(&self) -> Vec<String> {
self.0.executable_attributes()
}

fn phantom_type_attributes(&self) -> Vec<String> {
self.0.phantom_type_attributes()
}
}

// `PartialEq` and `Hash` cannot be derived on `Arc<dyn ...>`,
// but pointer-based equality and hash semantics are enough in this case.
impl PartialEq for MacroPluginLongId {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.0, &other.0)
}
}

impl Eq for MacroPluginLongId {}

impl Hash for MacroPluginLongId {
fn hash<H: Hasher>(&self, state: &mut H) {
Arc::as_ptr(&self.0).hash(state)
}
}

define_short_id!(
MacroPluginId,
MacroPluginLongId,
DefsGroup,
lookup_intern_macro_plugin,
intern_macro_plugin
);

/// An ID allowing for interning the [`InlineMacroExprPlugin`] into Salsa database.
#[derive(Clone, Debug)]
pub struct InlineMacroExprPluginLongId(pub Arc<dyn InlineMacroExprPlugin>);

impl InlineMacroExprPlugin for InlineMacroExprPluginLongId {
fn generate_code(
&self,
db: &dyn SyntaxGroup,
item_ast: &ast::ExprInlineMacro,
metadata: &crate::plugin::MacroPluginMetadata<'_>,
) -> crate::plugin::InlinePluginResult {
self.0.generate_code(db, item_ast, metadata)
}

fn documentation(&self) -> Option<String> {
self.0.documentation()
}
}

// `PartialEq` and `Hash` cannot be derived on `Arc<dyn ...>`,
// but pointer-based equality and hash semantics are enough in this case.
impl PartialEq for InlineMacroExprPluginLongId {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.0, &other.0)
}
}

impl Eq for InlineMacroExprPluginLongId {}

impl Hash for InlineMacroExprPluginLongId {
fn hash<H: Hasher>(&self, state: &mut H) {
Arc::as_ptr(&self.0).hash(state)
}
}

define_short_id!(
InlineMacroExprPluginId,
InlineMacroExprPluginLongId,
DefsGroup,
lookup_intern_inline_macro_plugin,
intern_inline_macro_plugin
);

define_language_element_id_as_enum! {
#[toplevel]
/// Id for direct children of a module.
Expand Down
3 changes: 2 additions & 1 deletion crates/cairo-lang-defs/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ 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,
Expand All @@ -40,6 +40,7 @@ impl Default for DatabaseForTesting {
fn default() -> Self {
let mut res = Self { storage: Default::default() };
init_files_group(&mut res);
init_defs_group(&mut res);
res.set_macro_plugins(vec![
Arc::new(FooToBarPlugin),
Arc::new(RemoveOrigPlugin),
Expand Down
6 changes: 4 additions & 2 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,7 @@ 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::{SemanticDatabase, SemanticGroup, init_semantic_group};
use cairo_lang_syntax::node::db::{SyntaxDatabase, SyntaxGroup};
use cairo_lang_utils::{Intern, Upcast};

Expand All @@ -33,6 +33,8 @@ impl Default for TestDatabase {
fn default() -> Self {
let mut res = Self { storage: Default::default() };
init_files_group(&mut res);
init_defs_group(&mut res);
init_semantic_group(&mut res);
res.set_macro_plugins(vec![]);
res
}
Expand Down
7 changes: 4 additions & 3 deletions crates/cairo-lang-lowering/src/test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
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::{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,11 +41,12 @@ impl LoweringDatabaseForTesting {
pub fn new() -> Self {
let mut res = LoweringDatabaseForTesting { storage: Default::default() };
init_files_group(&mut res);
init_defs_group(&mut res);
init_semantic_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);

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

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_defs::ids::ModuleId;
use cairo_lang_defs::plugin::{
MacroPlugin, MacroPluginMetadata, PluginDiagnostic, PluginGeneratedFile, PluginResult,
Expand Down Expand Up @@ -64,6 +64,7 @@ impl Default for DatabaseForTesting {
fn default() -> Self {
let mut res = Self { storage: Default::default() };
init_files_group(&mut res);
init_defs_group(&mut res);
res.set_macro_plugins(get_base_plugins());
res
}
Expand Down
Loading

0 comments on commit 445d1b6

Please sign in to comment.