Module opshin.optimize.optimize_remove_unreachable

Expand source code
from ast import *
from copy import copy

from ..typed_util import ScopedSequenceNodeTransformer

"""
Removes statements that are unreachable because a previous statement in the same
sequence is known not to fall through.
"""


class OptimizeRemoveUnreachable(ScopedSequenceNodeTransformer):
    step = "Removing unreachable statements"

    def visit_sequence(self, statements):
        visited = []
        for stmt in statements:
            if stmt is None:
                continue
            stmt_cp = self.visit(stmt)
            if stmt_cp is None:
                continue
            visited.append(stmt_cp)
            if not getattr(stmt_cp, "can_fall_through", True):
                break
        return visited

    def visit_If(self, node: If) -> If:
        node_cp = copy(node)
        node_cp.test = self.visit(node.test)
        node_cp.body = self.visit_sequence(node.body)
        node_cp.orelse = self.visit_sequence(node.orelse)
        return node_cp

    def visit_While(self, node: While) -> While:
        node_cp = copy(node)
        node_cp.test = self.visit(node.test)
        node_cp.body = self.visit_sequence(node.body)
        node_cp.orelse = self.visit_sequence(node.orelse)
        return node_cp

    def visit_For(self, node: For) -> For:
        node_cp = copy(node)
        node_cp.target = self.visit(node.target)
        node_cp.iter = self.visit(node.iter)
        node_cp.body = self.visit_sequence(node.body)
        node_cp.orelse = self.visit_sequence(node.orelse)
        return node_cp

Classes

class OptimizeRemoveUnreachable

Rewrite nested statement sequences while preserving the surrounding node.

Expand source code
class OptimizeRemoveUnreachable(ScopedSequenceNodeTransformer):
    step = "Removing unreachable statements"

    def visit_sequence(self, statements):
        visited = []
        for stmt in statements:
            if stmt is None:
                continue
            stmt_cp = self.visit(stmt)
            if stmt_cp is None:
                continue
            visited.append(stmt_cp)
            if not getattr(stmt_cp, "can_fall_through", True):
                break
        return visited

    def visit_If(self, node: If) -> If:
        node_cp = copy(node)
        node_cp.test = self.visit(node.test)
        node_cp.body = self.visit_sequence(node.body)
        node_cp.orelse = self.visit_sequence(node.orelse)
        return node_cp

    def visit_While(self, node: While) -> While:
        node_cp = copy(node)
        node_cp.test = self.visit(node.test)
        node_cp.body = self.visit_sequence(node.body)
        node_cp.orelse = self.visit_sequence(node.orelse)
        return node_cp

    def visit_For(self, node: For) -> For:
        node_cp = copy(node)
        node_cp.target = self.visit(node.target)
        node_cp.iter = self.visit(node.iter)
        node_cp.body = self.visit_sequence(node.body)
        node_cp.orelse = self.visit_sequence(node.orelse)
        return node_cp

Ancestors

Class variables

var step

Methods

def visit(self, node)

Inherited from: ScopedSequenceNodeTransformer.visit

Visit a node.

def visit_For(self, node: ast.For) ‑> ast.For
Expand source code
def visit_For(self, node: For) -> For:
    node_cp = copy(node)
    node_cp.target = self.visit(node.target)
    node_cp.iter = self.visit(node.iter)
    node_cp.body = self.visit_sequence(node.body)
    node_cp.orelse = self.visit_sequence(node.orelse)
    return node_cp
def visit_If(self, node: ast.If) ‑> ast.If
Expand source code
def visit_If(self, node: If) -> If:
    node_cp = copy(node)
    node_cp.test = self.visit(node.test)
    node_cp.body = self.visit_sequence(node.body)
    node_cp.orelse = self.visit_sequence(node.orelse)
    return node_cp
def visit_While(self, node: ast.While) ‑> ast.While
Expand source code
def visit_While(self, node: While) -> While:
    node_cp = copy(node)
    node_cp.test = self.visit(node.test)
    node_cp.body = self.visit_sequence(node.body)
    node_cp.orelse = self.visit_sequence(node.orelse)
    return node_cp
def visit_sequence(self, statements)
Expand source code
def visit_sequence(self, statements):
    visited = []
    for stmt in statements:
        if stmt is None:
            continue
        stmt_cp = self.visit(stmt)
        if stmt_cp is None:
            continue
        visited.append(stmt_cp)
        if not getattr(stmt_cp, "can_fall_through", True):
            break
    return visited