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 6, 2024
1 parent 25c59d2 commit 864ea77
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 4 deletions.
17 changes: 17 additions & 0 deletions crates/cairo-lang-defs/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,23 @@ pub trait DefsGroup:
#[salsa::input]
fn inline_macro_plugins(&self) -> Arc<OrderedHashMap<String, Arc<dyn InlineMacroExprPlugin>>>;

#[salsa::input]
fn crate_macro_plugins(&self, crate_id: CrateId) -> Vec<MacroPluginId>;
#[salsa::interned]
fn intern_macro_plugin(&self, plugin: MacroPluginLongId) -> MacroPluginId;

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

#[salsa::interned]
fn intern_inline_macro_plugin(
&self,
plugin: InlineMacroExprPluginLongId,
) -> 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
103 changes: 103 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,8 @@
//
// Call sites, variable usages, assignments, etc. are NOT definitions.

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 +39,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 +324,106 @@ define_short_id!(
intern_plugin_generated_file
);

/// An Id allowing interning [`MacroPlugin`] into Salsa database.
#[allow(clippy::derived_hash_with_manual_eq)]
#[derive(Debug, Hash)]
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()
}
}

impl Clone for MacroPluginLongId {
fn clone(&self) -> Self {
Self(Arc::clone(&self.0))
}
}

// `PartialEq` cannot be derived because of the `Arc`, but since [`MacroPlugin`] has `DynEq`
// providing `PartialEq`'s functionality, the implementation is easily delegated.
impl PartialEq for MacroPluginLongId {
fn eq(&self, other: &Self) -> bool {
*self.0 == *other.0
}
}

impl Eq for MacroPluginLongId {}

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

/// An Id allowing interning [`InlineExprMacroPlugin`] into Salsa database.
#[allow(clippy::derived_hash_with_manual_eq)]
#[derive(Debug, Hash)]
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()
}
}

impl Clone for InlineMacroExprPluginLongId {
fn clone(&self) -> Self {
Self(Arc::clone(&self.0))
}
}

// `PartialEq` cannot be derived because of the `Arc`, but since [`InlineMacroExprPlugin`] has
// `DynEq` providing `PartialEq`'s functionality, the implementation is easily delegated.
impl PartialEq for InlineMacroExprPluginLongId {
fn eq(&self, other: &Self) -> bool {
*self.0 == *other.0
}
}

impl Eq for InlineMacroExprPluginLongId {}

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
43 changes: 39 additions & 4 deletions crates/cairo-lang-semantic/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -23,6 +23,7 @@ use smol_str::SmolStr;

use crate::diagnostic::SemanticDiagnosticKind;
use crate::expr::inference::{self, ImplVar, ImplVarId};
use crate::ids::{AnalyzerPluginId, AnalyzerPluginLongId};
use crate::items::constant::{ConstValueId, Constant, ImplConstantId};
use crate::items::function_with_body::FunctionBody;
use crate::items::functions::{ImplicitPrecedence, InlineConfiguration};
Expand Down Expand Up @@ -1559,6 +1560,11 @@ pub trait SemanticGroup:
#[salsa::input]
fn analyzer_plugins(&self) -> Vec<Arc<dyn AnalyzerPlugin>>;

#[salsa::input]
fn crate_analyzer_plugins(&self, crate_id: CrateId) -> Vec<AnalyzerPluginId>;
#[salsa::interned]
fn intern_analyzer_plugin(&self, plugin: AnalyzerPluginLongId) -> AnalyzerPluginId;

/// Returns the set of `allow` that were declared as by a plugin.
/// An allow that is not in this set will be handled as an unknown allow.
fn declared_allows(&self) -> Arc<OrderedHashSet<String>>;
Expand Down Expand Up @@ -1869,6 +1875,35 @@ pub trait PluginSuiteInput: SemanticGroup {
self.set_inline_macro_plugins(Arc::new(inline_macro_plugins));
self.set_analyzer_plugins(analyzer_plugins);
}

/// Sets macro, inline macro and analyzer plugins present in the [`PluginSuite`] for a crate
/// pointed to by the [`CrateId`].
/// ---
/// NOTE: A replacement for `set_macro_plugin_from_suite` defined above.
fn set_crate_plugins_from_suite(&mut self, crate_id: CrateId, suite: PluginSuite) {
let PluginSuite { plugins, inline_macro_plugins, analyzer_plugins } = suite;

let macro_plugins = plugins
.into_iter()
.map(|plugin| self.intern_macro_plugin(MacroPluginLongId(plugin)))
.collect();

let inline_macro_plugins = 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();

self.set_crate_macro_plugins(crate_id, macro_plugins);
self.set_crate_inline_macro_plugins(crate_id, inline_macro_plugins);
self.set_crate_analyzer_plugins(crate_id, analyzer_plugins);
}
}

impl<T: SemanticGroup> PluginSuiteInput for T {}
49 changes: 49 additions & 0 deletions crates/cairo-lang-semantic/src/ids.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use std::sync::Arc;

use cairo_lang_utils::define_short_id;

use crate::db::SemanticGroup;
use crate::plugin::AnalyzerPlugin;

/// An Id allowing interning [`AnalyzerPlugin`] into Salsa database.
#[allow(clippy::derived_hash_with_manual_eq)]
#[derive(Debug, Hash)]
pub struct AnalyzerPluginLongId(pub Arc<dyn AnalyzerPlugin>);

impl AnalyzerPlugin for AnalyzerPluginLongId {
fn diagnostics(
&self,
db: &dyn crate::db::SemanticGroup,
module_id: cairo_lang_defs::ids::ModuleId,
) -> Vec<cairo_lang_defs::plugin::PluginDiagnostic> {
self.0.diagnostics(db, module_id)
}

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

impl Clone for AnalyzerPluginLongId {
fn clone(&self) -> Self {
Self(Arc::clone(&self.0))
}
}

// `PartialEq` cannot be derived because of the `Arc`, but since [`AnalyzerPlugin`] has
// `DynEq` providing `PartialEq`'s functionality, the implementation is easily delegated.
impl PartialEq for AnalyzerPluginLongId {
fn eq(&self, other: &Self) -> bool {
*self.0 == *other.0
}
}

impl Eq for AnalyzerPluginLongId {}

define_short_id!(
AnalyzerPluginId,
AnalyzerPluginLongId,
SemanticGroup,
lookup_intern_analyzer_plugin,
intern_analyzer_plugin
);
1 change: 1 addition & 0 deletions crates/cairo-lang-semantic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod corelib;
pub mod db;
pub mod diagnostic;
pub mod expr;
pub mod ids;
pub mod inline_macros;
pub mod items;
pub mod literals;
Expand Down
3 changes: 3 additions & 0 deletions crates/cairo-lang-semantic/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ use dyn_hash::DynHash;

use crate::db::SemanticGroup;

dyn_eq::eq_trait_object!(AnalyzerPlugin);
dyn_hash::hash_trait_object!(AnalyzerPlugin);

/// A trait for an analyzer plugin: external plugin that generates additional diagnostics for
/// modules.
pub trait AnalyzerPlugin: std::fmt::Debug + Sync + Send + DynEq + DynHash {
Expand Down

0 comments on commit 864ea77

Please sign in to comment.