GCC Code Coverage Report


Directory: ./
File: src/ast/ops/print.cpp
Date: 2023-04-27 00:55:30
Exec Total Coverage
Lines: 604 680 88.8%
Functions: 106 120 88.3%
Branches: 517 647 79.9%

Line Branch Exec Source
1 #include "ast/magic.h"
2 #include "ast/nodes.h"
3 #include "ast/values/native.h"
4 #include "ast/values/object.h"
5 #include "ast/visitor.h"
6 #include "dependencies/fmt.h"
7 #include "lexer/unlex.h"
8 #include "logging/logging.h"
9 #include "parser/parsing_error.h"
10 #include "utilities/allocator.h"
11 #include "utilities/strings.h"
12
13 namespace lython {
14
15 struct PrintTrait {
16 using Trace = std::false_type;
17 using StmtRet = bool;
18 using ExprRet = bool;
19 using ModRet = bool;
20 using PatRet = bool;
21
22 enum
23 { MaxRecursionDepth = LY_MAX_VISITOR_RECURSION_DEPTH };
24 };
25
26 int get_precedence(Node const* node);
27 void print_op(std::ostream& out, UnaryOperator op);
28 void print_op(std::ostream& out, CmpOperator op);
29 void print_op(std::ostream& out, BinaryOperator op, bool aug);
30 void print_op(std::ostream& out, BoolOperator op);
31
32 #define ReturnType bool
33
34 struct PrinterConfig {
35 //
36 int max_line;
37 };
38
39 struct PrinterContext {
40 //
41 };
42
43 // Change this to return strings so we can change the format of partial results
44
45 struct Printer: BaseVisitor<Printer, true, PrintTrait, std::ostream&, int> {
46 using Super = BaseVisitor<Printer, true, PrintTrait, std::ostream&, int>;
47
48 PrinterContext context;
49 String l0;
50 String latest = String(128, ' ');
51
52 String const indent(int level, int scale = 4) {
53
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 227 times.
610 if (level <= 0)
54 383 return l0;
55
56 // one time allocation of an empty string
57 227 latest.resize(std::size_t(scale * level), ' ');
58 227 return latest;
59 }
60
61 void maybe_inline_comment(
62 Comment* com, int depth, std::ostream& out, int level, CodeLocation const& loc) {
63
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 421 times.
583 if (com != nullptr) {
64 // lython::log(lython::LogLevel::Info, loc, "printing inline comment {}", com->comment);
65 162 out << " ";
66 162 exec(com, depth, out, level);
67 }
68 583 }
69
70 StringStream fmt(ExprNode const* node, int depth, int level) {
71 StringStream ss;
72 exec(node, depth, ss, level);
73 return ss;
74 }
75
76 ReturnType print_body(Array<StmtNode*> const& body,
77 int depth,
78 std::ostream& out,
79 int level,
80 bool print_last = false) {
81
82 357 int k = 0;
83
2/2
✓ Branch 5 taken 517 times.
✓ Branch 6 taken 357 times.
874 for (auto const& stmt: body) {
84 517 k += 1;
85
86
2/2
✓ Branch 1 taken 517 times.
✓ Branch 4 taken 517 times.
517 out << indent(level);
87
1/1
✓ Branch 1 taken 517 times.
517 bool printed_new_line = exec(stmt, depth, out, level);
88
89
3/3
✓ Branch 1 taken 517 times.
✓ Branch 3 taken 401 times.
✓ Branch 4 taken 116 times.
517 if (stmt->is_one_line()) {
90 maybe_inline_comment(stmt->comment, depth, out, level, LOC);
91 }
92
93 // out << "\n";
94
1/2
✓ Branch 0 taken 517 times.
✗ Branch 1 not taken.
517 if (!printed_new_line) {
95
6/6
✓ Branch 1 taken 357 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 312 times.
✓ Branch 5 taken 205 times.
✓ Branch 6 taken 312 times.
517 if (k < body.size() || print_last) {
96
1/1
✓ Branch 1 taken 205 times.
205 out << "\n";
97 }
98 }
99 }
100
101 357 return true;
102 }
103
104 ReturnType excepthandler(ExceptHandler const& self, int depth, std::ostream& out, int level) {
105
3/3
✓ Branch 2 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 8 taken 4 times.
4 out << '\n' << indent(level) << "except ";
106
107
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (self.type.has_value()) {
108 4 exec(self.type.value(), depth, out, level);
109 }
110
111
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (self.name.has_value()) {
112 4 out << " as ";
113
2/2
✓ Branch 2 taken 4 times.
✓ Branch 5 taken 4 times.
4 out << self.name.value();
114 }
115
116 4 out << ":";
117 maybe_inline_comment(self.comment, depth, out, level, LOC);
118 4 out << "\n";
119 4 return print_body(self.body, depth, out, level + 1);
120 }
121
122 ReturnType matchcase(MatchCase const& self, int depth, std::ostream& out, int level) {
123
3/3
✓ Branch 1 taken 30 times.
✓ Branch 4 taken 30 times.
✓ Branch 7 taken 30 times.
30 out << indent(level) << "case ";
124 30 exec(self.pattern, depth, out, level);
125
126
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 26 times.
30 if (self.guard.has_value()) {
127 4 out << " if ";
128 4 exec(self.guard.value(), depth, out, level);
129 }
130
131 30 out << ":";
132 maybe_inline_comment(self.comment, depth, out, level, LOC);
133 30 out << "\n";
134 30 return print_body(self.body, depth, out, level + 1);
135 }
136
137 void arguments(Arguments const& self, int depth, std::ostream& out, int level);
138 void withitem(WithItem const& self, int depth, std::ostream& out, int level);
139 void alias(Alias const& self, int depth, std::ostream& out, int level);
140 void keyword(Keyword const& self, int depth, std::ostream& out, int level);
141
142 void arg(Arg const& self, int depth, std::ostream& out, int level) {
143 out << self.arg;
144
145 if (self.annotation.has_value()) {
146 out << ": ";
147 exec(self.annotation.value(), depth, out, level);
148 }
149 }
150 #define FUNCTION_GEN(name, fun, rtype) \
151 rtype fun(const name* node, int depth, std::ostream& out, int level);
152
153 #define X(name, _)
154 #define SECTION(name)
155 #define EXPR(name, fun) FUNCTION_GEN(name, fun, ReturnType)
156 #define STMT(name, fun) FUNCTION_GEN(name, fun, ReturnType)
157 #define MOD(name, fun) FUNCTION_GEN(name, fun, ReturnType)
158 #define MATCH(name, fun) FUNCTION_GEN(name, fun, ReturnType)
159
160 NODEKIND_ENUM(X, SECTION, EXPR, STMT, MOD, MATCH)
161
162 #undef X
163 #undef SECTION
164 #undef EXPR
165 #undef STMT
166 #undef MOD
167 #undef MATCH
168
169 #undef FUNCTION_GEN
170 };
171
172 void comprehension(Printer& p, Comprehension const& self, int depth, std::ostream& out, int level);
173
174 void print(Comprehension const& self, std::ostream& out) {
175
1/1
✓ Branch 1 taken 39 times.
39 Printer p;
176
1/1
✓ Branch 1 taken 39 times.
39 comprehension(p, self, 0, out, 0);
177 39 }
178
179 ReturnType Printer::attribute(Attribute const* self, int depth, std::ostream& out, int level) {
180 16 exec(self->value, depth, out, level);
181 16 out << ".";
182
2/2
✓ Branch 1 taken 16 times.
✓ Branch 4 taken 16 times.
16 out << self->attr;
183 16 return false;
184 }
185
186 ReturnType Printer::subscript(Subscript const* self, int depth, std::ostream& out, int level) {
187 16 exec(self->value, depth, out, level);
188 16 out << "[";
189 16 exec(self->slice, depth, out, level);
190 16 out << "]";
191 16 return false;
192 }
193
194 ReturnType Printer::starred(Starred const* self, int depth, std::ostream& out, int level) {
195 3 out << "*";
196 3 exec(self->value, depth, out, level);
197 3 return false;
198 }
199
200 ReturnType Printer::module(Module const* self, int depth, std::ostream& out, int level) {
201 225 return print_body(self->body, depth, out, level);
202 }
203
204 ReturnType Printer::raise(Raise const* self, int depth, std::ostream& out, int level) {
205 7 out << "raise ";
206
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 if (self->exc.has_value()) {
207 7 exec(self->exc.value(), depth, out, level);
208 }
209
210
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 3 times.
7 if (self->cause.has_value()) {
211 4 out << " from ";
212 4 exec(self->cause.value(), depth, out, level);
213 }
214 7 return false;
215 }
216
217 ReturnType Printer::assertstmt(Assert const* self, int depth, std::ostream& out, int level) {
218 11 out << "assert ";
219 11 exec(self->test, depth, out, level);
220
221
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 4 times.
11 if (self->msg.has_value()) {
222 7 out << ", ";
223 7 exec(self->msg.value(), depth, out, level);
224 }
225 11 return false;
226 }
227
228 ReturnType Printer::with(With const* self, int depth, std::ostream& out, int level) {
229 10 out << "with ";
230
231 10 int i = 0;
232
2/2
✓ Branch 4 taken 20 times.
✓ Branch 5 taken 10 times.
30 for (auto const& item: self->items) {
233
1/1
✓ Branch 1 taken 20 times.
20 exec(item.context_expr, depth, out, level);
234
235
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 if (item.optional_vars.has_value()) {
236
1/1
✓ Branch 1 taken 20 times.
20 out << " as ";
237
1/1
✓ Branch 2 taken 20 times.
20 exec(item.optional_vars.value(), depth, out, level);
238 }
239
240
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 10 times.
20 if (i + 1 < self->items.size()) {
241
1/1
✓ Branch 1 taken 10 times.
10 out << ", ";
242 }
243 20 i += 1;
244 }
245 10 out << ":";
246 maybe_inline_comment(self->comment, depth, out, level, LOC);
247 10 out << "\n";
248
249 10 print_body(self->body, depth, out, level + 1);
250 10 return false;
251 }
252
253 ReturnType Printer::import(Import const* self, int depth, std::ostream& out, int level) {
254 9 out << "import ";
255
256 9 int i = 0;
257
2/2
✓ Branch 4 taken 19 times.
✓ Branch 5 taken 9 times.
28 for (auto const& alias: self->names) {
258
2/2
✓ Branch 1 taken 19 times.
✓ Branch 4 taken 19 times.
19 out << alias.name;
259
260
2/2
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 1 times.
19 if (alias.asname.has_value()) {
261
1/1
✓ Branch 1 taken 18 times.
18 out << " as ";
262
2/2
✓ Branch 2 taken 18 times.
✓ Branch 5 taken 18 times.
18 out << alias.asname.value();
263 }
264
265
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 9 times.
19 if (i + 1 < self->names.size()) {
266
1/1
✓ Branch 1 taken 10 times.
10 out << ", ";
267 }
268 19 i += 1;
269 }
270 9 return false;
271 }
272
273 ReturnType Printer::importfrom(ImportFrom const* self, int depth, std::ostream& out, int level) {
274 6 out << "from ";
275
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 if (self->module.has_value()) {
276
2/2
✓ Branch 2 taken 6 times.
✓ Branch 5 taken 6 times.
6 out << self->module.value();
277 }
278 6 out << " import ";
279
280 6 int i = 0;
281
2/2
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 6 times.
22 for (auto const& alias: self->names) {
282
2/2
✓ Branch 1 taken 16 times.
✓ Branch 4 taken 16 times.
16 out << alias.name;
283
284
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 if (alias.asname.has_value()) {
285
1/1
✓ Branch 1 taken 16 times.
16 out << " as ";
286
2/2
✓ Branch 2 taken 16 times.
✓ Branch 5 taken 16 times.
16 out << alias.asname.value();
287 }
288
289
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 6 times.
16 if (i + 1 < self->names.size()) {
290
1/1
✓ Branch 1 taken 10 times.
10 out << ", ";
291 }
292 16 i += 1;
293 }
294 6 return false;
295 }
296
297 ReturnType Printer::slice(Slice const* self, int depth, std::ostream& out, int level) {
298
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (self->lower.has_value()) {
299 12 exec(self->lower.value(), depth, out, level);
300 }
301
302 12 out << ":";
303
304
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 if (self->upper.has_value()) {
305 12 exec(self->upper.value(), depth, out, level);
306 }
307
308
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
12 if (self->step.has_value()) {
309 out << ":";
310 exec(self->step.value(), depth, out, level);
311 }
312 12 return false;
313 }
314
315 ReturnType Printer::tupleexpr(TupleExpr const* self, int depth, std::ostream& out, int level) {
316
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 5 times.
28 if (level == -1) {
317
3/3
✓ Branch 2 taken 23 times.
✓ Branch 5 taken 23 times.
✓ Branch 8 taken 23 times.
23 out << join<ExprNode*>(", ", self->elts);
318 } else {
319
4/4
✓ Branch 3 taken 5 times.
✓ Branch 6 taken 5 times.
✓ Branch 9 taken 5 times.
✓ Branch 12 taken 5 times.
5 out << "(" << join<ExprNode*>(", ", self->elts) << ")";
320 }
321 28 return false;
322 }
323
324 ReturnType Printer::listexpr(ListExpr const* self, int depth, std::ostream& out, int level) {
325
4/4
✓ Branch 3 taken 11 times.
✓ Branch 6 taken 11 times.
✓ Branch 9 taken 11 times.
✓ Branch 12 taken 11 times.
11 out << "[" << join<ExprNode*>(", ", self->elts) << "]";
326 11 return false;
327 }
328
329 ReturnType Printer::setexpr(SetExpr const* self, int depth, std::ostream& out, int level) {
330
4/4
✓ Branch 3 taken 10 times.
✓ Branch 6 taken 10 times.
✓ Branch 9 taken 10 times.
✓ Branch 12 taken 10 times.
10 out << "{" << join<ExprNode*>(", ", self->elts) << "}";
331 10 return false;
332 }
333
334 ReturnType Printer::dictexpr(DictExpr const* self, int depth, std::ostream& out, int level) {
335 12 Array<String> strs;
336
1/1
✓ Branch 2 taken 12 times.
12 strs.reserve(self->keys.size());
337
338
2/2
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 12 times.
36 for (int i = 0; i < self->keys.size(); i++) {
339
4/4
✓ Branch 2 taken 24 times.
✓ Branch 6 taken 24 times.
✓ Branch 9 taken 24 times.
✓ Branch 12 taken 24 times.
48 strs.push_back(fmtstr("{}: {}", str(self->keys[i]), str(self->values[i])));
340 }
341
342
5/5
✓ Branch 1 taken 12 times.
✓ Branch 5 taken 12 times.
✓ Branch 8 taken 12 times.
✓ Branch 11 taken 12 times.
✓ Branch 14 taken 12 times.
12 out << "{" << join(", ", strs) << "}";
343 12 return false;
344 12 }
345
346 ReturnType Printer::matchvalue(MatchValue const* self, int depth, std::ostream& out, int level) {
347 34 exec(self->value, depth, out, level);
348 34 return false;
349 }
350
351 ReturnType
352 Printer::matchsingleton(MatchSingleton const* self, int depth, std::ostream& out, int level) {
353 8 self->value.print(out);
354 8 return false;
355 }
356
357 ReturnType
358 Printer::matchsequence(MatchSequence const* self, int depth, std::ostream& out, int level) {
359
2/2
✓ Branch 2 taken 8 times.
✓ Branch 5 taken 8 times.
8 auto result = join(", ", self->patterns);
360
3/3
✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 7 taken 8 times.
8 out << "[" << result << "]";
361 8 return false;
362 8 }
363
364 ReturnType
365 Printer::matchmapping(MatchMapping const* self, int depth, std::ostream& out, int level) {
366 4 Array<String> strs;
367
1/1
✓ Branch 2 taken 4 times.
4 strs.reserve(self->keys.size());
368
369
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
6 for (int i = 0; i < self->keys.size(); i++) {
370
4/4
✓ Branch 2 taken 2 times.
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
✓ Branch 12 taken 2 times.
4 strs.push_back(fmtstr("{}: {}", str(self->keys[i]), str(self->patterns[i])));
371 }
372
373 4 String remains;
374
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
4 if (self->rest.has_value()) {
375
1/1
✓ Branch 1 taken 2 times.
2 StringStream ss;
376
3/3
✓ Branch 1 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 8 taken 2 times.
2 ss << ", **" << self->rest.value();
377
1/1
✓ Branch 1 taken 2 times.
2 remains = ss.str();
378 2 }
379
380
6/6
✓ Branch 1 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 8 taken 4 times.
✓ Branch 11 taken 4 times.
✓ Branch 14 taken 4 times.
✓ Branch 17 taken 4 times.
4 out << "{" << join(", ", strs) << remains << "}";
381 4 return false;
382 4 }
383
384 ReturnType Printer::matchclass(MatchClass const* self, int depth, std::ostream& out, int level) {
385
1/1
✓ Branch 1 taken 4 times.
4 exec(self->cls, depth, out, level);
386
4/4
✓ Branch 1 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 8 taken 4 times.
✓ Branch 11 taken 4 times.
4 out << "(" << join(", ", self->patterns);
387
388
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
4 if (!self->patterns.empty() && !self->kwd_attrs.empty()) {
389
1/1
✓ Branch 1 taken 4 times.
4 out << ", ";
390 }
391
392 4 Array<String> kwdpat;
393
1/1
✓ Branch 2 taken 4 times.
4 kwdpat.reserve(self->kwd_attrs.size());
394
395
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 for (int i = 0; i < self->kwd_attrs.size(); i++) {
396
3/3
✓ Branch 2 taken 4 times.
✓ Branch 6 taken 4 times.
✓ Branch 9 taken 4 times.
8 kwdpat.push_back(fmtstr("{}={}", self->kwd_attrs[i], str(self->kwd_patterns[i])));
397 }
398
399
3/3
✓ Branch 2 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 8 taken 4 times.
4 out << join(", ", kwdpat);
400
1/1
✓ Branch 1 taken 4 times.
4 out << ")";
401 4 return false;
402 4 }
403
404 ReturnType Printer::matchstar(MatchStar const* self, int depth, std::ostream& out, int level) {
405 2 out << "*";
406
407
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (self->name.has_value()) {
408
2/2
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
2 out << self->name.value();
409 }
410 2 return false;
411 }
412
413 ReturnType Printer::matchas(MatchAs const* self, int depth, std::ostream& out, int level) {
414
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (self->pattern.has_value()) {
415 4 exec(self->pattern.value(), depth, out, level);
416 }
417
418
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (self->name.has_value()) {
419
2/2
✓ Branch 3 taken 4 times.
✓ Branch 6 taken 4 times.
4 out << " as " << self->name.value();
420 }
421 4 return false;
422 }
423
424 ReturnType Printer::matchor(MatchOr const* self, int depth, std::ostream& out, int level) {
425
3/3
✓ Branch 2 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 8 taken 4 times.
4 out << join(" | ", self->patterns);
426 4 return false;
427 }
428
429 ReturnType Printer::ifstmt(If const* self, int depth, std::ostream& out, int level) {
430 2 out << "if ";
431 2 exec(self->test, depth, out, level);
432 2 out << ":";
433 maybe_inline_comment(self->comment, depth, out, level, LOC);
434 2 out << "\n";
435 2 print_body(self->body, depth, out, level + 1);
436
437
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
4 for (int i = 0; i < self->tests.size(); i++) {
438 2 auto& eliftest = self->tests[i];
439 2 auto& elifbody = self->bodies[i];
440
441
3/3
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 8 taken 2 times.
2 out << "\n" << indent(level) << "elif ";
442
443 2 exec(eliftest, depth, out, level);
444 2 out << ":";
445 maybe_inline_comment(self->tests_comment[i], depth, out, level, LOC);
446 2 out << "\n";
447 2 print_body(elifbody, depth, out, level + 1);
448 }
449
450
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!self->orelse.empty()) {
451
3/3
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 8 taken 2 times.
2 out << "\n" << indent(level) << "else:";
452 maybe_inline_comment(self->else_comment, depth, out, level, LOC);
453 2 out << "\n";
454
455 2 print_body(self->orelse, depth, out, level + 1);
456 }
457 2 return false;
458 }
459
460 ReturnType Printer::match(Match const* self, int depth, std::ostream& out, int level) {
461 9 out << "match ";
462 9 exec(self->subject, depth, out, level);
463 9 out << ":";
464 maybe_inline_comment(self->comment, depth, out, level, LOC);
465 9 out << "\n";
466
467 9 int i = 0;
468
2/2
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 9 times.
39 for (auto const& case_: self->cases) {
469
1/1
✓ Branch 1 taken 30 times.
30 matchcase(case_, depth, out, level + 1);
470
471
2/2
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 9 times.
30 if (i + 1 < self->cases.size()) {
472
1/1
✓ Branch 1 taken 21 times.
21 out << '\n';
473 }
474
475 30 i += 1;
476 }
477 9 return false;
478 }
479
480 ReturnType Printer::lambda(Lambda const* self, int depth, std::ostream& out, int level) {
481 3 out << "lambda ";
482 3 arguments(self->args, depth, out, 0);
483 3 out << ": ";
484 3 exec(self->body, depth, out, level);
485 3 return false;
486 }
487
488 ReturnType Printer::ifexp(IfExp const* self, int depth, std::ostream& out, int level) {
489 5 exec(self->body, depth, out, level);
490 5 out << " if ";
491 5 exec(self->test, depth, out, level);
492 5 out << " else ";
493 5 exec(self->orelse, depth, out, level);
494 5 return false;
495 }
496
497 ReturnType Printer::listcomp(ListComp const* self, int depth, std::ostream& out, int level) {
498 11 out << "[";
499 11 exec(self->elt, depth, out, level);
500
501
3/3
✓ Branch 2 taken 11 times.
✓ Branch 5 taken 11 times.
✓ Branch 8 taken 11 times.
11 out << join(" ", self->generators);
502
503 11 out << "]";
504 11 return false;
505 }
506
507 ReturnType Printer::setcomp(SetComp const* self, int depth, std::ostream& out, int level) {
508 11 out << "{";
509 11 exec(self->elt, depth, out, level);
510
511
3/3
✓ Branch 2 taken 11 times.
✓ Branch 5 taken 11 times.
✓ Branch 8 taken 11 times.
11 out << join(" ", self->generators);
512
513 11 out << "}";
514 11 return false;
515 }
516
517 ReturnType
518 Printer::generateexpr(GeneratorExp const* self, int depth, std::ostream& out, int level) {
519 11 out << "(";
520 11 exec(self->elt, depth, out, level);
521
522
3/3
✓ Branch 2 taken 11 times.
✓ Branch 5 taken 11 times.
✓ Branch 8 taken 11 times.
11 out << join(" ", self->generators);
523
524 11 out << ")";
525 11 return false;
526 }
527
528 ReturnType Printer::dictcomp(DictComp const* self, int depth, std::ostream& out, int level) {
529 6 out << "{";
530 6 exec(self->key, depth, out, level);
531 6 out << ": ";
532 6 exec(self->value, depth, out, level);
533
534
3/3
✓ Branch 2 taken 6 times.
✓ Branch 5 taken 6 times.
✓ Branch 8 taken 6 times.
6 out << join(" ", self->generators);
535 6 out << "}";
536 6 return false;
537 }
538
539 ReturnType Printer::await(Await const* self, int depth, std::ostream& out, int level) {
540 4 out << "await ";
541 4 exec(self->value, depth, out, level);
542 4 return false;
543 }
544
545 ReturnType Printer::yield(Yield const* self, int depth, std::ostream& out, int level) {
546 6 out << "yield";
547
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
6 if (self->value.has_value()) {
548 4 out << " ";
549 4 exec(self->value.value(), depth, out, level);
550 }
551 6 return false;
552 }
553
554 ReturnType Printer::yieldfrom(YieldFrom const* self, int depth, std::ostream& out, int level) {
555 3 out << "yield from ";
556 3 exec(self->value, depth, out, level);
557 3 return false;
558 }
559
560 ReturnType Printer::call(Call const* self, int depth, std::ostream& out, int level) {
561
562 // StringStream fname = fmt(self->func, depth, level);
563 // out << fname.str() << "(";
564
565 82 exec(self->func, depth, out, level);
566 82 out << "(";
567
568
2/2
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 82 times.
165 for (int i = 0; i < self->args.size(); i++) {
569 83 exec(self->args[i], depth, out, level);
570
571
6/6
✓ Branch 1 taken 61 times.
✓ Branch 2 taken 22 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 32 times.
✓ Branch 7 taken 51 times.
83 if (i < self->args.size() - 1 || !self->keywords.empty())
572 32 out << ", ";
573 }
574
575
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 82 times.
92 for (int i = 0; i < self->keywords.size(); i++) {
576 10 auto const& key = self->keywords[i];
577
578
2/2
✓ Branch 2 taken 10 times.
✓ Branch 5 taken 10 times.
10 out << self->keywords[i].arg;
579 10 out << "=";
580
581 10 exec(key.value, depth, out, level);
582
583
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if (i < self->keywords.size() - 1)
584 out << ", ";
585 }
586
587 82 out << ")";
588 82 return false;
589 }
590
591 ReturnType Printer::constant(Constant const* self, int depth, std::ostream& out, int level) {
592 497 self->value.print(out);
593 497 return false;
594 }
595
596 ReturnType Printer::namedexpr(NamedExpr const* self, int depth, std::ostream& out, int level) {
597 2 exec(self->target, depth, out, level);
598 2 out << " := ";
599 2 exec(self->value, depth, out, level);
600 2 return false;
601 }
602
603 ReturnType Printer::classdef(ClassDef const* self, int depth, std::ostream& out, int level) {
604 8 int k = 0;
605
2/2
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 8 times.
16 for (auto decorator: self->decorator_list) {
606
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (k > 0) {
607
2/2
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
4 out << indent(level);
608 }
609
610
1/1
✓ Branch 1 taken 8 times.
8 out << "@";
611
1/1
✓ Branch 1 taken 8 times.
8 exec(decorator.expr, depth, out, level);
612 maybe_inline_comment(decorator.comment, depth, out, level, LOC);
613
1/1
✓ Branch 1 taken 8 times.
8 out << "\n";
614 8 k += 1;
615 }
616
617
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 if (!self->decorator_list.empty()) {
618
2/2
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
4 out << indent(level);
619 }
620
621
3/3
✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 7 taken 8 times.
8 out << "class " << self->name;
622
2/2
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
8 if (self->bases.size() + size_t(!self->keywords.empty())) {
623
1/1
✓ Branch 1 taken 4 times.
4 out << '(';
624 }
625
626
3/3
✓ Branch 2 taken 8 times.
✓ Branch 5 taken 8 times.
✓ Branch 8 taken 8 times.
8 out << join<ExprNode*>(", ", self->bases);
627
628
5/6
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 4 times.
8 if (!self->bases.empty() && !self->keywords.empty()) {
629
1/1
✓ Branch 1 taken 4 times.
4 out << ", ";
630 }
631
632 8 Array<String> kwd;
633
1/1
✓ Branch 2 taken 8 times.
8 kwd.reserve(self->keywords.size());
634
635
2/2
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 8 times.
12 for (auto const& kw: self->keywords) {
636
4/4
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
✓ Branch 7 taken 4 times.
✓ Branch 10 taken 4 times.
8 kwd.push_back(fmtstr("{}={}", str(kw.arg), str(kw.value)));
637 }
638
639
3/3
✓ Branch 2 taken 8 times.
✓ Branch 5 taken 8 times.
✓ Branch 8 taken 8 times.
8 out << join(", ", kwd);
640
641
2/2
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
8 if (self->bases.size() + self->keywords.size() > 0) {
642
1/1
✓ Branch 1 taken 4 times.
4 out << ')';
643 }
644
645
1/1
✓ Branch 1 taken 8 times.
8 out << ":";
646 maybe_inline_comment(self->comment, depth, out, level, LOC);
647
1/1
✓ Branch 1 taken 8 times.
8 out << "\n";
648
649
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 if (self->docstring.has_value()) {
650 4 Docstring const& doc = self->docstring.value();
651
5/5
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
✓ Branch 7 taken 4 times.
✓ Branch 10 taken 4 times.
✓ Branch 13 taken 4 times.
4 out << indent(level + 1) << "\"\"\"" << doc.docstring << "\"\"\"";
652
653 maybe_inline_comment(doc.comment, depth, out, level, LOC);
654
1/1
✓ Branch 1 taken 4 times.
4 out << "\n";
655 }
656
657 8 bool assign = false;
658 8 k = 0;
659
2/2
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 8 times.
23 for (auto const& stmt: self->body) {
660
661
4/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 4 times.
24 assign = stmt->kind == NodeKind::Assign || stmt->kind == NodeKind::AnnAssign ||
662
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5 times.
9 stmt->kind == NodeKind::Pass;
663
664 // print an extra line before if not an attribute
665
4/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 4 times.
15 if (k > 0 && !assign) {
666
1/1
✓ Branch 1 taken 3 times.
3 out << "\n";
667 }
668
669
2/2
✓ Branch 1 taken 15 times.
✓ Branch 4 taken 15 times.
15 out << indent(level + 1);
670
1/1
✓ Branch 1 taken 15 times.
15 bool printed_new_line = exec(stmt, depth, out, level + 1);
671
672
3/3
✓ Branch 1 taken 15 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 7 times.
15 if (stmt->is_one_line()) {
673 maybe_inline_comment(stmt->comment, depth, out, level, LOC);
674 }
675
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (!printed_new_line) {
676
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 8 times.
15 if (k + 1 < self->body.size()) {
677
1/1
✓ Branch 1 taken 7 times.
7 out << "\n";
678 }
679 }
680 15 k += 1;
681 }
682 8 return false;
683 8 }
684
685 ReturnType Printer::functiondef(FunctionDef const* self, int depth, std::ostream& out, int level) {
686 45 int k = 0;
687
2/2
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 45 times.
53 for (auto decorator: self->decorator_list) {
688
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (k > 0) {
689
2/2
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 2 times.
2 out << indent(level);
690 }
691
692
1/1
✓ Branch 1 taken 8 times.
8 out << "@";
693
1/1
✓ Branch 1 taken 8 times.
8 exec(decorator.expr, depth, out, level);
694 maybe_inline_comment(decorator.comment, depth, out, level, LOC);
695
1/1
✓ Branch 1 taken 8 times.
8 out << "\n";
696 8 k += 1;
697 }
698
699
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 39 times.
45 if (!self->decorator_list.empty()) {
700
2/2
✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
6 out << indent(level);
701 }
702
703
3/3
✓ Branch 2 taken 45 times.
✓ Branch 5 taken 45 times.
✓ Branch 8 taken 45 times.
45 out << "def " << self->name << "(";
704 45 arguments(self->args, depth, out, level);
705 45 out << ")";
706
707
2/2
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 30 times.
45 if (self->returns.has_value()) {
708 15 out << " -> ";
709 15 exec(self->returns.value(), depth, out, level);
710 }
711
712 45 out << ":";
713 maybe_inline_comment(self->comment, depth, out, level, LOC);
714 45 out << "\n";
715
716
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 40 times.
45 if (self->docstring.has_value()) {
717 5 Docstring const& doc = self->docstring.value();
718
5/5
✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
✓ Branch 7 taken 5 times.
✓ Branch 10 taken 5 times.
✓ Branch 13 taken 5 times.
5 out << indent(level + 1) << "\"\"\"" << doc.docstring << "\"\"\"";
719
720 maybe_inline_comment(doc.comment, depth, out, level, LOC);
721 5 out << "\n";
722 }
723
724 45 print_body(self->body, depth, out, level + 1, true);
725
726 45 out << "\n";
727 45 return false;
728 }
729
730 ReturnType Printer::inlinestmt(Inline const* self, int depth, std::ostream& out, int level) {
731
2/2
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 2 times.
2 out << indent(level);
732
733 2 int k = 0;
734
2/2
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 2 times.
8 for (auto const& stmt: self->body) {
735
1/1
✓ Branch 1 taken 6 times.
6 exec(stmt, depth, out, level);
736
737
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
6 if (k + 1 < self->body.size()) {
738
1/1
✓ Branch 1 taken 4 times.
4 out << "; ";
739 }
740
741 6 k += 1;
742 }
743
744 2 return false;
745 }
746
747 ReturnType Printer::forstmt(For const* self, int depth, std::ostream& out, int level) {
748 16 out << "for ";
749 16 exec(self->target, depth, out, -1);
750 16 out << " in ";
751 16 exec(self->iter, depth, out, -1);
752 16 out << ":";
753
754 maybe_inline_comment(self->comment, depth, out, level, LOC);
755 16 out << "\n";
756
757 16 print_body(self->body, depth, out, level + 1);
758
759
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 14 times.
16 if (!self->orelse.empty()) {
760 2 out << '\n';
761
3/3
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 7 taken 2 times.
2 out << indent(level) << "else:";
762 maybe_inline_comment(self->else_comment, depth, out, level, LOC);
763 2 out << "\n";
764 2 print_body(self->orelse, depth, out, level + 1);
765 }
766
767 16 return false;
768 }
769
770 ReturnType Printer::trystmt(Try const* self, int depth, std::ostream& out, int level) {
771 4 out << "try:";
772 maybe_inline_comment(self->comment, depth, out, level, LOC);
773 4 out << "\n";
774
775 4 print_body(self->body, depth, out, level + 1);
776
777
2/2
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 4 times.
8 for (auto const& handler: self->handlers) {
778
1/1
✓ Branch 1 taken 4 times.
4 excepthandler(handler, depth, out, level);
779 }
780
781
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (!self->orelse.empty()) {
782
3/3
✓ Branch 2 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 8 taken 4 times.
4 out << "\n" << indent(level) << "else:";
783 maybe_inline_comment(self->else_comment, depth, out, level, LOC);
784 4 out << "\n";
785 4 print_body(self->orelse, depth, out, level + 1);
786 }
787
788
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (!self->finalbody.empty()) {
789
3/3
✓ Branch 2 taken 4 times.
✓ Branch 5 taken 4 times.
✓ Branch 8 taken 4 times.
4 out << "\n" << indent(level) << "finally:";
790 maybe_inline_comment(self->finally_comment, depth, out, level, LOC);
791 4 out << "\n";
792 4 print_body(self->finalbody, depth, out, level + 1);
793 }
794
795 4 return false;
796 }
797
798 ReturnType Printer::compare(Compare const* self, int depth, std::ostream& out, int level) {
799 77 exec(self->left, depth, out, level);
800 77 int n = int(self->comparators.size());
801
802
2/2
✓ Branch 1 taken 101 times.
✓ Branch 2 taken 77 times.
178 for (int i = 0; i < self->ops.size(); i++) {
803 101 print_op(out, self->ops[i]);
804
805 // this can happen when the user does not finish writing the expression
806
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 if (i < n) {
807 101 exec(self->comparators[i], depth, out, level);
808 }
809 }
810
811 77 return false;
812 }
813
814 ReturnType Printer::binop(BinOp const* self, int depth, std::ostream& out, int level) {
815 95 auto sself = get_precedence(self);
816 95 auto lhspred = get_precedence(self->left) < sself;
817 95 auto rhspred = get_precedence(self->right) < sself;
818
819
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 94 times.
95 if (lhspred) {
820 1 out << '(';
821 }
822 95 exec(self->left, depth, out, level);
823
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 94 times.
95 if (lhspred) {
824 1 out << ')';
825 }
826
827 95 print_op(out, self->op, false);
828
829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95 times.
95 if (rhspred) {
830 out << '(';
831 }
832 95 exec(self->right, depth, out, level);
833
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95 times.
95 if (rhspred) {
834 out << ')';
835 }
836
837 95 return false;
838 }
839
840 ReturnType
841 Printer::invalidstmt(InvalidStatement const* self, int depth, std::ostream& out, int level) {
842 //
843
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (!self->tokens.empty()) {
844 1 Unlex unlex;
845
1/1
✓ Branch 1 taken 1 times.
1 unlex.format(out, self->tokens);
846 }
847 2 return false;
848 }
849
850 ReturnType Printer::boolop(BoolOp const* self, int depth, std::ostream& out, int level) {
851
852 8 int m = self->opcount + 1;
853
854 8 int n = int(self->values.size());
855
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 8 times.
26 for (int i = 0; i < m; i++) {
856
857
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 if (i < n) {
858 18 exec(self->values[i], depth, out, level);
859 }
860
861
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 8 times.
18 if (i < m - 1) {
862 10 print_op(out, self->op);
863 }
864 }
865
866 8 return false;
867 }
868
869 ReturnType Printer::unaryop(UnaryOp const* self, int depth, std::ostream& out, int level) {
870 9 print_op(out, self->op);
871 9 out << " ";
872 9 exec(self->operand, depth, out, level);
873
874 9 return false;
875 }
876
877 ReturnType Printer::whilestmt(While const* self, int depth, std::ostream& out, int level) {
878 4 out << "while ";
879 4 exec(self->test, depth, out, level);
880 4 out << ":";
881 maybe_inline_comment(self->comment, depth, out, level, LOC);
882 4 out << "\n";
883 4 print_body(self->body, depth, out, level + 1);
884
885
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
4 if (!self->orelse.empty()) {
886
3/3
✓ Branch 2 taken 3 times.
✓ Branch 5 taken 3 times.
✓ Branch 8 taken 3 times.
3 out << '\n' << indent(level) << "else:";
887 maybe_inline_comment(self->else_comment, depth, out, level, LOC);
888 3 out << "\n";
889 3 print_body(self->orelse, depth, out, level + 1);
890 }
891
892 4 return false;
893 }
894
895 ReturnType Printer::returnstmt(Return const* self, int depth, std::ostream& out, int level) {
896 160 out << "return ";
897
898
1/2
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
160 if (self->value.has_value()) {
899 160 exec(self->value.value(), depth, out, -1);
900 }
901
902 160 return false;
903 }
904
905 ReturnType Printer::deletestmt(Delete const* self, int depth, std::ostream& out, int level) {
906 4 out << "del ";
907
908
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 4 times.
12 for (int i = 0; i < self->targets.size(); i++) {
909 8 exec(self->targets[i], depth, out, level);
910
911
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 if (i < self->targets.size() - 1)
912 4 out << ", ";
913 }
914
915 4 return false;
916 }
917
918 ReturnType Printer::augassign(AugAssign const* self, int depth, std::ostream& out, int level) {
919 11 exec(self->target, depth, out, -1);
920 11 print_op(out, self->op, true);
921 11 out << "= ";
922 11 exec(self->value, depth, out, -1);
923 11 return false;
924 }
925
926 ReturnType Printer::assign(Assign const* self, int depth, std::ostream& out, int level) {
927 76 exec(self->targets[0], depth, out, -1);
928 76 out << " = ";
929 76 exec(self->value, depth, out, -1);
930 76 return false;
931 }
932
933 ReturnType Printer::annassign(AnnAssign const* self, int depth, std::ostream& out, int level) {
934 19 exec(self->target, depth, out, level);
935 19 out << ": ";
936
937 19 exec(self->annotation, depth, out, level);
938
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 if (self->value.has_value()) {
939 19 out << " = ";
940 19 exec(self->value.value(), depth, out, level);
941 }
942
943 19 return false;
944 }
945
946 ReturnType Printer::pass(Pass const* self, int depth, std::ostream& out, int level) {
947 62 out << "pass";
948 62 return false;
949 }
950
951 ReturnType Printer::breakstmt(Break const* self, int depth, std::ostream& out, int level) {
952 2 out << "break";
953 2 return false;
954 }
955
956 ReturnType Printer::continuestmt(Continue const* self, int depth, std::ostream& out, int level) {
957 2 out << "continue";
958 2 return false;
959 }
960
961 ReturnType Printer::exprstmt(Expr const* self, int depth, std::ostream& out, int level) {
962
1/2
✓ Branch 0 taken 241 times.
✗ Branch 1 not taken.
241 if (self->value != nullptr)
963 241 exec(self->value, depth, out, -1);
964
965 241 return false;
966 }
967
968 ReturnType Printer::global(Global const* self, int depth, std::ostream& out, int level) {
969
3/3
✓ Branch 3 taken 2 times.
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 out << "global " << join(", ", self->names);
970 2 return false;
971 }
972
973 ReturnType Printer::nonlocal(Nonlocal const* self, int depth, std::ostream& out, int level) {
974
3/3
✓ Branch 3 taken 2 times.
✓ Branch 6 taken 2 times.
✓ Branch 9 taken 2 times.
2 out << "nonlocal " << join(", ", self->names);
975 2 return false;
976 }
977
978 ReturnType Printer::arrow(Arrow const* self, int depth, std::ostream& out, int level) {
979
4/4
✓ Branch 3 taken 233 times.
✓ Branch 6 taken 233 times.
✓ Branch 9 taken 233 times.
✓ Branch 12 taken 233 times.
233 out << '(' << join<ExprNode*>(", ", self->args) << ") -> ";
980
2/2
✓ Branch 1 taken 233 times.
✓ Branch 4 taken 233 times.
233 out << str(self->returns);
981 233 return false;
982 }
983
984 ReturnType Printer::dicttype(DictType const* self, int depth, std::ostream& out, int level) {
985 3 out << "Dict[";
986
2/2
✓ Branch 1 taken 3 times.
✓ Branch 4 taken 3 times.
3 out << str(self->key);
987 3 out << ", ";
988
3/3
✓ Branch 1 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 7 taken 3 times.
3 out << str(self->value) << "]";
989 3 return false;
990 }
991
992 ReturnType Printer::settype(SetType const* self, int depth, std::ostream& out, int level) {
993 3 out << "Set[";
994
3/3
✓ Branch 1 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 7 taken 3 times.
3 out << str(self->value) << "]";
995 3 return false;
996 }
997
998 ReturnType Printer::name(Name const* self, int depth, std::ostream& out, int level) {
999
2/2
✓ Branch 1 taken 2089 times.
✓ Branch 4 taken 2089 times.
2089 out << self->id;
1000 2089 return false;
1001 }
1002
1003 ReturnType Printer::arraytype(ArrayType const* self, int depth, std::ostream& out, int level) {
1004 3 out << "Array[";
1005
3/3
✓ Branch 1 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 7 taken 3 times.
3 out << str(self->value) << "]";
1006 3 return false;
1007 }
1008
1009 ReturnType Printer::tupletype(TupleType const* self, int depth, std::ostream& out, int level) {
1010 1 out << "Tuple[";
1011
4/4
✓ Branch 2 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 11 taken 1 times.
1 out << join<ExprNode*>(", ", self->types) << "]";
1012 1 return false;
1013 }
1014
1015 ReturnType Printer::builtintype(BuiltinType const* self, int depth, std::ostream& out, int level) {
1016
2/2
✓ Branch 1 taken 744 times.
✓ Branch 4 taken 744 times.
744 out << self->name;
1017 744 return false;
1018 }
1019
1020 ReturnType Printer::joinedstr(JoinedStr const* self, int depth, std::ostream& out, int level) {
1021 6 out << "f\"";
1022
1023
2/2
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 6 times.
20 for (auto* val: self->values) {
1024
3/3
✓ Branch 1 taken 14 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 6 times.
14 if (Constant* cst = cast<Constant>(val)) {
1025
1/1
✓ Branch 2 taken 8 times.
8 out << cst->value.get<String>();
1026 } else {
1027
1/1
✓ Branch 1 taken 6 times.
6 exec(val, depth, out, level);
1028 }
1029 }
1030
1031 6 out << '"';
1032 6 return false;
1033 }
1034
1035 ReturnType
1036 Printer::formattedvalue(FormattedValue const* self, int depth, std::ostream& out, int indent) {
1037 6 out << "{";
1038 6 exec(self->value, depth, out, indent);
1039 6 out << ":";
1040
1041
2/2
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 6 times.
16 for (auto* val: self->format_spec->values) {
1042
3/3
✓ Branch 1 taken 10 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 4 times.
10 if (Constant* cst = cast<Constant>(val)) {
1043
1/1
✓ Branch 2 taken 6 times.
6 out << cst->value.get<String>();
1044 } else {
1045
1/1
✓ Branch 1 taken 4 times.
4 out << "{";
1046
1/1
✓ Branch 1 taken 4 times.
4 exec(val, depth, out, indent);
1047
1/1
✓ Branch 1 taken 4 times.
4 out << "}";
1048 }
1049 }
1050
1051 6 out << "}";
1052 6 return false;
1053 }
1054
1055 ReturnType Printer::classtype(ClassType const* self, int depth, std::ostream& out, int level) {
1056 out << self->def->name;
1057 return false;
1058 }
1059
1060 // Helper
1061 // ==================================================
1062
1063 void ConstantValue::print(std::ostream& out) const {
1064
7/16
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 391 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 41 times.
✓ Branch 11 taken 27 times.
✓ Branch 12 taken 8 times.
✓ Branch 13 taken 25 times.
✓ Branch 14 taken 7 times.
✗ Branch 15 not taken.
505 switch (kind) {
1065 6 case TInvalid: out << "<Constant:Invalid>"; break;
1066
1067 case Ti8: out << value.i8; break;
1068 case Ti16: out << value.i16; break;
1069 391 case Ti32: out << value.i32; break;
1070 case Ti64: out << value.i64; break;
1071
1072 case Tu8: out << value.u8; break;
1073 case Tu16: out << value.u16; break;
1074 case Tu32: out << value.u32; break;
1075 case Tu64: out << value.u64; break;
1076
1077 case Tf32: out << value.f32; break;
1078
1079 41 case Tf64:
1080 // always print a float even without decimal point
1081
3/4
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 41 times.
✓ Branch 6 taken 41 times.
82 out << fmtstr("{:#}", value.f64);
1082 41 break;
1083
1084 27 case TBool:
1085
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 10 times.
27 if (value.boolean) {
1086 17 out << "True";
1087 } else {
1088 10 out << "False";
1089 }
1090 27 break;
1091
1092 8 case TNone: out << "None"; break;
1093
1094 25 case TString: out << "\"" << value.string << "\""; break;
1095
1096 7 case TObject: _print_object(out); break;
1097
1098 default: break;
1099 }
1100 505 }
1101
1102 void ConstantValue::_print_object(std::ostream& out) const {
1103
1104
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 if (value.object->class_id == meta::type_id<Object>()) {
1105 7 Array<String> frags;
1106 7 Object const* obj = reinterpret_cast<Object const*>(value.object);
1107
1108
2/2
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 7 times.
21 for (auto const& attr: obj->attributes) {
1109
2/2
✓ Branch 1 taken 14 times.
✓ Branch 4 taken 14 times.
14 frags.push_back(str(attr));
1110 }
1111
1112
7/7
✓ Branch 2 taken 7 times.
✓ Branch 5 taken 7 times.
✓ Branch 9 taken 7 times.
✓ Branch 12 taken 7 times.
✓ Branch 15 taken 7 times.
✓ Branch 19 taken 7 times.
✓ Branch 22 taken 7 times.
7 out << String("(") << join(", ", frags) << String(")");
1113 7 return;
1114 7 }
1115 out << "<object>";
1116 }
1117
1118 String Node::__str__() const {
1119
1/1
✓ Branch 1 taken 2850 times.
2850 StringStream ss;
1120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2850 times.
2850 if (kind <= NodeKind::Invalid) {
1121 kwerror("Node is invalid");
1122 return "<Invalid>";
1123 }
1124
1/1
✓ Branch 1 taken 2850 times.
2850 Printer p;
1125
1/1
✓ Branch 1 taken 2850 times.
2850 p.Super::exec<bool>(this, 0, ss, 0);
1126
1/1
✓ Branch 1 taken 2850 times.
2850 return ss.str();
1127 2850 }
1128
1129 // void Node::print(std::ostream &out, int indent) const {
1130 // out << "<not-implemented:";
1131 // out << str(kind);
1132 // out << ">";
1133 // }
1134
1135 void print_op(std::ostream& out, BoolOperator op) {
1136 // clang-format off
1137
2/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 switch (op) {
1138 4 case BoolOperator::And: out << " and "; return;
1139 6 case BoolOperator::Or: out << " or " ; return;
1140 case BoolOperator::None: out << " <Bool:None> " ; return;
1141 }
1142 // clang-format on
1143 }
1144
1145 void print_op(std::ostream& out, BinaryOperator op, bool aug) {
1146 // clang-format off
1147
6/17
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
106 switch (op) {
1148 62 case BinaryOperator::Add: out << " +"; break;
1149 34 case BinaryOperator::Sub: out << " -"; break;
1150 3 case BinaryOperator::Mult: out << " *"; break;
1151 case BinaryOperator::MatMult: out << " @"; break;
1152 1 case BinaryOperator::Div: out << " /"; break;
1153 case BinaryOperator::Mod: out << " %"; break;
1154 case BinaryOperator::Pow: out << " **"; break;
1155 2 case BinaryOperator::LShift: out << " <<"; break;
1156 case BinaryOperator::RShift: out << " >>"; break;
1157 case BinaryOperator::BitOr: out << " |"; break;
1158 4 case BinaryOperator::BitXor: out << " ^"; break;
1159 case BinaryOperator::BitAnd: out << " &"; break;
1160 case BinaryOperator::FloorDiv: out << " //"; break;
1161 case BinaryOperator::EltMult: out << " .*"; break;
1162 case BinaryOperator::EltDiv: out << " ./"; break;
1163 case BinaryOperator::None: out << " <Binary:None>"; break;
1164 }
1165 // clang-format on
1166
1167
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 11 times.
106 if (!aug) {
1168 95 out << " ";
1169 }
1170 106 }
1171
1172 void print_op(std::ostream& out, CmpOperator op) {
1173 // clang-format off
1174
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 57 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 5 times.
✓ Branch 8 taken 5 times.
✓ Branch 9 taken 5 times.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
101 switch (op) {
1175 case CmpOperator::None: out << " <Cmp:None> "; return;
1176 case CmpOperator::Eq: out << " == "; return;
1177 9 case CmpOperator::NotEq: out << " != "; return;
1178 15 case CmpOperator::Lt: out << " < "; return;
1179 case CmpOperator::LtE: out << " <= "; return;
1180 57 case CmpOperator::Gt: out << " > "; return;
1181 case CmpOperator::GtE: out << " >= "; return;
1182 5 case CmpOperator::Is: out << " is "; return;
1183 5 case CmpOperator::IsNot: out << " is not "; return;
1184 5 case CmpOperator::In: out << " in "; return;
1185 5 case CmpOperator::NotIn: out << " not in "; return;
1186 }
1187 // clang-format on
1188 }
1189
1190 void print_op(std::ostream& out, UnaryOperator op) {
1191 // clang-format off
1192
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
9 switch (op) {
1193 case UnaryOperator::None: out << "<Unary:None>"; return;
1194 2 case UnaryOperator::Invert: out << "~"; return;
1195 2 case UnaryOperator::Not: out << "!"; return;
1196 2 case UnaryOperator::UAdd: out << "+"; return;
1197 3 case UnaryOperator::USub: out << "-"; return;
1198 }
1199 // clang-format on
1200 }
1201
1202 void comprehension(Printer& p, Comprehension const& self, int depth, std::ostream& out, int level) {
1203 39 out << " for ";
1204 39 p.exec(self.target, depth, out, level);
1205 39 out << " in ";
1206 39 p.exec(self.iter, depth, out, level);
1207
1208
2/2
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 39 times.
78 for (auto* expr: self.ifs) {
1209
1/1
✓ Branch 1 taken 39 times.
39 out << " if ";
1210
1/1
✓ Branch 1 taken 39 times.
39 p.exec(expr, depth, out, level);
1211 }
1212 39 }
1213
1214 void Printer::keyword(Keyword const& self, int depth, std::ostream& out, int level) {
1215 out << self.arg;
1216 if (self.value != nullptr) {
1217 out << " = ";
1218 exec(self.value, depth, out, level);
1219 }
1220 }
1221
1222 void Printer::alias(Alias const& self, int depth, std::ostream& out, int level) {
1223 out << self.name;
1224 if (self.asname.has_value()) {
1225 out << " as " << self.asname.value();
1226 }
1227 }
1228
1229 ReturnType
1230 Printer::functiontype(FunctionType const* self, int depth, std::ostream& out, int indent) {
1231 return false;
1232 }
1233
1234 ReturnType Printer::expression(Expression const* self, int depth, std::ostream& out, int level) {
1235 return false;
1236 }
1237
1238 ReturnType Printer::interactive(Interactive const* self, int depth, std::ostream& out, int level) {
1239 return false;
1240 }
1241
1242 void Printer::withitem(WithItem const& self, int depth, std::ostream& out, int level) {
1243 exec(self.context_expr, depth, out, level);
1244 if (self.optional_vars.has_value()) {
1245 out << " as ";
1246 exec(self.optional_vars.value(), depth, out, level);
1247 }
1248 }
1249
1250 ReturnType Printer::comment(Comment const* n, int depth, std::ostream& out, int level) {
1251 278 out << "#" << n->comment;
1252 278 return false;
1253 }
1254
1255 void Printer::arguments(Arguments const& self, int depth, std::ostream& out, int level) {
1256 48 int i = 0;
1257
1258
2/2
✓ Branch 4 taken 51 times.
✓ Branch 5 taken 48 times.
99 for (auto& arg: self.args) {
1259
2/2
✓ Branch 1 taken 51 times.
✓ Branch 4 taken 51 times.
51 out << arg.arg;
1260
1261
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 23 times.
51 if (arg.annotation.has_value()) {
1262
1/1
✓ Branch 1 taken 28 times.
28 out << ": ";
1263
1/1
✓ Branch 2 taken 28 times.
28 exec(arg.annotation.value(), depth, out, level);
1264 }
1265
1266 51 auto default_offset = self.args.size() - 1 - i;
1267
6/6
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 39 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 45 times.
51 if (self.defaults.size() > 0 && default_offset < self.defaults.size()) {
1268
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
6 if (arg.annotation.has_value()) {
1269
1/1
✓ Branch 1 taken 2 times.
2 out << " = ";
1270 } else {
1271
1/1
✓ Branch 1 taken 4 times.
4 out << "=";
1272 }
1273
1/1
✓ Branch 2 taken 6 times.
6 exec(self.defaults[default_offset], depth, out, -1);
1274 }
1275
1276
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 37 times.
51 if (i + 1 < self.args.size()) {
1277
1/1
✓ Branch 1 taken 14 times.
14 out << ", ";
1278 }
1279 51 i += 1;
1280 }
1281
1282
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 44 times.
48 if (self.vararg.has_value()) {
1283
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (self.args.size() > 0) {
1284 4 out << ", ";
1285 }
1286
1287
2/2
✓ Branch 3 taken 4 times.
✓ Branch 6 taken 4 times.
4 out << "*" << self.vararg.value().arg;
1288 }
1289
1290
7/8
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 37 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 33 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 44 times.
48 if ((self.args.size() > 0 || self.vararg.has_value()) && self.kwonlyargs.size() > 0) {
1291 4 out << ", ";
1292 }
1293
1294 48 i = 0;
1295
2/2
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 48 times.
52 for (auto const& kw: self.kwonlyargs) {
1296
2/2
✓ Branch 1 taken 4 times.
✓ Branch 4 taken 4 times.
4 out << kw.arg;
1297
1298
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (kw.annotation.has_value()) {
1299 out << ": ";
1300 exec(kw.annotation.value(), depth, out, level);
1301 }
1302
1303 4 auto default_offset = self.kwonlyargs.size() - 1 - i;
1304
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
4 if (self.kw_defaults.size() > 0 && default_offset < self.kw_defaults.size()) {
1305
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (kw.annotation.has_value()) {
1306 out << " = ";
1307 } else {
1308
1/1
✓ Branch 1 taken 4 times.
4 out << "=";
1309 }
1310
1/1
✓ Branch 2 taken 4 times.
4 exec(self.kw_defaults[default_offset], depth, out, -1);
1311 }
1312
1313
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (i + 1 < self.kwonlyargs.size()) {
1314 out << ", ";
1315 }
1316 4 i += 1;
1317 }
1318
1319
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 44 times.
48 if (self.kwarg.has_value()) {
1320
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (!self.kwonlyargs.empty()) {
1321 4 out << ", ";
1322 }
1323
2/2
✓ Branch 3 taken 4 times.
✓ Branch 6 taken 4 times.
4 out << "**" << self.kwarg.value().arg;
1324 }
1325 48 }
1326
1327 int get_precedence(Node const* node) {
1328
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 285 times.
285 if (node == nullptr) {
1329 return 1000;
1330 }
1331
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 181 times.
285 if (node->kind == NodeKind::BinOp) {
1332 104 BinOp* op = (BinOp*)(node);
1333 // clang-format off
1334
6/7
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 2 times.
104 switch (op->op) {
1335 61 case BinaryOperator::Add: return 1;
1336 29 case BinaryOperator::Sub: return 1;
1337 4 case BinaryOperator::Mult: return 2;
1338 2 case BinaryOperator::Div: return 2;
1339 case BinaryOperator::Pow: return 3;
1340 6 case BinaryOperator::BitXor: return 3;
1341 }
1342 // clang-format on
1343 2 return 10;
1344 }
1345 181 return 1000;
1346 }
1347
1348 void print(Node const* obj, std::ostream& out) {
1349 Printer p;
1350 p.exec<bool>(obj, 0, out, 0);
1351 }
1352 void print(ExprNode const* obj, std::ostream& out) {
1353 Printer p;
1354 p.exec(obj, 0, out, 0);
1355 }
1356 void print(Pattern const* obj, std::ostream& out) {
1357 Printer p;
1358 p.exec(obj, 0, out, 0);
1359 }
1360 void print(StmtNode const* obj, std::ostream& out) {
1361 Printer p;
1362 p.exec(obj, 0, out, 0);
1363 }
1364 void print(ModNode const* obj, std::ostream& out) {
1365 Printer p;
1366 p.exec(obj, 0, out, 0);
1367 }
1368
1369 String str(ExprNode const* obj) {
1370 StringStream ss;
1371 print(obj, ss);
1372 return ss.str();
1373 }
1374
1375 } // namespace lython
1376