Exemplo n.º 1
0
    def visit_If(self, node):
        test = self.append_node(IfNode(node.test, node, path=self.filenames[-1]))

        body_connect_stmts = self.stmt_star_handler(node.body)
        if isinstance(body_connect_stmts, IgnoredNode):
            body_connect_stmts = ConnectStatements(
                first_statement=test, last_statements=[], break_statements=[]
            )
        if test is not None:
            test.connect(body_connect_stmts.first_statement)

        if node.orelse:
            orelse_last_nodes = self.handle_or_else(node.orelse, test)
            if isinstance(orelse_last_nodes, IgnoredNode):
                return IgnoredNode()
            body_connect_stmts.last_statements.extend(orelse_last_nodes)
        else:
            body_connect_stmts.last_statements.append(
                test
            )  # if there is no orelse, test needs an edge to the next_node

        last_statements = remove_breaks(body_connect_stmts.last_statements)

        return ControlFlowNode(
            test, last_statements, break_statements=body_connect_stmts.break_statements
        )
Exemplo n.º 2
0
 def handle_stmt_star_ignore_node(self, body, fallback_cfg_node):
     try:
         if fallback_cfg_node is not None:
             fallback_cfg_node.connect(body.first_statement)
     except AttributeError:
         body = ConnectStatements(
             first_statement=[fallback_cfg_node],
             last_statements=[fallback_cfg_node],
             break_statements=[],
         )
     return body
Exemplo n.º 3
0
    def stmt_star_handler(self, stmts, prev_node_to_avoid=None):
        """Handle stmt* expressions in an AST node.

        Links all statements together in a list of statements, accounting for statements with multiple last nodes.
        """
        break_nodes = list()
        cfg_statements = list()
        self.prev_nodes_to_avoid.append(prev_node_to_avoid)
        self.last_control_flow_nodes.append(None)

        first_node = None
        node_not_to_step_past = self.nodes[-1]
        for stmt in stmts:
            node = self.visit(stmt)
            if isinstance(node, IgnoredNode):
                continue
            if isinstance(node, ControlFlowNode) and not isinstance(
                    node.test, TryNode):
                self.last_control_flow_nodes.append(node.test)
            else:
                self.last_control_flow_nodes.append(None)

            if isinstance(node, ControlFlowNode):
                break_nodes.extend(node.break_statements)
            elif isinstance(node, BreakNode):
                break_nodes.append(node)
            cfg_statements.append(node)
            if not first_node:
                if isinstance(node, ControlFlowNode):
                    first_node = node.test
                else:
                    first_node = get_first_node(node, node_not_to_step_past)

        self.prev_nodes_to_avoid.pop()
        self.last_control_flow_nodes.pop()
        if cfg_statements:
            connect_nodes(cfg_statements)
            if first_node:
                first_statement = first_node
            else:
                first_statement = get_first_statement(cfg_statements[0])

            last_statements = get_last_statements(cfg_statements)
            return ConnectStatements(
                first_statement=first_statement,
                last_statements=last_statements,
                break_statements=break_nodes,
            )
        else:  # When body of module only contains ignored nodes
            return IgnoredNode()