def make_if(self, instr, left, and_block): block = [instr] + and_block[:-1] maxmax = max(block, key=lambda ins: (0, 0) if (ins.op not in JUMP_OPS) else (self.jump_map.get(ins.oparg, ins.oparg), ins.i)) idx = block.index(maxmax) assert idx is not None hi = self.process_logic(block[:idx + 1]) if hi.right is None and hi.parent is None: if instr.opname == 'POP_JUMP_IF_TRUE': cond = _ast.UnaryOp(op=_ast.Not(), operand=left, lineno=0, col_offset=0) else: cond = left else: cond = self.logic_ast(instr, left, hi) jump = and_block[-1] if jump.opname == 'RETURN_VALUE': body_block = block[idx + 1:] + [jump] else: body_block = block[idx + 1:] body = self.decompile_block(body_block).stmnt() if jump.is_jump: else_block = self.make_block(jump.to, inclusive=False, raise_=False) else: # it is a return else_block = [] if len(else_block): else_ = self.decompile_block(else_block).stmnt() # # if len(else_lst) == 1 and isinstance(else_lst[0], _ast.If): # elif_ = else_lst[0] # tests.extend(elif_.tests) # else_ = elif_.else_ # else: # else_ = else_lst else: else_ = [] if_ = _ast.If(test=cond, body=body, orelse=else_, lineno=instr.lineno, col_offset=0) self.ast_stack.append(if_)
def refactor_ifs(stmnt, ifs): ''' for if statements in list comprehension ''' if isinstance(stmnt, _ast.BoolOp): test, right = stmnt.values if isinstance(stmnt.op, _ast.Or): test = _ast.UnaryOp(op=_ast.Not(), operand=test, lineno=0, col_offset=0) ifs.append(test) return refactor_ifs(right, ifs) return stmnt
def Not(): return _ast.Not()