use proc_macro::TokenStream;
use quote::quote;
use syn::{Ident, parse_macro_input};
const WIT: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/wit/plugin.wit"));
#[proc_macro]
pub fn plugin(input: TokenStream) -> TokenStream {
let ty = parse_macro_input!(input as Ident);
let wit = WIT;
quote! {
wit_bindgen::generate!({
inline: #wit,
world: "analyzer",
});
#[allow(unused_imports)]
use cha::plugin::types::{
ClassInfo, FunctionInfo, ImportInfo, Location, OptionValue, Severity, SmellCategory,
};
pub trait PluginImpl {
fn name() -> String;
fn analyze(input: AnalysisInput) -> Vec<Finding>;
}
struct __ChaPluginWrapper(std::marker::PhantomData<#ty>);
impl Guest for __ChaPluginWrapper {
fn name() -> String { <#ty as PluginImpl>::name() }
fn version() -> String { env!("CARGO_PKG_VERSION").to_string() }
fn description() -> String {
let d = env!("CARGO_PKG_DESCRIPTION");
if d.is_empty() { <#ty as PluginImpl>::name() } else { d.to_string() }
}
fn authors() -> Vec<String> {
let a = env!("CARGO_PKG_AUTHORS");
if a.is_empty() { vec![] } else { a.split(':').map(str::to_string).collect() }
}
fn analyze(input: AnalysisInput) -> Vec<Finding> { <#ty as PluginImpl>::analyze(input) }
}
export!(__ChaPluginWrapper);
}
.into()
}