Ejemplo n.º 1
0
def buildReturnNode(provider, node, source_ref):
    if not provider.isExpressionFunctionBody() or \
       provider.isClassDictCreation():
        SyntaxErrors.raiseSyntaxError(
            "'return' outside function",
            source_ref,
            None if Utils.python_version < 300 else (
                node.col_offset
                  if provider.isPythonModule() else
                node.col_offset+4
            )
        )

    expression = buildNode(provider, node.value, source_ref, allow_none = True)

    if expression is None:
        expression = ExpressionConstantRef(
            constant      = None,
            source_ref    = source_ref,
            user_provided = True
        )

    # Indicate exceptions to potentially try/finally structures.
    indicator_statements = makeTryFinallyIndicatorStatements(
        is_loop_exit = False,
        source_ref   = source_ref
    )

    if indicator_statements and expression.mayRaiseException(BaseException):
        tmp_variable = provider.allocateTempVariable(
            temp_scope = provider.allocateTempScope("return"),
            name       = "value"
        )

        statements = [
                StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_variable,
                    source_ref = expression.getSourceReference()
                ),
                source       = expression,
                source_ref   = source_ref
            )
        ] + indicator_statements + [
            StatementReturn(
                expression = ExpressionTempVariableRef(
                    variable   = tmp_variable,
                    source_ref = expression.getSourceReference()
                ),
                source_ref = source_ref
            )
        ]

        return makeTryFinallyStatement(
            tried      = statements,
            final      = StatementReleaseVariable(
                variable   = tmp_variable,
                tolerant   = True,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    else:
        return makeStatementsSequenceOrStatement(
            statements = indicator_statements + [
                StatementReturn(
                    expression = expression,
                    source_ref = source_ref
                )
            ],
            source_ref = source_ref
        )