Find all types with `#[visit]` attribute or manual VisitableTrait impl
(dir: &str, matches: &mut HashSet<VisitableNode>, path_callback: impl Fn(&PathBuf) + Copy)
| 173 | |
| 174 | /// Find all types with `#[visit]` attribute or manual VisitableTrait impl |
| 175 | pub fn find_visitable_nodes(dir: &str, matches: &mut HashSet<VisitableNode>, path_callback: impl Fn(&PathBuf) + Copy) { |
| 176 | let attr_matcher = build_visit_attr_matcher(); |
| 177 | let manual_matcher = build_manual_impl_matcher(); |
| 178 | let mut searcher = SearcherBuilder::new().line_number(false).multi_line(true).build(); |
| 179 | let entries: Vec<_> = glob(dir).unwrap().filter_map(|p| p.ok()).collect(); |
| 180 | let mut all: HashSet<VisitableNode> = HashSet::new(); |
| 181 | // First pass: find types with derive(Visitable) |
| 182 | for entry in &entries { |
| 183 | path_callback(entry); |
| 184 | let context = NodeMatcher { matcher: &attr_matcher, matches: &mut all }; |
| 185 | searcher.search_path(&attr_matcher, entry, context).unwrap(); |
| 186 | } |
| 187 | // Second pass: find types with manual impl VisitableTrait |
| 188 | for entry in &entries { |
| 189 | let context = ManualImplMatcher { matcher: &manual_matcher, matches: &mut all }; |
| 190 | searcher.search_path(&manual_matcher, entry, context).unwrap(); |
| 191 | } |
| 192 | matches.extend(all.into_iter().filter(|node| !matches!(node.visit_mode, VisitMode::Children))); |
| 193 | } |
| 194 | |
| 195 | /// Find types that are queryable (have `#[visit]`, `#[visit(self)]`, or `#[visit(all)]` - not skip/children) |
| 196 | /// |