# Should the first rule be somehow folded into the 2nd one? build_class ::= LOAD_BUILD_CLASS mkfunc LOAD_CLASSNAME {expr}^n-1 CALL_FUNCTION_n LOAD_CONST CALL_FUNCTION_n build_class ::= LOAD_BUILD_CLASS mkfunc
(self, opname, i, token, tokens, customize, is_pypy)
| 512 | return "%s_0" % (token.kind) |
| 513 | |
| 514 | def custom_build_class_rule(self, opname, i, token, tokens, customize, is_pypy): |
| 515 | """ |
| 516 | # Should the first rule be somehow folded into the 2nd one? |
| 517 | build_class ::= LOAD_BUILD_CLASS mkfunc |
| 518 | LOAD_CLASSNAME {expr}^n-1 CALL_FUNCTION_n |
| 519 | LOAD_CONST CALL_FUNCTION_n |
| 520 | build_class ::= LOAD_BUILD_CLASS mkfunc |
| 521 | expr |
| 522 | call |
| 523 | CALL_FUNCTION_3 |
| 524 | """ |
| 525 | # FIXME: I bet this can be simplified |
| 526 | # look for next MAKE_FUNCTION |
| 527 | for i in range(i + 1, len(tokens)): |
| 528 | if tokens[i].kind.startswith("MAKE_FUNCTION"): |
| 529 | break |
| 530 | elif tokens[i].kind.startswith("MAKE_CLOSURE"): |
| 531 | break |
| 532 | pass |
| 533 | assert i < len( |
| 534 | tokens |
| 535 | ), "build_class needs to find MAKE_FUNCTION or MAKE_CLOSURE" |
| 536 | assert ( |
| 537 | tokens[i + 1].kind == "LOAD_STR" |
| 538 | ), "build_class expecting CONST after MAKE_FUNCTION/MAKE_CLOSURE" |
| 539 | call_fn_tok = None |
| 540 | for i in range(i, len(tokens)): |
| 541 | if tokens[i].kind.startswith("CALL_FUNCTION"): |
| 542 | call_fn_tok = tokens[i] |
| 543 | break |
| 544 | if not call_fn_tok: |
| 545 | raise RuntimeError( |
| 546 | "build_class custom rule for %s needs to find CALL_FUNCTION" % opname |
| 547 | ) |
| 548 | |
| 549 | # customize build_class rule |
| 550 | # FIXME: What's the deal with the two rules? Different Python versions? |
| 551 | # Different situations? Note that the above rule is based on the CALL_FUNCTION |
| 552 | # token found, while this one doesn't. |
| 553 | if self.version < (3, 6): |
| 554 | call_function = self.call_fn_name(call_fn_tok) |
| 555 | pos_args_count, kw_args_count = self.get_pos_kw(call_fn_tok) |
| 556 | rule = "build_class ::= LOAD_BUILD_CLASS mkfunc %s" "%s" % ( |
| 557 | ("expr " * (pos_args_count - 1) + ("kwarg " * kw_args_count)), |
| 558 | call_function, |
| 559 | ) |
| 560 | else: |
| 561 | # 3.6+ handling |
| 562 | call_function = call_fn_tok.kind |
| 563 | if call_function.startswith("CALL_FUNCTION_KW"): |
| 564 | self.addRule("classdef ::= build_class_kw store", nop_func) |
| 565 | if is_pypy: |
| 566 | pos_args_count, kw_args_count = self.get_pos_kw(call_fn_tok) |
| 567 | rule = "build_class_kw ::= LOAD_BUILD_CLASS mkfunc %s%s%s" % ( |
| 568 | "expr " * (pos_args_count - 1), |
| 569 | "kwarg " * (kw_args_count), |
| 570 | call_function, |
| 571 | ) |
no test coverage detected