1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use syntax::ast::*;
use syntax::symbol::Symbol;
use syntax::visit::{self, Visitor};
use crate::ast_manip::Visit;
use crate::command::CommandState;
use c2rust_ast_builder::IntoSymbol;
struct ContainsMarkVisitor<'a> {
st: &'a CommandState,
label: Symbol,
found: bool,
}
macro_rules! gen_method {
($name:ident (& $lt:tt $ArgTy:ty) -> $walk:ident) => {
fn $name(&mut self, x: & $lt $ArgTy) {
if self.found {
return;
}
if self.st.marked(x.id, self.label) {
self.found = true;
return;
}
visit::$walk(self, x);
}
};
}
impl<'a, 'ast> Visitor<'ast> for ContainsMarkVisitor<'a> {
gen_method!(visit_expr(&'ast Expr) -> walk_expr);
gen_method!(visit_pat(&'ast Pat) -> walk_pat);
gen_method!(visit_ty(&'ast Ty) -> walk_ty);
gen_method!(visit_stmt(&'ast Stmt) -> walk_stmt);
gen_method!(visit_item(&'ast Item) -> walk_item);
}
pub fn contains_mark<T, S>(target: &T, label: S, st: &CommandState) -> bool
where
T: Visit,
S: IntoSymbol,
{
let mut v = ContainsMarkVisitor {
st: st,
label: label.into_symbol(),
found: false,
};
target.visit(&mut v);
v.found
}