/src/jsonnet/core/pass.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Copyright 2015 Google Inc. All rights reserved. |
3 | | |
4 | | Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | you may not use this file except in compliance with the License. |
6 | | You may obtain a copy of the License at |
7 | | |
8 | | http://www.apache.org/licenses/LICENSE-2.0 |
9 | | |
10 | | Unless required by applicable law or agreed to in writing, software |
11 | | distributed under the License is distributed on an "AS IS" BASIS, |
12 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | See the License for the specific language governing permissions and |
14 | | limitations under the License. |
15 | | */ |
16 | | |
17 | | #include "pass.h" |
18 | | |
19 | | void CompilerPass::fodder(Fodder &fodder) |
20 | 2.06M | { |
21 | 2.06M | for (auto &f : fodder) |
22 | 5.04k | fodderElement(f); |
23 | 2.06M | } |
24 | | |
25 | | void CompilerPass::specs(std::vector<ComprehensionSpec> &specs) |
26 | 0 | { |
27 | 0 | for (auto &spec : specs) { |
28 | 0 | fodder(spec.openFodder); |
29 | 0 | switch (spec.kind) { |
30 | 0 | case ComprehensionSpec::FOR: |
31 | 0 | fodder(spec.varFodder); |
32 | 0 | fodder(spec.inFodder); |
33 | 0 | expr(spec.expr); |
34 | 0 | break; |
35 | 0 | case ComprehensionSpec::IF: expr(spec.expr); break; |
36 | 0 | } |
37 | 0 | } |
38 | 0 | } |
39 | | |
40 | | void CompilerPass::params(Fodder &fodder_l, ArgParams ¶ms, Fodder &fodder_r) |
41 | 2.13k | { |
42 | 2.13k | fodder(fodder_l); |
43 | 4.29k | for (auto ¶m : params) { |
44 | 4.29k | fodder(param.idFodder); |
45 | 4.29k | if (param.expr) { |
46 | 4.29k | fodder(param.eqFodder); |
47 | 4.29k | expr(param.expr); |
48 | 4.29k | } |
49 | 4.29k | fodder(param.commaFodder); |
50 | 4.29k | } |
51 | 2.13k | fodder(fodder_r); |
52 | 2.13k | } |
53 | | |
54 | | void CompilerPass::fieldParams(ObjectField &field) |
55 | 0 | { |
56 | 0 | if (field.methodSugar) { |
57 | 0 | params(field.fodderL, field.params, field.fodderR); |
58 | 0 | } |
59 | 0 | } |
60 | | |
61 | | void CompilerPass::fields(ObjectFields &fields) |
62 | 0 | { |
63 | 0 | for (auto &field : fields) { |
64 | 0 | switch (field.kind) { |
65 | 0 | case ObjectField::LOCAL: { |
66 | 0 | fodder(field.fodder1); |
67 | 0 | fodder(field.fodder2); |
68 | 0 | fieldParams(field); |
69 | 0 | fodder(field.opFodder); |
70 | 0 | expr(field.expr2); |
71 | 0 | } break; |
72 | | |
73 | 0 | case ObjectField::FIELD_ID: |
74 | 0 | case ObjectField::FIELD_STR: |
75 | 0 | case ObjectField::FIELD_EXPR: { |
76 | 0 | if (field.kind == ObjectField::FIELD_ID) { |
77 | 0 | fodder(field.fodder1); |
78 | |
|
79 | 0 | } else if (field.kind == ObjectField::FIELD_STR) { |
80 | 0 | expr(field.expr1); |
81 | |
|
82 | 0 | } else if (field.kind == ObjectField::FIELD_EXPR) { |
83 | 0 | fodder(field.fodder1); |
84 | 0 | expr(field.expr1); |
85 | 0 | fodder(field.fodder2); |
86 | 0 | } |
87 | 0 | fieldParams(field); |
88 | 0 | fodder(field.opFodder); |
89 | 0 | expr(field.expr2); |
90 | |
|
91 | 0 | } break; |
92 | | |
93 | 0 | case ObjectField::ASSERT: { |
94 | 0 | fodder(field.fodder1); |
95 | 0 | expr(field.expr2); |
96 | 0 | if (field.expr3 != nullptr) { |
97 | 0 | fodder(field.opFodder); |
98 | 0 | expr(field.expr3); |
99 | 0 | } |
100 | 0 | } break; |
101 | 0 | } |
102 | | |
103 | 0 | fodder(field.commaFodder); |
104 | 0 | } |
105 | 0 | } |
106 | | |
107 | | void CompilerPass::expr(AST *&ast_) |
108 | 1.64M | { |
109 | 1.64M | fodder(ast_->openFodder); |
110 | 1.64M | visitExpr(ast_); |
111 | 1.64M | } |
112 | | |
113 | | void CompilerPass::visit(Apply *ast) |
114 | 2.13k | { |
115 | 2.13k | expr(ast->target); |
116 | 2.13k | params(ast->fodderL, ast->args, ast->fodderR); |
117 | 2.13k | if (ast->tailstrict) { |
118 | 108 | fodder(ast->tailstrictFodder); |
119 | 108 | } |
120 | 2.13k | } |
121 | | |
122 | | void CompilerPass::visit(ApplyBrace *ast) |
123 | 0 | { |
124 | 0 | expr(ast->left); |
125 | 0 | expr(ast->right); |
126 | 0 | } |
127 | | |
128 | | void CompilerPass::visit(Array *ast) |
129 | 27.8k | { |
130 | 27.8k | for (auto &element : ast->elements) { |
131 | 18.5k | expr(element.expr); |
132 | 18.5k | fodder(element.commaFodder); |
133 | 18.5k | } |
134 | 27.8k | fodder(ast->closeFodder); |
135 | 27.8k | } |
136 | | |
137 | | void CompilerPass::visit(ArrayComprehension *ast) |
138 | 0 | { |
139 | 0 | expr(ast->body); |
140 | 0 | fodder(ast->commaFodder); |
141 | 0 | specs(ast->specs); |
142 | 0 | fodder(ast->closeFodder); |
143 | 0 | } |
144 | | |
145 | | void CompilerPass::visit(Assert *ast) |
146 | 0 | { |
147 | 0 | expr(ast->cond); |
148 | 0 | if (ast->message != nullptr) { |
149 | 0 | fodder(ast->colonFodder); |
150 | 0 | expr(ast->message); |
151 | 0 | } |
152 | 0 | fodder(ast->semicolonFodder); |
153 | 0 | expr(ast->rest); |
154 | 0 | } |
155 | | |
156 | | void CompilerPass::visit(Binary *ast) |
157 | 202k | { |
158 | 202k | expr(ast->left); |
159 | 202k | fodder(ast->opFodder); |
160 | 202k | expr(ast->right); |
161 | 202k | } |
162 | | |
163 | | void CompilerPass::visit(Conditional *ast) |
164 | 67.0k | { |
165 | 67.0k | expr(ast->cond); |
166 | 67.0k | fodder(ast->thenFodder); |
167 | 67.0k | if (ast->branchFalse != nullptr) { |
168 | 67.0k | expr(ast->branchTrue); |
169 | 67.0k | fodder(ast->elseFodder); |
170 | 67.0k | expr(ast->branchFalse); |
171 | 67.0k | } else { |
172 | 0 | expr(ast->branchTrue); |
173 | 0 | } |
174 | 67.0k | } |
175 | | |
176 | | void CompilerPass::visit(Error *ast) |
177 | 225 | { |
178 | 225 | expr(ast->expr); |
179 | 225 | } |
180 | | |
181 | | void CompilerPass::visit(Function *ast) |
182 | 0 | { |
183 | 0 | params(ast->parenLeftFodder, ast->params, ast->parenRightFodder); |
184 | 0 | expr(ast->body); |
185 | 0 | } |
186 | | |
187 | | void CompilerPass::visit(Import *ast) |
188 | 0 | { |
189 | 0 | visit(ast->file); |
190 | 0 | } |
191 | | |
192 | | void CompilerPass::visit(Importstr *ast) |
193 | 0 | { |
194 | 0 | visit(ast->file); |
195 | 0 | } |
196 | | |
197 | | void CompilerPass::visit(InSuper *ast) |
198 | 30.5k | { |
199 | 30.5k | expr(ast->element); |
200 | 30.5k | } |
201 | | |
202 | | void CompilerPass::visit(Index *ast) |
203 | 2.16k | { |
204 | 2.16k | expr(ast->target); |
205 | 2.16k | if (ast->id != nullptr) { |
206 | 2.16k | } else { |
207 | 2.16k | if (ast->isSlice) { |
208 | 0 | if (ast->index != nullptr) |
209 | 0 | expr(ast->index); |
210 | 0 | if (ast->end != nullptr) |
211 | 0 | expr(ast->end); |
212 | 0 | if (ast->step != nullptr) |
213 | 0 | expr(ast->step); |
214 | 2.16k | } else { |
215 | 2.16k | expr(ast->index); |
216 | 2.16k | } |
217 | 2.16k | } |
218 | 2.16k | } |
219 | | |
220 | | void CompilerPass::visit(Local *ast) |
221 | 6.30k | { |
222 | 6.30k | assert(ast->binds.size() > 0); |
223 | 6.30k | for (auto &bind : ast->binds) { |
224 | 6.30k | fodder(bind.varFodder); |
225 | 6.30k | if (bind.functionSugar) { |
226 | 0 | params(bind.parenLeftFodder, bind.params, bind.parenRightFodder); |
227 | 0 | } |
228 | 6.30k | fodder(bind.opFodder); |
229 | 6.30k | expr(bind.body); |
230 | 6.30k | fodder(bind.closeFodder); |
231 | 6.30k | } |
232 | 6.30k | expr(ast->body); |
233 | 6.30k | } |
234 | | |
235 | | void CompilerPass::visit(Object *ast) |
236 | 0 | { |
237 | 0 | fields(ast->fields); |
238 | 0 | fodder(ast->closeFodder); |
239 | 0 | } |
240 | | |
241 | | void CompilerPass::visit(DesugaredObject *ast) |
242 | 154k | { |
243 | 154k | for (AST *assert : ast->asserts) { |
244 | 108 | expr(assert); |
245 | 108 | } |
246 | 154k | for (auto &field : ast->fields) { |
247 | 66.9k | expr(field.name); |
248 | 66.9k | expr(field.body); |
249 | 66.9k | } |
250 | 154k | } |
251 | | |
252 | | void CompilerPass::visit(ObjectComprehension *ast) |
253 | 0 | { |
254 | 0 | fields(ast->fields); |
255 | 0 | specs(ast->specs); |
256 | 0 | fodder(ast->closeFodder); |
257 | 0 | } |
258 | | |
259 | | void CompilerPass::visit(ObjectComprehensionSimple *ast) |
260 | 0 | { |
261 | 0 | expr(ast->field); |
262 | 0 | expr(ast->value); |
263 | 0 | expr(ast->array); |
264 | 0 | } |
265 | | |
266 | | void CompilerPass::visit(Parens *ast) |
267 | 0 | { |
268 | 0 | expr(ast->expr); |
269 | 0 | fodder(ast->closeFodder); |
270 | 0 | } |
271 | | |
272 | | void CompilerPass::visit(SuperIndex *ast) |
273 | 31.0k | { |
274 | 31.0k | if (ast->id != nullptr) { |
275 | 31.0k | } else { |
276 | 31.0k | expr(ast->index); |
277 | 31.0k | } |
278 | 31.0k | } |
279 | | |
280 | | void CompilerPass::visit(Unary *ast) |
281 | 753k | { |
282 | 753k | expr(ast->expr); |
283 | 753k | } |
284 | | |
285 | | #define VISIT(var,astType,astClass) \ |
286 | 1.64M | case astType: { \ |
287 | 1.64M | assert(dynamic_cast<astClass *>(var)); \ |
288 | 1.64M | auto *ast = static_cast<astClass *>(var); \ |
289 | 1.64M | visit(ast); \ |
290 | 1.64M | } break |
291 | | |
292 | | void CompilerPass::visitExpr(AST *&ast_) |
293 | 1.64M | { |
294 | 1.64M | switch(ast_->type) { |
295 | 2.13k | VISIT(ast_, AST_APPLY, Apply); |
296 | 0 | VISIT(ast_, AST_APPLY_BRACE, ApplyBrace); |
297 | 27.8k | VISIT(ast_, AST_ARRAY, Array); |
298 | 0 | VISIT(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehension); |
299 | | // VISIT(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehensionSimple); |
300 | 0 | VISIT(ast_, AST_ASSERT, Assert); |
301 | 202k | VISIT(ast_, AST_BINARY, Binary); |
302 | 0 | VISIT(ast_, AST_BUILTIN_FUNCTION, BuiltinFunction); |
303 | 67.0k | VISIT(ast_, AST_CONDITIONAL, Conditional); |
304 | 154k | VISIT(ast_, AST_DESUGARED_OBJECT, DesugaredObject); |
305 | 0 | VISIT(ast_, AST_DOLLAR, Dollar); |
306 | 225 | VISIT(ast_, AST_ERROR, Error); |
307 | 0 | VISIT(ast_, AST_FUNCTION, Function); |
308 | 0 | VISIT(ast_, AST_IMPORT, Import); |
309 | 0 | VISIT(ast_, AST_IMPORTSTR, Importstr); |
310 | 2.16k | VISIT(ast_, AST_INDEX, Index); |
311 | 30.5k | VISIT(ast_, AST_IN_SUPER, InSuper); |
312 | 108 | VISIT(ast_, AST_LITERAL_BOOLEAN, LiteralBoolean); |
313 | 12 | VISIT(ast_, AST_LITERAL_NULL, LiteralNull); |
314 | 18.1k | VISIT(ast_, AST_LITERAL_NUMBER, LiteralNumber); |
315 | 169k | VISIT(ast_, AST_LITERAL_STRING, LiteralString); |
316 | 6.30k | VISIT(ast_, AST_LOCAL, Local); |
317 | 0 | VISIT(ast_, AST_OBJECT, Object); |
318 | 0 | VISIT(ast_, AST_OBJECT_COMPREHENSION, ObjectComprehension); |
319 | 0 | VISIT(ast_, AST_OBJECT_COMPREHENSION_SIMPLE, ObjectComprehensionSimple); |
320 | 0 | VISIT(ast_, AST_PARENS, Parens); |
321 | 7.36k | VISIT(ast_, AST_SELF, Self); |
322 | 31.0k | VISIT(ast_, AST_SUPER_INDEX, SuperIndex); |
323 | 753k | VISIT(ast_, AST_UNARY, Unary); |
324 | 175k | VISIT(ast_, AST_VAR, Var); |
325 | 0 | default: |
326 | 0 | std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl; |
327 | 0 | std::abort(); |
328 | 0 | break; |
329 | 1.64M | } |
330 | 1.64M | } |
331 | | |
332 | | void CompilerPass::file(AST *&body, Fodder &final_fodder) |
333 | 0 | { |
334 | 0 | expr(body); |
335 | 0 | fodder(final_fodder); |
336 | 0 | } |
337 | | |
338 | | /** A pass that clones the AST it is given. */ |
339 | | class ClonePass : public CompilerPass { |
340 | | public: |
341 | 38.0k | ClonePass(Allocator &alloc) : CompilerPass(alloc) {} |
342 | | virtual void expr(AST *&ast); |
343 | | }; |
344 | | |
345 | | #define CLONE(var,astType,astClass) \ |
346 | 1.17M | case astType: { \ |
347 | 1.17M | assert(dynamic_cast<astClass *>(var)); \ |
348 | 1.17M | auto *ast = static_cast<astClass *>(var); \ |
349 | 1.17M | var = alloc.clone(ast); \ |
350 | 1.17M | } break |
351 | | |
352 | | void ClonePass::expr(AST *&ast_) |
353 | 1.17M | { |
354 | 1.17M | switch(ast_->type) { |
355 | 2.10k | CLONE(ast_, AST_APPLY, Apply); |
356 | 0 | CLONE(ast_, AST_APPLY_BRACE, ApplyBrace); |
357 | 18.5k | CLONE(ast_, AST_ARRAY, Array); |
358 | 0 | CLONE(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehension); |
359 | | // CLONE(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehensionSimple); |
360 | 0 | CLONE(ast_, AST_ASSERT, Assert); |
361 | 145k | CLONE(ast_, AST_BINARY, Binary); |
362 | 0 | CLONE(ast_, AST_BUILTIN_FUNCTION, BuiltinFunction); |
363 | 48.8k | CLONE(ast_, AST_CONDITIONAL, Conditional); |
364 | 113k | CLONE(ast_, AST_DESUGARED_OBJECT, DesugaredObject); |
365 | 0 | CLONE(ast_, AST_DOLLAR, Dollar); |
366 | 150 | CLONE(ast_, AST_ERROR, Error); |
367 | 0 | CLONE(ast_, AST_FUNCTION, Function); |
368 | 0 | CLONE(ast_, AST_IMPORT, Import); |
369 | 0 | CLONE(ast_, AST_IMPORTSTR, Importstr); |
370 | 2.13k | CLONE(ast_, AST_INDEX, Index); |
371 | 30.5k | CLONE(ast_, AST_IN_SUPER, InSuper); |
372 | 72 | CLONE(ast_, AST_LITERAL_BOOLEAN, LiteralBoolean); |
373 | 12 | CLONE(ast_, AST_LITERAL_NULL, LiteralNull); |
374 | 13.5k | CLONE(ast_, AST_LITERAL_NUMBER, LiteralNumber); |
375 | 138k | CLONE(ast_, AST_LITERAL_STRING, LiteralString); |
376 | 6.30k | CLONE(ast_, AST_LOCAL, Local); |
377 | 0 | CLONE(ast_, AST_OBJECT, Object); |
378 | 0 | CLONE(ast_, AST_OBJECT_COMPREHENSION, ObjectComprehension); |
379 | 0 | CLONE(ast_, AST_OBJECT_COMPREHENSION_SIMPLE, ObjectComprehensionSimple); |
380 | 0 | CLONE(ast_, AST_PARENS, Parens); |
381 | 7.36k | CLONE(ast_, AST_SELF, Self); |
382 | 31.0k | CLONE(ast_, AST_SUPER_INDEX, SuperIndex); |
383 | 502k | CLONE(ast_, AST_UNARY, Unary); |
384 | 112k | CLONE(ast_, AST_VAR, Var); |
385 | 0 | default: |
386 | 0 | std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl; |
387 | 0 | std::abort(); |
388 | 0 | break; |
389 | 1.17M | } |
390 | | |
391 | 1.17M | CompilerPass::expr(ast_); |
392 | 1.17M | } |
393 | | |
394 | | AST *clone_ast(Allocator &alloc, AST *ast) |
395 | 38.0k | { |
396 | 38.0k | AST *r = ast; |
397 | 38.0k | ClonePass(alloc).expr(r); |
398 | 38.0k | return r; |
399 | 38.0k | } |