turbo_tasks_macros_shared/
self_filter.rs1use proc_macro2::TokenTree;
2use quote::ToTokens;
3use syn::visit::{Visit, visit_block, visit_expr, visit_item, visit_macro};
4
5pub fn is_self_used(block: &syn::Block) -> bool {
6 let mut finder = SelfFinder { found: false };
7 finder.visit_block(block);
8 finder.found
9}
10
11struct SelfFinder {
12 found: bool,
13}
14
15impl Visit<'_> for SelfFinder {
16 fn visit_block(&mut self, n: &syn::Block) {
17 if self.found {
18 return;
19 }
20
21 visit_block(self, n);
22 }
23
24 fn visit_expr(&mut self, expr: &syn::Expr) {
25 if self.found {
26 return;
27 }
28
29 if let syn::Expr::Path(path) = expr {
30 if path.path.is_ident("self") {
31 self.found = true;
32 return;
33 }
34 }
35
36 visit_expr(self, expr);
37 }
38
39 fn visit_item(&mut self, n: &syn::Item) {
40 if self.found {
41 return;
42 }
43
44 visit_item(self, n);
45 }
46
47 fn visit_item_impl(&mut self, _: &syn::ItemImpl) {
48 }
51
52 fn visit_macro(&mut self, mac: &syn::Macro) {
53 if self.found {
54 return;
55 }
56
57 for token in mac.tokens.to_token_stream() {
58 if contains_self_token(&token) {
59 self.found = true;
60 return;
61 }
62 }
63
64 visit_macro(self, mac);
65 }
66}
67
68fn contains_self_token(tok: &TokenTree) -> bool {
69 match tok {
70 TokenTree::Group(group) => {
71 for token in group.stream() {
72 if contains_self_token(&token) {
73 return true;
74 }
75 }
76 false
77 }
78 TokenTree::Ident(ident) => ident == "self",
79 TokenTree::Punct(..) | TokenTree::Literal(..) => false,
80 }
81}