microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/fix-wasm-logging-issue

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/compiler/qsc_ast/src/mut_visit.rs

472lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::ast::{
5 Attr, Block, CallableBody, CallableDecl, Expr, ExprKind, FieldAccess, FieldAssign, FieldDef,
6 FunctorExpr, FunctorExprKind, Ident, ImportKind, ImportOrExportItem, Item, ItemKind, Namespace,
7 Package, Pat, PatKind, Path, PathKind, QubitInit, QubitInitKind, SpecBody, SpecDecl, Stmt,
8 StmtKind, StringComponent, StructDecl, TopLevelNode, Ty, TyDef, TyDefKind, TyKind,
9 TypeParameter,
10};
11use qsc_data_structures::span::Span;
12
13pub trait MutVisitor: Sized {
14 fn visit_package(&mut self, package: &mut Package) {
15 walk_package(self, package);
16 }
17
18 fn visit_namespace(&mut self, namespace: &mut Namespace) {
19 walk_namespace(self, namespace);
20 }
21
22 fn visit_item(&mut self, item: &mut Item) {
23 walk_item(self, item);
24 }
25
26 fn visit_attr(&mut self, attr: &mut Attr) {
27 walk_attr(self, attr);
28 }
29
30 fn visit_ty_def(&mut self, def: &mut TyDef) {
31 walk_ty_def(self, def);
32 }
33
34 fn visit_callable_decl(&mut self, decl: &mut CallableDecl) {
35 walk_callable_decl(self, decl);
36 }
37
38 fn visit_struct_decl(&mut self, decl: &mut StructDecl) {
39 walk_struct_decl(self, decl);
40 }
41
42 fn visit_import_or_export(&mut self, item: &mut ImportOrExportItem) {
43 walk_import_or_export(self, item);
44 }
45
46 fn visit_field_def(&mut self, def: &mut FieldDef) {
47 walk_field_def(self, def);
48 }
49
50 fn visit_spec_decl(&mut self, decl: &mut SpecDecl) {
51 walk_spec_decl(self, decl);
52 }
53
54 fn visit_functor_expr(&mut self, expr: &mut FunctorExpr) {
55 walk_functor_expr(self, expr);
56 }
57
58 fn visit_ty(&mut self, ty: &mut Ty) {
59 walk_ty(self, ty);
60 }
61
62 fn visit_block(&mut self, block: &mut Block) {
63 walk_block(self, block);
64 }
65
66 fn visit_stmt(&mut self, stmt: &mut Stmt) {
67 walk_stmt(self, stmt);
68 }
69
70 fn visit_expr(&mut self, expr: &mut Expr) {
71 walk_expr(self, expr);
72 }
73
74 fn visit_field_assign(&mut self, assign: &mut FieldAssign) {
75 walk_field_assign(self, assign);
76 }
77
78 fn visit_pat(&mut self, pat: &mut Pat) {
79 walk_pat(self, pat);
80 }
81
82 fn visit_qubit_init(&mut self, init: &mut QubitInit) {
83 walk_qubit_init(self, init);
84 }
85
86 fn visit_path(&mut self, path: &mut Path) {
87 walk_path(self, path);
88 }
89
90 fn visit_path_kind(&mut self, path: &mut PathKind) {
91 walk_path_kind(self, path);
92 }
93
94 fn visit_ident(&mut self, ident: &mut Ident) {
95 walk_ident(self, ident);
96 }
97
98 fn visit_idents(&mut self, ident: &mut [Ident]) {
99 walk_idents(self, ident);
100 }
101
102 fn visit_span(&mut self, _: &mut Span) {}
103}
104
105pub fn walk_package(vis: &mut impl MutVisitor, package: &mut Package) {
106 package.nodes.iter_mut().for_each(|n| match n {
107 TopLevelNode::Namespace(ns) => vis.visit_namespace(ns),
108 TopLevelNode::Stmt(stmt) => vis.visit_stmt(stmt),
109 });
110 package.entry.iter_mut().for_each(|e| vis.visit_expr(e));
111}
112
113pub fn walk_namespace(vis: &mut impl MutVisitor, namespace: &mut Namespace) {
114 vis.visit_span(&mut namespace.span);
115 vis.visit_idents(&mut namespace.name);
116
117 namespace.items.iter_mut().for_each(|i| vis.visit_item(i));
118}
119
120pub fn walk_item(vis: &mut impl MutVisitor, item: &mut Item) {
121 vis.visit_span(&mut item.span);
122 item.attrs.iter_mut().for_each(|a| vis.visit_attr(a));
123
124 match &mut *item.kind {
125 ItemKind::Callable(decl) => vis.visit_callable_decl(decl),
126 ItemKind::Err => {}
127 ItemKind::Open(ns, alias) => {
128 vis.visit_path_kind(ns);
129 for a in alias.iter_mut() {
130 vis.visit_ident(a);
131 }
132 }
133 ItemKind::Ty(ident, def) => {
134 vis.visit_ident(ident);
135 vis.visit_ty_def(def);
136 }
137 ItemKind::Struct(decl) => vis.visit_struct_decl(decl),
138 ItemKind::ImportOrExport(decl) => {
139 vis.visit_span(&mut decl.span);
140 decl.items
141 .iter_mut()
142 .for_each(|item| vis.visit_import_or_export(item));
143 }
144 }
145}
146
147pub fn walk_attr(vis: &mut impl MutVisitor, attr: &mut Attr) {
148 vis.visit_span(&mut attr.span);
149 vis.visit_ident(&mut attr.name);
150 vis.visit_expr(&mut attr.arg);
151}
152
153pub fn walk_ty_def(vis: &mut impl MutVisitor, def: &mut TyDef) {
154 vis.visit_span(&mut def.span);
155
156 match &mut *def.kind {
157 TyDefKind::Field(name, ty, _) => {
158 for n in name.iter_mut() {
159 vis.visit_ident(n);
160 }
161 vis.visit_ty(ty);
162 }
163 TyDefKind::Paren(def) => vis.visit_ty_def(def),
164 TyDefKind::Tuple(defs) => defs.iter_mut().for_each(|d| vis.visit_ty_def(d)),
165 TyDefKind::Err => {}
166 }
167}
168
169pub fn walk_callable_decl(vis: &mut impl MutVisitor, decl: &mut CallableDecl) {
170 vis.visit_span(&mut decl.span);
171 vis.visit_ident(&mut decl.name);
172 decl.generics.iter_mut().for_each(|p| {
173 vis.visit_ident(&mut p.ty);
174 p.constraints.0.iter_mut().for_each(|b| {
175 vis.visit_ident(&mut b.name);
176 b.parameters
177 .iter_mut()
178 .for_each(|crate::ast::ConstraintParameter { ty, .. }| {
179 vis.visit_ty(ty);
180 });
181 });
182 });
183 vis.visit_pat(&mut decl.input);
184 vis.visit_ty(&mut decl.output);
185 decl.functors
186 .iter_mut()
187 .for_each(|f| vis.visit_functor_expr(f));
188
189 match &mut *decl.body {
190 CallableBody::Block(block) => vis.visit_block(block),
191 CallableBody::Specs(specs) => specs.iter_mut().for_each(|s| vis.visit_spec_decl(s)),
192 }
193}
194
195pub fn walk_struct_decl(vis: &mut impl MutVisitor, decl: &mut StructDecl) {
196 vis.visit_span(&mut decl.span);
197 vis.visit_ident(&mut decl.name);
198 decl.fields.iter_mut().for_each(|f| vis.visit_field_def(f));
199}
200
201pub fn walk_import_or_export(vis: &mut impl MutVisitor, item: &mut ImportOrExportItem) {
202 vis.visit_span(&mut item.span);
203 vis.visit_path_kind(&mut item.path);
204 if let ImportKind::Direct { alias: Some(alias) } = &mut item.kind {
205 vis.visit_ident(alias);
206 }
207}
208
209pub fn walk_field_def(vis: &mut impl MutVisitor, def: &mut FieldDef) {
210 vis.visit_span(&mut def.span);
211 vis.visit_ident(&mut def.name);
212 vis.visit_ty(&mut def.ty);
213}
214
215pub fn walk_spec_decl(vis: &mut impl MutVisitor, decl: &mut SpecDecl) {
216 vis.visit_span(&mut decl.span);
217
218 match &mut decl.body {
219 SpecBody::Gen(_) => {}
220 SpecBody::Impl(pat, block) => {
221 vis.visit_pat(pat);
222 vis.visit_block(block);
223 }
224 }
225}
226
227pub fn walk_functor_expr(vis: &mut impl MutVisitor, expr: &mut FunctorExpr) {
228 vis.visit_span(&mut expr.span);
229
230 match &mut *expr.kind {
231 FunctorExprKind::BinOp(_, lhs, rhs) => {
232 vis.visit_functor_expr(lhs);
233 vis.visit_functor_expr(rhs);
234 }
235 FunctorExprKind::Lit(_) => {}
236 FunctorExprKind::Paren(expr) => vis.visit_functor_expr(expr),
237 }
238}
239
240pub fn walk_ty(vis: &mut impl MutVisitor, ty: &mut Ty) {
241 vis.visit_span(&mut ty.span);
242
243 match &mut *ty.kind {
244 TyKind::Array(item) => vis.visit_ty(item),
245 TyKind::Arrow(_, lhs, rhs, functors) => {
246 vis.visit_ty(lhs);
247 vis.visit_ty(rhs);
248 for f in functors.iter_mut() {
249 vis.visit_functor_expr(f);
250 }
251 }
252 TyKind::Hole | TyKind::Err => {}
253 TyKind::Paren(ty) => vis.visit_ty(ty),
254 TyKind::Param(TypeParameter {
255 ty,
256 constraints: bounds,
257 ..
258 }) => {
259 for bound in &mut bounds.0 {
260 vis.visit_ident(&mut bound.name);
261 bound.parameters.iter_mut().for_each(
262 |crate::ast::ConstraintParameter { ty, .. }| {
263 vis.visit_ty(ty);
264 },
265 );
266 }
267 vis.visit_ident(ty);
268 }
269 TyKind::Path(path) => vis.visit_path_kind(path),
270 TyKind::Tuple(tys) => tys.iter_mut().for_each(|t| vis.visit_ty(t)),
271 }
272}
273
274pub fn walk_block(vis: &mut impl MutVisitor, block: &mut Block) {
275 vis.visit_span(&mut block.span);
276 block.stmts.iter_mut().for_each(|s| vis.visit_stmt(s));
277}
278
279pub fn walk_stmt(vis: &mut impl MutVisitor, stmt: &mut Stmt) {
280 vis.visit_span(&mut stmt.span);
281
282 match &mut *stmt.kind {
283 StmtKind::Empty | StmtKind::Err => {}
284 StmtKind::Expr(expr) | StmtKind::Semi(expr) => vis.visit_expr(expr),
285 StmtKind::Item(item) => vis.visit_item(item),
286 StmtKind::Local(_, pat, value) => {
287 vis.visit_pat(pat);
288 vis.visit_expr(value);
289 }
290 StmtKind::Qubit(_, pat, init, block) => {
291 vis.visit_pat(pat);
292 vis.visit_qubit_init(init);
293 for b in block.iter_mut() {
294 vis.visit_block(b);
295 }
296 }
297 }
298}
299
300#[allow(clippy::too_many_lines)]
301pub fn walk_expr(vis: &mut impl MutVisitor, expr: &mut Expr) {
302 vis.visit_span(&mut expr.span);
303
304 match &mut *expr.kind {
305 ExprKind::Array(exprs) => exprs.iter_mut().for_each(|e| vis.visit_expr(e)),
306 ExprKind::ArrayRepeat(item, size) => {
307 vis.visit_expr(item);
308 vis.visit_expr(size);
309 }
310 ExprKind::Assign(lhs, rhs)
311 | ExprKind::AssignOp(_, lhs, rhs)
312 | ExprKind::BinOp(_, lhs, rhs) => {
313 vis.visit_expr(lhs);
314 vis.visit_expr(rhs);
315 }
316 ExprKind::AssignUpdate(record, index, value) => {
317 vis.visit_expr(record);
318 vis.visit_expr(index);
319 vis.visit_expr(value);
320 }
321 ExprKind::Block(block) => vis.visit_block(block),
322 ExprKind::Call(callee, arg) => {
323 vis.visit_expr(callee);
324 vis.visit_expr(arg);
325 }
326 ExprKind::Conjugate(within, apply) => {
327 vis.visit_block(within);
328 vis.visit_block(apply);
329 }
330 ExprKind::Fail(msg) => vis.visit_expr(msg),
331 ExprKind::Field(record, name) => {
332 vis.visit_expr(record);
333 if let FieldAccess::Ok(name) = name {
334 vis.visit_ident(name);
335 }
336 }
337 ExprKind::For(pat, iter, block) => {
338 vis.visit_pat(pat);
339 vis.visit_expr(iter);
340 vis.visit_block(block);
341 }
342 ExprKind::If(cond, body, otherwise) => {
343 vis.visit_expr(cond);
344 vis.visit_block(body);
345 for e in otherwise.iter_mut() {
346 vis.visit_expr(e);
347 }
348 }
349 ExprKind::Index(array, index) => {
350 vis.visit_expr(array);
351 vis.visit_expr(index);
352 }
353 ExprKind::Interpolate(components) => {
354 for component in components.iter_mut() {
355 match component {
356 StringComponent::Expr(expr) => vis.visit_expr(expr.as_mut()),
357 StringComponent::Lit(_) => {}
358 }
359 }
360 }
361 ExprKind::Lambda(_, pat, expr) => {
362 vis.visit_pat(pat);
363 vis.visit_expr(expr);
364 }
365 ExprKind::Paren(expr) | ExprKind::Return(expr) | ExprKind::UnOp(_, expr) => {
366 vis.visit_expr(expr);
367 }
368 ExprKind::Path(path) => vis.visit_path_kind(path),
369 ExprKind::Range(start, step, end) => {
370 for s in start.iter_mut() {
371 vis.visit_expr(s);
372 }
373 for s in step.iter_mut() {
374 vis.visit_expr(s);
375 }
376 for e in end.iter_mut() {
377 vis.visit_expr(e);
378 }
379 }
380 ExprKind::Repeat(body, until, fixup) => {
381 vis.visit_block(body);
382 vis.visit_expr(until);
383 for f in fixup.iter_mut() {
384 vis.visit_block(f);
385 }
386 }
387 ExprKind::Struct(name, copy, fields) => {
388 vis.visit_path_kind(name);
389 for c in copy.iter_mut() {
390 vis.visit_expr(c);
391 }
392 fields.iter_mut().for_each(|f| vis.visit_field_assign(f));
393 }
394 ExprKind::TernOp(_, e1, e2, e3) => {
395 vis.visit_expr(e1);
396 vis.visit_expr(e2);
397 vis.visit_expr(e3);
398 }
399 ExprKind::Tuple(exprs) => exprs.iter_mut().for_each(|e| vis.visit_expr(e)),
400 ExprKind::While(cond, block) => {
401 vis.visit_expr(cond);
402 vis.visit_block(block);
403 }
404 ExprKind::Err | ExprKind::Hole | ExprKind::Lit(_) => {}
405 }
406}
407
408pub fn walk_field_assign(vis: &mut impl MutVisitor, assign: &mut FieldAssign) {
409 vis.visit_span(&mut assign.span);
410 vis.visit_ident(&mut assign.field);
411 vis.visit_expr(&mut assign.value);
412}
413
414pub fn walk_pat(vis: &mut impl MutVisitor, pat: &mut Pat) {
415 vis.visit_span(&mut pat.span);
416
417 match &mut *pat.kind {
418 PatKind::Bind(name, ty) => {
419 vis.visit_ident(name);
420 for t in ty.iter_mut() {
421 vis.visit_ty(t);
422 }
423 }
424 PatKind::Discard(ty) => ty.iter_mut().for_each(|t| vis.visit_ty(t)),
425 PatKind::Elided | PatKind::Err => {}
426 PatKind::Paren(pat) => vis.visit_pat(pat),
427 PatKind::Tuple(pats) => pats.iter_mut().for_each(|p| vis.visit_pat(p)),
428 }
429}
430
431pub fn walk_qubit_init(vis: &mut impl MutVisitor, init: &mut QubitInit) {
432 vis.visit_span(&mut init.span);
433
434 match &mut *init.kind {
435 QubitInitKind::Array(len) => vis.visit_expr(len),
436 QubitInitKind::Paren(init) => vis.visit_qubit_init(init),
437 QubitInitKind::Single | QubitInitKind::Err => {}
438 QubitInitKind::Tuple(inits) => inits.iter_mut().for_each(|i| vis.visit_qubit_init(i)),
439 }
440}
441
442pub fn walk_path(vis: &mut impl MutVisitor, path: &mut Path) {
443 vis.visit_span(&mut path.span);
444 if let Some(ref mut parts) = path.segments {
445 vis.visit_idents(parts);
446 }
447 vis.visit_ident(&mut path.name);
448}
449
450pub fn walk_path_kind(vis: &mut impl MutVisitor, path: &mut PathKind) {
451 match path {
452 PathKind::Ok(path) => vis.visit_path(path),
453 PathKind::Err(Some(incomplete_path)) => {
454 vis.visit_span(&mut incomplete_path.span);
455
456 for ref mut ident in &mut incomplete_path.segments {
457 vis.visit_ident(ident);
458 }
459 }
460 PathKind::Err(None) => {}
461 }
462}
463
464pub fn walk_ident(vis: &mut impl MutVisitor, ident: &mut Ident) {
465 vis.visit_span(&mut ident.span);
466}
467
468pub fn walk_idents(vis: &mut impl MutVisitor, idents: &mut [Ident]) {
469 for ref mut ident in idents {
470 vis.visit_ident(ident);
471 }
472}
473