def selectNextBuiltinClass(iterator, default, source_ref):
     if default is None:
         return ExpressionBuiltinNext1(value=iterator, source_ref=source_ref)
     else:
         return ExpressionBuiltinNext2(
             iterator=iterator, default=default, source_ref=source_ref
         )
def _makeIteratorNext(qual, iterator_ref, source_ref):
    if getattr(qual, "is_async", 0):
        return ExpressionYieldFromWaitable(
            expression=ExpressionAsyncNext(value=iterator_ref, source_ref=source_ref),
            source_ref=source_ref,
        )
    else:
        return ExpressionBuiltinNext1(value=iterator_ref, source_ref=source_ref)
Exemple #3
0
def getSetUnpackingHelper():
    helper_name = "_unpack_set"

    result = makeInternalHelperFunctionBody(
        name=helper_name,
        parameters=ParameterSpec(
            ps_name=helper_name,
            ps_normal_args=(),
            ps_list_star_arg="args",
            ps_dict_star_arg=None,
            ps_default_count=0,
            ps_kw_only_args=(),
            ps_pos_only_args=(),
        ),
    )

    temp_scope = None

    tmp_result_variable = result.allocateTempVariable(temp_scope, "set")
    tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter")
    tmp_item_variable = result.allocateTempVariable(temp_scope, "keys")

    loop_body = makeStatementsSequenceFromStatements(
        makeTryExceptSingleHandlerNode(
            tried=StatementAssignmentVariable(
                variable=tmp_item_variable,
                source=ExpressionBuiltinNext1(
                    value=ExpressionTempVariableRef(
                        variable=tmp_iter_variable,
                        source_ref=internal_source_ref),
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ),
            exception_name="StopIteration",
            handler_body=StatementLoopBreak(source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        StatementExpressionOnly(
            expression=ExpressionSetOperationUpdate(
                set_arg=ExpressionTempVariableRef(
                    variable=tmp_result_variable,
                    source_ref=internal_source_ref),
                value=ExpressionTempVariableRef(
                    variable=tmp_item_variable,
                    source_ref=internal_source_ref),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
    )

    args_variable = result.getVariableForAssignment(variable_name="args")

    final = (
        StatementReleaseVariable(variable=tmp_result_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_iter_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_item_variable,
                                 source_ref=internal_source_ref),
    )

    tried = makeStatementsSequenceFromStatements(
        StatementAssignmentVariable(
            variable=tmp_iter_variable,
            source=ExpressionBuiltinIter1(
                value=ExpressionVariableRef(variable=args_variable,
                                            source_ref=internal_source_ref),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
        StatementAssignmentVariable(
            variable=tmp_result_variable,
            source=makeConstantRefNode(constant=set(),
                                       source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        StatementLoop(body=loop_body, source_ref=internal_source_ref),
        StatementReturn(
            expression=ExpressionTempVariableRef(
                variable=tmp_result_variable, source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
    )

    result.setBody(
        makeStatementsSequenceFromStatement(
            makeTryFinallyStatement(
                provider=result,
                tried=tried,
                final=final,
                source_ref=internal_source_ref,
            )))

    return result
Exemple #4
0
def getClassBasesMroConversionHelper():
    helper_name = "_mro_entries_conversion"

    result = makeInternalHelperFunctionBody(
        name=helper_name,
        parameters=ParameterSpec(
            ps_name=helper_name,
            ps_normal_args=("bases", ),
            ps_pos_only_args=(),
            ps_list_star_arg=None,
            ps_dict_star_arg=None,
            ps_default_count=0,
            ps_kw_only_args=(),
        ),
        inline_const_args=False,  # TODO: Allow this.
    )

    temp_scope = None

    tmp_result_variable = result.allocateTempVariable(temp_scope, "list")
    tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter")
    tmp_item_variable = result.allocateTempVariable(temp_scope, "base")

    args_variable = result.getVariableForAssignment(variable_name="bases")

    non_type_case = makeStatementConditional(
        condition=ExpressionAttributeCheck(
            expression=ExpressionTempVariableRef(
                variable=tmp_item_variable, source_ref=internal_source_ref),
            attribute_name="__mro_entries__",
            source_ref=internal_source_ref,
        ),
        yes_branch=StatementExpressionOnly(
            expression=ExpressionListOperationExtend(
                list_arg=ExpressionTempVariableRef(
                    variable=tmp_result_variable,
                    source_ref=internal_source_ref),
                value=makeExpressionCall(
                    called=ExpressionAttributeLookup(
                        expression=ExpressionTempVariableRef(
                            variable=tmp_item_variable,
                            source_ref=internal_source_ref),
                        attribute_name="__mro_entries__",
                        source_ref=internal_source_ref,
                    ),
                    args=makeExpressionMakeTuple(
                        elements=(ExpressionVariableRef(
                            variable=args_variable,
                            source_ref=internal_source_ref), ),
                        source_ref=internal_source_ref,
                    ),
                    kw=None,
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
        no_branch=StatementListOperationAppend(
            list_arg=ExpressionTempVariableRef(variable=tmp_result_variable,
                                               source_ref=internal_source_ref),
            value=ExpressionTempVariableRef(variable=tmp_item_variable,
                                            source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        source_ref=internal_source_ref,
    )

    type_case = StatementListOperationAppend(
        list_arg=ExpressionTempVariableRef(variable=tmp_result_variable,
                                           source_ref=internal_source_ref),
        value=ExpressionTempVariableRef(variable=tmp_item_variable,
                                        source_ref=internal_source_ref),
        source_ref=internal_source_ref,
    )

    loop_body = makeStatementsSequenceFromStatements(
        makeTryExceptSingleHandlerNode(
            tried=StatementAssignmentVariable(
                variable=tmp_item_variable,
                source=ExpressionBuiltinNext1(
                    value=ExpressionTempVariableRef(
                        variable=tmp_iter_variable,
                        source_ref=internal_source_ref),
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ),
            exception_name="StopIteration",
            handler_body=StatementLoopBreak(source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        makeStatementConditional(
            condition=ExpressionConditionalAnd(
                left=ExpressionBuiltinIsinstance(
                    instance=ExpressionTempVariableRef(
                        variable=tmp_item_variable,
                        source_ref=internal_source_ref),
                    classes=makeConstantRefNode(
                        constant=type, source_ref=internal_source_ref),
                    source_ref=internal_source_ref,
                ),
                right=ExpressionBuiltinIssubclass(
                    cls=ExpressionTempVariableRef(
                        variable=tmp_item_variable,
                        source_ref=internal_source_ref),
                    classes=makeConstantRefNode(
                        constant=type, source_ref=internal_source_ref),
                    source_ref=internal_source_ref,
                ),
                source_ref=internal_source_ref,
            ),
            yes_branch=type_case,
            no_branch=non_type_case,
            source_ref=internal_source_ref,
        ),
    )

    final = (
        StatementReleaseVariable(variable=args_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_result_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_iter_variable,
                                 source_ref=internal_source_ref),
        StatementReleaseVariable(variable=tmp_item_variable,
                                 source_ref=internal_source_ref),
    )

    tried = makeStatementsSequenceFromStatements(
        StatementAssignmentVariable(
            variable=tmp_iter_variable,
            source=ExpressionBuiltinIter1(
                value=ExpressionVariableRef(variable=args_variable,
                                            source_ref=internal_source_ref),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
        StatementAssignmentVariable(
            variable=tmp_result_variable,
            source=makeConstantRefNode(constant=[],
                                       source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        StatementLoop(loop_body=loop_body, source_ref=internal_source_ref),
        StatementReturn(
            expression=ExpressionBuiltinTuple(
                value=ExpressionTempVariableRef(
                    variable=tmp_result_variable,
                    source_ref=internal_source_ref),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
    )

    result.setChild(
        "body",
        makeStatementsSequenceFromStatement(
            makeTryFinallyStatement(
                provider=result,
                tried=tried,
                final=final,
                source_ref=internal_source_ref,
            )),
    )

    return result
Exemple #5
0
def getDictUnpackingHelper():
    helper_name = "_unpack_dict"

    result = ExpressionFunctionBody(
        provider   = getInternalModule(),
        name       = helper_name,
        doc        = None,
        parameters = ParameterSpec(
            ps_name          = helper_name,
            ps_normal_args   = (),
            ps_list_star_arg = "args",
            ps_dict_star_arg = None,
            ps_default_count = 0,
            ps_kw_only_args  = ()
        ),
        flags      = set(),
        source_ref = internal_source_ref
    )

    temp_scope = None

    tmp_result_variable = result.allocateTempVariable(temp_scope, "dict")
    tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter")
    tmp_item_variable = result.allocateTempVariable(temp_scope, "keys")

    loop_body = makeStatementsSequenceFromStatements(
        makeTryExceptSingleHandlerNode(
            tried          = StatementAssignmentVariable(
                variable   = tmp_item_variable,
                source     = ExpressionBuiltinNext1(
                    value      = ExpressionTempVariableRef(
                        variable   = tmp_iter_variable,
                        source_ref = internal_source_ref
                    ),
                    source_ref = internal_source_ref
                ),
                source_ref = internal_source_ref
            ),
            exception_name = "StopIteration",
            handler_body   = StatementLoopBreak(
                source_ref = internal_source_ref
            ),
            source_ref     = internal_source_ref
        ),
        makeTryExceptSingleHandlerNode(
            tried          = StatementDictOperationUpdate(
                dict_arg   = ExpressionTempVariableRef(
                    variable   = tmp_result_variable,
                    source_ref = internal_source_ref
                ),
                value      = ExpressionTempVariableRef(
                    variable   = tmp_item_variable,
                    source_ref = internal_source_ref
                ),
                source_ref = internal_source_ref
            ),
            exception_name = "AttributeError",
            handler_body   = StatementRaiseException(
                exception_type  = ExpressionBuiltinMakeException(
                    exception_name = "TypeError",
                    args           = (
                        makeBinaryOperationNode(
                            operator   = "Mod",
                            left       =  makeConstantRefNode(
                                constant      = """\
'%s' object is not a mapping""",
                                source_ref    = internal_source_ref,
                                user_provided = True
                            ),
                            right      = ExpressionMakeTuple(
                                elements   = (
                                    ExpressionAttributeLookup(
                                        source         = ExpressionBuiltinType1(
                                            value      = ExpressionTempVariableRef(
                                                variable   = tmp_item_variable,
                                                source_ref = internal_source_ref
                                            ),
                                            source_ref = internal_source_ref
                                        ),
                                        attribute_name = "__name__",
                                        source_ref     = internal_source_ref
                                    ),
                                ),
                                source_ref = internal_source_ref
                            ),
                            source_ref = internal_source_ref
                        ),
                    ),
                    source_ref     = internal_source_ref
                ),
                exception_value = None,
                exception_trace = None,
                exception_cause = None,
                source_ref      = internal_source_ref
            ),
            source_ref     = internal_source_ref
        )
    )

    args_variable = result.getVariableForAssignment(
        variable_name = "args"
    )

    final = (
        StatementReleaseVariable(
            variable   = tmp_result_variable,
            source_ref = internal_source_ref
        ),
        StatementReleaseVariable(
            variable   = tmp_iter_variable,
            source_ref = internal_source_ref
        ),
        StatementReleaseVariable(
            variable   = tmp_item_variable,
            source_ref = internal_source_ref
        ),
        # We get handed our args responsibility.
        StatementDelVariable(
            variable   = args_variable,
            tolerant   = False,
            source_ref = internal_source_ref
        )
    )

    tried = makeStatementsSequenceFromStatements(
        StatementAssignmentVariable(
            variable   = tmp_iter_variable,
            source     = ExpressionBuiltinIter1(
                value      = ExpressionVariableRef(
                    variable   = args_variable,
                    source_ref = internal_source_ref
                ),
                source_ref = internal_source_ref
            ),
            source_ref = internal_source_ref
        ),
        StatementAssignmentVariable(
            variable   = tmp_result_variable,
            source     = makeConstantRefNode(
                constant   = {},
                source_ref = internal_source_ref
            ),
            source_ref = internal_source_ref
        ),
        StatementLoop(
            body       = loop_body,
            source_ref = internal_source_ref
        ),
        StatementReturn(
            expression = ExpressionTempVariableRef(
                variable   = tmp_result_variable,
                source_ref = internal_source_ref
            ),
            source_ref = internal_source_ref
        )
    )

    result.setBody(
        makeStatementsSequenceFromStatement(
            makeTryFinallyStatement(
                provider   = result,
                tried      = tried,
                final      = final,
                source_ref = internal_source_ref
            )
        )
    )

    return result
Exemple #6
0
def _buildForLoopNode(provider, node, sync, source_ref):
    # The for loop is re-formulated according to developer manual. An iterator
    # is created, and looped until it gives StopIteration. The else block is
    # taken if a for loop exits normally, i.e. because of iterator
    # exhaustion. We do this by introducing an indicator variable.

    # We handle async and sync both here, leading to cases, pylint: disable=too-many-locals

    source = buildNode(provider, node.iter, source_ref)

    # Temporary variables, we need one for the iterator, and one for the current
    # value.
    temp_scope = provider.allocateTempScope("for_loop")

    tmp_iter_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "for_iterator"
    )
    tmp_value_variable = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "iter_value"
    )

    else_block = buildStatementsNode(
        provider   = provider,
        nodes      = node.orelse if node.orelse else None,
        source_ref = source_ref
    )

    if else_block is not None:
        tmp_break_indicator = provider.allocateTempVariable(
            temp_scope = temp_scope,
            name       = "break_indicator"
        )

        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_break_indicator,
                    source_ref = source_ref
                ),
                source       = makeConstantRefNode(
                    constant   = True,
                    source_ref = source_ref
                ),
                source_ref   = source_ref
            )
        ]
    else:
        statements = []

    statements.append(
        StatementLoopBreak(
            source_ref = source_ref
        )
    )

    handler_body = makeStatementsSequence(
        statements = statements,
        allow_none = False,
        source_ref = source_ref
    )

    if sync:
        next_node = ExpressionBuiltinNext1(
            value      = ExpressionTempVariableRef(
                variable   = tmp_iter_variable,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    else:
        next_node = ExpressionAsyncNext(
            value      = ExpressionTempVariableRef(
                variable   = tmp_iter_variable,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )

    statements = (
        makeTryExceptSingleHandlerNode(
            tried          = StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_value_variable,
                    source_ref = source_ref
                ),
                source       = next_node,
                source_ref   = source_ref
            ),
            exception_name = "StopIteration" if sync else "StopAsyncIteration",
            handler_body   = handler_body,
            source_ref     = source_ref
        ),
        buildAssignmentStatements(
            provider   = provider,
            node       = node.target,
            source     = ExpressionTempVariableRef(
                variable   = tmp_value_variable,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    )

    pushBuildContext("loop_body")
    statements += (
        buildStatementsNode(
            provider   = provider,
            nodes      = node.body,
            source_ref = source_ref
        ),
    )
    popBuildContext()

    loop_body = makeStatementsSequence(
        statements = statements,
        allow_none = True,
        source_ref = source_ref
    )

    cleanup_statements = [
        StatementReleaseVariable(
            variable   = tmp_value_variable,
            source_ref = source_ref
        ),
        StatementReleaseVariable(
            variable   = tmp_iter_variable,
            source_ref = source_ref
        )
    ]

    if else_block is not None:
        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_break_indicator,
                    source_ref = source_ref
                ),
                source       = makeConstantRefNode(
                    constant   = False,
                    source_ref = source_ref
                ),
                source_ref   = source_ref
            )
        ]
    else:
        statements = []

    if sync:
        iter_source = ExpressionBuiltinIter1(
            value      = source,
            source_ref = source.getSourceReference()
        )
    else:
        iter_source = ExpressionAsyncIter(
            value      = source,
            source_ref = source.getSourceReference()
        )

    statements += [
        # First create the iterator and store it.
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_iter_variable,
                source_ref = source_ref
            ),
            source       = iter_source,
            source_ref   = source_ref
        ),
        makeTryFinallyStatement(
            provider   = provider,
            tried      = StatementLoop(
                body       = loop_body,
                source_ref = source_ref
            ),
            final      = StatementsSequence(
                statements = cleanup_statements,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    ]

    if else_block is not None:
        statements += [
            StatementConditional(
                condition  = ExpressionComparisonIs(
                    left       = ExpressionTempVariableRef(
                        variable   = tmp_break_indicator,
                        source_ref = source_ref
                    ),
                    right      = makeConstantRefNode(
                        constant   = True,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_branch = else_block,
                no_branch  = None,
                source_ref = source_ref
            )
        ]

        statements = (
            makeTryFinallyStatement(
                provider   = provider,
                tried      = statements,
                final      = StatementReleaseVariable(
                    variable   = tmp_break_indicator,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
        )

    return makeStatementsSequenceFromStatements(
        *statements
    )
Exemple #7
0
def _buildContractionBodyNode(provider, node, emit_class, start_value,
                              container_tmp, iter_tmp, temp_scope,
                              assign_provider, function_body, source_ref):

    # This uses lots of variables and branches. There is no good way
    # around that, and we deal with many cases, due to having generator
    # expressions sharing this code, pylint: disable=too-many-branches,too-many-locals

    # Note: The assign_provider is only to cover Python2 list contractions,
    # assigning one of the loop variables to the outside scope.

    tmp_variables = []

    if assign_provider:
        tmp_variables.append(iter_tmp)

    if container_tmp is not None:
        tmp_variables.append(container_tmp)

    # First assign the iterator if we are an outline.
    if assign_provider:
        statements = [
            StatementAssignmentVariable(
                variable_ref=makeVariableTargetRefNode(variable=iter_tmp,
                                                       source_ref=source_ref),
                source=ExpressionBuiltinIter1(value=buildNode(
                    provider=provider,
                    node=node.generators[0].iter,
                    source_ref=source_ref),
                                              source_ref=source_ref),
                source_ref=source_ref.atInternal())
        ]
    else:
        statements = []

    if start_value is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=container_tmp, source_ref=source_ref),
                source=start_value,
                source_ref=source_ref.atInternal()))

    if hasattr(node, "elt"):
        if start_value is not None:
            current_body = emit_class(ExpressionTempVariableRef(
                variable=container_tmp, source_ref=source_ref),
                                      buildNode(provider=function_body,
                                                node=node.elt,
                                                source_ref=source_ref),
                                      source_ref=source_ref)
        else:
            assert emit_class is ExpressionYield

            current_body = emit_class(buildNode(provider=function_body,
                                                node=node.elt,
                                                source_ref=source_ref),
                                      source_ref=source_ref)
    else:
        assert emit_class is StatementDictOperationSet

        current_body = StatementDictOperationSet(
            dict_arg=ExpressionTempVariableRef(variable=container_tmp,
                                               source_ref=source_ref),
            key=buildNode(
                provider=function_body,
                node=node.key,
                source_ref=source_ref,
            ),
            value=buildNode(
                provider=function_body,
                node=node.value,
                source_ref=source_ref,
            ),
            source_ref=source_ref)

    if current_body.isExpression():
        current_body = StatementExpressionOnly(expression=current_body,
                                               source_ref=source_ref)

    for count, qual in enumerate(reversed(node.generators)):
        tmp_value_variable = function_body.allocateTempVariable(
            temp_scope=temp_scope, name="iter_value_%d" % count)

        tmp_variables.append(tmp_value_variable)

        # The first iterated value is to be calculated outside of the function
        # and will be given as a parameter "_iterated", the others are built
        # inside the function.

        if qual is node.generators[0]:
            iterator_ref = makeVariableRefNode(variable=iter_tmp,
                                               source_ref=source_ref)

            tmp_iter_variable = None

            nested_statements = []
        else:
            # First create the iterator and store it, next should be loop body
            value_iterator = ExpressionBuiltinIter1(value=buildNode(
                provider=function_body, node=qual.iter, source_ref=source_ref),
                                                    source_ref=source_ref)

            tmp_iter_variable = function_body.allocateTempVariable(
                temp_scope=temp_scope, name="contraction_iter_%d" % count)

            tmp_variables.append(tmp_iter_variable)

            nested_statements = [
                StatementAssignmentVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=tmp_iter_variable, source_ref=source_ref),
                    source=value_iterator,
                    source_ref=source_ref)
            ]

            iterator_ref = ExpressionTempVariableRef(
                variable=tmp_iter_variable, source_ref=source_ref)

        loop_statements = [
            makeTryExceptSingleHandlerNode(
                tried=StatementAssignmentVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=tmp_value_variable, source_ref=source_ref),
                    source=ExpressionBuiltinNext1(value=iterator_ref,
                                                  source_ref=source_ref),
                    source_ref=source_ref),
                exception_name="StopIteration",
                handler_body=StatementLoopBreak(
                    source_ref=source_ref.atInternal()),
                source_ref=source_ref),
            buildAssignmentStatements(
                provider=provider if assign_provider else function_body,
                temp_provider=function_body,
                node=qual.target,
                source=ExpressionTempVariableRef(variable=tmp_value_variable,
                                                 source_ref=source_ref),
                source_ref=source_ref)
        ]

        conditions = buildNodeList(provider=function_body,
                                   nodes=qual.ifs,
                                   source_ref=source_ref)

        if len(conditions) >= 1:
            loop_statements.append(
                StatementConditional(
                    condition=buildAndNode(values=conditions,
                                           source_ref=source_ref),
                    yes_branch=makeStatementsSequenceFromStatement(
                        statement=current_body),
                    no_branch=None,
                    source_ref=source_ref))
        else:
            loop_statements.append(current_body)

        nested_statements.append(
            StatementLoop(body=StatementsSequence(
                statements=mergeStatements(loop_statements),
                source_ref=source_ref),
                          source_ref=source_ref))

        if tmp_iter_variable is not None:
            nested_statements.append(
                StatementReleaseVariable(variable=tmp_iter_variable,
                                         source_ref=source_ref))

        current_body = StatementsSequence(statements=mergeStatements(
            nested_statements, False),
                                          source_ref=source_ref)

    statements.append(current_body)
    statements = mergeStatements(statements)

    release_statements = [
        StatementReleaseVariable(variable=tmp_variable, source_ref=source_ref)
        for tmp_variable in tmp_variables
    ]

    return statements, release_statements