def buildAssignNode( provider, node, source_ref ):
    assert len( node.targets ) >= 1, source_ref

    # Evaluate the right hand side first, so it can get names provided
    # before the left hand side exists.
    source = buildNode( provider, node.value, source_ref )

    if len( node.targets ) == 1:
        # Simple assignment case, one source, one target.

        return buildAssignmentStatements(
            provider   = provider,
            node       = node.targets[0],
            source     = source,
            source_ref = source_ref
        )
    else:
        # Complex assignment case, one source, but multiple targets. We keep the source in
        # a temporary variable, and then assign from it multiple times.

        result = StatementTempBlock(
            source_ref = source_ref
        )

        tmp_source = result.getTempVariable( "assign_source" )

        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_source.makeReference( result ),
                    source_ref = source_ref
                ),
                source       = source,
                source_ref   = source_ref
            )
        ]

        for target in node.targets:
            statements.append(
                buildAssignmentStatements(
                    provider   = provider,
                    node       = target,
                    source     = ExpressionTempVariableRef(
                        variable   = tmp_source.makeReference( result ),
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                )
            )

        result.setBody(
            StatementsSequence(
                statements = statements,
                source_ref = source_ref
            )
        )

        return result
def buildAssignNode(provider, node, source_ref):
    assert len(node.targets) >= 1, source_ref

    # Evaluate the right hand side first, so it can get names provided
    # before the left hand side exists.
    source = buildNode(provider, node.value, source_ref)

    if len(node.targets) == 1:
        # Simple assignment case, one source, one target.

        return buildAssignmentStatements(provider=provider,
                                         node=node.targets[0],
                                         source=source,
                                         source_ref=source_ref)
    else:
        # Complex assignment case, one source, but multiple targets. We keep the source in
        # a temporary variable, and then assign from it multiple times.

        result = StatementTempBlock(source_ref=source_ref)

        tmp_source = result.getTempVariable("assign_source")

        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_source.makeReference(result),
                    source_ref=source_ref),
                source=source,
                source_ref=source_ref)
        ]

        for target in node.targets:
            statements.append(
                buildAssignmentStatements(
                    provider=provider,
                    node=target,
                    source=ExpressionTempVariableRef(
                        variable=tmp_source.makeReference(result),
                        source_ref=source_ref),
                    source_ref=source_ref))

        result.setBody(
            StatementsSequence(statements=statements, source_ref=source_ref))

        return result
Exemplo n.º 3
0
def _buildClassNode3(provider, node, source_ref):
    # Many variables, due to the huge re-formulation that is going on here, which just has
    # the complexity, pylint: disable=R0914

    # This function is the Python3 special case with special re-formulation as according
    # to developer manual.
    class_statements, class_doc = extractDocFromBody(node)

    # The result will be a temp block that holds the temporary variables.
    result = StatementTempBlock(source_ref=source_ref)

    tmp_bases = result.getTempVariable("bases")
    tmp_class_decl_dict = result.getTempVariable("class_decl_dict")
    tmp_metaclass = result.getTempVariable("metaclass")
    tmp_prepared = result.getTempVariable("prepared")

    class_creation_function = ExpressionFunctionBody(
        provider=provider,
        is_class=True,
        parameters=make_class_parameters,
        name=node.name,
        doc=class_doc,
        source_ref=source_ref)

    # Hack:
    class_creation_function.parent = provider

    body = buildStatementsNode(provider=class_creation_function,
                               nodes=class_statements,
                               frame=True,
                               source_ref=source_ref)

    if body is not None:
        # The frame guard has nothing to tell its line number to.
        body.source_ref = source_ref.atInternal()

    statements = [
        StatementSetLocals(new_locals=ExpressionTempVariableRef(
            variable=tmp_prepared.makeReference(result),
            source_ref=source_ref),
                           source_ref=source_ref.atInternal()),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetVariableRef(
                variable_name="__module__", source_ref=source_ref),
            source=ExpressionConstantRef(
                constant=provider.getParentModule().getName(),
                source_ref=source_ref),
            source_ref=source_ref.atInternal())
    ]

    if class_doc is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetVariableRef(
                    variable_name="__doc__", source_ref=source_ref),
                source=ExpressionConstantRef(constant=class_doc,
                                             source_ref=source_ref),
                source_ref=source_ref.atInternal()))

    if Utils.python_version >= 330:
        if provider.isExpressionFunctionBody():
            qualname = provider.getName() + ".<locals>." + node.name
        else:
            qualname = node.name

        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetVariableRef(
                    variable_name="__qualname__", source_ref=source_ref),
                source=ExpressionConstantRef(constant=qualname,
                                             source_ref=source_ref),
                source_ref=source_ref.atInternal()))

    statements += [
        body,
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetVariableRef(variable_name="__class__",
                                                     source_ref=source_ref),
            source=ExpressionCall(
                called=ExpressionTempVariableRef(
                    variable=tmp_metaclass.makeReference(result),
                    source_ref=source_ref),
                args=ExpressionMakeTuple(
                    elements=(ExpressionConstantRef(constant=node.name,
                                                    source_ref=source_ref),
                              ExpressionTempVariableRef(
                                  variable=tmp_bases.makeReference(result),
                                  source_ref=source_ref),
                              ExpressionBuiltinLocals(source_ref=source_ref)),
                    source_ref=source_ref),
                kw=ExpressionTempVariableRef(
                    variable=tmp_class_decl_dict.makeReference(result),
                    source_ref=source_ref),
                source_ref=source_ref),
            source_ref=source_ref.atInternal()),
        StatementReturn(expression=ExpressionVariableRef(
            variable_name="__class__", source_ref=source_ref),
                        source_ref=source_ref.atInternal())
    ]

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

    # The class body is basically a function that implicitely, at the end returns its
    # locals and cannot have other return statements contained.

    class_creation_function.setBody(body)

    # The class body is basically a function that implicitely, at the end returns its
    # created class and cannot have other return statements contained.

    decorated_body = ExpressionFunctionCall(
        function=ExpressionFunctionCreation(function_ref=ExpressionFunctionRef(
            function_body=class_creation_function, source_ref=source_ref),
                                            defaults=(),
                                            kw_defaults=None,
                                            annotations=None,
                                            source_ref=source_ref),
        values=(),
        source_ref=source_ref)

    for decorator in buildNodeList(provider, reversed(node.decorator_list),
                                   source_ref):
        decorated_body = ExpressionCallNoKeywords(
            called=decorator,
            args=ExpressionMakeTuple(elements=(decorated_body, ),
                                     source_ref=source_ref),
            source_ref=decorator.getSourceReference())

    statements = [
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_bases.makeReference(result),
                source_ref=source_ref),
            source=ExpressionMakeTuple(elements=buildNodeList(
                provider, node.bases, source_ref),
                                       source_ref=source_ref),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_class_decl_dict.makeReference(result),
                source_ref=source_ref),
            source=ExpressionMakeDict(pairs=[
                ExpressionKeyValuePair(
                    key=ExpressionConstantRef(constant=keyword.arg,
                                              source_ref=source_ref),
                    value=buildNode(provider, keyword.value, source_ref),
                    source_ref=source_ref) for keyword in node.keywords
            ],
                                      source_ref=source_ref),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_metaclass.makeReference(result),
                source_ref=source_ref),
            source=ExpressionSelectMetaclass(
                metaclass=ExpressionConditional(
                    condition=ExpressionComparison(
                        comparator="In",
                        left=ExpressionConstantRef(constant="metaclass",
                                                   source_ref=source_ref),
                        right=ExpressionTempVariableRef(
                            variable=tmp_class_decl_dict.makeReference(result),
                            source_ref=source_ref),
                        source_ref=source_ref),
                    yes_expression=ExpressionDictOperationGet(
                        dicte=ExpressionTempVariableRef(
                            variable=tmp_class_decl_dict.makeReference(result),
                            source_ref=source_ref),
                        key=ExpressionConstantRef(constant="metaclass",
                                                  source_ref=source_ref),
                        source_ref=source_ref),
                    no_expression=ExpressionConditional(
                        condition=ExpressionTempVariableRef(
                            variable=tmp_bases.makeReference(result),
                            source_ref=source_ref),
                        no_expression=ExpressionBuiltinRef(
                            builtin_name="type", source_ref=source_ref),
                        yes_expression=ExpressionBuiltinType1(
                            value=ExpressionSubscriptLookup(
                                expression=ExpressionTempVariableRef(
                                    variable=tmp_bases.makeReference(result),
                                    source_ref=source_ref),
                                subscript=ExpressionConstantRef(
                                    constant=0, source_ref=source_ref),
                                source_ref=source_ref),
                            source_ref=source_ref),
                        source_ref=source_ref),
                    source_ref=source_ref),
                bases=ExpressionTempVariableRef(
                    variable=tmp_bases.makeReference(result),
                    source_ref=source_ref),
                source_ref=source_ref),
            source_ref=source_ref),
        StatementConditional(
            condition=ExpressionComparison(
                comparator="In",
                left=ExpressionConstantRef(constant="metaclass",
                                           source_ref=source_ref),
                right=ExpressionTempVariableRef(
                    variable=tmp_class_decl_dict.makeReference(result),
                    source_ref=source_ref),
                source_ref=source_ref),
            no_branch=None,
            yes_branch=makeStatementsSequenceFromStatement(
                statement=StatementDictOperationRemove(
                    dicte=ExpressionTempVariableRef(
                        variable=tmp_class_decl_dict.makeReference(result),
                        source_ref=source_ref),
                    key=ExpressionConstantRef(constant="metaclass",
                                              source_ref=source_ref),
                    source_ref=source_ref)),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_prepared.makeReference(result),
                source_ref=source_ref),
            source=ExpressionConditional(
                condition=ExpressionBuiltinHasattr(
                    object=ExpressionTempVariableRef(
                        variable=tmp_metaclass.makeReference(result),
                        source_ref=source_ref),
                    name=ExpressionConstantRef(constant="__prepare__",
                                               source_ref=source_ref),
                    source_ref=source_ref),
                no_expression=ExpressionConstantRef(constant={},
                                                    source_ref=source_ref),
                yes_expression=ExpressionCall(
                    called=ExpressionAttributeLookup(
                        expression=ExpressionTempVariableRef(
                            variable=tmp_metaclass.makeReference(result),
                            source_ref=source_ref),
                        attribute_name="__prepare__",
                        source_ref=source_ref),
                    args=ExpressionMakeTuple(
                        elements=(ExpressionConstantRef(constant=node.name,
                                                        source_ref=source_ref),
                                  ExpressionTempVariableRef(
                                      variable=tmp_bases.makeReference(result),
                                      source_ref=source_ref)),
                        source_ref=source_ref),
                    kw=ExpressionTempVariableRef(
                        variable=tmp_class_decl_dict.makeReference(result),
                        source_ref=source_ref),
                    source_ref=source_ref),
                source_ref=source_ref),
            source_ref=source_ref),
        StatementAssignmentVariable(variable_ref=ExpressionTargetVariableRef(
            variable_name=node.name, source_ref=source_ref),
                                    source=decorated_body,
                                    source_ref=source_ref)
    ]

    result.setBody(
        StatementsSequence(statements=statements, source_ref=source_ref))

    return result
