GCC Code Coverage Report


Directory: ./
File: src/ast/ops/circle.cpp
Date: 2023-04-27 00:55:30
Exec Total Coverage
Lines: 55 257 21.4%
Functions: 24 93 25.8%
Branches: 64 452 14.2%

Line Branch Exec Source
1 #include "ast/magic.h"
2 #include "ast/nodes.h"
3 #include "ast/visitor.h"
4 #include "compatibility/compatibility.h"
5 #include "dependencies/fmt.h"
6 #include "lexer/unlex.h"
7 #include "logging/logging.h"
8 #include "parser/parsing_error.h"
9 #include "utilities/strings.h"
10
11 namespace lython {
12
13 struct CircleTrait {
14 using Trace = std::true_type;
15 using StmtRet = bool;
16 using ExprRet = bool;
17 using ModRet = bool;
18 using PatRet = bool;
19
20 enum
21 { MaxRecursionDepth = LY_MAX_VISITOR_RECURSION_DEPTH };
22 };
23
24 #define ReturnType bool
25
26 // Circle should not happen
27 // Weird things can happen during sema where we create/resolve types
28 // this is here so we can do a sanity check and prevent stack overflows while debugging
29 struct Circle: BaseVisitor<Circle, true, CircleTrait> {
30 using Super = BaseVisitor<Circle, true, CircleTrait>;
31 Array<Node const*> visited;
32
33 bool in(Node const* obj, int depth) {
34
2/2
✓ Branch 0 taken 195 times.
✓ Branch 1 taken 564 times.
759 if (obj == nullptr) {
35 195 return false;
36 }
37
38
2/2
✓ Branch 5 taken 971 times.
✓ Branch 6 taken 564 times.
1535 for (Node const* item: visited) {
39
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 971 times.
971 if (item == obj) {
40 kwtrace(depth, "Duplicate is: {}", meta::type_name(item->class_id));
41 return true;
42 }
43 }
44
45 564 visited.push_back(obj);
46 564 return false;
47 }
48
49 ReturnType exec(ModNode_t* mod, int depth) {
50
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (in(mod, depth)) {
51 return true;
52 }
53
54 1 return Super::exec(mod, depth);
55 }
56 ReturnType exec(Pattern_t* pat, int depth) {
57 if (in(pat, depth)) {
58 return true;
59 }
60
61 return Super::exec(pat, depth);
62 }
63 ReturnType exec(ExprNode_t* expr, int depth) {
64
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 747 times.
747 if (in(expr, depth)) {
65 return true;
66 }
67
68 747 return Super::exec(expr, depth);
69 }
70 ReturnType exec(StmtNode_t* stmt, int depth) {
71
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if (in(stmt, depth)) {
72 return true;
73 }
74
75 11 return Super::exec(stmt, depth);
76 }
77
78 template <typename T>
79 bool any_of(Array<T> const& elts, int depth) {
80 // std::any_of produce so much asm crap in gcc-12 & clang-15
81 // zig++ generates fine code though
82 // msvc generates the worst code by far
83
2/2
✓ Branch 5 taken 13 times.
✓ Branch 6 taken 9 times.
44 for (auto const& elt: elts) { // NOLINT
84
2/3
✓ Branch 1 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
26 if (exec(elt, depth))
85 return true;
86 }
87 18 return false;
88 }
89
90 ReturnType exec_body(Array<StmtNode*> const& body, int depth) { return any_of(body, depth); }
91
92 ReturnType excepthandler(ExceptHandler const& self, int depth) {
93 if (self.type.has_value()) {
94 if (exec(self.type.value(), depth))
95 return true;
96 }
97
98 return exec(self.comment, depth) || exec_body(self.body, depth + 1);
99 }
100
101 ReturnType matchcase(MatchCase const& self, int depth) {
102 if (exec(self.pattern, depth)) {
103 return true;
104 }
105
106 if (self.guard.has_value()) {
107 if (exec(self.guard.value(), depth))
108 return true;
109 }
110
111 return exec(self.comment, depth) || exec_body(self.body, depth + 1);
112 }
113
114 bool comprehension(Comprehension const& self, int depth);
115 bool arguments(Arguments const& self, int depth);
116 bool withitem(WithItem const& self, int depth);
117 bool alias(Alias const& self, int depth);
118 bool keyword(Keyword const& self, int depth);
119
120 bool arg(Arg const& self, int depth) {
121 if (self.annotation.has_value()) {
122 if (exec(self.annotation.value(), depth)) {
123 return true;
124 }
125 }
126 return false;
127 }
128
129 #define FUNCTION_GEN(name, fun, rtype) rtype fun(const name* node, int depth);
130
131 #define X(name, _)
132 #define SECTION(name)
133 #define EXPR(name, fun) FUNCTION_GEN(name, fun, ReturnType)
134 #define STMT(name, fun) FUNCTION_GEN(name, fun, ReturnType)
135 #define MOD(name, fun) FUNCTION_GEN(name, fun, ReturnType)
136 #define MATCH(name, fun) FUNCTION_GEN(name, fun, ReturnType)
137
138 NODEKIND_ENUM(X, SECTION, EXPR, STMT, MOD, MATCH)
139
140 #undef X
141 #undef SECTION
142 #undef EXPR
143 #undef STMT
144 #undef MOD
145 #undef MATCH
146
147 #undef FUNCTION_GEN
148 } LY_ALIGN(32);
149
150 ReturnType Circle::attribute(Attribute const* self, int depth) { return exec(self->value, depth); }
151
152 ReturnType Circle::subscript(Subscript const* self, int depth) {
153
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
1 return exec(self->value, depth) || exec(self->slice, depth);
154 }
155
156 ReturnType Circle::starred(Starred const* self, int depth) { return exec(self->value, depth); }
157
158 ReturnType Circle::module(Module const* self, int depth) { return exec_body(self->body, depth); }
159
160 ReturnType Circle::raise(Raise const* self, int depth) {
161 if (self->exc.has_value()) {
162 if (exec(self->exc.value(), depth))
163 return true;
164 }
165
166 if (self->cause.has_value()) {
167 if (exec(self->cause.value(), depth)) {
168 return true;
169 }
170 }
171 return false;
172 }
173
174 ReturnType Circle::assertstmt(Assert const* self, int depth) {
175 if (exec(self->test, depth)) {
176 return true;
177 }
178
179 if (self->msg.has_value()) {
180 if (exec(self->msg.value(), depth)) {
181 return true;
182 }
183 }
184
185 return false;
186 }
187
188 ReturnType Circle::with(With const* self, int depth) {
189 for (auto const& item: self->items) {
190 if (exec(item.context_expr, depth)) {
191 return true;
192 }
193
194 if (item.optional_vars.has_value()) {
195 if (exec(item.optional_vars.value(), depth)) {
196 return true;
197 }
198 }
199 }
200
201 return exec(self->comment, depth) || exec_body(self->body, depth + 1);
202 }
203
204 ReturnType Circle::import(Import const* self, int depth) { return false; }
205
206 ReturnType Circle::importfrom(ImportFrom const* self, int depth) { return false; }
207
208 ReturnType Circle::slice(Slice const* self, int depth) {
209 if (self->lower.has_value()) {
210 if (exec(self->lower.value(), depth)) {
211 return true;
212 }
213 }
214
215 if (self->upper.has_value()) {
216 if (exec(self->upper.value(), depth))
217 return true;
218 }
219
220 if (self->step.has_value()) {
221 if (exec(self->step.value(), depth))
222 return true;
223 }
224 return false;
225 }
226
227 ReturnType Circle::tupleexpr(TupleExpr const* self, int depth) { return any_of(self->elts, depth); }
228
229 ReturnType Circle::listexpr(ListExpr const* self, int depth) { return any_of(self->elts, depth); }
230
231 ReturnType Circle::setexpr(SetExpr const* self, int depth) { return any_of(self->elts, depth); }
232
233 ReturnType Circle::dictexpr(DictExpr const* self, int depth) {
234 for (int i = 0; i < self->keys.size(); i++) {
235 if (exec(self->keys[i], depth) || exec(self->values[i], depth)) {
236 return true;
237 }
238 }
239 return false;
240 }
241
242 ReturnType Circle::matchvalue(MatchValue const* self, int depth) {
243 return exec(self->value, depth);
244 }
245
246 ReturnType Circle::matchsingleton(MatchSingleton const* self, int depth) { return false; }
247
248 ReturnType Circle::matchsequence(MatchSequence const* self, int depth) {
249 return any_of(self->patterns, depth);
250 }
251
252 ReturnType Circle::matchmapping(MatchMapping const* self, int depth) {
253 for (int i = 0; i < self->keys.size(); i++) {
254 if (exec(self->keys[i], depth) || exec(self->patterns[i], depth)) {
255 return true;
256 }
257 }
258 return false;
259 }
260
261 ReturnType Circle::matchclass(MatchClass const* self, int depth) {
262 return exec(self->cls, depth) || //
263 any_of(self->patterns, depth) || //
264 any_of(self->kwd_patterns, depth);
265 }
266
267 ReturnType Circle::matchstar(MatchStar const* self, int depth) { return false; }
268
269 ReturnType Circle::matchas(MatchAs const* self, int depth) {
270 if (self->pattern.has_value()) {
271 if (exec(self->pattern.value(), depth)) {
272 return true;
273 }
274 }
275 return false;
276 }
277
278 ReturnType Circle::matchor(MatchOr const* self, int depth) { return any_of(self->patterns, depth); }
279
280 ReturnType Circle::ifstmt(If const* self, int depth) {
281
282 if (exec(self->test, depth) || exec(self->comment, depth) || exec_body(self->body, depth + 1)) {
283 return true;
284 }
285
286 for (int i = 0; i < self->tests.size(); i++) {
287 auto const& eliftest = self->tests[i];
288 auto const& elifbody = self->bodies[i];
289
290 if (exec(eliftest, depth) || exec(self->tests_comment[i], depth) ||
291 exec_body(elifbody, depth + 1)) {
292 return true;
293 }
294 }
295
296 if (!self->orelse.empty()) {
297 if (exec(self->else_comment, depth) || exec_body(self->orelse, depth + 1)) {
298 return true;
299 }
300 }
301 return false;
302 }
303
304 ReturnType Circle::match(Match const* self, int depth) {
305 if (exec(self->subject, depth) || exec(self->comment, depth)) {
306 return true;
307 }
308
309 for (auto& case_: self->cases) { // NOLINT
310 if (matchcase(case_, depth + 1)) {
311 return true;
312 }
313 }
314 return false;
315 }
316
317 ReturnType Circle::lambda(Lambda const* self, int depth) {
318 return arguments(self->args, depth) || exec(self->body, depth);
319 }
320
321 ReturnType Circle::ifexp(IfExp const* self, int depth) {
322 return exec(self->body, depth) || exec(self->test, depth) || exec(self->orelse, depth);
323 }
324
325 ReturnType Circle::listcomp(ListComp const* self, int depth) {
326 if (exec(self->elt, depth)) {
327 return true;
328 }
329
330 for (int i = 0; i < self->generators.size(); i++) {
331 if (comprehension(self->generators[i], depth)) {
332 return true;
333 }
334 }
335 return false;
336 }
337
338 ReturnType Circle::setcomp(SetComp const* self, int depth) {
339 if (exec(self->elt, depth)) {
340 return true;
341 }
342
343 for (int i = 0; i < self->generators.size(); i++) {
344 if (comprehension(self->generators[i], depth)) {
345 return true;
346 }
347 }
348 return false;
349 }
350
351 ReturnType Circle::generateexpr(GeneratorExp const* self, int depth) {
352 if (exec(self->elt, depth)) {
353 return true;
354 }
355
356 for (int i = 0; i < self->generators.size(); i++) {
357 if (comprehension(self->generators[i], depth)) {
358 return true;
359 }
360 }
361 return false;
362 }
363
364 ReturnType Circle::dictcomp(DictComp const* self, int depth) {
365
366 if (exec(self->key, depth) || exec(self->value, depth)) {
367 return true;
368 }
369
370 for (int i = 0; i < self->generators.size(); i++) {
371 if (comprehension(self->generators[i], depth)) {
372 return true;
373 }
374 }
375 return false;
376 }
377
378 ReturnType Circle::await(Await const* self, int depth) { return exec(self->value, depth); }
379
380 ReturnType Circle::yield(Yield const* self, int depth) {
381 return self->value.has_value() && exec(self->value.value(), depth);
382 }
383
384 ReturnType Circle::yieldfrom(YieldFrom const* self, int depth) { return exec(self->value, depth); }
385
386 ReturnType Circle::call(Call const* self, int depth) {
387
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
4 if (exec(self->func, depth) || any_of(self->args, depth)) {
388 return true;
389 }
390
391
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 for (int i = 0; i < self->keywords.size(); i++) {
392 auto const& key = self->keywords[i];
393
394 if (exec(key.value, depth)) {
395 return true;
396 }
397 }
398
399 4 return false;
400 }
401
402 ReturnType Circle::constant(Constant const* self, int depth) { return false; }
403
404 ReturnType Circle::namedexpr(NamedExpr const* self, int depth) {
405 return exec(self->target, depth) || exec(self->value, depth);
406 }
407
408 ReturnType Circle::classdef(ClassDef const* self, int depth) {
409
1/2
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
1 for (auto decorator: self->decorator_list) {
410 if (exec(decorator.expr, depth) || exec(decorator.comment, depth)) {
411 return true;
412 }
413 }
414
415
1/4
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
1 for (auto kw: self->keywords) { // NOLINT
416 if (exec(kw.value, depth)) {
417 return true;
418 }
419 }
420
421
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
1 if (any_of(self->bases, depth) || exec(self->comment, depth)) {
422 return true;
423 }
424
425
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
1 if (self->docstring.has_value() && exec(self->docstring.value().comment, depth)) {
426 return true;
427 }
428
429
2/2
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
2 for (auto& stmt: self->body) { // NOLINT
430
5/8
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
1 if (exec(stmt, depth + 1) || exec(stmt->comment, depth)) {
431 return true;
432 }
433 }
434 1 return false;
435 }
436
437 ReturnType Circle::functiondef(FunctionDef const* self, int depth) {
438
1/2
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
2 for (auto decorator: self->decorator_list) {
439 if (exec(decorator.expr, depth) || exec(decorator.comment, depth)) {
440 return true;
441 }
442 }
443
444
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (arguments(self->args, depth)) {
445 return true;
446 }
447
448
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
2 if (self->returns.has_value() && exec(self->returns.value(), depth)) {
449 return true;
450 }
451
452
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (exec(self->comment, depth)) {
453 return true;
454 }
455
456
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
2 if (self->docstring.has_value() && exec(self->docstring.value().comment, depth)) {
457 return true;
458 }
459
460
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2 return exec_body(self->body, depth + 1) || exec(self->type, depth);
461 }
462
463 ReturnType Circle::inlinestmt(Inline const* self, int depth) {
464 return exec_body(self->body, depth);
465 }
466
467 ReturnType Circle::forstmt(For const* self, int depth) {
468
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
1 if (exec(self->target, depth) || exec(self->iter, depth) || exec(self->comment, depth)) {
469 return true;
470 }
471
472
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (exec_body(self->body, depth + 1)) {
473 return true;
474 }
475
476
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (!self->orelse.empty()) {
477 if (exec(self->else_comment, depth) || exec_body(self->orelse, depth + 1)) {
478 return true;
479 }
480 }
481
482 1 return false;
483 }
484
485 ReturnType Circle::trystmt(Try const* self, int depth) {
486 if (exec(self->comment, depth) || exec_body(self->body, depth + 1)) {
487 return true;
488 }
489
490 for (auto const& handler: self->handlers) {
491 if (excepthandler(handler, depth)) {
492 return true;
493 }
494 }
495
496 if (!self->orelse.empty()) {
497 if (exec(self->else_comment, depth) || exec_body(self->orelse, depth + 1)) {
498 return true;
499 }
500 }
501
502 if (!self->finalbody.empty()) {
503
504 if (exec(self->finally_comment, depth) || exec_body(self->finalbody, depth + 1)) {
505 return true;
506 }
507 }
508
509 return false;
510 }
511
512 ReturnType Circle::compare(Compare const* self, int depth) {
513 if (exec(self->left, depth)) {
514 return true;
515 }
516
517 int n = int(self->comparators.size());
518 for (int i = 0; i < self->ops.size(); i++) {
519
520 if (i < n && exec(self->comparators[i], depth)) {
521 return true;
522 }
523 }
524
525 return false;
526 }
527
528 ReturnType Circle::binop(BinOp const* self, int depth) {
529 return exec(self->left, depth) || exec(self->right, depth);
530 }
531
532 ReturnType Circle::invalidstmt(InvalidStatement const* self, int depth) { return false; }
533
534 ReturnType Circle::boolop(BoolOp const* self, int depth) {
535
536 int m = self->opcount + 1;
537 int n = int(self->values.size());
538
539 for (int i = 0; i < m; i++) {
540
541 if (i < n && exec(self->values[i], depth)) {
542 return true;
543 }
544 }
545
546 return false;
547 }
548
549 ReturnType Circle::unaryop(UnaryOp const* self, int depth) { return exec(self->operand, depth); }
550
551 ReturnType Circle::whilestmt(While const* self, int depth) {
552 if (exec(self->test, depth) || exec(self->comment, depth) || exec_body(self->body, depth + 1)) {
553 return true;
554 }
555
556 if (!self->orelse.empty()) {
557 return exec(self->else_comment, depth) || exec_body(self->orelse, depth + 1);
558 }
559
560 return false;
561 }
562
563 ReturnType Circle::returnstmt(Return const* self, int depth) {
564
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (self->value.has_value()) {
565
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (exec(self->value.value(), depth)) {
566 return true;
567 }
568 }
569
570 1 return false;
571 }
572
573 ReturnType Circle::deletestmt(Delete const* self, int depth) {
574 for (int i = 0; i < self->targets.size(); i++) {
575 if (exec(self->targets[i], depth)) {
576 return true;
577 }
578 }
579 return false;
580 }
581
582 ReturnType Circle::augassign(AugAssign const* self, int depth) {
583 return exec(self->target, depth) || exec(self->value, depth);
584 }
585
586 ReturnType Circle::assign(Assign const* self, int depth) {
587
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
1 return exec(self->targets[0], depth) || exec(self->value, depth);
588 }
589
590 ReturnType Circle::annassign(AnnAssign const* self, int depth) {
591 if (exec(self->target, depth) || exec(self->annotation, depth)) {
592 return true;
593 }
594
595 if (self->value.has_value()) {
596 if (exec(self->value.value(), depth)) {
597 return true;
598 }
599 }
600
601 return false;
602 }
603
604 ReturnType Circle::pass(Pass const* self, int depth) { return false; }
605
606 ReturnType Circle::breakstmt(Break const* self, int depth) { return false; }
607
608 ReturnType Circle::continuestmt(Continue const* self, int depth) { return false; }
609
610 ReturnType Circle::exprstmt(Expr const* self, int depth) {
611
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (self->value != nullptr)
612
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (exec(self->value, depth)) {
613 return true;
614 }
615
616 3 return false;
617 }
618
619 ReturnType Circle::global(Global const* self, int depth) { return false; }
620
621 ReturnType Circle::nonlocal(Nonlocal const* self, int depth) { return false; }
622
623 ReturnType Circle::arrow(Arrow const* self, int depth) {
624
2/2
✓ Branch 5 taken 293 times.
✓ Branch 6 taken 216 times.
509 for (ExprNode* node: self->args) {
625
2/3
✓ Branch 1 taken 293 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 293 times.
293 if (exec(node, depth)) {
626 return true;
627 }
628 }
629 216 return exec(self->returns, depth);
630 }
631
632 ReturnType Circle::dicttype(DictType const* self, int depth) {
633 return exec(self->key, depth) || exec(self->value, depth);
634 }
635
636 ReturnType Circle::settype(SetType const* self, int depth) { return false; }
637
638 ReturnType Circle::name(Name const* self, int depth) { return false; }
639
640 ReturnType Circle::arraytype(ArrayType const* self, int depth) { return exec(self->value, depth); }
641
642 ReturnType Circle::tupletype(TupleType const* self, int depth) {
643 return any_of(self->types, depth);
644 }
645
646 ReturnType Circle::builtintype(BuiltinType const* self, int depth) { return false; }
647
648 ReturnType Circle::joinedstr(JoinedStr const* self, int depth) { return false; }
649
650 ReturnType Circle::formattedvalue(FormattedValue const* self, int depth) { return false; }
651
652 ReturnType Circle::classtype(ClassType const* self, int depth) { return false; }
653
654 // Helper
655 // ==================================================
656
657 bool Circle::comprehension(Comprehension const& self, int depth) {
658
659 return exec(self.target, depth) || //
660 exec(self.iter, depth) || //
661 any_of(self.ifs, depth);
662 }
663
664 bool Circle::keyword(Keyword const& self, int depth) {
665 return (self.value != nullptr) && exec(self.value, depth);
666 }
667
668 bool Circle::alias(Alias const& self, int depth) { return false; }
669
670 ReturnType Circle::functiontype(FunctionType const* self, int depth) { return false; }
671
672 ReturnType Circle::expression(Expression const* self, int depth) { return false; }
673
674 ReturnType Circle::interactive(Interactive const* self, int depth) { return false; }
675
676 bool Circle::withitem(WithItem const& self, int depth) {
677 if (exec(self.context_expr, depth)) {
678 return true;
679 }
680
681 if (self.optional_vars.has_value()) {
682
683 if (exec(self.optional_vars.value(), depth)) {
684 return true;
685 }
686 }
687
688 return false;
689 }
690
691 ReturnType Circle::comment(Comment const* n, int depth) { return false; }
692
693 bool Circle::arguments(Arguments const& self, int depth) {
694 2 int i = 0;
695
696
2/2
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
4 for (auto const& arg: self.args) {
697
2/8
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
2 if (arg.annotation.has_value() && exec(arg.annotation.value(), depth)) {
698 return true;
699 }
700
701 2 auto default_offset = self.args.size() - 1 - i;
702
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
2 if (!self.defaults.empty() && default_offset < self.defaults.size()) {
703 if (exec(self.defaults[default_offset], depth)) {
704 return true;
705 }
706 }
707
708 2 i += 1;
709 }
710
711 2 i = 0;
712
1/2
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2 for (auto const& kw: self.kwonlyargs) {
713 if (kw.annotation.has_value()) {
714 if (exec(kw.annotation.value(), depth)) {
715 return true;
716 }
717 }
718
719 auto default_offset = self.kwonlyargs.size() - 1 - i;
720 if (!self.kw_defaults.empty() && default_offset < self.kw_defaults.size()) {
721 if (exec(self.kw_defaults[default_offset], depth)) {
722 return true;
723 }
724 }
725
726 i += 1;
727 }
728
729 2 return false;
730 }
731
732 bool has_circle(ExprNode const* obj) { return Circle().exec(obj, 0); }
733 bool has_circle(Pattern const* obj) { return Circle().exec(obj, 0); }
734 bool has_circle(StmtNode const* obj) { return Circle().exec(obj, 0); }
735 bool has_circle(ModNode const* obj) { return Circle().exec(obj, 0); }
736
737 } // namespace lython
738