cairo_lang_semantic/
plugin.rs

1use std::sync::Arc;
2
3use cairo_lang_defs::ids::ModuleId;
4use cairo_lang_defs::plugin::{InlineMacroExprPlugin, MacroPlugin, NamedPlugin, PluginDiagnostic};
5use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
6
7use crate::db::SemanticGroup;
8
9/// A trait for an analyzer plugin: external plugin that generates additional diagnostics for
10/// modules.
11pub trait AnalyzerPlugin: std::fmt::Debug + Sync + Send {
12    /// Runs the plugin on a module.
13    fn diagnostics(&self, db: &dyn SemanticGroup, module_id: ModuleId) -> Vec<PluginDiagnostic>;
14    /// Allows this plugin supplies.
15    /// Any allow the plugin supplies without declaring here are likely to cause a
16    /// compilation error for unknown allow.
17    /// If the plugin checks for patterns that you want to allow in some places, for example
18    /// `#[allow(some_pattern)]` you will need to declare it here.
19    fn declared_allows(&self) -> Vec<String> {
20        Vec::new()
21    }
22}
23
24/// A suite of plugins.
25#[derive(Clone, Debug, Default)]
26pub struct PluginSuite {
27    /// The macro plugins, running on all items.
28    pub plugins: Vec<Arc<dyn MacroPlugin>>,
29    /// The inline macro plugins, running on matching inline macro expressions.
30    pub inline_macro_plugins: OrderedHashMap<String, Arc<dyn InlineMacroExprPlugin>>,
31    /// The analyzer plugins, running on all modules.
32    pub analyzer_plugins: Vec<Arc<dyn AnalyzerPlugin>>,
33}
34impl PluginSuite {
35    /// Adds a macro plugin.
36    pub fn add_plugin_ex(&mut self, plugin: Arc<dyn MacroPlugin>) -> &mut Self {
37        self.plugins.push(plugin);
38        self
39    }
40    /// Adds a macro plugin.
41    pub fn add_plugin<T: MacroPlugin + Default + 'static>(&mut self) -> &mut Self {
42        self.add_plugin_ex(Arc::new(T::default()))
43    }
44    /// Adds an inline macro plugin.
45    pub fn add_inline_macro_plugin_ex(
46        &mut self,
47        name: &str,
48        plugin: Arc<dyn InlineMacroExprPlugin>,
49    ) -> &mut Self {
50        self.inline_macro_plugins.insert(name.into(), plugin);
51        self
52    }
53    /// Adds an inline macro plugin.
54    pub fn add_inline_macro_plugin<T: NamedPlugin + InlineMacroExprPlugin>(&mut self) -> &mut Self {
55        self.add_inline_macro_plugin_ex(T::NAME, Arc::new(T::default()));
56        self
57    }
58    /// Adds an analyzer plugin.
59    pub fn add_analyzer_plugin_ex(&mut self, plugin: Arc<dyn AnalyzerPlugin>) -> &mut Self {
60        self.analyzer_plugins.push(plugin);
61        self
62    }
63    /// Adds an analyzer plugin.
64    pub fn add_analyzer_plugin<T: AnalyzerPlugin + Default + 'static>(&mut self) -> &mut Self {
65        self.add_analyzer_plugin_ex(Arc::new(T::default()))
66    }
67    /// Adds another plugin suite into this suite.
68    pub fn add(&mut self, suite: PluginSuite) -> &mut Self {
69        self.plugins.extend(suite.plugins);
70        self.inline_macro_plugins.extend(suite.inline_macro_plugins);
71        self.analyzer_plugins.extend(suite.analyzer_plugins);
72        self
73    }
74}