| 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 |