microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.25.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/compiler/qsc_fir/src/mut_visit.rs

225lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::fir::{
5 Block, BlockId, CallableDecl, CallableImpl, Expr, ExprId, ExprKind, FieldAssign, Ident, Item,
6 ItemKind, Package, Pat, PatId, PatKind, SpecDecl, SpecImpl, Stmt, StmtId, StmtKind,
7 StringComponent,
8};
9
10pub trait MutVisitor<'a>: Sized {
11 fn visit_package(&mut self, package: &'a mut Package) {
12 walk_package(self, package);
13 }
14
15 fn visit_item(&mut self, item: &'a mut Item) {
16 walk_item(self, item);
17 }
18
19 fn visit_callable_decl(&mut self, decl: &'a mut CallableDecl) {
20 walk_callable_decl(self, decl);
21 }
22
23 fn visit_callable_impl(&mut self, callable_impl: &'a mut CallableImpl) {
24 walk_callable_impl(self, callable_impl);
25 }
26
27 fn visit_spec_impl(&mut self, spec_impl: &'a mut SpecImpl) {
28 walk_spec_impl(self, spec_impl);
29 }
30
31 fn visit_spec_decl(&mut self, decl: &'a mut SpecDecl) {
32 walk_spec_decl(self, decl);
33 }
34
35 fn visit_block(&mut self, block: BlockId) {
36 walk_block(self, block);
37 }
38
39 fn visit_stmt(&mut self, stmt: StmtId) {
40 walk_stmt(self, stmt);
41 }
42
43 fn visit_expr(&mut self, expr: ExprId) {
44 walk_expr(self, expr);
45 }
46
47 fn visit_pat(&mut self, pat: PatId) {
48 walk_pat(self, pat);
49 }
50
51 fn visit_ident(&mut self, _: &'a mut Ident) {}
52
53 fn get_block(&mut self, id: BlockId) -> &'a mut Block;
54 fn get_expr(&mut self, id: ExprId) -> &'a mut Expr;
55 fn get_pat(&mut self, id: PatId) -> &'a mut Pat;
56 fn get_stmt(&mut self, id: StmtId) -> &'a mut Stmt;
57}
58
59pub fn walk_package<'a>(vis: &mut impl MutVisitor<'a>, package: &'a mut Package) {
60 package.items.values_mut().for_each(|i| vis.visit_item(i));
61 package.entry.iter_mut().for_each(|e| vis.visit_expr(*e));
62}
63
64pub fn walk_item<'a>(vis: &mut impl MutVisitor<'a>, item: &'a mut Item) {
65 match &mut item.kind {
66 ItemKind::Callable(decl) => vis.visit_callable_decl(decl),
67 ItemKind::Namespace(name, _) | ItemKind::Ty(name, _) | ItemKind::Export(name, _) => {
68 vis.visit_ident(name);
69 }
70 }
71}
72
73pub fn walk_callable_decl<'a>(vis: &mut impl MutVisitor<'a>, decl: &'a mut CallableDecl) {
74 vis.visit_ident(&mut decl.name);
75 vis.visit_pat(decl.input);
76 vis.visit_callable_impl(&mut decl.implementation);
77}
78
79pub fn walk_callable_impl<'a>(vis: &mut impl MutVisitor<'a>, callable_impl: &'a mut CallableImpl) {
80 match callable_impl {
81 CallableImpl::Intrinsic => {}
82 CallableImpl::Spec(spec_impl) => {
83 vis.visit_spec_impl(spec_impl);
84 }
85 CallableImpl::SimulatableIntrinsic(spec_decl) => {
86 vis.visit_spec_decl(spec_decl);
87 }
88 }
89}
90
91pub fn walk_spec_impl<'a>(vis: &mut impl MutVisitor<'a>, spec_impl: &'a mut SpecImpl) {
92 vis.visit_spec_decl(&mut spec_impl.body);
93 spec_impl
94 .adj
95 .iter_mut()
96 .for_each(|spec| vis.visit_spec_decl(spec));
97 spec_impl
98 .ctl
99 .iter_mut()
100 .for_each(|spec| vis.visit_spec_decl(spec));
101 spec_impl
102 .ctl_adj
103 .iter_mut()
104 .for_each(|spec| vis.visit_spec_decl(spec));
105}
106
107pub fn walk_spec_decl<'a>(vis: &mut impl MutVisitor<'a>, decl: &'a mut SpecDecl) {
108 decl.input.iter().for_each(|pat| vis.visit_pat(*pat));
109 vis.visit_block(decl.block);
110}
111
112pub fn walk_block<'a>(vis: &mut impl MutVisitor<'a>, block: BlockId) {
113 let block = vis.get_block(block);
114 block.stmts.iter().for_each(|s| vis.visit_stmt(*s));
115}
116
117pub fn walk_stmt<'a>(vis: &mut impl MutVisitor<'a>, id: StmtId) {
118 let stmt = vis.get_stmt(id);
119 match &mut stmt.kind {
120 StmtKind::Item(_) => {}
121 StmtKind::Expr(expr) | StmtKind::Semi(expr) => vis.visit_expr(*expr),
122 StmtKind::Local(_, pat, value) => {
123 vis.visit_pat(*pat);
124 vis.visit_expr(*value);
125 }
126 }
127}
128
129pub fn walk_expr<'a>(vis: &mut impl MutVisitor<'a>, expr: ExprId) {
130 let expr = vis.get_expr(expr);
131 match &expr.kind {
132 ExprKind::Array(exprs) | ExprKind::ArrayLit(exprs) => {
133 for e in exprs {
134 vis.visit_expr(*e);
135 }
136 }
137 ExprKind::ArrayRepeat(item, size) => {
138 vis.visit_expr(*item);
139 vis.visit_expr(*size);
140 }
141 ExprKind::Assign(lhs, rhs)
142 | ExprKind::AssignOp(_, lhs, rhs)
143 | ExprKind::BinOp(_, lhs, rhs) => {
144 vis.visit_expr(*lhs);
145 vis.visit_expr(*rhs);
146 }
147 ExprKind::AssignField(record, _, replace) | ExprKind::UpdateField(record, _, replace) => {
148 vis.visit_expr(*record);
149 vis.visit_expr(*replace);
150 }
151 ExprKind::AssignIndex(array, index, replace) => {
152 vis.visit_expr(*array);
153 vis.visit_expr(*index);
154 vis.visit_expr(*replace);
155 }
156 ExprKind::Block(block) => vis.visit_block(*block),
157 ExprKind::Call(callee, arg) => {
158 vis.visit_expr(*callee);
159 vis.visit_expr(*arg);
160 }
161 ExprKind::Fail(msg) => vis.visit_expr(*msg),
162 ExprKind::Field(record, _) => vis.visit_expr(*record),
163 ExprKind::If(cond, body, otherwise) => {
164 vis.visit_expr(*cond);
165 vis.visit_expr(*body);
166 if let Some(e) = otherwise {
167 vis.visit_expr(*e);
168 }
169 }
170 ExprKind::Index(array, index) => {
171 vis.visit_expr(*array);
172 vis.visit_expr(*index);
173 }
174 ExprKind::Return(expr) | ExprKind::UnOp(_, expr) => {
175 vis.visit_expr(*expr);
176 }
177 ExprKind::Range(start, step, end) => {
178 if let Some(s) = start {
179 vis.visit_expr(*s);
180 }
181 if let Some(s) = step {
182 vis.visit_expr(*s);
183 }
184 if let Some(e) = end {
185 vis.visit_expr(*e);
186 }
187 }
188 ExprKind::Struct(_, copy, fields) => {
189 if let Some(c) = copy {
190 vis.visit_expr(*c);
191 }
192 for FieldAssign { value, .. } in fields {
193 vis.visit_expr(*value);
194 }
195 }
196 ExprKind::String(components) => {
197 for component in components {
198 match component {
199 StringComponent::Expr(expr) => vis.visit_expr(*expr),
200 StringComponent::Lit(_) => {}
201 }
202 }
203 }
204 ExprKind::UpdateIndex(e1, e2, e3) => {
205 vis.visit_expr(*e1);
206 vis.visit_expr(*e2);
207 vis.visit_expr(*e3);
208 }
209 ExprKind::Tuple(exprs) => exprs.iter().for_each(|e| vis.visit_expr(*e)),
210 ExprKind::While(cond, block) => {
211 vis.visit_expr(*cond);
212 vis.visit_block(*block);
213 }
214 ExprKind::Closure(_, _) | ExprKind::Hole | ExprKind::Lit(_) | ExprKind::Var(_, _) => {}
215 }
216}
217
218pub fn walk_pat<'a>(vis: &mut impl MutVisitor<'a>, pat: PatId) {
219 let pat = vis.get_pat(pat);
220 match &mut pat.kind {
221 PatKind::Bind(name) => vis.visit_ident(name),
222 PatKind::Discard => {}
223 PatKind::Tuple(pats) => pats.iter().for_each(|p| vis.visit_pat(*p)),
224 }
225}
226