cairo_lang_starknet/plugin/
mod.rs

1#[cfg(test)]
2mod test;
3
4pub mod consts;
5
6use cairo_lang_defs::plugin::{MacroPlugin, MacroPluginMetadata, PluginResult};
7use cairo_lang_syntax::node::db::SyntaxGroup;
8use cairo_lang_syntax::node::helpers::QueryAttrs;
9use cairo_lang_syntax::node::{Terminal, ast};
10use consts::*;
11
12pub mod aux_data;
13mod derive;
14mod dispatcher;
15mod embeddable;
16mod entry_point;
17pub mod events;
18mod starknet_module;
19mod storage;
20pub(crate) mod storage_interfaces;
21pub(crate) mod utils;
22
23use dispatcher::handle_trait;
24
25use self::derive::{derive_needed, handle_derive};
26use self::embeddable::handle_embeddable;
27use self::starknet_module::{handle_module, handle_module_by_storage};
28
29#[derive(Debug, Default)]
30#[non_exhaustive]
31pub struct StarkNetPlugin;
32
33impl MacroPlugin for StarkNetPlugin {
34    fn generate_code(
35        &self,
36        db: &dyn SyntaxGroup,
37        item_ast: ast::ModuleItem,
38        metadata: &MacroPluginMetadata<'_>,
39    ) -> PluginResult {
40        match item_ast {
41            ast::ModuleItem::Module(module_ast) => handle_module(db, module_ast),
42            ast::ModuleItem::Trait(trait_ast) => handle_trait(db, trait_ast),
43            ast::ModuleItem::Impl(impl_ast) if impl_ast.has_attr(db, EMBEDDABLE_ATTR) => {
44                handle_embeddable(db, impl_ast)
45            }
46            ast::ModuleItem::Struct(struct_ast) if struct_ast.has_attr(db, STORAGE_ATTR) => {
47                handle_module_by_storage(db, struct_ast, metadata).unwrap_or_default()
48            }
49            ast::ModuleItem::Struct(_) | ast::ModuleItem::Enum(_)
50                if derive_needed(&item_ast, db) =>
51            {
52                handle_derive(db, item_ast, metadata)
53            }
54            ast::ModuleItem::InlineMacro(inline_macro_ast)
55                if inline_macro_ast.name(db).text(db) == COMPONENT_INLINE_MACRO =>
56            {
57                // The macro is expanded in handle_module_by_storage, but we also need to remove the
58                // original code.
59                starknet_module::contract::remove_component_inline_macro(db, &inline_macro_ast)
60            }
61            // Nothing to do for other items.
62            _ => PluginResult::default(),
63        }
64    }
65
66    fn declared_attributes(&self) -> Vec<String> {
67        vec![
68            ABI_ATTR.to_string(),
69            COMPONENT_ATTR.to_string(),
70            CONSTRUCTOR_ATTR.to_string(),
71            CONTRACT_ATTR.to_string(),
72            EMBEDDABLE_AS_ATTR.to_string(),
73            EMBEDDABLE_ATTR.to_string(),
74            EVENT_ATTR.to_string(),
75            EXTERNAL_ATTR.to_string(),
76            FLAT_ATTR.to_string(),
77            INTERFACE_ATTR.to_string(),
78            KEY_ATTR.to_string(),
79            L1_HANDLER_ATTR.to_string(),
80            NESTED_ATTR.to_string(),
81            RAW_OUTPUT_ATTR.to_string(),
82            STORAGE_ATTR.to_string(),
83            SUBSTORAGE_ATTR.to_string(),
84        ]
85    }
86
87    fn declared_derives(&self) -> Vec<String> {
88        vec![EVENT_TRAIT.to_string(), STORE_TRAIT.to_string()]
89    }
90
91    fn phantom_type_attributes(&self) -> Vec<String> {
92        vec![STORAGE_ATTR.to_string()]
93    }
94}