Exemplo n.º 4
0
def _buildClassNode2(provider, node, source_ref):
    class_statements, class_doc = extractDocFromBody(node)

    # This function is the Python3 special case with special re-formulation as according
    # to developer manual.

    # The result will be a temp block that holds the temporary variables.
    result = StatementTempBlock(source_ref=source_ref)

    tmp_bases = result.getTempVariable("bases")
    tmp_class_dict = result.getTempVariable("class_dict")
    tmp_metaclass = result.getTempVariable("metaclass")
    tmp_class = result.getTempVariable("class")

    class_creation_function = ExpressionFunctionBody(
        provider=provider,
        is_class=True,
        parameters=make_class_parameters,
        name=node.name,
        doc=class_doc,
        source_ref=source_ref)

    body = buildStatementsNode(provider=class_creation_function,
                               nodes=class_statements,
                               frame=True,
                               source_ref=source_ref)

    if body is not None:
        # The frame guard has nothing to tell its line number to.
        body.source_ref = source_ref.atInternal()

    # The class body is basically a function that implicitely, at the end returns its
    # locals and cannot have other return statements contained, and starts out with a
    # variables "__module__" and potentially "__doc__" set.
    statements = [
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetVariableRef(
                variable_name="__module__", source_ref=source_ref),
            source=ExpressionConstantRef(
                constant=provider.getParentModule().getName(),
                source_ref=source_ref),
            source_ref=source_ref.atInternal())
    ]

    if class_doc is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetVariableRef(
                    variable_name="__doc__", source_ref=source_ref),
                source=ExpressionConstantRef(constant=class_doc,
                                             source_ref=source_ref),
                source_ref=source_ref.atInternal()))

    statements += [
        body,
        StatementReturn(
            expression=ExpressionBuiltinLocals(source_ref=source_ref),
            source_ref=source_ref.atInternal())
    ]

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

    # The class body is basically a function that implicitely, at the end returns its
    # locals and cannot have other return statements contained.

    class_creation_function.setBody(body)

    statements = [
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_bases.makeReference(result),
                source_ref=source_ref),
            source=ExpressionMakeTuple(elements=buildNodeList(
                provider, node.bases, source_ref),
                                       source_ref=source_ref),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_class_dict.makeReference(result),
                source_ref=source_ref),
            source=ExpressionFunctionCall(function=ExpressionFunctionCreation(
                function_ref=ExpressionFunctionRef(
                    function_body=class_creation_function,
                    source_ref=source_ref),
                defaults=(),
                kw_defaults=None,
                annotations=None,
                source_ref=source_ref),
                                          values=(),
                                          source_ref=source_ref),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_metaclass.makeReference(result),
                source_ref=source_ref),
            source=ExpressionConditional(
                condition=ExpressionComparison(
                    comparator="In",
                    left=ExpressionConstantRef(constant="__metaclass__",
                                               source_ref=source_ref),
                    right=ExpressionTempVariableRef(
                        variable=tmp_class_dict.makeReference(result),
                        source_ref=source_ref),
                    source_ref=source_ref),
                yes_expression=ExpressionDictOperationGet(
                    dicte=ExpressionTempVariableRef(
                        variable=tmp_class_dict.makeReference(result),
                        source_ref=source_ref),
                    key=ExpressionConstantRef(constant="__metaclass__",
                                              source_ref=source_ref),
                    source_ref=source_ref),
                no_expression=ExpressionSelectMetaclass(
                    metaclass=None,
                    bases=ExpressionTempVariableRef(
                        variable=tmp_bases.makeReference(result),
                        source_ref=source_ref),
                    source_ref=source_ref),
                source_ref=source_ref),
            source_ref=source_ref),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_class.makeReference(result),
                source_ref=source_ref),
            source=ExpressionCallNoKeywords(
                called=ExpressionTempVariableRef(
                    variable=tmp_metaclass.makeReference(result),
                    source_ref=source_ref),
                args=ExpressionMakeTuple(elements=(
                    ExpressionConstantRef(constant=node.name,
                                          source_ref=source_ref),
                    ExpressionTempVariableRef(
                        variable=tmp_bases.makeReference(result),
                        source_ref=source_ref),
                    ExpressionTempVariableRef(
                        variable=tmp_class_dict.makeReference(result),
                        source_ref=source_ref)),
                                         source_ref=source_ref),
                source_ref=source_ref),
            source_ref=source_ref)
    ]

    for decorator in buildNodeList(provider, reversed(node.decorator_list),
                                   source_ref):
        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_class.makeReference(result),
                    source_ref=source_ref),
                source=ExpressionCallNoKeywords(
                    called=decorator,
                    args=ExpressionMakeTuple(
                        elements=(ExpressionTempVariableRef(
                            variable=tmp_class.makeReference(result),
                            source_ref=source_ref), ),
                        source_ref=source_ref),
                    source_ref=decorator.getSourceReference()),
                source_ref=decorator.getSourceReference()))

    statements.append(
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetVariableRef(variable_name=node.name,
                                                     source_ref=source_ref),
            source=ExpressionTempVariableRef(
                variable=tmp_class.makeReference(result),
                source_ref=source_ref),
            source_ref=source_ref))

    result.setBody(
        StatementsSequence(statements=statements, source_ref=source_ref))

    return result
