microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/pr-review

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_ast/src/mut_visit.rs

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