qlty_analysis/code/
visitor.rs

1use crate::Language;
2use tree_sitter::{Node, TreeCursor};
3
4pub trait Visitor {
5    fn process_node(&mut self, cursor: &mut TreeCursor) {
6        let node = cursor.node();
7        let kind = node.kind();
8        let language = self.language();
9
10        if self.skip_node(&node) {
11            return;
12        }
13
14        if language.invisible_container_nodes().contains(&kind) {
15            self.visit_invisible_container(cursor);
16        } else if language.if_nodes().contains(&kind) {
17            self.visit_if(cursor);
18        } else if language.elsif_nodes().contains(&kind) {
19            self.visit_elsif(cursor);
20        } else if language.else_nodes().contains(&kind) {
21            self.visit_else(cursor);
22        } else if language.conditional_assignment_nodes().contains(&kind) {
23            self.visit_conditional_assignment(cursor);
24        } else if language.ternary_nodes().contains(&kind) {
25            self.visit_ternary(cursor);
26        } else if language.switch_nodes().contains(&kind) {
27            self.visit_switch(cursor);
28        } else if language.case_nodes().contains(&kind) {
29            self.visit_case(cursor);
30        } else if language.loop_nodes().contains(&kind) {
31            self.visit_loop(cursor);
32        } else if language.except_nodes().contains(&kind) {
33            self.visit_except(cursor);
34        } else if language.try_expression_nodes().contains(&kind) {
35            self.visit_try_expression(cursor);
36        } else if language.jump_nodes().contains(&kind) {
37            self.visit_jump(cursor);
38        } else if language.return_nodes().contains(&kind) {
39            self.visit_return(cursor);
40        } else if language.binary_nodes().contains(&kind) {
41            self.visit_binary(cursor);
42        } else if language.field_nodes().contains(&kind) {
43            self.visit_field(cursor);
44        } else if language.call_nodes().contains(&kind) {
45            self.visit_call(cursor);
46        } else if language.function_nodes().contains(&kind) {
47            self.visit_function(cursor);
48        } else if language.closure_nodes().contains(&kind) {
49            self.visit_closure(cursor);
50        } else if language.comment_nodes().contains(&kind) {
51            self.visit_comment(cursor);
52        } else if language.string_nodes().contains(&kind) {
53            self.visit_string(cursor);
54        } else if language.block_nodes().contains(&kind) {
55            self.visit_block(cursor);
56        } else {
57            self.visit_unknown(cursor);
58        }
59    }
60
61    fn visit_invisible_container(&mut self, cursor: &mut TreeCursor) {
62        self.process_children(cursor);
63    }
64
65    fn visit_if(&mut self, cursor: &mut TreeCursor) {
66        self.process_children(cursor);
67    }
68
69    fn visit_elsif(&mut self, cursor: &mut TreeCursor) {
70        self.process_children(cursor);
71    }
72
73    fn visit_else(&mut self, cursor: &mut TreeCursor) {
74        self.process_children(cursor);
75    }
76
77    fn visit_conditional_assignment(&mut self, cursor: &mut TreeCursor) {
78        self.process_children(cursor);
79    }
80
81    fn visit_ternary(&mut self, cursor: &mut TreeCursor) {
82        self.process_children(cursor);
83    }
84
85    fn visit_switch(&mut self, cursor: &mut TreeCursor) {
86        self.process_children(cursor);
87    }
88
89    fn visit_case(&mut self, cursor: &mut TreeCursor) {
90        self.process_children(cursor);
91    }
92
93    fn visit_loop(&mut self, cursor: &mut TreeCursor) {
94        self.process_children(cursor);
95    }
96
97    fn visit_except(&mut self, cursor: &mut TreeCursor) {
98        self.process_children(cursor);
99    }
100
101    fn visit_try_expression(&mut self, cursor: &mut TreeCursor) {
102        self.process_children(cursor);
103    }
104
105    fn visit_jump(&mut self, cursor: &mut TreeCursor) {
106        self.process_children(cursor);
107    }
108
109    fn visit_return(&mut self, cursor: &mut TreeCursor) {
110        self.process_children(cursor);
111    }
112
113    fn visit_binary(&mut self, cursor: &mut TreeCursor) {
114        self.process_children(cursor);
115    }
116
117    fn visit_field(&mut self, cursor: &mut TreeCursor) {
118        self.process_children(cursor);
119    }
120
121    fn visit_call(&mut self, cursor: &mut TreeCursor) {
122        self.process_children(cursor);
123    }
124
125    fn visit_function(&mut self, cursor: &mut TreeCursor) {
126        self.process_children(cursor);
127    }
128
129    fn visit_closure(&mut self, cursor: &mut TreeCursor) {
130        self.process_children(cursor);
131    }
132
133    fn visit_comment(&mut self, cursor: &mut TreeCursor) {
134        self.process_children(cursor);
135    }
136
137    fn visit_string(&mut self, cursor: &mut TreeCursor) {
138        self.process_children(cursor);
139    }
140
141    fn visit_block(&mut self, cursor: &mut TreeCursor) {
142        self.process_children(cursor);
143    }
144
145    fn visit_unknown(&mut self, cursor: &mut TreeCursor) {
146        self.process_children(cursor);
147    }
148
149    fn process_children(&mut self, cursor: &mut TreeCursor) {
150        if cursor.goto_first_child() {
151            loop {
152                self.process_node(cursor);
153
154                if !cursor.goto_next_sibling() {
155                    break;
156                }
157            }
158
159            cursor.goto_parent();
160        }
161    }
162
163    fn skip_node(&self, node: &Node) -> bool {
164        !node.is_named()
165    }
166
167    #[allow(clippy::borrowed_box)]
168    fn language(&self) -> &Box<dyn Language + Sync>;
169}