def buildForLoopNode( provider, node, 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.

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

    result = StatementTempBlock(
        source_ref = source_ref
    )

    tmp_iter_variable = result.getTempVariable( "for_iterator" )

    iterate_tmp_block = StatementTempBlock(
        source_ref = source_ref
    )

    tmp_value_variable = iterate_tmp_block.getTempVariable( "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_variable = result.getTempVariable( "break_indicator" )

        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_break_indicator_variable.makeReference( result ),
                    source_ref = source_ref
                ),
                source     = ExpressionConstantRef(
                    constant   = True,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        ]
    else:
        statements = []

    statements.append(
        StatementBreakLoop(
            source_ref = source_ref.atInternal()
        )
    )

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

    statements = (
        makeTryExceptSingleHandlerNode(
            tried         = makeStatementsSequenceFromStatement(
                statement = StatementAssignmentVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = tmp_value_variable.makeReference( iterate_tmp_block ),
                        source_ref = source_ref
                    ),
                    source     = ExpressionBuiltinNext1(
                        value      = ExpressionTempVariableRef(
                            variable   = tmp_iter_variable.makeReference( result ),
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                )
            ),
            exception_name = "StopIteration",
            handler_body   = handler_body,
            source_ref     = source_ref
        ),
        buildAssignmentStatements(
            provider   = provider,
            node       = node.target,
            source     = ExpressionTempVariableRef(
                variable   = tmp_value_variable.makeReference( iterate_tmp_block ),
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    )

    iterate_tmp_block.setBody(
        StatementsSequence(
            statements = statements,
            source_ref = source_ref
        )
    )

    statements = (
        iterate_tmp_block,
        buildStatementsNode(
            provider   = provider,
            nodes      = node.body,
            source_ref = source_ref
        )
    )

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

    if else_block is not None:
        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_break_indicator_variable.makeReference( result ),
                    source_ref = source_ref
                ),
                source     = ExpressionConstantRef(
                    constant = False,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        ]
    else:
        statements = []

    statements += [
        # First create the iterator and store it.
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_iter_variable.makeReference( result ),
                source_ref = source_ref
            ),
            source     = ExpressionBuiltinIter1(
                value       = source,
                source_ref  = source.getSourceReference()
            ),
            source_ref = source_ref
        ),
        StatementLoop(
            body       = loop_body,
            source_ref = source_ref
        )
    ]

    if else_block is not None:
        statements += [
            StatementConditional(
                condition  = ExpressionComparisonIs(
                    left       = ExpressionTempVariableRef(
                        variable   = tmp_break_indicator_variable.makeReference( result ),
                        source_ref = source_ref
                    ),
                    right      = ExpressionConstantRef(
                        constant   = True,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_branch = else_block,
                no_branch  = None,
                source_ref = source_ref
            )
        ]

    result.setBody(
        StatementsSequence(
            statements = statements,
            source_ref = source_ref
        )
    )

    return result
def buildWhileLoopNode( provider, node, source_ref ):
    # The while loop is re-formulated according to developer manual. The condition becomes
    # an early condition to break the loop. The else block is taken if a while loop exits
    # normally, i.e. because of condition not being true. We do this by introducing an
    # indicator variable.

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

    if else_block is not None:
        temp_block = StatementTempBlock(
            source_ref = source_ref
        )

        tmp_break_indicator_variable = temp_block.getTempVariable( "break_indicator" )

        statements = (
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_break_indicator_variable.makeReference( temp_block ),
                    source_ref = source_ref
                ),
                source     = ExpressionConstantRef(
                    constant   = True,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            StatementBreakLoop(
                source_ref = source_ref
            )
        )
    else:
        statements = (
            StatementBreakLoop(
                source_ref = source_ref
            ),
        )

    # The loop body contains a conditional statement at the start that breaks the loop if
    # it fails.
    loop_body = makeStatementsSequence(
        statements = (
            StatementConditional(
                condition = buildNode( provider, node.test, source_ref ),
                no_branch = StatementsSequence(
                    statements = statements,
                    source_ref = source_ref
                ),
                yes_branch = None,
                source_ref = source_ref
            ),
            buildStatementsNode(
                provider   = provider,
                nodes      = node.body,
                source_ref = source_ref
            )
        ),
        allow_none = True,
        source_ref = source_ref
    )

    loop_statement = StatementLoop(
        body       = loop_body,
        source_ref = source_ref
    )

    if else_block is None:
        return loop_statement
    else:
        statements = (
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_break_indicator_variable.makeReference( temp_block ),
                    source_ref = source_ref
                ),
                source = ExpressionConstantRef(
                    constant   = False,
                    source_ref = source_ref
                ),
                source_ref   = source_ref
            ),
            loop_statement,
            StatementConditional(
                condition  = ExpressionComparisonIs(
                    left       = ExpressionTempVariableRef(
                        variable   = tmp_break_indicator_variable.makeReference( temp_block ),
                        source_ref = source_ref
                    ),
                    right      = ExpressionConstantRef(
                        constant   = True,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_branch = else_block,
                no_branch  = None,
                source_ref = source_ref
            )
        )

        temp_block.setBody(
            StatementsSequence(
               statements = statements,
               source_ref = source_ref
            )
        )

        return temp_block
def buildInplaceAssignNode( provider, node, source_ref ):
    # There are many inplace assignment variables, and the detail is unpacked into names,
    # so we end up with a lot of variables, which is on purpose, pylint: disable=R0914

    operator = getKind( node.op )

    if operator == "Div" and source_ref.getFutureSpec().isFutureDivision():
        operator = "TrueDiv"

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

    result = StatementTempBlock(
        source_ref = source_ref
    )

    kind, detail = decodeAssignTarget( provider, node.target, source_ref )

    if kind == "Name":
        variable_ref = detail

        tmp_variable1 = result.getTempVariable( "inplace_start" )
        tmp_variable2 = result.getTempVariable( "inplace_end" )

        statements = _buildInplaceAssignVariableNode(
            result        = result,
            variable_ref  = variable_ref,
            tmp_variable1 = tmp_variable1,
            tmp_variable2 = tmp_variable2,
            operator      = operator,
            expression    = expression,
            source_ref    = source_ref
        )
    elif kind == "Attribute":
        lookup_source, attribute_name = detail

        tmp_variable1 = result.getTempVariable( "inplace_start" )
        tmp_variable2 = result.getTempVariable( "inplace_end" )

        statements = _buildInplaceAssignAttributeNode(
            result         = result,
            lookup_source  = lookup_source,
            attribute_name = attribute_name,
            tmp_variable1  = tmp_variable1,
            tmp_variable2  = tmp_variable2,
            operator       = operator,
            expression     = expression,
            source_ref     = source_ref
        )
    elif kind == "Subscript":
        subscribed, subscript = detail

        tmp_variable1 = result.getTempVariable( "inplace_target" )
        tmp_variable2 = result.getTempVariable( "inplace_subscript" )

        statements = _buildInplaceAssignSubscriptNode(
            result        = result,
            subscribed    = subscribed,
            subscript     = subscript,
            tmp_variable1 = tmp_variable1,
            tmp_variable2 = tmp_variable2,
            operator      = operator,
            expression    = expression,
            source_ref    = source_ref
        )
    elif kind == "Slice":
        lookup_source, lower, upper = detail

        tmp_variable1 = result.getTempVariable( "inplace_target" )
        tmp_variable2 = result.getTempVariable( "inplace_lower" ) if lower is not None else None
        tmp_variable3 = result.getTempVariable( "inplace_upper" ) if upper is not None else None

        statements = _buildInplaceAssignSliceNode(
            result        = result,
            lookup_source = lookup_source,
            lower         = lower,
            upper         = upper,
            tmp_variable1 = tmp_variable1,
            tmp_variable2 = tmp_variable2,
            tmp_variable3 = tmp_variable3,
            operator      = operator,
            expression    = expression,
            source_ref    = source_ref
        )
    else:
        assert False, kind

    result.setBody(
        StatementsSequence(
            statements = statements,
            source_ref = source_ref
        )
    )

    return result
def makeTryExceptNoRaise(tried, handlers, no_raise, source_ref):
    # This helper executes the core re-formulation of "no_raise" blocks, which are the
    # "else" blocks of try/except statements. We use an indicator variable instead, which
    # will signal that the tried block executed up to the end. And then we make the else
    # block be a conditional statement checking that. This is a separate function, so it
    # can be re-used in other re-formulations, e.g. with statements.

    assert no_raise is not None
    assert len(handlers) > 0

    result = StatementTempBlock(source_ref=source_ref)

    tmp_handler_indicator_variable = result.getTempVariable("unhandled_indicator")

    for handler in handlers:
        handler.setExceptionBranch(
            makeStatementsSequence(
                statements=(
                    StatementAssignmentVariable(
                        variable_ref=ExpressionTargetTempVariableRef(
                            variable=tmp_handler_indicator_variable.makeReference(result),
                            source_ref=source_ref.atInternal(),
                        ),
                        source=ExpressionConstantRef(constant=False, source_ref=source_ref),
                        source_ref=no_raise.getSourceReference().atInternal(),
                    ),
                    handler.getExceptionBranch(),
                ),
                allow_none=True,
                source_ref=source_ref,
            )
        )

    result.setBody(
        StatementsSequence(
            statements=(
                StatementAssignmentVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=tmp_handler_indicator_variable.makeReference(result),
                        source_ref=source_ref.atInternal(),
                    ),
                    source=ExpressionConstantRef(constant=True, source_ref=source_ref),
                    source_ref=source_ref,
                ),
                StatementTryExcept(tried=tried, handlers=handlers, source_ref=source_ref),
                StatementConditional(
                    condition=ExpressionComparisonIs(
                        left=ExpressionTempVariableRef(
                            variable=tmp_handler_indicator_variable.makeReference(result), source_ref=source_ref
                        ),
                        right=ExpressionConstantRef(constant=True, source_ref=source_ref),
                        source_ref=source_ref,
                    ),
                    yes_branch=no_raise,
                    no_branch=None,
                    source_ref=source_ref,
                ),
            ),
            source_ref=source_ref,
        )
    )

    return result
