use std::any::{self, Any};
use std::sync::Arc;
use cairo_lang_defs::ids::{InlineMacroExprPluginId, MacroPluginId, ModuleId};
use cairo_lang_defs::plugin::{InlineMacroExprPlugin, MacroPlugin, NamedPlugin, PluginDiagnostic};
use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
use salsa::Database;
use crate::ids::AnalyzerPluginId;
pub trait AnalyzerPlugin: std::fmt::Debug + Sync + Send + Any {
fn diagnostics<'db>(
&self,
db: &'db dyn Database,
module_id: ModuleId<'db>,
) -> Vec<PluginDiagnostic<'db>>;
fn declared_allows(&self) -> Vec<String> {
Vec::new()
}
fn plugin_type_id(&self) -> any::TypeId {
self.type_id()
}
}
#[derive(Clone, Debug, Default)]
pub struct PluginSuite {
pub plugins: Vec<Arc<dyn MacroPlugin>>,
pub inline_macro_plugins: OrderedHashMap<String, Arc<dyn InlineMacroExprPlugin>>,
pub analyzer_plugins: Vec<Arc<dyn AnalyzerPlugin>>,
}
impl PluginSuite {
pub fn add_plugin_ex(&mut self, plugin: Arc<dyn MacroPlugin>) -> &mut Self {
self.plugins.push(plugin);
self
}
pub fn add_plugin<T: MacroPlugin + Default + 'static>(&mut self) -> &mut Self {
self.add_plugin_ex(Arc::new(T::default()))
}
pub fn add_inline_macro_plugin_ex(
&mut self,
name: &str,
plugin: Arc<dyn InlineMacroExprPlugin>,
) -> &mut Self {
self.inline_macro_plugins.insert(name.into(), plugin);
self
}
pub fn add_inline_macro_plugin<T: NamedPlugin + InlineMacroExprPlugin>(&mut self) -> &mut Self {
self.add_inline_macro_plugin_ex(T::NAME, Arc::new(T::default()));
self
}
pub fn add_analyzer_plugin_ex(&mut self, plugin: Arc<dyn AnalyzerPlugin>) -> &mut Self {
self.analyzer_plugins.push(plugin);
self
}
pub fn add_analyzer_plugin<T: AnalyzerPlugin + Default + 'static>(&mut self) -> &mut Self {
self.add_analyzer_plugin_ex(Arc::new(T::default()))
}
pub fn add(&mut self, suite: PluginSuite) -> &mut Self {
self.plugins.extend(suite.plugins);
self.inline_macro_plugins.extend(suite.inline_macro_plugins);
self.analyzer_plugins.extend(suite.analyzer_plugins);
self
}
}
#[derive(Clone, Debug)]
pub struct InternedPluginSuite<'db> {
pub macro_plugins: Arc<[MacroPluginId<'db>]>,
pub inline_macro_plugins: Arc<OrderedHashMap<String, InlineMacroExprPluginId<'db>>>,
pub analyzer_plugins: Arc<[AnalyzerPluginId<'db>]>,
}