cairo_lang_defs/
plugin.rs1use std::any::{self, Any};
2use std::ops::Deref;
3use std::sync::Arc;
4
5use cairo_lang_diagnostics::Severity;
6use cairo_lang_filesystem::cfg::CfgSet;
7use cairo_lang_filesystem::db::Edition;
8use cairo_lang_filesystem::ids::CodeMapping;
9use cairo_lang_filesystem::span::TextSpan;
10use cairo_lang_syntax::node::ast;
11use cairo_lang_syntax::node::db::SyntaxGroup;
12use cairo_lang_syntax::node::ids::SyntaxStablePtrId;
13use cairo_lang_utils::ordered_hash_set::OrderedHashSet;
14use serde::{Deserialize, Serialize};
15use smol_str::SmolStr;
16
17#[typetag::serde]
19pub trait GeneratedFileAuxData: std::fmt::Debug + Sync + Send {
20 fn as_any(&self) -> &dyn Any;
21 fn eq(&self, other: &dyn GeneratedFileAuxData) -> bool;
22}
23
24#[derive(Clone, Debug, Serialize, Deserialize)]
25pub struct DynGeneratedFileAuxData(pub Arc<dyn GeneratedFileAuxData>);
26impl DynGeneratedFileAuxData {
27 pub fn new<T: GeneratedFileAuxData + 'static>(aux_data: T) -> Self {
28 DynGeneratedFileAuxData(Arc::new(aux_data))
29 }
30}
31impl Deref for DynGeneratedFileAuxData {
32 type Target = Arc<dyn GeneratedFileAuxData>;
33
34 fn deref(&self) -> &Self::Target {
35 &self.0
36 }
37}
38impl PartialEq for DynGeneratedFileAuxData {
39 fn eq(&self, that: &DynGeneratedFileAuxData) -> bool {
40 GeneratedFileAuxData::eq(&*self.0, &*that.0)
41 }
42}
43impl Eq for DynGeneratedFileAuxData {}
44
45pub struct PluginGeneratedFile {
47 pub name: SmolStr,
49 pub content: String,
51 pub code_mappings: Vec<CodeMapping>,
54 pub aux_data: Option<DynGeneratedFileAuxData>,
56 pub diagnostics_note: Option<String>,
60}
61
62#[derive(Default)]
64pub struct PluginResult {
65 pub code: Option<PluginGeneratedFile>,
67 pub diagnostics: Vec<PluginDiagnostic>,
69 pub remove_original_item: bool,
71}
72
73#[derive(Clone, Debug, Eq, Hash, PartialEq)]
74pub struct PluginDiagnostic {
75 pub stable_ptr: SyntaxStablePtrId,
76 pub relative_span: Option<TextSpan>,
81 pub message: String,
82 pub severity: Severity,
83}
84impl PluginDiagnostic {
85 pub fn error(stable_ptr: impl Into<SyntaxStablePtrId>, message: String) -> PluginDiagnostic {
86 PluginDiagnostic {
87 stable_ptr: stable_ptr.into(),
88 relative_span: None,
89 message,
90 severity: Severity::Error,
91 }
92 }
93 pub fn warning(stable_ptr: impl Into<SyntaxStablePtrId>, message: String) -> PluginDiagnostic {
94 PluginDiagnostic {
95 stable_ptr: stable_ptr.into(),
96 relative_span: None,
97 message,
98 severity: Severity::Warning,
99 }
100 }
101
102 pub fn with_relative_span(mut self, span: TextSpan) -> Self {
103 self.relative_span = Some(span);
104 self
105 }
106}
107
108pub struct MacroPluginMetadata<'a> {
111 pub cfg_set: &'a CfgSet,
113 pub declared_derives: &'a OrderedHashSet<String>,
115 pub allowed_features: &'a OrderedHashSet<SmolStr>,
117 pub edition: Edition,
119}
120
121pub trait MacroPlugin: std::fmt::Debug + Sync + Send + Any {
124 fn generate_code(
128 &self,
129 db: &dyn SyntaxGroup,
130 item_ast: ast::ModuleItem,
131 metadata: &MacroPluginMetadata<'_>,
132 ) -> PluginResult;
133
134 fn declared_attributes(&self) -> Vec<String>;
140
141 fn declared_derives(&self) -> Vec<String> {
147 Vec::new()
148 }
149
150 fn executable_attributes(&self) -> Vec<String> {
156 Vec::new()
157 }
158
159 fn phantom_type_attributes(&self) -> Vec<String> {
163 Vec::new()
164 }
165
166 fn plugin_type_id(&self) -> any::TypeId {
169 self.type_id()
170 }
171}
172
173#[derive(Default)]
175pub struct InlinePluginResult {
176 pub code: Option<PluginGeneratedFile>,
177 pub diagnostics: Vec<PluginDiagnostic>,
179}
180
181pub trait InlineMacroExprPlugin: std::fmt::Debug + Sync + Send + Any {
182 fn generate_code(
186 &self,
187 db: &dyn SyntaxGroup,
188 item_ast: &ast::ExprInlineMacro,
189 metadata: &MacroPluginMetadata<'_>,
190 ) -> InlinePluginResult;
191
192 fn documentation(&self) -> Option<String> {
194 None
195 }
196
197 fn plugin_type_id(&self) -> any::TypeId {
200 self.type_id()
201 }
202}
203
204pub trait NamedPlugin: Default + 'static {
206 const NAME: &'static str;
207}