def _buildContractionNode( provider, node, name, emit_class, start_value, assign_provider, source_ref ):
    # The contraction nodes are reformulated to function bodies, with loops as described
    # in the developer manual. They use a lot of temporary names, nested blocks, etc. and
    # so a lot of variable names. There is no good way around that, and we deal with many
    # cases, due to having generator expressions sharing this code,
    # pylint: disable=R0912,R0914

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

    assert provider.isParentVariableProvider(), provider

    function_body = ExpressionFunctionBody(
        provider   = provider,
        name       = name,
        doc        = None,
        parameters = make_contraction_parameters,
        source_ref = source_ref
    )

    temp_block = StatementTempBlock(
        source_ref = source_ref
    )

    if start_value is not None:
        container_tmp = temp_block.getTempVariable( "result" )

        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = container_tmp.makeReference( temp_block ),
                    source_ref = source_ref
                ),
                source     = start_value,
                source_ref = source_ref.atInternal()
            )
        ]
    else:
        statements = []

    if hasattr( node, "elt" ):
        if start_value is not None:
            current_body = emit_class(
                ExpressionTempVariableRef(
                    variable   = container_tmp.makeReference( temp_block ),
                    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

            function_body.markAsGenerator()

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

        current_body = emit_class(
            ExpressionTempVariableRef(
                variable   = container_tmp.makeReference( temp_block ),
                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
        )

    current_body = StatementExpressionOnly(
        expression = current_body,
        source_ref = source_ref
    )

    for qual in reversed( node.generators ):
        nested_temp_block = StatementTempBlock(
            source_ref = source_ref
        )

        tmp_iter_variable = nested_temp_block.getTempVariable( "contraction_iter" )

        tmp_value_variable = nested_temp_block.getTempVariable( "iter_value" )

        # The first iterated value is to be calculated outside of the function and
        # will be given as a parameter "_iterated".
        if qual is node.generators[0]:
            value_iterator = ExpressionVariableRef(
                variable_name = "__iterator",
                source_ref    = source_ref
            )
        else:
            value_iterator = ExpressionBuiltinIter1(
                value      = buildNode(
                    provider   = function_body,
                    node       = qual.iter,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )

        # First create the iterator and store it, next should be loop body
        nested_statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_iter_variable.makeReference( nested_temp_block ),
                    source_ref = source_ref
                ),
                source     = value_iterator,
                source_ref = source_ref
            )
        ]

        loop_statements = [
            makeTryExceptSingleHandlerNode(
                tried          = makeStatementsSequenceFromStatement(
                    statement = StatementAssignmentVariable(
                        variable_ref = ExpressionTargetTempVariableRef(
                            variable   = tmp_value_variable.makeReference( nested_temp_block ),
                            source_ref = source_ref
                        ),
                        source     = ExpressionBuiltinNext1(
                            value      = ExpressionTempVariableRef(
                                variable   = tmp_iter_variable.makeReference( nested_temp_block ),
                                source_ref = source_ref
                            ),
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    )
                ),
                exception_name = "StopIteration",
                handler_body   = makeStatementsSequenceFromStatement(
                    statement = StatementBreakLoop(
                        source_ref = source_ref.atInternal()
                    )
                ),
                source_ref     = source_ref
            ),
            buildAssignmentStatements(
                provider   = provider if assign_provider else function_body,
                node       = qual.target,
                source     = ExpressionTempVariableRef(
                    variable   = tmp_value_variable.makeReference( nested_temp_block ),
                    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  = conditions[0],
                    yes_branch = makeStatementsSequenceFromStatement(
                        statement = current_body
                    ),
                    no_branch  = None,
                    source_ref = source_ref
                )
            )
        elif len( conditions ) > 1:
            loop_statements.append(
                StatementConditional(
                    condition = buildAndNode(
                        provider   = function_body,
                        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 = loop_statements,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        )

        nested_temp_block.setBody(
            StatementsSequence(
                statements = nested_statements,
                source_ref = source_ref
            )
        )

        current_body = nested_temp_block

    statements.append( current_body )

    if start_value is not None:
        statements.append(
            StatementReturn(
                expression = ExpressionTempVariableRef(
                    variable   = container_tmp.makeReference( temp_block ),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        )

    temp_block.setBody(
        StatementsSequence(
            statements = statements,
            source_ref = source_ref
        )
    )

    function_body.setBody(
        StatementsFrame(
            statements    = [ temp_block ],
            guard_mode    = "pass_through" if emit_class is not ExpressionYield else "generator",
            arg_names     = (),
            kw_only_count = 0,
            code_name     = "contraction",
            source_ref    = source_ref
        )
    )

    return ExpressionFunctionCall(
        function   = ExpressionFunctionCreation(
            function_ref = ExpressionFunctionRef(
                function_body = function_body,
                source_ref    = source_ref
            ),
            defaults     = (),
            kw_defaults  = None,
            annotations  = None,
            source_ref   = source_ref
        ),
        values     = (
            ExpressionBuiltinIter1(
                value      = buildNode(
                    provider   = provider,
                    node       = node.generators[0].iter,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
        ),
        source_ref = source_ref
    )
Exemplo n.º 10
0
def _buildClassNode2( provider, node, source_ref ):
    class_statements, class_doc = extractDocFromBody( node )

    # This function is the Python3 special case with special re-formulation as according
    # to developer manual.

    # The result will be a temp block that holds the temporary variables.
    result = StatementTempBlock(
        source_ref = source_ref
    )

    tmp_bases = result.getTempVariable( "bases" )
    tmp_class_dict = result.getTempVariable( "class_dict" )
    tmp_metaclass = result.getTempVariable( "metaclass" )
    tmp_class = result.getTempVariable( "class" )

    class_creation_function = ExpressionFunctionBody(
        provider   = provider,
        is_class   = True,
        parameters = make_class_parameters,
        name       = node.name,
        doc        = class_doc,
        source_ref = source_ref
    )

    body = buildStatementsNode(
        provider   = class_creation_function,
        nodes      = class_statements,
        frame      = True,
        source_ref = source_ref
    )

    if body is not None:
        # The frame guard has nothing to tell its line number to.
        body.source_ref = source_ref.atInternal()

    # The class body is basically a function that implicitely, at the end returns its
    # locals and cannot have other return statements contained, and starts out with a
    # variables "__module__" and potentially "__doc__" set.
    statements = [
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetVariableRef(
                variable_name = "__module__",
                source_ref    = source_ref
            ),
            source        = ExpressionConstantRef(
                constant   = provider.getParentModule().getName(),
                source_ref = source_ref
            ),
            source_ref   = source_ref.atInternal()
        )
    ]

    if class_doc is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__doc__",
                    source_ref    = source_ref
                ),
                source        = ExpressionConstantRef(
                    constant   = class_doc,
                    source_ref = source_ref
                ),
                source_ref   = source_ref.atInternal()
            )
        )

    statements += [
        body,
        StatementReturn(
            expression = ExpressionBuiltinLocals(
                source_ref = source_ref
            ),
            source_ref = source_ref.atInternal()
        )
    ]

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

    # The class body is basically a function that implicitely, at the end returns its
    # locals and cannot have other return statements contained.

    class_creation_function.setBody( body )

    statements = [
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases.makeReference( result ),
                source_ref = source_ref
            ),
            source       = ExpressionMakeTuple(
                elements   = buildNodeList( provider, node.bases, source_ref ),
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_dict.makeReference( result ),
                source_ref = source_ref
            ),
            source       =   ExpressionFunctionCall(
                function = ExpressionFunctionCreation(
                    function_ref = ExpressionFunctionRef(
                        function_body = class_creation_function,
                        source_ref    = source_ref
                    ),
                    defaults     = (),
                    kw_defaults  = None,
                    annotations  = None,
                    source_ref   = source_ref
                ),
                values     = (),
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass.makeReference( result ),
                source_ref = source_ref
            ),
            source       = ExpressionConditional(
                condition =  ExpressionComparison(
                    comparator = "In",
                    left       = ExpressionConstantRef(
                        constant   = "__metaclass__",
                        source_ref = source_ref
                    ),
                    right      = ExpressionTempVariableRef(
                        variable   = tmp_class_dict.makeReference( result ),
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_expression = ExpressionDictOperationGet(
                    dicte = ExpressionTempVariableRef(
                        variable   = tmp_class_dict.makeReference( result ),
                        source_ref = source_ref
                    ),
                    key   = ExpressionConstantRef(
                        constant   = "__metaclass__",
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                no_expression = ExpressionSelectMetaclass(
                    metaclass = None,
                    bases     = ExpressionTempVariableRef(
                        variable   = tmp_bases.makeReference( result ),
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class.makeReference( result ),
                source_ref = source_ref
            ),
            source     = ExpressionCallNoKeywords(
                called         = ExpressionTempVariableRef(
                    variable   = tmp_metaclass.makeReference( result ),
                    source_ref = source_ref
                ),
                args           = ExpressionMakeTuple(
                    elements   = (
                        ExpressionConstantRef(
                            constant = node.name,
                            source_ref     = source_ref
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_bases.makeReference( result ),
                            source_ref = source_ref
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_class_dict.makeReference( result ),
                            source_ref = source_ref
                        )
                    ),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    ]

    for decorator in buildNodeList( provider, reversed( node.decorator_list ), source_ref ):
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_class.makeReference( result ),
                    source_ref = source_ref
                ),
                source       = ExpressionCallNoKeywords(
                    called     = decorator,
                    args       = ExpressionMakeTuple(
                        elements  = (
                            ExpressionTempVariableRef(
                                variable   = tmp_class.makeReference( result ),
                                source_ref = source_ref
                            ),
                        ),
                        source_ref = source_ref
                    ),
                    source_ref = decorator.getSourceReference()
                ),
                source_ref   = decorator.getSourceReference()
            )
        )

    statements.append(
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetVariableRef(
                variable_name = node.name,
                source_ref    = source_ref
            ),
            source     = ExpressionTempVariableRef(
                variable   = tmp_class.makeReference( result ),
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    )

    result.setBody(
        StatementsSequence(
            statements = statements,
            source_ref = source_ref
        )
    )

    return result
Exemplo n.º 11
0
def _buildClassNode3( provider, node, source_ref ):
    # Many variables, due to the huge re-formulation that is going on here, which just has
    # the complexity, pylint: disable=R0914

    # This function is the Python3 special case with special re-formulation as according
    # to developer manual.
    class_statements, class_doc = extractDocFromBody( node )

    # The result will be a temp block that holds the temporary variables.
    result = StatementTempBlock(
        source_ref = source_ref
    )

    tmp_bases = result.getTempVariable( "bases" )
    tmp_class_decl_dict = result.getTempVariable( "class_decl_dict" )
    tmp_metaclass = result.getTempVariable( "metaclass" )
    tmp_prepared = result.getTempVariable( "prepared" )

    class_creation_function = ExpressionFunctionBody(
        provider   = provider,
        is_class   = True,
        parameters = make_class_parameters,
        name       = node.name,
        doc        = class_doc,
        source_ref = source_ref
    )

    # Hack:
    class_creation_function.parent = provider

    body = buildStatementsNode(
        provider   = class_creation_function,
        nodes      = class_statements,
        frame      = True,
        source_ref = source_ref
    )

    if body is not None:
        # The frame guard has nothing to tell its line number to.
        body.source_ref = source_ref.atInternal()

    statements = [
        StatementSetLocals(
            new_locals = ExpressionTempVariableRef(
                variable   = tmp_prepared.makeReference( result ),
                source_ref = source_ref
            ),
            source_ref = source_ref.atInternal()
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetVariableRef(
                variable_name = "__module__",
                source_ref    = source_ref
            ),
            source        = ExpressionConstantRef(
                constant   = provider.getParentModule().getName(),
                source_ref = source_ref
            ),
            source_ref   = source_ref.atInternal()
        )
    ]

    if class_doc is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__doc__",
                    source_ref    = source_ref
                ),
                source        = ExpressionConstantRef(
                    constant   = class_doc,
                    source_ref = source_ref
                ),
                source_ref   = source_ref.atInternal()
            )
        )

    if Utils.python_version >= 330:
        if provider.isExpressionFunctionBody():
            qualname = provider.getName() + ".<locals>." + node.name
        else:
            qualname = node.name

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__qualname__",
                    source_ref    = source_ref
                ),
                source        = ExpressionConstantRef(
                    constant   = qualname,
                    source_ref = source_ref
                ),
                source_ref   = source_ref.atInternal()
            )
        )

    statements += [
        body,
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetVariableRef(
                variable_name = "__class__",
                source_ref    = source_ref
            ),
            source       = ExpressionCall(
                called     = ExpressionTempVariableRef(
                    variable   = tmp_metaclass.makeReference( result ),
                    source_ref = source_ref
                ),
                args       = ExpressionMakeTuple(
                    elements   = (
                        ExpressionConstantRef(
                            constant   = node.name,
                            source_ref = source_ref
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_bases.makeReference( result ),
                            source_ref = source_ref
                        ),
                        ExpressionBuiltinLocals(
                            source_ref = source_ref
                        )
                    ),
                    source_ref = source_ref
                ),
                kw         = ExpressionTempVariableRef(
                    variable   = tmp_class_decl_dict.makeReference( result ),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref   = source_ref.atInternal()
        ),
        StatementReturn(
            expression = ExpressionVariableRef(
                variable_name = "__class__",
                source_ref    = source_ref
            ),
            source_ref = source_ref.atInternal()
        )
    ]

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

    # The class body is basically a function that implicitely, at the end returns its
    # locals and cannot have other return statements contained.

    class_creation_function.setBody( body )

    # The class body is basically a function that implicitely, at the end returns its
    # created class and cannot have other return statements contained.

    decorated_body = ExpressionFunctionCall(
        function   = ExpressionFunctionCreation(
            function_ref = ExpressionFunctionRef(
                function_body = class_creation_function,
                source_ref    = source_ref
            ),
            defaults     = (),
            kw_defaults  = None,
            annotations  = None,
            source_ref   = source_ref
        ),
        values     = (),
        source_ref = source_ref
    )

    for decorator in buildNodeList( provider, reversed( node.decorator_list ), source_ref ):
        decorated_body = ExpressionCallNoKeywords(
            called     = decorator,
            args       = ExpressionMakeTuple(
                elements   = ( decorated_body, ),
                source_ref = source_ref
            ),
            source_ref = decorator.getSourceReference()
        )

    statements = [
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases.makeReference( result ),
                source_ref = source_ref
            ),
            source       = ExpressionMakeTuple(
                elements   = buildNodeList( provider, node.bases, source_ref ),
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_decl_dict.makeReference( result ),
                source_ref = source_ref
            ),
            source       = ExpressionMakeDict(
                pairs      = [
                    ExpressionKeyValuePair(
                        key        = ExpressionConstantRef(
                            constant   = keyword.arg,
                            source_ref = source_ref
                        ),
                        value      = buildNode( provider, keyword.value, source_ref ),
                        source_ref = source_ref
                    )
                    for keyword in
                    node.keywords
                ],
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass.makeReference( result ),
                source_ref = source_ref
            ),
            source       = ExpressionSelectMetaclass(
                metaclass = ExpressionConditional(
                    condition = ExpressionComparison(
                        comparator = "In",
                        left       = ExpressionConstantRef(
                            constant   = "metaclass",
                            source_ref = source_ref
                        ),
                        right      = ExpressionTempVariableRef(
                            variable   = tmp_class_decl_dict.makeReference( result ),
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    yes_expression = ExpressionDictOperationGet(
                        dicte      = ExpressionTempVariableRef(
                            variable   = tmp_class_decl_dict.makeReference( result ),
                            source_ref = source_ref
                        ),
                        key        = ExpressionConstantRef(
                            constant   = "metaclass",
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    no_expression  = ExpressionConditional(
                        condition      = ExpressionTempVariableRef(
                            variable   = tmp_bases.makeReference( result ),
                            source_ref = source_ref
                        ),
                        no_expression  = ExpressionBuiltinRef(
                            builtin_name = "type",
                            source_ref   = source_ref
                        ),
                        yes_expression = ExpressionBuiltinType1(
                            value      = ExpressionSubscriptLookup(
                                expression = ExpressionTempVariableRef(
                                    variable   = tmp_bases.makeReference( result ),
                                    source_ref = source_ref
                                ),
                                subscript  = ExpressionConstantRef(
                                    constant   = 0,
                                    source_ref = source_ref
                                ),
                                source_ref = source_ref
                            ),
                            source_ref = source_ref
                        ),
                        source_ref     = source_ref
                    ),
                    source_ref     = source_ref
                ),
                bases     = ExpressionTempVariableRef(
                    variable   = tmp_bases.makeReference( result ),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        StatementConditional(
            condition  = ExpressionComparison(
                comparator = "In",
                left       = ExpressionConstantRef(
                    constant   = "metaclass",
                    source_ref = source_ref
                ),
                right      = ExpressionTempVariableRef(
                    variable   = tmp_class_decl_dict.makeReference( result ),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            no_branch  = None,
            yes_branch = makeStatementsSequenceFromStatement(
                statement = StatementDictOperationRemove(
                    dicte = ExpressionTempVariableRef(
                        variable   = tmp_class_decl_dict.makeReference( result ),
                        source_ref = source_ref
                    ),
                    key   = ExpressionConstantRef(
                        constant   = "metaclass",
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                )
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_prepared.makeReference( result ),
                source_ref = source_ref
            ),
            source       = ExpressionConditional(
                condition = ExpressionBuiltinHasattr(
                    object     = ExpressionTempVariableRef(
                        variable   = tmp_metaclass.makeReference( result ),
                        source_ref = source_ref
                    ),
                    name       = ExpressionConstantRef(
                        constant   = "__prepare__",
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                no_expression = ExpressionConstantRef(
                    constant   = {},
                    source_ref = source_ref
                ),
                yes_expression = ExpressionCall(
                    called     = ExpressionAttributeLookup(
                        expression     = ExpressionTempVariableRef(
                            variable   = tmp_metaclass.makeReference( result ),
                            source_ref = source_ref
                        ),
                        attribute_name = "__prepare__",
                        source_ref     = source_ref
                    ),
                    args       = ExpressionMakeTuple(
                        elements   = (
                            ExpressionConstantRef(
                                constant = node.name,
                                source_ref     = source_ref
                            ),
                            ExpressionTempVariableRef(
                                variable   = tmp_bases.makeReference( result ),
                                source_ref = source_ref
                            )
                        ),
                        source_ref = source_ref
                    ),
                    kw         = ExpressionTempVariableRef(
                        variable   = tmp_class_decl_dict.makeReference( result ),
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetVariableRef(
                variable_name = node.name,
                source_ref    = source_ref
            ),
            source     = decorated_body,
            source_ref = source_ref
        )
    ]

    result.setBody(
        StatementsSequence(
            statements = statements,
            source_ref = source_ref
        )
    )

    return result
def makeTryExceptNoRaise( tried, handlers, no_raise, source_ref ):
    # This helper executes the core re-formulation of "no_raise" blocks, which are the
    # "else" blocks of try/except statements. We use an indicator variable instead, which
    # will signal that the tried block executed up to the end. And then we make the else
    # block be a conditional statement checking that. This is a separate function, so it
    # can be re-used in other re-formulations, e.g. with statements.

    assert no_raise is not None
    assert len( handlers ) > 0

    result = StatementTempBlock(
        source_ref = source_ref
    )

    tmp_handler_indicator_variable = result.getTempVariable( "unhandled_indicator" )

    for handler in handlers:
        handler.setExceptionBranch(
            makeStatementsSequence(
                statements = (
                    StatementAssignmentVariable(
                        variable_ref = ExpressionTargetTempVariableRef(
                            variable   = tmp_handler_indicator_variable.makeReference( result ),
                            source_ref = source_ref.atInternal()
                        ),
                        source       = ExpressionConstantRef(
                            constant   = False,
                            source_ref = source_ref
                        ),
                        source_ref   = no_raise.getSourceReference().atInternal()
                    ),
                    handler.getExceptionBranch()
                ),
                allow_none = True,
                source_ref = source_ref
            )
        )

    result.setBody(
        StatementsSequence(
            statements = (
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = tmp_handler_indicator_variable.makeReference( result ),
                        source_ref = source_ref.atInternal()
                    ),
                    source     = ExpressionConstantRef(
                        constant   = True,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                StatementTryExcept(
                    tried      = tried,
                    handlers   = handlers,
                    source_ref = source_ref
                ),
                StatementConditional(
                    condition  = ExpressionComparisonIs(
                        left = ExpressionTempVariableRef(
                            variable   = tmp_handler_indicator_variable.makeReference( result ),
                            source_ref = source_ref
                        ),
                        right = ExpressionConstantRef(
                            constant   = True,
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    yes_branch = no_raise,
                    no_branch  = None,
                    source_ref = source_ref
                )
            ),
            source_ref = source_ref
        )
    )

    return result
def buildAssignmentStatementsFromDecoded(provider, kind, detail, source,
                                         source_ref):
    # This is using many variable names on purpose, so as to give names to the unpacked
    # detail values, pylint: disable=R0914

    if kind == "Name":
        variable_ref = detail

        return StatementAssignmentVariable(variable_ref=variable_ref,
                                           source=source,
                                           source_ref=source_ref)
    elif kind == "Attribute":
        lookup_source, attribute_name = detail

        return StatementAssignmentAttribute(expression=lookup_source,
                                            attribute_name=attribute_name,
                                            source=source,
                                            source_ref=source_ref)
    elif kind == "Subscript":
        subscribed, subscript = detail

        return StatementAssignmentSubscript(expression=subscribed,
                                            subscript=subscript,
                                            source=source,
                                            source_ref=source_ref)
    elif kind == "Slice":
        lookup_source, lower, upper = detail

        return StatementAssignmentSlice(expression=lookup_source,
                                        lower=lower,
                                        upper=upper,
                                        source=source,
                                        source_ref=source_ref)
    elif kind == "Tuple":
        result = StatementTempBlock(source_ref=source_ref)

        source_iter_var = result.getTempVariable("source_iter")

        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=source_iter_var.makeReference(result),
                    source_ref=source_ref),
                source=ExpressionBuiltinIter1(value=source,
                                              source_ref=source_ref),
                source_ref=source_ref)
        ]

        element_vars = [
            result.getTempVariable("element_%d" % (element_index + 1))
            for element_index in range(len(detail))
        ]

        starred = False

        for element_index, element in enumerate(detail):
            if element[0] != "Starred":
                statements.append(
                    StatementAssignmentVariable(
                        variable_ref=ExpressionTargetTempVariableRef(
                            variable=element_vars[element_index].makeReference(
                                result),
                            source_ref=source_ref),
                        source=ExpressionSpecialUnpack(
                            value=ExpressionTempVariableRef(
                                variable=source_iter_var.makeReference(result),
                                source_ref=source_ref),
                            count=element_index + 1,
                            source_ref=source_ref),
                        source_ref=source_ref))
            else:
                starred = True

                statements.append(
                    StatementAssignmentVariable(
                        variable_ref=ExpressionTargetTempVariableRef(
                            variable=element_vars[element_index].makeReference(
                                result),
                            source_ref=source_ref),
                        source=ExpressionBuiltinList(
                            value=ExpressionTempVariableRef(
                                variable=source_iter_var.makeReference(result),
                                source_ref=source_ref),
                            source_ref=source_ref),
                        source_ref=source_ref))

        if not starred:
            statements.append(
                StatementSpecialUnpackCheck(iterator=ExpressionTempVariableRef(
                    variable=source_iter_var.makeReference(result),
                    source_ref=source_ref),
                                            count=len(detail),
                                            source_ref=source_ref))

        for element_index, element in enumerate(detail):
            if element[0] == "Starred":
                element = element[1]

            statements.append(
                buildAssignmentStatementsFromDecoded(
                    provider=provider,
                    kind=element[0],
                    detail=element[1],
                    source=ExpressionTempVariableRef(
                        variable=element_vars[element_index].makeReference(
                            result),
                        source_ref=source_ref),
                    source_ref=source_ref))

        result.setBody(
            StatementsSequence(statements=statements, source_ref=source_ref))

        return result
    else:
        assert False, (kind, source_ref, detail)

    return result
def buildInplaceAssignNode(provider, node, source_ref):
    # There are many inplace assignment variables, and the detail is unpacked into names,
    # so we end up with a lot of variables, which is on purpose, pylint: disable=R0914

    operator = getKind(node.op)

    if operator == "Div" and source_ref.getFutureSpec().isFutureDivision():
        operator = "TrueDiv"

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

    result = StatementTempBlock(source_ref=source_ref)

    kind, detail = decodeAssignTarget(provider, node.target, source_ref)

    if kind == "Name":
        variable_ref = detail

        tmp_variable1 = result.getTempVariable("inplace_start")
        tmp_variable2 = result.getTempVariable("inplace_end")

        statements = _buildInplaceAssignVariableNode(
            result=result,
            variable_ref=variable_ref,
            tmp_variable1=tmp_variable1,
            tmp_variable2=tmp_variable2,
            operator=operator,
            expression=expression,
            source_ref=source_ref)
    elif kind == "Attribute":
        lookup_source, attribute_name = detail

        tmp_variable1 = result.getTempVariable("inplace_start")
        tmp_variable2 = result.getTempVariable("inplace_end")

        statements = _buildInplaceAssignAttributeNode(
            result=result,
            lookup_source=lookup_source,
            attribute_name=attribute_name,
            tmp_variable1=tmp_variable1,
            tmp_variable2=tmp_variable2,
            operator=operator,
            expression=expression,
            source_ref=source_ref)
    elif kind == "Subscript":
        subscribed, subscript = detail

        tmp_variable1 = result.getTempVariable("inplace_target")
        tmp_variable2 = result.getTempVariable("inplace_subscript")

        statements = _buildInplaceAssignSubscriptNode(
            result=result,
            subscribed=subscribed,
            subscript=subscript,
            tmp_variable1=tmp_variable1,
            tmp_variable2=tmp_variable2,
            operator=operator,
            expression=expression,
            source_ref=source_ref)
    elif kind == "Slice":
        lookup_source, lower, upper = detail

        tmp_variable1 = result.getTempVariable("inplace_target")
        tmp_variable2 = result.getTempVariable(
            "inplace_lower") if lower is not None else None
        tmp_variable3 = result.getTempVariable(
            "inplace_upper") if upper is not None else None

        statements = _buildInplaceAssignSliceNode(result=result,
                                                  lookup_source=lookup_source,
                                                  lower=lower,
                                                  upper=upper,
                                                  tmp_variable1=tmp_variable1,
                                                  tmp_variable2=tmp_variable2,
                                                  tmp_variable3=tmp_variable3,
                                                  operator=operator,
                                                  expression=expression,
                                                  source_ref=source_ref)
    else:
        assert False, kind

    result.setBody(
        StatementsSequence(statements=statements, source_ref=source_ref))

    return result
Exemplo n.º 15
0
def buildLambdaNode(provider, node, source_ref):
    assert getKind(node) == "Lambda"

    function_body = ExpressionFunctionBody(
        provider=provider,
        name="<lambda>",
        doc=None,
        parameters=buildParameterSpec("<lambda>", node, source_ref),
        source_ref=source_ref,
    )

    defaults = buildNodeList(provider, node.args.defaults, source_ref)
    kw_defaults = buildParameterKwDefaults(provider, node, function_body,
                                           source_ref)

    body = buildNode(
        provider=function_body,
        node=node.body,
        source_ref=source_ref,
    )

    if function_body.isGenerator():
        if Utils.python_version < 270:
            temp_block = StatementTempBlock(source_ref=source_ref, )

            tmp_return_value = temp_block.getTempVariable("yield_return")

            statements = (StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_return_value.makeReference(temp_block),
                    source_ref=source_ref,
                ),
                source=body,
                source_ref=source_ref),
                          StatementConditional(
                              condition=ExpressionComparisonIsNOT(
                                  left=ExpressionTempVariableRef(
                                      variable=tmp_return_value.makeReference(
                                          temp_block),
                                      source_ref=source_ref,
                                  ),
                                  right=ExpressionConstantRef(
                                      constant=None, source_ref=source_ref),
                                  source_ref=source_ref),
                              yes_branch=makeStatementsSequenceFromStatement(
                                  statement=StatementExpressionOnly(
                                      expression=ExpressionYield(
                                          expression=ExpressionTempVariableRef(
                                              variable=tmp_return_value.
                                              makeReference(temp_block),
                                              source_ref=source_ref,
                                          ),
                                          source_ref=source_ref),
                                      source_ref=source_ref)),
                              no_branch=None,
                              source_ref=source_ref))

            temp_block.setBody(
                StatementsSequence(statements=statements,
                                   source_ref=source_ref))

            body = temp_block
        else:
            body = StatementExpressionOnly(expression=body,
                                           source_ref=source_ref)
    else:
        body = StatementReturn(expression=body, source_ref=source_ref)

    body = StatementsFrame(
        statements=(body, ),
        guard_mode="generator" if function_body.isGenerator() else "full",
        arg_names=function_body.getParameters().getCoArgNames(),
        kw_only_count=function_body.getParameters().getKwOnlyParameterCount(),
        code_name="<lambda>",
        source_ref=body.getSourceReference())

    function_body.setBody(body)

    annotations = buildParameterAnnotations(provider, node, source_ref)

    return ExpressionFunctionCreation(function_ref=ExpressionFunctionRef(
        function_body=function_body, source_ref=source_ref),
                                      defaults=defaults,
                                      kw_defaults=kw_defaults,
                                      annotations=annotations,
                                      source_ref=source_ref)
def buildLambdaNode( provider, node, source_ref ):
    assert getKind( node ) == "Lambda"

    function_body = ExpressionFunctionBody(
        provider   = provider,
        name       = "<lambda>",
        doc        = None,
        parameters = buildParameterSpec( "<lambda>", node, source_ref ),
        source_ref = source_ref,
    )

    defaults = buildNodeList( provider, node.args.defaults, source_ref )
    kw_defaults = buildParameterKwDefaults( provider, node, function_body, source_ref )

    body = buildNode(
        provider   = function_body,
        node       = node.body,
        source_ref = source_ref,
    )

    if function_body.isGenerator():
        if Utils.python_version < 270:
            temp_block = StatementTempBlock(
                source_ref = source_ref,
            )

            tmp_return_value = temp_block.getTempVariable( "yield_return" )

            statements = (
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable = tmp_return_value.makeReference( temp_block ),
                        source_ref = source_ref,
                    ),
                    source     = body,
                    source_ref = source_ref
                ),
                StatementConditional(
                    condition = ExpressionComparisonIsNOT(
                        left       = ExpressionTempVariableRef(
                            variable = tmp_return_value.makeReference( temp_block ),
                            source_ref = source_ref,
                        ),
                        right      = ExpressionConstantRef(
                            constant   = None,
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    yes_branch = makeStatementsSequenceFromStatement(
                        statement = StatementExpressionOnly(
                            expression = ExpressionYield(
                                expression = ExpressionTempVariableRef(
                                    variable = tmp_return_value.makeReference( temp_block ),
                                    source_ref = source_ref,
                                ),
                                source_ref = source_ref
                            ),
                            source_ref = source_ref
                        )
                    ),
                    no_branch  = None,
                    source_ref = source_ref
                )
            )

            temp_block.setBody(
                StatementsSequence(
                    statements = statements,
                    source_ref = source_ref
                )
            )

            body = temp_block
        else:
            body = StatementExpressionOnly(
                expression = body,
                source_ref = source_ref
            )
    else:
        body = StatementReturn(
            expression = body,
            source_ref = source_ref
        )

    body = StatementsFrame(
        statements    = ( body, ),
        guard_mode    = "generator" if function_body.isGenerator() else "full",
        arg_names     = function_body.getParameters().getCoArgNames(),
        kw_only_count = function_body.getParameters().getKwOnlyParameterCount(),
        code_name     = "<lambda>",
        source_ref    = body.getSourceReference()
    )

    function_body.setBody( body )

    annotations = buildParameterAnnotations( provider, node, source_ref )

    return ExpressionFunctionCreation(
        function_ref = ExpressionFunctionRef(
            function_body = function_body,
            source_ref    = source_ref
        ),
        defaults     = defaults,
        kw_defaults  = kw_defaults,
        annotations  = annotations,
        source_ref   = source_ref
    )
Exemplo n.º 17
0
def buildWhileLoopNode(provider, node, source_ref):
    # The while loop is re-formulated according to developer manual. The condition becomes
    # an early condition to break the loop. The else block is taken if a while loop exits
    # normally, i.e. because of condition not being true. We do this by introducing an
    # indicator variable.

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

    if else_block is not None:
        temp_block = StatementTempBlock(source_ref=source_ref)

        tmp_break_indicator_variable = temp_block.getTempVariable(
            "break_indicator")

        statements = (StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_break_indicator_variable.makeReference(
                    temp_block),
                source_ref=source_ref),
            source=ExpressionConstantRef(constant=True, source_ref=source_ref),
            source_ref=source_ref), StatementBreakLoop(source_ref=source_ref))
    else:
        statements = (StatementBreakLoop(source_ref=source_ref), )

    # The loop body contains a conditional statement at the start that breaks the loop if
    # it fails.
    loop_body = makeStatementsSequence(statements=(StatementConditional(
        condition=buildNode(provider, node.test, source_ref),
        no_branch=StatementsSequence(statements=statements,
                                     source_ref=source_ref),
        yes_branch=None,
        source_ref=source_ref),
                                                   buildStatementsNode(
                                                       provider=provider,
                                                       nodes=node.body,
                                                       source_ref=source_ref)),
                                       allow_none=True,
                                       source_ref=source_ref)

    loop_statement = StatementLoop(body=loop_body, source_ref=source_ref)

    if else_block is None:
        return loop_statement
    else:
        statements = (StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_break_indicator_variable.makeReference(
                    temp_block),
                source_ref=source_ref),
            source=ExpressionConstantRef(constant=False,
                                         source_ref=source_ref),
            source_ref=source_ref), loop_statement,
                      StatementConditional(condition=ExpressionComparisonIs(
                          left=ExpressionTempVariableRef(
                              variable=tmp_break_indicator_variable.
                              makeReference(temp_block),
                              source_ref=source_ref),
                          right=ExpressionConstantRef(constant=True,
                                                      source_ref=source_ref),
                          source_ref=source_ref),
                                           yes_branch=else_block,
                                           no_branch=None,
                                           source_ref=source_ref))

        temp_block.setBody(
            StatementsSequence(statements=statements, source_ref=source_ref))

        return temp_block
Exemplo n.º 18
0
def buildForLoopNode(provider, node, 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.

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

    result = StatementTempBlock(source_ref=source_ref)

    tmp_iter_variable = result.getTempVariable("for_iterator")

    iterate_tmp_block = StatementTempBlock(source_ref=source_ref)

    tmp_value_variable = iterate_tmp_block.getTempVariable("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_variable = result.getTempVariable(
            "break_indicator")

        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_break_indicator_variable.makeReference(
                        result),
                    source_ref=source_ref),
                source=ExpressionConstantRef(constant=True,
                                             source_ref=source_ref),
                source_ref=source_ref)
        ]
    else:
        statements = []

    statements.append(StatementBreakLoop(source_ref=source_ref.atInternal()))

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

    statements = (makeTryExceptSingleHandlerNode(
        tried=makeStatementsSequenceFromStatement(
            statement=StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_value_variable.makeReference(
                        iterate_tmp_block),
                    source_ref=source_ref),
                source=ExpressionBuiltinNext1(value=ExpressionTempVariableRef(
                    variable=tmp_iter_variable.makeReference(result),
                    source_ref=source_ref),
                                              source_ref=source_ref),
                source_ref=source_ref)),
        exception_name="StopIteration",
        handler_body=handler_body,
        source_ref=source_ref),
                  buildAssignmentStatements(
                      provider=provider,
                      node=node.target,
                      source=ExpressionTempVariableRef(
                          variable=tmp_value_variable.makeReference(
                              iterate_tmp_block),
                          source_ref=source_ref),
                      source_ref=source_ref))

    iterate_tmp_block.setBody(
        StatementsSequence(statements=statements, source_ref=source_ref))

    statements = (iterate_tmp_block,
                  buildStatementsNode(provider=provider,
                                      nodes=node.body,
                                      source_ref=source_ref))

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

    if else_block is not None:
        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_break_indicator_variable.makeReference(
                        result),
                    source_ref=source_ref),
                source=ExpressionConstantRef(constant=False,
                                             source_ref=source_ref),
                source_ref=source_ref)
        ]
    else:
        statements = []

    statements += [
        # First create the iterator and store it.
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_iter_variable.makeReference(result),
                source_ref=source_ref),
            source=ExpressionBuiltinIter1(
                value=source, source_ref=source.getSourceReference()),
            source_ref=source_ref),
        StatementLoop(body=loop_body, source_ref=source_ref)
    ]

    if else_block is not None:
        statements += [
            StatementConditional(condition=ExpressionComparisonIs(
                left=ExpressionTempVariableRef(
                    variable=tmp_break_indicator_variable.makeReference(
                        result),
                    source_ref=source_ref),
                right=ExpressionConstantRef(constant=True,
                                            source_ref=source_ref),
                source_ref=source_ref),
                                 yes_branch=else_block,
                                 no_branch=None,
                                 source_ref=source_ref)
        ]

    result.setBody(
        StatementsSequence(statements=statements, source_ref=source_ref))

    return result
Exemplo n.º 19
0
def _buildWithNode( provider, context_expr, assign_target, body, source_ref ):
    with_source = buildNode( provider, context_expr, source_ref )

    result = StatementTempBlock(
        source_ref = source_ref
    )

    tmp_source_variable = result.getTempVariable( "with_source" )
    tmp_exit_variable = result.getTempVariable( "with_exit" )
    tmp_enter_variable = result.getTempVariable( "with_enter" )
    tmp_indicator_variable = result.getTempVariable( "indicator" )

    statements = (
        buildAssignmentStatements(
            provider   = provider,
            node       = assign_target,
            allow_none = True,
            source     = ExpressionTempVariableRef(
                variable   = tmp_enter_variable.makeReference( result ),
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        body
    )

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

    # The "__enter__" and "__exit__" were normal attribute lookups under CPython2.6, but
    # that changed with CPython2.7.
    if Utils.python_version < 270:
        attribute_lookup_class = ExpressionAttributeLookup
    else:
        attribute_lookup_class = ExpressionSpecialAttributeLookup

    statements = [
        # First assign the with context to a temporary variable.
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_source_variable.makeReference( result ),
                source_ref = source_ref
            ),
            source       = with_source,
            source_ref   = source_ref
        ),
        # Next, assign "__enter__" and "__exit__" attributes to temporary variables.
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_exit_variable.makeReference( result ),
                source_ref = source_ref
            ),
            source       = attribute_lookup_class(
                expression     = ExpressionTempVariableRef(
                    variable   = tmp_source_variable.makeReference( result ),
                    source_ref = source_ref
                ),
                attribute_name = "__exit__",
                source_ref     = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_enter_variable.makeReference( result ),
                source_ref = source_ref
            ),
            source       = ExpressionCallEmpty(
                called         = attribute_lookup_class(
                    expression     = ExpressionTempVariableRef(
                        variable   = tmp_source_variable.makeReference( result ),
                        source_ref = source_ref
                    ),
                    attribute_name = "__enter__",
                    source_ref     = source_ref
                ),
                source_ref      = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_indicator_variable.makeReference( result ),
                source_ref = source_ref
            ),
            source       = ExpressionConstantRef(
                constant   = True,
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
    ]

    source_ref = source_ref.atInternal()

    statements += [
        StatementTryFinally(
            tried      = makeStatementsSequenceFromStatement(
                statement = makeTryExceptSingleHandlerNode(
                    tried          = with_body,
                    exception_name = "BaseException",
                    handler_body   = StatementsSequence(
                        statements = (
                            # Prevents final block from calling __exit__ as well.
                            StatementAssignmentVariable(
                                variable_ref = ExpressionTargetTempVariableRef(
                                    variable   = tmp_indicator_variable.makeReference( result ),
                                    source_ref = source_ref
                                ),
                                source       = ExpressionConstantRef(
                                    constant   = False,
                                    source_ref = source_ref
                                ),
                                source_ref   = source_ref
                            ),
                            StatementConditional(
                                condition  = ExpressionCallNoKeywords(
                                    called          = ExpressionTempVariableRef(
                                        variable   = tmp_exit_variable.makeReference( result ),
                                        source_ref = source_ref
                                    ),
                                    args = ExpressionMakeTuple(
                                        elements   = (
                                            ExpressionCaughtExceptionTypeRef(
                                                source_ref = source_ref
                                            ),
                                            ExpressionCaughtExceptionValueRef(
                                                source_ref = source_ref
                                            ),
                                            ExpressionCaughtExceptionTracebackRef(
                                                source_ref = source_ref
                                            ),
                                        ),
                                        source_ref = source_ref
                                    ),
                                    source_ref      = source_ref
                                ),
                                no_branch  = makeStatementsSequenceFromStatement(
                                    statement = StatementRaiseException(
                                        exception_type  = None,
                                        exception_value = None,
                                        exception_trace = None,
                                        exception_cause = None,
                                        source_ref      = source_ref
                                    )
                                ),
                                yes_branch = None,
                                source_ref = source_ref
                            ),
                        ),
                        source_ref     = source_ref
                    ),
                    source_ref = source_ref
                ),
            ),
            final      = makeStatementsSequenceFromStatement(
                statement = StatementConditional(
                    condition      = ExpressionComparisonIs(
                        left       = ExpressionTempVariableRef(
                            variable   = tmp_indicator_variable.makeReference( result ),
                            source_ref = source_ref
                        ),
                        right      = ExpressionConstantRef(
                            constant    = True,
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    yes_branch = makeStatementsSequenceFromStatement(
                        statement = StatementExpressionOnly(
                            expression = ExpressionCallNoKeywords(
                                called     = ExpressionTempVariableRef(
                                    variable   = tmp_exit_variable.makeReference( result ),
                                    source_ref = source_ref
                                ),
                                args       = ExpressionConstantRef(
                                    constant   = ( None, None, None ),
                                    source_ref = source_ref
                                ),
                                source_ref = source_ref
                            ),
                            source_ref     = source_ref
                        )
                    ),
                    no_branch  = None,
                    source_ref = source_ref
                )
            ),
            source_ref = source_ref
        )
    ]

    result.setBody(
        StatementsSequence(
            statements = statements,
            source_ref = source_ref
        )
    )

    return result
def buildAssignmentStatementsFromDecoded( provider, kind, detail, source, source_ref ):
    # This is using many variable names on purpose, so as to give names to the unpacked
    # detail values, pylint: disable=R0914

    if kind == "Name":
        variable_ref = detail

        return StatementAssignmentVariable(
            variable_ref = variable_ref,
            source       = source,
            source_ref   = source_ref
        )
    elif kind == "Attribute":
        lookup_source, attribute_name = detail

        return StatementAssignmentAttribute(
            expression     = lookup_source,
            attribute_name = attribute_name,
            source         = source,
            source_ref     = source_ref
        )
    elif kind == "Subscript":
        subscribed, subscript = detail

        return StatementAssignmentSubscript(
            expression = subscribed,
            subscript  = subscript,
            source     = source,
            source_ref = source_ref
        )
    elif kind == "Slice":
        lookup_source, lower, upper = detail

        return StatementAssignmentSlice(
            expression = lookup_source,
            lower      = lower,
            upper      = upper,
            source     = source,
            source_ref = source_ref
        )
    elif kind == "Tuple":
        result = StatementTempBlock(
            source_ref = source_ref
        )

        source_iter_var = result.getTempVariable( "source_iter" )

        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = source_iter_var.makeReference( result ),
                    source_ref = source_ref
                ),
                source = ExpressionBuiltinIter1(
                    value      = source,
                    source_ref = source_ref
                ),
                source_ref   = source_ref
            )
        ]

        element_vars = [
            result.getTempVariable( "element_%d" % ( element_index + 1 ) )
            for element_index in
            range( len( detail ) )
        ]

        starred = False

        for element_index, element in enumerate( detail ):
            if element[0] != "Starred":
                statements.append(
                    StatementAssignmentVariable(
                        variable_ref = ExpressionTargetTempVariableRef(
                            variable   = element_vars[ element_index ].makeReference( result ),
                            source_ref = source_ref
                        ),
                        source = ExpressionSpecialUnpack(
                            value      = ExpressionTempVariableRef(
                                variable   = source_iter_var.makeReference( result ),
                                source_ref = source_ref
                            ),
                            count      = element_index + 1,
                            source_ref = source_ref
                        ),
                        source_ref   = source_ref
                    )
                )
            else:
                starred = True

                statements.append(
                    StatementAssignmentVariable(
                        variable_ref = ExpressionTargetTempVariableRef(
                            variable   = element_vars[ element_index ].makeReference( result ),
                            source_ref = source_ref
                        ),
                        source = ExpressionBuiltinList(
                            value      = ExpressionTempVariableRef(
                                variable   = source_iter_var.makeReference( result ),
                                source_ref = source_ref
                            ),
                            source_ref = source_ref
                        ),
                        source_ref   = source_ref
                    )
                )

        if not starred:
            statements.append(
                StatementSpecialUnpackCheck(
                    iterator   = ExpressionTempVariableRef(
                        variable   = source_iter_var.makeReference( result ),
                        source_ref = source_ref
                    ),
                    count      = len( detail ),
                    source_ref = source_ref
                )
            )

        for element_index, element in enumerate( detail ):
            if element[0] == "Starred":
                element = element[1]

            statements.append(
                buildAssignmentStatementsFromDecoded(
                    provider   = provider,
                    kind       = element[0],
                    detail     = element[1],
                    source     = ExpressionTempVariableRef(
                        variable   = element_vars[ element_index ].makeReference( result ),
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                )
            )

        result.setBody(
            StatementsSequence(
               statements = statements,
               source_ref = source_ref
            )
        )

        return result
    else:
        assert False, ( kind, source_ref, detail )

    return result
Exemplo n.º 21
0
def _buildContractionNode(provider, node, name, emit_class, start_value,
                          assign_provider, source_ref):
    # The contraction nodes are reformulated to function bodies, with loops as described
    # in the developer manual. They use a lot of temporary names, nested blocks, etc. and
    # so a lot of variable names. There is no good way around that, and we deal with many
    # cases, due to having generator expressions sharing this code,
    # pylint: disable=R0912,R0914

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

    assert provider.isParentVariableProvider(), provider

    function_body = ExpressionFunctionBody(
        provider=provider,
        name=name,
        doc=None,
        parameters=make_contraction_parameters,
        source_ref=source_ref)

    temp_block = StatementTempBlock(source_ref=source_ref)

    if start_value is not None:
        container_tmp = temp_block.getTempVariable("result")

        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=container_tmp.makeReference(temp_block),
                    source_ref=source_ref),
                source=start_value,
                source_ref=source_ref.atInternal())
        ]
    else:
        statements = []

    if hasattr(node, "elt"):
        if start_value is not None:
            current_body = emit_class(ExpressionTempVariableRef(
                variable=container_tmp.makeReference(temp_block),
                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

            function_body.markAsGenerator()

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

        current_body = emit_class(ExpressionTempVariableRef(
            variable=container_tmp.makeReference(temp_block),
            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)

    current_body = StatementExpressionOnly(expression=current_body,
                                           source_ref=source_ref)

    for qual in reversed(node.generators):
        nested_temp_block = StatementTempBlock(source_ref=source_ref)

        tmp_iter_variable = nested_temp_block.getTempVariable(
            "contraction_iter")

        tmp_value_variable = nested_temp_block.getTempVariable("iter_value")

        # The first iterated value is to be calculated outside of the function and
        # will be given as a parameter "_iterated".
        if qual is node.generators[0]:
            value_iterator = ExpressionVariableRef(variable_name="__iterator",
                                                   source_ref=source_ref)
        else:
            value_iterator = ExpressionBuiltinIter1(value=buildNode(
                provider=function_body, node=qual.iter, source_ref=source_ref),
                                                    source_ref=source_ref)

        # First create the iterator and store it, next should be loop body
        nested_statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_iter_variable.makeReference(
                        nested_temp_block),
                    source_ref=source_ref),
                source=value_iterator,
                source_ref=source_ref)
        ]

        loop_statements = [
            makeTryExceptSingleHandlerNode(
                tried=makeStatementsSequenceFromStatement(
                    statement=StatementAssignmentVariable(
                        variable_ref=ExpressionTargetTempVariableRef(
                            variable=tmp_value_variable.makeReference(
                                nested_temp_block),
                            source_ref=source_ref),
                        source=ExpressionBuiltinNext1(
                            value=ExpressionTempVariableRef(
                                variable=tmp_iter_variable.makeReference(
                                    nested_temp_block),
                                source_ref=source_ref),
                            source_ref=source_ref),
                        source_ref=source_ref)),
                exception_name="StopIteration",
                handler_body=makeStatementsSequenceFromStatement(
                    statement=StatementBreakLoop(
                        source_ref=source_ref.atInternal())),
                source_ref=source_ref),
            buildAssignmentStatements(
                provider=provider if assign_provider else function_body,
                node=qual.target,
                source=ExpressionTempVariableRef(
                    variable=tmp_value_variable.makeReference(
                        nested_temp_block),
                    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=conditions[0],
                    yes_branch=makeStatementsSequenceFromStatement(
                        statement=current_body),
                    no_branch=None,
                    source_ref=source_ref))
        elif len(conditions) > 1:
            loop_statements.append(
                StatementConditional(
                    condition=buildAndNode(provider=function_body,
                                           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=loop_statements,
                                                  source_ref=source_ref),
                          source_ref=source_ref))

        nested_temp_block.setBody(
            StatementsSequence(statements=nested_statements,
                               source_ref=source_ref))

        current_body = nested_temp_block

    statements.append(current_body)

    if start_value is not None:
        statements.append(
            StatementReturn(expression=ExpressionTempVariableRef(
                variable=container_tmp.makeReference(temp_block),
                source_ref=source_ref),
                            source_ref=source_ref))

    temp_block.setBody(
        StatementsSequence(statements=statements, source_ref=source_ref))

    function_body.setBody(
        StatementsFrame(statements=[temp_block],
                        guard_mode="pass_through"
                        if emit_class is not ExpressionYield else "generator",
                        arg_names=(),
                        kw_only_count=0,
                        code_name="contraction",
                        source_ref=source_ref))

    return ExpressionFunctionCall(function=ExpressionFunctionCreation(
        function_ref=ExpressionFunctionRef(function_body=function_body,
                                           source_ref=source_ref),
        defaults=(),
        kw_defaults=None,
        annotations=None,
        source_ref=source_ref),
                                  values=(ExpressionBuiltinIter1(
                                      value=buildNode(
                                          provider=provider,
                                          node=node.generators[0].iter,
                                          source_ref=source_ref),
                                      source_ref=source_ref), ),
                                  source_ref=source_ref)