microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.2.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_ast/src/mut_visit.rs

342lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::ast::{
5 Attr, Block, CallableBody, CallableDecl, Expr, ExprKind, FunctorExpr, FunctorExprKind, Ident,
6 Item, ItemKind, Namespace, Package, Pat, PatKind, Path, QubitInit, QubitInitKind, SpecBody,
7 SpecDecl, Stmt, StmtKind, StringComponent, TopLevelNode, Ty, TyDef, TyDefKind, TyKind,
8 Visibility,
9};
10use qsc_data_structures::span::Span;
11
12pub trait MutVisitor: Sized {
13 fn visit_package(&mut self, package: &mut Package) {
14 walk_package(self, package);
15 }
16
17 fn visit_namespace(&mut self, namespace: &mut Namespace) {
18 walk_namespace(self, namespace);
19 }
20
21 fn visit_item(&mut self, item: &mut Item) {
22 walk_item(self, item);
23 }
24
25 fn visit_attr(&mut self, attr: &mut Attr) {
26 walk_attr(self, attr);
27 }
28
29 fn visit_visibility(&mut self, _: &mut Visibility) {}
30
31 fn visit_ty_def(&mut self, def: &mut TyDef) {
32 walk_ty_def(self, def);
33 }
34
35 fn visit_callable_decl(&mut self, decl: &mut CallableDecl) {
36 walk_callable_decl(self, decl);
37 }
38
39 fn visit_spec_decl(&mut self, decl: &mut SpecDecl) {
40 walk_spec_decl(self, decl);
41 }
42
43 fn visit_functor_expr(&mut self, expr: &mut FunctorExpr) {
44 walk_functor_expr(self, expr);
45 }
46
47 fn visit_ty(&mut self, ty: &mut Ty) {
48 walk_ty(self, ty);
49 }
50
51 fn visit_block(&mut self, block: &mut Block) {
52 walk_block(self, block);
53 }
54
55 fn visit_stmt(&mut self, stmt: &mut Stmt) {
56 walk_stmt(self, stmt);
57 }
58
59 fn visit_expr(&mut self, expr: &mut Expr) {
60 walk_expr(self, expr);
61 }
62
63 fn visit_pat(&mut self, pat: &mut Pat) {
64 walk_pat(self, pat);
65 }
66
67 fn visit_qubit_init(&mut self, init: &mut QubitInit) {
68 walk_qubit_init(self, init);
69 }
70
71 fn visit_path(&mut self, path: &mut Path) {
72 walk_path(self, path);
73 }
74
75 fn visit_ident(&mut self, ident: &mut Ident) {
76 walk_ident(self, ident);
77 }
78
79 fn visit_span(&mut self, _: &mut Span) {}
80}
81
82pub fn walk_package(vis: &mut impl MutVisitor, package: &mut Package) {
83 package.nodes.iter_mut().for_each(|n| match n {
84 TopLevelNode::Namespace(ns) => vis.visit_namespace(ns),
85 TopLevelNode::Stmt(stmt) => vis.visit_stmt(stmt),
86 });
87 package.entry.iter_mut().for_each(|e| vis.visit_expr(e));
88}
89
90pub fn walk_namespace(vis: &mut impl MutVisitor, namespace: &mut Namespace) {
91 vis.visit_span(&mut namespace.span);
92 vis.visit_ident(&mut namespace.name);
93 namespace.items.iter_mut().for_each(|i| vis.visit_item(i));
94}
95
96pub fn walk_item(vis: &mut impl MutVisitor, item: &mut Item) {
97 vis.visit_span(&mut item.span);
98 item.attrs.iter_mut().for_each(|a| vis.visit_attr(a));
99 item.visibility
100 .iter_mut()
101 .for_each(|v| vis.visit_visibility(v));
102
103 match &mut *item.kind {
104 ItemKind::Callable(decl) => vis.visit_callable_decl(decl),
105 ItemKind::Err => {}
106 ItemKind::Open(ns, alias) => {
107 vis.visit_ident(ns);
108 alias.iter_mut().for_each(|a| vis.visit_ident(a));
109 }
110 ItemKind::Ty(ident, def) => {
111 vis.visit_ident(ident);
112 vis.visit_ty_def(def);
113 }
114 }
115}
116
117pub fn walk_attr(vis: &mut impl MutVisitor, attr: &mut Attr) {
118 vis.visit_span(&mut attr.span);
119 vis.visit_ident(&mut attr.name);
120 vis.visit_expr(&mut attr.arg);
121}
122
123pub fn walk_ty_def(vis: &mut impl MutVisitor, def: &mut TyDef) {
124 vis.visit_span(&mut def.span);
125
126 match &mut *def.kind {
127 TyDefKind::Field(name, ty) => {
128 name.iter_mut().for_each(|n| vis.visit_ident(n));
129 vis.visit_ty(ty);
130 }
131 TyDefKind::Paren(def) => vis.visit_ty_def(def),
132 TyDefKind::Tuple(defs) => defs.iter_mut().for_each(|d| vis.visit_ty_def(d)),
133 TyDefKind::Err => {}
134 }
135}
136
137pub fn walk_callable_decl(vis: &mut impl MutVisitor, decl: &mut CallableDecl) {
138 vis.visit_span(&mut decl.span);
139 vis.visit_ident(&mut decl.name);
140 decl.generics.iter_mut().for_each(|p| vis.visit_ident(p));
141 vis.visit_pat(&mut decl.input);
142 vis.visit_ty(&mut decl.output);
143 decl.functors
144 .iter_mut()
145 .for_each(|f| vis.visit_functor_expr(f));
146
147 match &mut *decl.body {
148 CallableBody::Block(block) => vis.visit_block(block),
149 CallableBody::Specs(specs) => specs.iter_mut().for_each(|s| vis.visit_spec_decl(s)),
150 }
151}
152
153pub fn walk_spec_decl(vis: &mut impl MutVisitor, decl: &mut SpecDecl) {
154 vis.visit_span(&mut decl.span);
155
156 match &mut decl.body {
157 SpecBody::Gen(_) => {}
158 SpecBody::Impl(pat, block) => {
159 vis.visit_pat(pat);
160 vis.visit_block(block);
161 }
162 }
163}
164
165pub fn walk_functor_expr(vis: &mut impl MutVisitor, expr: &mut FunctorExpr) {
166 vis.visit_span(&mut expr.span);
167
168 match &mut *expr.kind {
169 FunctorExprKind::BinOp(_, lhs, rhs) => {
170 vis.visit_functor_expr(lhs);
171 vis.visit_functor_expr(rhs);
172 }
173 FunctorExprKind::Lit(_) => {}
174 FunctorExprKind::Paren(expr) => vis.visit_functor_expr(expr),
175 }
176}
177
178pub fn walk_ty(vis: &mut impl MutVisitor, ty: &mut Ty) {
179 vis.visit_span(&mut ty.span);
180
181 match &mut *ty.kind {
182 TyKind::Array(item) => vis.visit_ty(item),
183 TyKind::Arrow(_, lhs, rhs, functors) => {
184 vis.visit_ty(lhs);
185 vis.visit_ty(rhs);
186 functors.iter_mut().for_each(|f| vis.visit_functor_expr(f));
187 }
188 TyKind::Hole | TyKind::Err => {}
189 TyKind::Paren(ty) => vis.visit_ty(ty),
190 TyKind::Param(name) => vis.visit_ident(name),
191 TyKind::Path(path) => vis.visit_path(path),
192 TyKind::Tuple(tys) => tys.iter_mut().for_each(|t| vis.visit_ty(t)),
193 }
194}
195
196pub fn walk_block(vis: &mut impl MutVisitor, block: &mut Block) {
197 vis.visit_span(&mut block.span);
198 block.stmts.iter_mut().for_each(|s| vis.visit_stmt(s));
199}
200
201pub fn walk_stmt(vis: &mut impl MutVisitor, stmt: &mut Stmt) {
202 vis.visit_span(&mut stmt.span);
203
204 match &mut *stmt.kind {
205 StmtKind::Empty | StmtKind::Err => {}
206 StmtKind::Expr(expr) | StmtKind::Semi(expr) => vis.visit_expr(expr),
207 StmtKind::Item(item) => vis.visit_item(item),
208 StmtKind::Local(_, pat, value) => {
209 vis.visit_pat(pat);
210 vis.visit_expr(value);
211 }
212 StmtKind::Qubit(_, pat, init, block) => {
213 vis.visit_pat(pat);
214 vis.visit_qubit_init(init);
215 block.iter_mut().for_each(|b| vis.visit_block(b));
216 }
217 }
218}
219
220pub fn walk_expr(vis: &mut impl MutVisitor, expr: &mut Expr) {
221 vis.visit_span(&mut expr.span);
222
223 match &mut *expr.kind {
224 ExprKind::Array(exprs) => exprs.iter_mut().for_each(|e| vis.visit_expr(e)),
225 ExprKind::ArrayRepeat(item, size) => {
226 vis.visit_expr(item);
227 vis.visit_expr(size);
228 }
229 ExprKind::Assign(lhs, rhs)
230 | ExprKind::AssignOp(_, lhs, rhs)
231 | ExprKind::BinOp(_, lhs, rhs) => {
232 vis.visit_expr(lhs);
233 vis.visit_expr(rhs);
234 }
235 ExprKind::AssignUpdate(record, index, value) => {
236 vis.visit_expr(record);
237 vis.visit_expr(index);
238 vis.visit_expr(value);
239 }
240 ExprKind::Block(block) => vis.visit_block(block),
241 ExprKind::Call(callee, arg) => {
242 vis.visit_expr(callee);
243 vis.visit_expr(arg);
244 }
245 ExprKind::Conjugate(within, apply) => {
246 vis.visit_block(within);
247 vis.visit_block(apply);
248 }
249 ExprKind::Fail(msg) => vis.visit_expr(msg),
250 ExprKind::Field(record, name) => {
251 vis.visit_expr(record);
252 vis.visit_ident(name);
253 }
254 ExprKind::For(pat, iter, block) => {
255 vis.visit_pat(pat);
256 vis.visit_expr(iter);
257 vis.visit_block(block);
258 }
259 ExprKind::If(cond, body, otherwise) => {
260 vis.visit_expr(cond);
261 vis.visit_block(body);
262 otherwise.iter_mut().for_each(|e| vis.visit_expr(e));
263 }
264 ExprKind::Index(array, index) => {
265 vis.visit_expr(array);
266 vis.visit_expr(index);
267 }
268 ExprKind::Interpolate(components) => {
269 for component in components.iter_mut() {
270 match component {
271 StringComponent::Expr(expr) => vis.visit_expr(expr.as_mut()),
272 StringComponent::Lit(_) => {}
273 }
274 }
275 }
276 ExprKind::Lambda(_, pat, expr) => {
277 vis.visit_pat(pat);
278 vis.visit_expr(expr);
279 }
280 ExprKind::Paren(expr) | ExprKind::Return(expr) | ExprKind::UnOp(_, expr) => {
281 vis.visit_expr(expr);
282 }
283 ExprKind::Path(path) => vis.visit_path(path),
284 ExprKind::Range(start, step, end) => {
285 start.iter_mut().for_each(|s| vis.visit_expr(s));
286 step.iter_mut().for_each(|s| vis.visit_expr(s));
287 end.iter_mut().for_each(|e| vis.visit_expr(e));
288 }
289 ExprKind::Repeat(body, until, fixup) => {
290 vis.visit_block(body);
291 vis.visit_expr(until);
292 fixup.iter_mut().for_each(|f| vis.visit_block(f));
293 }
294 ExprKind::TernOp(_, e1, e2, e3) => {
295 vis.visit_expr(e1);
296 vis.visit_expr(e2);
297 vis.visit_expr(e3);
298 }
299 ExprKind::Tuple(exprs) => exprs.iter_mut().for_each(|e| vis.visit_expr(e)),
300 ExprKind::While(cond, block) => {
301 vis.visit_expr(cond);
302 vis.visit_block(block);
303 }
304 ExprKind::Err | ExprKind::Hole | ExprKind::Lit(_) => {}
305 }
306}
307
308pub fn walk_pat(vis: &mut impl MutVisitor, pat: &mut Pat) {
309 vis.visit_span(&mut pat.span);
310
311 match &mut *pat.kind {
312 PatKind::Bind(name, ty) => {
313 vis.visit_ident(name);
314 ty.iter_mut().for_each(|t| vis.visit_ty(t));
315 }
316 PatKind::Discard(ty) => ty.iter_mut().for_each(|t| vis.visit_ty(t)),
317 PatKind::Elided | PatKind::Err => {}
318 PatKind::Paren(pat) => vis.visit_pat(pat),
319 PatKind::Tuple(pats) => pats.iter_mut().for_each(|p| vis.visit_pat(p)),
320 }
321}
322
323pub fn walk_qubit_init(vis: &mut impl MutVisitor, init: &mut QubitInit) {
324 vis.visit_span(&mut init.span);
325
326 match &mut *init.kind {
327 QubitInitKind::Array(len) => vis.visit_expr(len),
328 QubitInitKind::Paren(init) => vis.visit_qubit_init(init),
329 QubitInitKind::Single | QubitInitKind::Err => {}
330 QubitInitKind::Tuple(inits) => inits.iter_mut().for_each(|i| vis.visit_qubit_init(i)),
331 }
332}
333
334pub fn walk_path(vis: &mut impl MutVisitor, path: &mut Path) {
335 vis.visit_span(&mut path.span);
336 path.namespace.iter_mut().for_each(|n| vis.visit_ident(n));
337 vis.visit_ident(&mut path.name);
338}
339
340pub fn walk_ident(vis: &mut impl MutVisitor, ident: &mut Ident) {
341 vis.visit_span(&mut ident.span);
342}
343