microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
billti/qdk-test

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_ast/src/mut_visit.rs

341lines · 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 }
134}
135
136pub fn walk_callable_decl(vis: &mut impl MutVisitor, decl: &mut CallableDecl) {
137 vis.visit_span(&mut decl.span);
138 vis.visit_ident(&mut decl.name);
139 decl.generics.iter_mut().for_each(|p| vis.visit_ident(p));
140 vis.visit_pat(&mut decl.input);
141 vis.visit_ty(&mut decl.output);
142 decl.functors
143 .iter_mut()
144 .for_each(|f| vis.visit_functor_expr(f));
145
146 match &mut *decl.body {
147 CallableBody::Block(block) => vis.visit_block(block),
148 CallableBody::Specs(specs) => specs.iter_mut().for_each(|s| vis.visit_spec_decl(s)),
149 }
150}
151
152pub fn walk_spec_decl(vis: &mut impl MutVisitor, decl: &mut SpecDecl) {
153 vis.visit_span(&mut decl.span);
154
155 match &mut decl.body {
156 SpecBody::Gen(_) => {}
157 SpecBody::Impl(pat, block) => {
158 vis.visit_pat(pat);
159 vis.visit_block(block);
160 }
161 }
162}
163
164pub fn walk_functor_expr(vis: &mut impl MutVisitor, expr: &mut FunctorExpr) {
165 vis.visit_span(&mut expr.span);
166
167 match &mut *expr.kind {
168 FunctorExprKind::BinOp(_, lhs, rhs) => {
169 vis.visit_functor_expr(lhs);
170 vis.visit_functor_expr(rhs);
171 }
172 FunctorExprKind::Lit(_) => {}
173 FunctorExprKind::Paren(expr) => vis.visit_functor_expr(expr),
174 }
175}
176
177pub fn walk_ty(vis: &mut impl MutVisitor, ty: &mut Ty) {
178 vis.visit_span(&mut ty.span);
179
180 match &mut *ty.kind {
181 TyKind::Array(item) => vis.visit_ty(item),
182 TyKind::Arrow(_, lhs, rhs, functors) => {
183 vis.visit_ty(lhs);
184 vis.visit_ty(rhs);
185 functors.iter_mut().for_each(|f| vis.visit_functor_expr(f));
186 }
187 TyKind::Hole => {}
188 TyKind::Paren(ty) => vis.visit_ty(ty),
189 TyKind::Param(name) => vis.visit_ident(name),
190 TyKind::Path(path) => vis.visit_path(path),
191 TyKind::Tuple(tys) => tys.iter_mut().for_each(|t| vis.visit_ty(t)),
192 }
193}
194
195pub fn walk_block(vis: &mut impl MutVisitor, block: &mut Block) {
196 vis.visit_span(&mut block.span);
197 block.stmts.iter_mut().for_each(|s| vis.visit_stmt(s));
198}
199
200pub fn walk_stmt(vis: &mut impl MutVisitor, stmt: &mut Stmt) {
201 vis.visit_span(&mut stmt.span);
202
203 match &mut *stmt.kind {
204 StmtKind::Empty | StmtKind::Err => {}
205 StmtKind::Expr(expr) | StmtKind::Semi(expr) => vis.visit_expr(expr),
206 StmtKind::Item(item) => vis.visit_item(item),
207 StmtKind::Local(_, pat, value) => {
208 vis.visit_pat(pat);
209 vis.visit_expr(value);
210 }
211 StmtKind::Qubit(_, pat, init, block) => {
212 vis.visit_pat(pat);
213 vis.visit_qubit_init(init);
214 block.iter_mut().for_each(|b| vis.visit_block(b));
215 }
216 }
217}
218
219pub fn walk_expr(vis: &mut impl MutVisitor, expr: &mut Expr) {
220 vis.visit_span(&mut expr.span);
221
222 match &mut *expr.kind {
223 ExprKind::Array(exprs) => exprs.iter_mut().for_each(|e| vis.visit_expr(e)),
224 ExprKind::ArrayRepeat(item, size) => {
225 vis.visit_expr(item);
226 vis.visit_expr(size);
227 }
228 ExprKind::Assign(lhs, rhs)
229 | ExprKind::AssignOp(_, lhs, rhs)
230 | ExprKind::BinOp(_, lhs, rhs) => {
231 vis.visit_expr(lhs);
232 vis.visit_expr(rhs);
233 }
234 ExprKind::AssignUpdate(record, index, value) => {
235 vis.visit_expr(record);
236 vis.visit_expr(index);
237 vis.visit_expr(value);
238 }
239 ExprKind::Block(block) => vis.visit_block(block),
240 ExprKind::Call(callee, arg) => {
241 vis.visit_expr(callee);
242 vis.visit_expr(arg);
243 }
244 ExprKind::Conjugate(within, apply) => {
245 vis.visit_block(within);
246 vis.visit_block(apply);
247 }
248 ExprKind::Fail(msg) => vis.visit_expr(msg),
249 ExprKind::Field(record, name) => {
250 vis.visit_expr(record);
251 vis.visit_ident(name);
252 }
253 ExprKind::For(pat, iter, block) => {
254 vis.visit_pat(pat);
255 vis.visit_expr(iter);
256 vis.visit_block(block);
257 }
258 ExprKind::If(cond, body, otherwise) => {
259 vis.visit_expr(cond);
260 vis.visit_block(body);
261 otherwise.iter_mut().for_each(|e| vis.visit_expr(e));
262 }
263 ExprKind::Index(array, index) => {
264 vis.visit_expr(array);
265 vis.visit_expr(index);
266 }
267 ExprKind::Interpolate(components) => {
268 for component in components.iter_mut() {
269 match component {
270 StringComponent::Expr(expr) => vis.visit_expr(expr.as_mut()),
271 StringComponent::Lit(_) => {}
272 }
273 }
274 }
275 ExprKind::Lambda(_, pat, expr) => {
276 vis.visit_pat(pat);
277 vis.visit_expr(expr);
278 }
279 ExprKind::Paren(expr) | ExprKind::Return(expr) | ExprKind::UnOp(_, expr) => {
280 vis.visit_expr(expr);
281 }
282 ExprKind::Path(path) => vis.visit_path(path),
283 ExprKind::Range(start, step, end) => {
284 start.iter_mut().for_each(|s| vis.visit_expr(s));
285 step.iter_mut().for_each(|s| vis.visit_expr(s));
286 end.iter_mut().for_each(|e| vis.visit_expr(e));
287 }
288 ExprKind::Repeat(body, until, fixup) => {
289 vis.visit_block(body);
290 vis.visit_expr(until);
291 fixup.iter_mut().for_each(|f| vis.visit_block(f));
292 }
293 ExprKind::TernOp(_, e1, e2, e3) => {
294 vis.visit_expr(e1);
295 vis.visit_expr(e2);
296 vis.visit_expr(e3);
297 }
298 ExprKind::Tuple(exprs) => exprs.iter_mut().for_each(|e| vis.visit_expr(e)),
299 ExprKind::While(cond, block) => {
300 vis.visit_expr(cond);
301 vis.visit_block(block);
302 }
303 ExprKind::Err | ExprKind::Hole | ExprKind::Lit(_) => {}
304 }
305}
306
307pub fn walk_pat(vis: &mut impl MutVisitor, pat: &mut Pat) {
308 vis.visit_span(&mut pat.span);
309
310 match &mut *pat.kind {
311 PatKind::Bind(name, ty) => {
312 vis.visit_ident(name);
313 ty.iter_mut().for_each(|t| vis.visit_ty(t));
314 }
315 PatKind::Discard(ty) => ty.iter_mut().for_each(|t| vis.visit_ty(t)),
316 PatKind::Elided => {}
317 PatKind::Paren(pat) => vis.visit_pat(pat),
318 PatKind::Tuple(pats) => pats.iter_mut().for_each(|p| vis.visit_pat(p)),
319 }
320}
321
322pub fn walk_qubit_init(vis: &mut impl MutVisitor, init: &mut QubitInit) {
323 vis.visit_span(&mut init.span);
324
325 match &mut *init.kind {
326 QubitInitKind::Array(len) => vis.visit_expr(len),
327 QubitInitKind::Paren(init) => vis.visit_qubit_init(init),
328 QubitInitKind::Single => {}
329 QubitInitKind::Tuple(inits) => inits.iter_mut().for_each(|i| vis.visit_qubit_init(i)),
330 }
331}
332
333pub fn walk_path(vis: &mut impl MutVisitor, path: &mut Path) {
334 vis.visit_span(&mut path.span);
335 path.namespace.iter_mut().for_each(|n| vis.visit_ident(n));
336 vis.visit_ident(&mut path.name);
337}
338
339pub fn walk_ident(vis: &mut impl MutVisitor, ident: &mut Ident) {
340 vis.visit_span(&mut ident.span);
341}
342