Пример #1
0
    def computeStatement(self, constraint_collection):
        outer_constraint_collection = constraint_collection
        constraint_collection = ConstraintCollectionBranch(
            parent = constraint_collection,
            name   = "loop"
        )

        loop_body, break_collections = self.computeLoopBody(constraint_collection)

        # Consider trailing "continue" statements, these have no effect, so we
        # can remove them.
        if loop_body is not None:
            assert loop_body.isStatementsSequence()

            statements = loop_body.getStatements()
            assert statements # Cannot be empty

            # If the last statement is a "continue" statement, it can simply
            # be discarded.
            last_statement = statements[-1]
            if last_statement.isStatementContinueLoop():
                if len(statements) == 1:
                    self.setLoopBody(None)
                    loop_body = None
                else:
                    last_statement.replaceWith(None)

                constraint_collection.signalChange(
                    "new_statements",
                    last_statement.getSourceReference(),
                    """\
Removed useless terminal 'continue' as last statement of loop."""
                )

        if break_collections:
            outer_constraint_collection.mergeMultipleBranches(break_collections)

        # Consider leading "break" statements, they should be the only, and
        # should lead to removing the whole loop statement. Trailing "break"
        # statements could also be handled, but that would need to consider if
        # there are other "break" statements too. Numbering loop exits is
        # nothing we have yet.
        if loop_body is not None:
            assert loop_body.isStatementsSequence()

            statements = loop_body.getStatements()
            assert statements # Cannot be empty

            if len(statements) == 1 and statements[-1].isStatementBreakLoop():
                return None, "new_statements", """\
Removed useless loop with immediate 'break' statement."""

        # Also consider the threading intermission. TODO: We ought to make it
        # explicit, so we can see it potentially disrupting and changing the
        # global variables. It may also raise.
        outer_constraint_collection.onExceptionRaiseExit(BaseException)

        return self, None, None