use crate::adapters::analyzers::architecture::{MatchLocation, ViolationKind};
use syn::spanned::Spanned;
use syn::visit::{self, Visit};
pub fn find_macro_calls(file: &str, ast: &syn::File, names: &[String]) -> Vec<MatchLocation> {
let mut visitor = MacroCallVisitor {
file,
names,
hits: Vec::new(),
};
visitor.visit_file(ast);
visitor.hits
}
struct MacroCallVisitor<'a> {
file: &'a str,
names: &'a [String],
hits: Vec<MatchLocation>,
}
impl<'ast> Visit<'ast> for MacroCallVisitor<'_> {
fn visit_macro(&mut self, node: &'ast syn::Macro) {
if let Some(last) = node.path.segments.last() {
let name = last.ident.to_string();
if self.names.iter().any(|n| n == &name) {
let start = last.ident.span().start();
self.hits.push(MatchLocation {
file: self.file.to_string(),
line: start.line,
column: start.column,
kind: ViolationKind::MacroCall { name },
});
}
}
for expr in crate::adapters::shared::macro_tokens::recover_exprs(&node.tokens) {
visit::visit_expr(self, &expr);
}
visit::visit_macro(self, node);
}
}