def makeTryFinallyStatement(provider, tried, final, source_ref, public_exc = False):
    # Complex handling, due to the many variants, pylint: disable=R0912,R0914

    if type(tried) in (tuple, list):
        tried = makeStatementsSequenceFromStatements(
            *tried
        )
    if type(final) in (tuple, list):
        final = StatementsSequence(
            statements = mergeStatements(final, False),
            source_ref = source_ref
        )

    if tried is not None and not tried.isStatementsSequence():
        tried = makeStatementsSequenceFromStatement(tried)
    if final is not None and not final.isStatementsSequence():
        final = makeStatementsSequenceFromStatement(final)

    if tried is None:
        return final

    if final is None:
        return tried

    if provider is not None:
        tried.parent = provider
        final.parent = provider

    assert tried is not None, source_ref
    assert final is not None, source_ref

    if isDebug():
        final2 = final.makeClone()
        final2.parent = provider

        import nuitka.TreeXML
        if nuitka.TreeXML.Element is not None:
            f1 = final.asXml()
            f2 = final2.asXml()

            def compare(a, b):
                for c1, c2 in zip(a, b):
                    compare(c1, c2)

                assert a.attrib == b.attrib, (a.attrib, b.attrib)

            compare(f1, f2)

    if tried.mayRaiseException(BaseException):
        except_handler = final.makeClone()

        except_handler = getStatementsAppended(
            statement_sequence = except_handler,
            statements         = makeReraiseExceptionStatement(
                source_ref = source_ref
            )
        )

        if public_exc:
            preserver_id = provider.allocatePreserverId()

            except_handler = getStatementsPrepended(
                statement_sequence = except_handler,
                statements         = (
                    StatementPreserveFrameException(
                        preserver_id = preserver_id,
                        source_ref   = source_ref.atInternal()
                    ),
                    StatementPublishException(
                        source_ref = source_ref
                    )
                )
            )

            except_handler = makeTryFinallyStatement(
                provider   = provider,
                tried      = except_handler,
                final      = StatementRestoreFrameException(
                    preserver_id = preserver_id,
                    source_ref   = source_ref.atInternal()
                ),
                public_exc = False,
                source_ref = source_ref,
            )

            except_handler = makeStatementsSequenceFromStatement(
                statement = except_handler
            )

        except_handler.parent = provider
    else:
        except_handler = None

    if tried.mayBreak():
        break_handler = getStatementsAppended(
            statement_sequence = final.makeClone(),
            statements         = StatementLoopBreak(
                source_ref = source_ref
            )
        )

        break_handler.parent = provider
    else:
        break_handler = None

    if tried.mayContinue():
        continue_handler = getStatementsAppended(
            statement_sequence = final.makeClone(),
            statements         = StatementLoopContinue(
                source_ref = source_ref
            )
        )

        continue_handler.parent = provider
    else:
        continue_handler = None

    if tried.mayReturn():
        return_handler = getStatementsAppended(
            statement_sequence = final.makeClone(),
            statements         = StatementReturn(
                expression = ExpressionReturnedValueRef(
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        )

    else:
        return_handler = None

    result = StatementTry(
        tried            = tried,
        except_handler   = except_handler,
        break_handler    = break_handler,
        continue_handler = continue_handler,
        return_handler   = return_handler,
        source_ref       = source_ref
    )

    if result.isStatementAborting():
        return result
    else:
        return makeStatementsSequence(
            statements = (
                result,
                final
            ),
            allow_none = False,
            source_ref = source_ref
        )
def makeTryFinallyStatement(provider, tried, final, source_ref, public_exc = False):
    # Complex handling, due to the many variants, pylint: disable=too-many-branches,too-many-locals

    if type(tried) in (tuple, list):
        tried = makeStatementsSequenceFromStatements(
            *tried
        )
    if type(final) in (tuple, list):
        final = StatementsSequence(
            statements = mergeStatements(final, False),
            source_ref = source_ref
        )

    if tried is not None and not tried.isStatementsSequence():
        tried = makeStatementsSequenceFromStatement(tried)
    if final is not None and not final.isStatementsSequence():
        final = makeStatementsSequenceFromStatement(final)

    if tried is None:
        return final

    if final is None:
        return tried

    if provider is not None:
        tried.parent = provider
        final.parent = provider

    assert tried is not None, source_ref
    assert final is not None, source_ref

    # TODO: Currently it's not possible anymore to get at XML for all codes
    # during the building phase. So this error catcher cannot work currently.
    if False and isDebug():
        final2 = final.makeClone()
        final2.parent = provider

        import nuitka.TreeXML
        if nuitka.TreeXML.Element is not None:
            f1 = final.asXml()
            f2 = final2.asXml()

            def compare(a, b):
                for c1, c2 in zip(a, b):
                    compare(c1, c2)

                assert a.attrib == b.attrib, (a.attrib, b.attrib)

            compare(f1, f2)

    def getFinal():
        # Make a clone of "final" only if necessary.
        if hasattr(getFinal, "used"):
            return final.makeClone()
        else:
            getFinal.used = True
            return final

    if tried.mayRaiseException(BaseException):
        except_handler = getStatementsAppended(
            statement_sequence = getFinal(),
            statements         = makeReraiseExceptionStatement(
                source_ref = source_ref
            )
        )

        if public_exc:
            preserver_id = provider.allocatePreserverId()

            except_handler = getStatementsPrepended(
                statement_sequence = except_handler,
                statements         = (
                    StatementPreserveFrameException(
                        preserver_id = preserver_id,
                        source_ref   = source_ref.atInternal()
                    ),
                    StatementPublishException(
                        source_ref = source_ref
                    )
                )
            )

            except_handler = makeTryFinallyStatement(
                provider   = provider,
                tried      = except_handler,
                final      = StatementRestoreFrameException(
                    preserver_id = preserver_id,
                    source_ref   = source_ref.atInternal()
                ),
                public_exc = False,
                source_ref = source_ref,
            )

            except_handler = makeStatementsSequenceFromStatement(
                statement = except_handler
            )

        except_handler.parent = provider
    else:
        except_handler = None

    if tried.mayBreak():
        break_handler = getStatementsAppended(
            statement_sequence = getFinal(),
            statements         = StatementLoopBreak(
                source_ref = source_ref
            )
        )

        break_handler.parent = provider
    else:
        break_handler = None

    if tried.mayContinue():
        continue_handler = getStatementsAppended(
            statement_sequence = getFinal(),
            statements         = StatementLoopContinue(
                source_ref = source_ref
            )
        )

        continue_handler.parent = provider
    else:
        continue_handler = None

    if tried.mayReturn():
        return_handler = getStatementsAppended(
            statement_sequence = getFinal(),
            statements         = StatementReturn(
                expression = ExpressionReturnedValueRef(
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        )

        return_handler.parent = provider
    else:
        return_handler = None

    result = StatementTry(
        tried            = tried,
        except_handler   = except_handler,
        break_handler    = break_handler,
        continue_handler = continue_handler,
        return_handler   = return_handler,
        source_ref       = source_ref
    )

    if result.isStatementAborting():
        return result
    else:
        return makeStatementsSequence(
            statements = (
                result,
                getFinal()
            ),
            allow_none = False,
            source_ref = source_ref
        )
Exemplo n.º 3
0
def makeTryFinallyStatement(provider,
                            tried,
                            final,
                            source_ref,
                            public_exc=False):
    # Complex handling, due to the many variants, pylint: disable=R0912,R0914

    if type(tried) in (tuple, list):
        tried = makeStatementsSequenceFromStatements(*tried)
    if type(final) in (tuple, list):
        final = StatementsSequence(statements=mergeStatements(final, False),
                                   source_ref=source_ref)

    if tried is not None and not tried.isStatementsSequence():
        tried = makeStatementsSequenceFromStatement(tried)
    if final is not None and not final.isStatementsSequence():
        final = makeStatementsSequenceFromStatement(final)

    if tried is None:
        return final

    if final is None:
        return tried

    if provider is not None:
        tried.parent = provider
        final.parent = provider

    assert tried is not None, source_ref
    assert final is not None, source_ref

    if isDebug():
        final2 = final.makeClone()
        final2.parent = provider

        import nuitka.TreeXML
        if nuitka.TreeXML.Element is not None:
            f1 = final.asXml()
            f2 = final2.asXml()

            def compare(a, b):
                for c1, c2 in zip(a, b):
                    compare(c1, c2)

                assert a.attrib == b.attrib, (a.attrib, b.attrib)

            compare(f1, f2)

    if tried.mayRaiseException(BaseException):
        except_handler = final.makeClone()

        except_handler = getStatementsAppended(
            statement_sequence=except_handler,
            statements=makeReraiseExceptionStatement(source_ref=source_ref))

        if public_exc:
            preserver_id = provider.allocatePreserverId()

            except_handler = getStatementsPrepended(
                statement_sequence=except_handler,
                statements=(StatementPreserveFrameException(
                    preserver_id=preserver_id,
                    source_ref=source_ref.atInternal()),
                            StatementPublishException(source_ref=source_ref)))

            except_handler = makeTryFinallyStatement(
                provider=provider,
                tried=except_handler,
                final=StatementRestoreFrameException(
                    preserver_id=preserver_id,
                    source_ref=source_ref.atInternal()),
                public_exc=False,
                source_ref=source_ref,
            )

            except_handler = makeStatementsSequenceFromStatement(
                statement=except_handler)

        except_handler.parent = provider
    else:
        except_handler = None

    if tried.mayBreak():
        break_handler = getStatementsAppended(
            statement_sequence=final.makeClone(),
            statements=StatementLoopBreak(source_ref=source_ref))

        break_handler.parent = provider
    else:
        break_handler = None

    if tried.mayContinue():
        continue_handler = getStatementsAppended(
            statement_sequence=final.makeClone(),
            statements=StatementLoopContinue(source_ref=source_ref))

        continue_handler.parent = provider
    else:
        continue_handler = None

    if tried.mayReturn():
        return_handler = getStatementsAppended(
            statement_sequence=final.makeClone(),
            statements=StatementReturn(
                expression=ExpressionReturnedValueRef(source_ref=source_ref),
                source_ref=source_ref))

    else:
        return_handler = None

    result = StatementTry(tried=tried,
                          except_handler=except_handler,
                          break_handler=break_handler,
                          continue_handler=continue_handler,
                          return_handler=return_handler,
                          source_ref=source_ref)

    if result.isStatementAborting():
        return result
    else:
        return makeStatementsSequence(statements=(result, final),
                                      allow_none=False,
                                      source_ref=source_ref)