Skip to main content

cairo_lang_plugins/plugins/
compile_error.rs

1use cairo_lang_defs::extract_macro_single_unnamed_arg;
2use cairo_lang_defs::plugin::{MacroPlugin, MacroPluginMetadata, PluginDiagnostic, PluginResult};
3use cairo_lang_defs::plugin_utils::{PluginResultTrait, not_legacy_macro_diagnostic};
4use cairo_lang_parser::macro_helpers::AsLegacyInlineMacro;
5use cairo_lang_syntax::node::db::SyntaxGroup;
6use cairo_lang_syntax::node::{Terminal, TypedSyntaxNode, ast};
7
8/// Plugin that allows writing item level `compile_error!` causing a diagnostic.
9/// Useful for testing that `cfg` attributes are valid.
10#[derive(Debug, Default)]
11#[non_exhaustive]
12pub struct CompileErrorPlugin;
13
14impl MacroPlugin for CompileErrorPlugin {
15    fn generate_code(
16        &self,
17        db: &dyn SyntaxGroup,
18        item_ast: ast::ModuleItem,
19        _metadata: &MacroPluginMetadata<'_>,
20    ) -> PluginResult {
21        let item_ast_ptr = item_ast.stable_ptr(db);
22        if let ast::ModuleItem::InlineMacro(inline_macro_ast) = item_ast.clone() {
23            let Some(legacy_inline_macro_ast) = inline_macro_ast.as_legacy_inline_macro(db) else {
24                return PluginResult::diagnostic_only(not_legacy_macro_diagnostic(
25                    inline_macro_ast.as_syntax_node().stable_ptr(db),
26                ));
27            };
28            if legacy_inline_macro_ast.path(db).as_syntax_node().get_text_without_trivia(db)
29                == "compile_error"
30            {
31                let compilation_error_arg = extract_macro_single_unnamed_arg!(
32                    db,
33                    &legacy_inline_macro_ast,
34                    ast::WrappedArgList::ParenthesizedArgList(_),
35                    item_ast_ptr
36                );
37                let ast::Expr::String(err_message) = compilation_error_arg.clone() else {
38                    return PluginResult::diagnostic_only(PluginDiagnostic::error_with_inner_span(
39                        db,
40                        item_ast_ptr,
41                        compilation_error_arg.as_syntax_node(),
42                        "`compile_error!` argument must be an unnamed string argument.".to_string(),
43                    ));
44                };
45                return PluginResult::diagnostic_only(PluginDiagnostic::error(
46                    item_ast_ptr,
47                    err_message.text(db).to_string(),
48                ));
49            }
50        }
51        PluginResult { code: None, diagnostics: vec![], remove_original_item: false }
52    }
53
54    fn declared_attributes(&self) -> Vec<String> {
55        vec![]
56    }
57}