Skip to main content

cairo_lang_semantic/inline_macros/
array.rs

1use cairo_lang_defs::patcher::PatchBuilder;
2use cairo_lang_defs::plugin::{
3    InlineMacroExprPlugin, InlinePluginResult, MacroPluginMetadata, NamedPlugin,
4    PluginGeneratedFile,
5};
6use cairo_lang_defs::plugin_utils::{
7    PluginResultTrait, not_legacy_macro_diagnostic, unsupported_bracket_diagnostic,
8};
9use cairo_lang_parser::macro_helpers::AsLegacyInlineMacro;
10use cairo_lang_syntax::node::{TypedSyntaxNode, ast};
11use indoc::indoc;
12use salsa::Database;
13
14#[derive(Debug, Default)]
15pub struct ArrayMacro;
16impl NamedPlugin for ArrayMacro {
17    const NAME: &'static str = "array";
18}
19impl InlineMacroExprPlugin for ArrayMacro {
20    fn generate_code<'db>(
21        &self,
22        db: &'db dyn Database,
23        syntax: &ast::ExprInlineMacro<'db>,
24        _metadata: &MacroPluginMetadata<'_>,
25    ) -> InlinePluginResult<'db> {
26        let Some(legacy_inline_macro) = syntax.as_legacy_inline_macro(db) else {
27            return InlinePluginResult::diagnostic_only(not_legacy_macro_diagnostic(
28                syntax.as_syntax_node().stable_ptr(db),
29            ));
30        };
31        let ast::WrappedArgList::BracketedArgList(args) = legacy_inline_macro.arguments(db) else {
32            return unsupported_bracket_diagnostic(db, &legacy_inline_macro, syntax.stable_ptr(db));
33        };
34        let mut builder = PatchBuilder::new(db, syntax);
35        builder.add_str(
36            "{
37            let mut __array_builder_macro_result__ = core::array::ArrayTrait::new();",
38        );
39        for arg in args.arguments(db).elements(db) {
40            builder.add_str(
41                "\n            core::array::ArrayTrait::append(ref __array_builder_macro_result__,",
42            );
43            builder.add_node(arg.as_syntax_node());
44            builder.add_str(");");
45        }
46        builder.add_str(
47            "\n            __array_builder_macro_result__
48        }",
49        );
50        let (content, code_mappings) = builder.build();
51        InlinePluginResult {
52            code: Some(PluginGeneratedFile {
53                name: "array_inline_macro".into(),
54                content,
55                code_mappings,
56                aux_data: None,
57                diagnostics_note: Default::default(),
58                is_unhygienic: false,
59            }),
60            diagnostics: vec![],
61        }
62    }
63
64    fn documentation(&self) -> Option<String> {
65        Some(
66            indoc! {r#"
67            Creates a new array containing the provided elements.
68            The `array!` macro allows you to create an array by specifying a list of elements. \
69            The elements are added to a new array in the order they are provided.
70
71            # Syntax
72            ```cairo
73            array![element1, element2, element3, ...]
74            ```
75            # Returns
76            An array containing the specified elements.
77
78            # Examples
79            ```cairo
80            let arr = array![]; // Creates an empty array.
81            let arr = array![1, 2, 3]; // Creates an array containing 1, 2, and 3.
82            let x = 5;
83            let y = 10;
84            let arr = array![x, y, x + y]; // Creates an array containing 5, 10, and 15.
85            ```
86            # Notes
87            - Elements must be of the same type or convertible to a common type.
88            - Elements are added in the order provided.
89            "#}
90            .to_string(),
91        )
92    }
93}