Example #1
0
def makeInternalHelperFunctionBody(name, parameters):
    return ExpressionFunctionBody(
        provider    = getInternalModule(),
        name        = name,
        code_object = None,
        doc         = None,
        parameters  = parameters,
        flags       = set(),
        source_ref  = internal_source_ref
    )
def _buildClassNode2(provider, node, source_ref):
    class_statements, class_doc = extractDocFromBody(node)

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

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

    body = buildStatementsNode(
        provider   = function_body,
        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().getFullName(),
                source_ref    = source_ref,
                user_provided = True
            ),
            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,
                    user_provided = True
                ),
                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.

    function_body.setBody( body )

    temp_scope = provider.allocateTempScope( "class_creation" )

    tmp_bases = provider.allocateTempVariable( temp_scope, "bases" )
    tmp_class_dict = provider.allocateTempVariable(temp_scope, "class_dict")
    tmp_metaclass = provider.allocateTempVariable(temp_scope, "metaclass")
    tmp_class = provider.allocateTempVariable(temp_scope, "class")

    statements = [
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases.makeReference( provider ),
                source_ref = source_ref
            ),
            source       = makeSequenceCreationOrConstant(
                sequence_kind = "tuple",
                elements      = buildNodeList(
                    provider, node.bases, source_ref
                ),
                source_ref    = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_dict.makeReference(provider),
                source_ref = source_ref
            ),
            source       =   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     = (),
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass.makeReference(provider),
                source_ref = source_ref
            ),
            source       = ExpressionConditional(
                condition =  ExpressionComparison(
                    comparator = "In",
                    left       = ExpressionConstantRef(
                        constant      = "__metaclass__",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    right      = ExpressionTempVariableRef(
                        variable   = tmp_class_dict.makeReference(provider),
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_expression = ExpressionDictOperationGet(
                    dicte = ExpressionTempVariableRef(
                        variable   = tmp_class_dict.makeReference(provider),
                        source_ref = source_ref
                    ),
                    key   = ExpressionConstantRef(
                        constant      = "__metaclass__",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    source_ref = source_ref
                ),
                no_expression = ExpressionSelectMetaclass(
                    metaclass = None,
                    bases     = ExpressionTempVariableRef(
                        variable   = tmp_bases.makeReference( provider ),
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class.makeReference(provider),
                source_ref = source_ref
            ),
            source     = ExpressionCallNoKeywords(
                called         = ExpressionTempVariableRef(
                    variable   = tmp_metaclass.makeReference(provider),
                    source_ref = source_ref
                ),
                args           = ExpressionMakeTuple(
                    elements   = (
                        ExpressionConstantRef(
                            constant      = node.name,
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_bases.makeReference( provider ),
                            source_ref = source_ref
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_class_dict.makeReference(
                                provider
                            ),
                            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(provider),
                    source_ref = source_ref
                ),
                source       = ExpressionCallNoKeywords(
                    called     = decorator,
                    args       = ExpressionMakeTuple(
                        elements  = (
                            ExpressionTempVariableRef(
                                variable   = tmp_class.makeReference(
                                    provider
                                ),
                                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(provider),
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    )

    final = (
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class.makeReference(provider),
                source_ref = source_ref
            ),
            tolerant   = True,
            source_ref = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases.makeReference( provider ),
                source_ref = source_ref
            ),
            tolerant   = True,
            source_ref = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_dict.makeReference(provider),
                source_ref = source_ref
            ),
            tolerant   = True,
            source_ref = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass.makeReference(provider),
                source_ref = source_ref
            ),
            tolerant   = True,
            source_ref = source_ref
        )
    )

    return makeTryFinallyStatement(
        tried      = statements,
        final      = final,
        source_ref = source_ref
    )
Example #3
0
def buildFunctionWithParsing(provider, function_kind, name, function_doc,
                             flags, node, source_ref):
    # This contains a complex re-formulation for nested parameter functions.
    # pylint: disable=R0914

    kind = getKind(node)

    assert kind in ("FunctionDef", "Lambda",
                    "AsyncFunctionDef"), "unsupported for kind " + kind

    def extractArg(arg):
        if arg is None:
            return None
        elif type(arg) is str:
            return mangleName(arg, provider)
        elif getKind(arg) == "Name":
            return mangleName(arg.id, provider)
        elif getKind(arg) == "arg":
            return mangleName(arg.arg, provider)
        elif getKind(arg) == "Tuple":
            # These are to be re-formulated on the outside.
            assert False
        else:
            assert False, getKind(arg)

    special_args = {}

    def extractNormalArgs(args):
        normal_args = []

        for arg in args:
            if type(arg) is not str and getKind(arg) == "Tuple":
                special_arg_name = ".%d" % (len(special_args) + 1)

                special_args[special_arg_name] = arg.elts
                normal_args.append(special_arg_name)
            else:
                normal_args.append(extractArg(arg))

        return normal_args

    normal_args = extractNormalArgs(node.args.args)

    parameters = ParameterSpec(
        ps_name=name,
        ps_normal_args=normal_args,
        ps_kw_only_args=[extractArg(arg) for arg in node.args.kwonlyargs]
        if python_version >= 300 else [],
        ps_list_star_arg=extractArg(node.args.vararg),
        ps_dict_star_arg=extractArg(node.args.kwarg),
        ps_default_count=len(node.args.defaults))

    message = parameters.checkValid()

    if message is not None:
        SyntaxErrors.raiseSyntaxError(message, source_ref)

    code_object = CodeObjectSpec(
        co_name=name,
        co_kind=function_kind,
        co_varnames=parameters.getParameterNames(),
        co_argcount=parameters.getArgumentCount(),
        co_kwonlyargcount=parameters.getKwOnlyParameterCount(),
        co_has_starlist=parameters.getStarListArgumentName() is not None,
        co_has_stardict=parameters.getStarDictArgumentName() is not None)

    outer_body = ExpressionFunctionBody(provider=provider,
                                        name=name,
                                        flags=flags,
                                        doc=function_doc,
                                        parameters=parameters,
                                        source_ref=source_ref)

    if special_args:
        inner_name = name.strip("<>") + "$inner"
        inner_arg_names = []
        iter_vars = []

        values = []

        statements = []

        def unpackFrom(source, arg_names):
            accesses = []

            sub_special_index = 0

            iter_var = outer_body.allocateTempVariable(
                None, "arg_iter_%d" % len(iter_vars))
            iter_vars.append(iter_var)

            statements.append(
                StatementAssignmentVariable(
                    variable_ref=ExpressionTargetTempVariableRef(
                        variable=iter_var, source_ref=source_ref),
                    source=ExpressionBuiltinIter1(value=source,
                                                  source_ref=source_ref),
                    source_ref=source_ref))

            for element_index, arg_name in enumerate(arg_names):
                if getKind(arg_name) == "Name":
                    inner_arg_names.append(arg_name.id)

                    arg_var = outer_body.allocateTempVariable(
                        None, "tmp_" + arg_name.id)

                    statements.append(
                        StatementAssignmentVariable(
                            variable_ref=ExpressionTargetTempVariableRef(
                                variable=arg_var, source_ref=source_ref),
                            source=ExpressionSpecialUnpack(
                                value=ExpressionTempVariableRef(
                                    variable=iter_var, source_ref=source_ref),
                                count=element_index + 1,
                                expected=len(arg_names),
                                source_ref=source_ref),
                            source_ref=source_ref))

                    accesses.append(
                        ExpressionTempVariableRef(variable=arg_var,
                                                  source_ref=source_ref))
                elif getKind(arg_name) == "Tuple":
                    accesses.extend(
                        unpackFrom(source=ExpressionSpecialUnpack(
                            value=ExpressionTempVariableRef(
                                variable=iter_var, source_ref=source_ref),
                            count=element_index + 1,
                            expected=len(arg_names),
                            source_ref=source_ref),
                                   arg_names=arg_name.elts))

                    sub_special_index += 1
                else:
                    assert False, arg_name

            statements.append(
                StatementSpecialUnpackCheck(iterator=ExpressionTempVariableRef(
                    variable=iter_var, source_ref=source_ref),
                                            count=len(arg_names),
                                            source_ref=source_ref))

            return accesses

        for arg_name in parameters.getParameterNames():
            if arg_name.startswith('.'):
                source = ExpressionVariableRef(variable_name=arg_name,
                                               source_ref=source_ref)

                values.extend(unpackFrom(source, special_args[arg_name]))
            else:
                values.append(
                    ExpressionVariableRef(variable_name=arg_name,
                                          source_ref=source_ref))

                inner_arg_names.append(arg_name)

        inner_parameters = ParameterSpec(ps_name=inner_name,
                                         ps_normal_args=inner_arg_names,
                                         ps_kw_only_args=(),
                                         ps_list_star_arg=None,
                                         ps_dict_star_arg=None,
                                         ps_default_count=None)

        function_body = ExpressionFunctionBody(provider=outer_body,
                                               name=inner_name,
                                               flags=flags,
                                               doc=function_doc,
                                               parameters=inner_parameters,
                                               source_ref=source_ref)

        statements.append(
            StatementReturn(ExpressionFunctionCall(
                function=ExpressionFunctionCreation(
                    function_ref=ExpressionFunctionRef(
                        function_body=function_body, source_ref=source_ref),
                    code_object=code_object,
                    defaults=(),
                    kw_defaults=None,
                    annotations=None,
                    source_ref=source_ref),
                values=values,
                source_ref=source_ref),
                            source_ref=source_ref))

        outer_body.setBody(
            makeStatementsSequenceFromStatement(
                statement=makeTryFinallyStatement(
                    provider,
                    tried=statements,
                    final=[
                        StatementReleaseVariable(variable=variable,
                                                 source_ref=source_ref)
                        for variable in outer_body.getTempVariables()
                    ],
                    source_ref=source_ref,
                    public_exc=False)))
    else:
        function_body = outer_body

    return outer_body, function_body, code_object
Example #4
0
def getDictUnpackingHelper():
    helper_name = "_unpack_dict"

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

    temp_scope = None

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

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

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

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

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

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

    return result
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=ParameterSpec(
                                               name="contraction",
                                               normal_args=("__iterator", ),
                                               list_star_arg=None,
                                               dict_star_arg=None,
                                               default_count=0,
                                               kw_only_args=()),
                                           source_ref=source_ref)

    if start_value is not None:
        container_tmp = function_body.allocateTempVariable(
            temp_scope=None, name="contraction_result")
    else:
        container_tmp = None

    outer_iter_ref = ExpressionVariableRef(variable_name="__iterator",
                                           source_ref=source_ref)

    statements, del_statements = _buildContractionBodyNode(
        function_body=function_body,
        assign_provider=assign_provider,
        provider=provider,
        node=node,
        emit_class=emit_class,
        outer_iter_ref=outer_iter_ref,
        temp_scope=None,
        start_value=start_value,
        container_tmp=container_tmp,
        source_ref=source_ref,
    )

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

    statements = (makeTryFinallyStatement(
        tried=statements,
        final=del_statements,
        source_ref=source_ref.atInternal()), )

    function_body.setBody(
        StatementsFrame(statements=statements,
                        guard_mode="pass_through"
                        if emit_class is not ExpressionYield else "generator",
                        var_names=(),
                        arg_count=0,
                        kw_only_count=0,
                        has_starlist=False,
                        has_stardict=False,
                        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)
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)

    # We need a scope for the temporary variables, and they might be closured.
    temp_scope = provider.allocateTempScope(
        name          = "class_creation",
        allow_closure = True
    )

    tmp_bases = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "bases"
    )
    tmp_class_decl_dict = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "class_decl_dict"
    )
    tmp_metaclass = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "metaclass"
    )
    tmp_prepared = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "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: This allows some APIs to work although this is not yet officially a
    # child yet.
    class_creation_function.parent = provider

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

    source_ref_orig = source_ref

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

    module_variable = class_creation_function.getVariableForAssignment(
        "__module__"
    )

    statements = [
        StatementSetLocals(
            new_locals = ExpressionTempVariableRef(
                variable   = tmp_prepared,
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetVariableRef(
                variable_name = "__module__",
                variable      = module_variable,
                source_ref    = source_ref
            ),
            source       = ExpressionConstantRef(
                constant      = provider.getParentModule().getFullName(),
                source_ref    = source_ref,
                user_provided = True
            ),
            source_ref   = source_ref
        )
    ]

    if class_doc is not None:
        doc_variable = class_creation_function.getVariableForAssignment(
            "__doc__"
        )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__doc__",
                    variable      = doc_variable,
                    source_ref    = source_ref
                ),
                source       = ExpressionConstantRef(
                    constant      = class_doc,
                    source_ref    = source_ref,
                    user_provided = True
                ),
                source_ref   = source_ref
            )
        )

    # The "__qualname__" attribute is new in Python 3.3.
    if Utils.python_version >= 330:
        qualname = class_creation_function.getFunctionQualname()
        qualname_variable = class_creation_function.getVariableForAssignment(
            "__qualname__"
        )

        if Utils.python_version < 340:
            qualname_ref = ExpressionConstantRef(
                constant      = qualname,
                source_ref    = source_ref,
                user_provided = True
            )
        else:
            qualname_ref = ExpressionFunctionQualnameRef(
                function_body = class_creation_function,
                source_ref    = source_ref,
            )

        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetVariableRef(
                    variable_name = "__qualname__",
                    variable      = qualname_variable,
                    source_ref    = source_ref
                ),
                source       = qualname_ref,
                source_ref   = source_ref
            )
        )

        if Utils.python_version >= 340:
            qualname_assign = statements[-1]

    if Utils.python_version >= 340 and False: # TODO: Temporarily reverted:
        tmp_class = class_creation_function.allocateTempVariable(
            temp_scope = None,
            name       = "__class__"
        )

        class_target_variable_ref = ExpressionTargetTempVariableRef(
            variable   = tmp_class,
            source_ref = source_ref
        )
        class_variable_ref = ExpressionTempVariableRef(
            variable   = tmp_class,
            source_ref = source_ref
        )
    else:
        class_variable = class_creation_function.getVariableForAssignment(
            "__class__"
        )

        class_target_variable_ref = ExpressionTargetVariableRef(
            variable_name = "__class__",
            variable      = class_variable,
            source_ref    = source_ref
        )
        class_variable_ref = ExpressionVariableRef(
            variable_name = "__class__",
            variable      = class_variable,
            source_ref    = source_ref
        )

    statements += [
        body,
        StatementAssignmentVariable(
            variable_ref = class_target_variable_ref,
            source       = ExpressionCall(
                called     = ExpressionTempVariableRef(
                    variable   = tmp_metaclass,
                    source_ref = source_ref
                ),
                args       = makeSequenceCreationOrConstant(
                    sequence_kind = "tuple",
                    elements      = (
                        ExpressionConstantRef(
                            constant      = node.name,
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_bases,
                            source_ref = source_ref
                        ),
                        ExpressionBuiltinLocals(
                            source_ref = source_ref
                        )
                    ),
                    source_ref    = source_ref
                ),
                kw         = ExpressionTempVariableRef(
                    variable   = tmp_class_decl_dict,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementReturn(
            expression = class_variable_ref,
            source_ref = source_ref
        )
    ]

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

    # The class body is basically a function that implicitly, 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 implicitly, 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,
                source_ref = source_ref
            ),
            source       = makeSequenceCreationOrConstant(
                sequence_kind = "tuple",
                elements      = buildNodeList(
                    provider, node.bases, source_ref
                ),
                source_ref    = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_decl_dict,
                source_ref = source_ref
            ),
            source       = makeDictCreationOrConstant(
                keys       = [
                    ExpressionConstantRef(
                        constant      = keyword.arg,
                        source_ref    = source_ref,
                        user_provided = True
                    )
                    for keyword in
                    node.keywords
                ],
                values     = [
                    buildNode(provider, keyword.value, source_ref)
                    for keyword in
                    node.keywords
                ],
                lazy_order = False,
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass,
                source_ref = source_ref
            ),
            source       = ExpressionSelectMetaclass(
                metaclass  = ExpressionConditional(
                    condition      = ExpressionComparison(
                        comparator = "In",
                        left       = ExpressionConstantRef(
                            constant      = "metaclass",
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        right      = ExpressionTempVariableRef(
                            variable   = tmp_class_decl_dict,
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    yes_expression = ExpressionDictOperationGet(
                        dicte      = ExpressionTempVariableRef(
                            variable   = tmp_class_decl_dict,
                            source_ref = source_ref
                        ),
                        key        = ExpressionConstantRef(
                            constant      = "metaclass",
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        source_ref = source_ref
                    ),
                    no_expression  = ExpressionConditional(
                        condition      = ExpressionTempVariableRef(
                            variable   = tmp_bases,
                            source_ref = source_ref
                        ),
                        no_expression  = ExpressionBuiltinRef(
                            builtin_name = "type",
                            source_ref   = source_ref
                        ),
                        yes_expression = ExpressionBuiltinType1(
                            value      = ExpressionSubscriptLookup(
                                subscribed = ExpressionTempVariableRef(
                                    variable   = tmp_bases,
                                    source_ref = source_ref
                                ),
                                subscript  = ExpressionConstantRef(
                                    constant      = 0,
                                    source_ref    = source_ref,
                                    user_provided = True
                                ),
                                source_ref = source_ref
                            ),
                            source_ref = source_ref
                        ),
                        source_ref     = source_ref
                    ),
                    source_ref     = source_ref
                ),
                bases      = ExpressionTempVariableRef(
                    variable   = tmp_bases,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref   = source_ref_orig
        ),
        StatementConditional(
            condition  = ExpressionComparison(
                comparator = "In",
                left       = ExpressionConstantRef(
                    constant      = "metaclass",
                    source_ref    = source_ref,
                    user_provided = True
                ),
                right      = ExpressionTempVariableRef(
                    variable   = tmp_class_decl_dict,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            no_branch  = None,
            yes_branch = makeStatementsSequenceFromStatement(
                statement = StatementDictOperationRemove(
                    dicte      = ExpressionTempVariableRef(
                        variable   = tmp_class_decl_dict,
                        source_ref = source_ref
                    ),
                    key        = ExpressionConstantRef(
                        constant      = "metaclass",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    source_ref = source_ref
                )
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_prepared,
                source_ref = source_ref
            ),
            source       = ExpressionConditional(
                condition      = ExpressionBuiltinHasattr(
                    object     = ExpressionTempVariableRef(
                        variable   = tmp_metaclass,
                        source_ref = source_ref
                    ),
                    name       = ExpressionConstantRef(
                        constant      = "__prepare__",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    source_ref = source_ref
                ),
                no_expression  = ExpressionConstantRef(
                    constant      = {},
                    source_ref    = source_ref,
                    user_provided = True
                ),
                yes_expression = ExpressionCall(
                    called     = ExpressionAttributeLookup(
                        source         = ExpressionTempVariableRef(
                            variable   = tmp_metaclass,
                            source_ref = source_ref
                        ),
                        attribute_name = "__prepare__",
                        source_ref     = source_ref
                    ),
                    args       = ExpressionMakeTuple(
                        elements   = (
                            ExpressionConstantRef(
                                constant      = node.name,
                                source_ref    = source_ref,
                                user_provided = True
                            ),
                            ExpressionTempVariableRef(
                                variable   = tmp_bases,
                                source_ref = source_ref
                            )
                        ),
                        source_ref = source_ref
                    ),
                    kw         = ExpressionTempVariableRef(
                        variable   = tmp_class_decl_dict,
                        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
        ),
    )

    if Utils.python_version >= 340:
        class_assign = statements[-1]

        # assert False, class_creation_function
        class_creation_function.qualname_setup = class_assign, qualname_assign



    final = (
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_decl_dict,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_prepared,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        )
    )

    return makeTryFinallyStatement(
        tried      = statements,
        final      = final,
        source_ref = source_ref
    )
Example #7
0
def buildLambdaNode(provider, node, source_ref):
    assert getKind(node) == "Lambda"

    parameters = buildParameterSpec(provider, "<lambda>", node, source_ref)

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

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

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

    if function_body.isGenerator():
        if Utils.python_version < 270:
            tmp_return_value = function_body.allocateTempVariable(
                temp_scope=None, name="yield_return")

            statements = (StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_return_value,
                    source_ref=source_ref,
                ),
                source=body,
                source_ref=source_ref),
                          StatementConditional(
                              condition=ExpressionComparisonIsNOT(
                                  left=ExpressionTempVariableRef(
                                      variable=tmp_return_value,
                                      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,
                                              source_ref=source_ref,
                                          ),
                                          source_ref=source_ref),
                                      source_ref=source_ref)),
                              no_branch=None,
                              source_ref=source_ref))
            body = makeTryFinallyStatement(tried=statements,
                                           final=StatementReleaseVariable(
                                               variable=tmp_return_value,
                                               tolerant=True,
                                               source_ref=source_ref),
                                           source_ref=source_ref)
        else:
            body = StatementExpressionOnly(expression=body,
                                           source_ref=source_ref)
    else:
        body = StatementReturn(expression=body, source_ref=source_ref)

    body = StatementsFrame(
        statements=mergeStatements((body, )),
        guard_mode="generator" if function_body.isGenerator() else "full",
        var_names=parameters.getCoArgNames(),
        arg_count=parameters.getArgumentCount(),
        kw_only_count=parameters.getKwOnlyParameterCount(),
        has_starlist=parameters.getStarListArgumentName() is not None,
        has_stardict=parameters.getStarDictArgumentName() is not None,
        code_name="<lambda>",
        source_ref=body.getSourceReference())

    body = makeStatementsSequenceFromStatement(statement=body, )

    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"

    parameters = buildParameterSpec(provider, "<lambda>", node, source_ref)

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

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

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

    if function_body.isGenerator():
        if Utils.python_version < 270:
            tmp_return_value = function_body.allocateTempVariable(
                temp_scope = None,
                name       = "yield_return"
            )

            statements = (
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = tmp_return_value,
                        source_ref = source_ref,
                    ),
                    source       = body,
                    source_ref   = source_ref
                ),
                StatementConditional(
                    condition  = ExpressionComparisonIsNOT(
                        left       = ExpressionTempVariableRef(
                            variable   = tmp_return_value,
                            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,
                                    source_ref = source_ref,
                                ),
                                source_ref = source_ref
                            ),
                            source_ref = source_ref
                        )
                    ),
                    no_branch  = None,
                    source_ref = source_ref
                )
            )
            body = makeTryFinallyStatement(
                provider   = provider,
                tried      = statements,
                final      = StatementReleaseVariable(
                    variable   = tmp_return_value,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        else:
            body = StatementExpressionOnly(
                expression = body,
                source_ref = source_ref
            )
    else:
        body = StatementReturn(
            expression = body,
            source_ref = source_ref
        )

    body = StatementsFrame(
        statements    = mergeStatements(
            (body,)
        ),
        guard_mode    = "generator" if function_body.isGenerator() else "full",
        var_names     = parameters.getCoArgNames(),
        arg_count     = parameters.getArgumentCount(),
        kw_only_count = parameters.getKwOnlyParameterCount(),
        has_starlist  = parameters.getStarListArgumentName() is not None,
        has_stardict  = parameters.getStarDictArgumentName() is not None,
        code_name     = "<lambda>",
        source_ref    = body.getSourceReference()
    )


    body = makeStatementsSequenceFromStatement(
        statement = body,
    )

    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 _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.

    # Note: The assign_provider is only to cover Python2 list contractions,
    # assigning one of the loop variables to the outside scope.
    if assign_provider:
        function_body = ExpressionOutlineBody(
            provider=provider,
            name=name,
            body=None,  # later
            source_ref=source_ref)

        iter_tmp = function_body.allocateTempVariable(temp_scope=None,
                                                      name=".0")
    else:
        function_body = ExpressionFunctionBody(provider=provider,
                                               name=name,
                                               doc=None,
                                               parameters=ParameterSpec(
                                                   name="contraction",
                                                   normal_args=(".0", ),
                                                   list_star_arg=None,
                                                   dict_star_arg=None,
                                                   default_count=0,
                                                   kw_only_args=()),
                                               is_class=False,
                                               source_ref=source_ref)

        iter_tmp = function_body.getVariableForAssignment(variable_name=".0")
        assert iter_tmp.isParameterVariable()

    if start_value is not None:
        container_tmp = function_body.allocateTempVariable(
            temp_scope=None, name="contraction_result")
    else:
        container_tmp = None

    statements, release_statements = _buildContractionBodyNode(
        function_body=function_body,
        assign_provider=assign_provider,
        provider=provider,
        node=node,
        emit_class=emit_class,
        iter_tmp=iter_tmp,
        temp_scope=None,
        start_value=start_value,
        container_tmp=container_tmp,
        source_ref=source_ref,
    )

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

    statements = (makeTryFinallyStatement(
        provider=function_body,
        tried=statements,
        final=release_statements,
        source_ref=source_ref.atInternal()), )

    function_body.setBody(
        makeStatementsSequenceFromStatement(statement=StatementsFrame(
            statements=mergeStatements(statements, False),
            guard_mode="pass_through"
            if emit_class is not ExpressionYield else "generator",
            var_names=(),
            arg_count=0,
            kw_only_count=0,
            has_starlist=False,
            has_stardict=False,
            code_name="contraction",
            source_ref=source_ref)))

    if not assign_provider:
        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)
    else:
        return function_body
def getDictUnpackingHelper():
    helper_name = "_unpack_dict"

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

    temp_scope = None

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

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

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

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

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

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

    return result
Example #11
0
def buildFunctionNode(provider, node, source_ref):
    assert getKind(node) == "FunctionDef"

    function_statements, function_doc = extractDocFromBody(node)

    function_body = ExpressionFunctionBody(provider=provider,
                                           name=node.name,
                                           doc=function_doc,
                                           parameters=buildParameterSpec(
                                               provider, node.name, node,
                                               source_ref),
                                           is_class=False,
                                           source_ref=source_ref)

    decorators = buildNodeList(provider=provider,
                               nodes=reversed(node.decorator_list),
                               source_ref=source_ref)

    defaults = buildNodeList(provider=provider,
                             nodes=node.args.defaults,
                             source_ref=source_ref)

    kw_defaults = buildParameterKwDefaults(provider=provider,
                                           node=node,
                                           function_body=function_body,
                                           source_ref=source_ref)

    function_statements_body = buildStatementsNode(provider=function_body,
                                                   nodes=function_statements,
                                                   frame=True,
                                                   source_ref=source_ref)

    if function_body.isGenerator():
        # TODO: raise generator exit?
        pass
    else:
        function_statements_body = _insertFinalReturnStatement(
            function_statements_body=function_statements_body,
            source_ref=source_ref)

    if function_statements_body.isStatementsFrame():
        function_statements_body = makeStatementsSequenceFromStatement(
            statement=function_statements_body)

    function_body.setBody(function_statements_body)

    annotations = buildParameterAnnotations(provider, node, source_ref)

    function_creation = ExpressionFunctionCreation(
        function_ref=ExpressionFunctionRef(function_body=function_body,
                                           source_ref=source_ref),
        defaults=defaults,
        kw_defaults=kw_defaults,
        annotations=annotations,
        source_ref=source_ref)

    # Add the "staticmethod" decorator to __new__ methods if not provided.

    # CPython made these optional, but secretly applies them when it does
    # "class __new__".  We add them earlier, so our optimization will see it.
    if node.name == "__new__" and \
       not decorators and \
       provider.isExpressionClassBody():

        decorators = (ExpressionBuiltinRef(builtin_name="staticmethod",
                                           source_ref=source_ref), )

    decorated_function = function_creation
    for decorator in decorators:
        decorated_function = ExpressionCallNoKeywords(
            called=decorator,
            args=ExpressionMakeTuple(elements=(decorated_function, ),
                                     source_ref=source_ref),
            source_ref=decorator.getSourceReference())

    result = StatementAssignmentVariable(
        variable_ref=ExpressionTargetVariableRef(variable_name=mangleName(
            node.name, provider),
                                                 source_ref=source_ref),
        source=decorated_function,
        source_ref=source_ref)

    if Utils.python_version >= 340:
        function_body.qualname_setup = result.getTargetVariableRef()

    return result
Example #12
0
def buildAsyncFunctionNode(provider, node, source_ref):
    # We are creating a function here that creates coroutine objects, with
    # many details each, pylint: disable=R0914
    assert getKind(node) == "AsyncFunctionDef"

    function_statements, function_doc = extractDocFromBody(node)

    creator_function_body = ExpressionFunctionBody(
        provider=provider,
        name=node.name,
        doc=function_doc,
        parameters=buildParameterSpec(provider, node.name, node, source_ref),
        is_class=False,
        source_ref=source_ref)

    function_body = ExpressionCoroutineBody(provider=creator_function_body,
                                            name=node.name,
                                            source_ref=source_ref)

    decorators = buildNodeList(provider=provider,
                               nodes=reversed(node.decorator_list),
                               source_ref=source_ref)

    defaults = buildNodeList(provider=provider,
                             nodes=node.args.defaults,
                             source_ref=source_ref)

    function_statements_body = buildStatementsNode(provider=function_body,
                                                   nodes=function_statements,
                                                   frame=True,
                                                   source_ref=source_ref)

    function_statements_body = _insertFinalReturnStatement(
        function_statements_body=function_statements_body,
        source_ref=source_ref)

    if function_statements_body.isStatementsFrame():
        function_statements_body = makeStatementsSequenceFromStatement(
            statement=function_statements_body)

    function_body.setBody(function_statements_body)

    annotations = buildParameterAnnotations(provider, node, source_ref)

    kw_defaults = buildParameterKwDefaults(provider=provider,
                                           node=node,
                                           function_body=creator_function_body,
                                           source_ref=source_ref)

    creator_function_body.setBody(
        makeStatementsSequenceFromStatement(
            statement=StatementReturn(expression=ExpressionCoroutineCreation(
                coroutine_body=function_body, source_ref=source_ref),
                                      source_ref=source_ref)))

    function_creation = ExpressionFunctionCreation(
        function_ref=ExpressionFunctionRef(function_body=creator_function_body,
                                           source_ref=source_ref),
        defaults=defaults,
        kw_defaults=kw_defaults,
        annotations=annotations,
        source_ref=source_ref)

    decorated_function = function_creation
    for decorator in decorators:
        decorated_function = ExpressionCallNoKeywords(
            called=decorator,
            args=ExpressionMakeTuple(elements=(decorated_function, ),
                                     source_ref=source_ref),
            source_ref=decorator.getSourceReference())

    result = StatementAssignmentVariable(
        variable_ref=ExpressionTargetVariableRef(variable_name=mangleName(
            node.name, provider),
                                                 source_ref=source_ref),
        source=decorated_function,
        source_ref=source_ref)

    function_body.qualname_setup = result.getTargetVariableRef()

    return result
Example #13
0
def getClassBasesMroConversionHelper():
    helper_name = "_mro_entries_conversion"

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

    temp_scope = None

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

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

    non_type_case = makeStatementConditional(
        condition  = ExpressionBuiltinHasattr(
            object_arg = ExpressionTempVariableRef(
                variable   = tmp_item_variable,
                source_ref = internal_source_ref
            ),
            name       = makeConstantRefNode(
                constant   = "__mro_entries__",
                source_ref = internal_source_ref
            ),
            source_ref = internal_source_ref
        ),
        yes_branch = StatementExpressionOnly(
            expression = ExpressionListOperationExtend(
                list_arg   = ExpressionTempVariableRef(
                    variable   = tmp_result_variable,
                    source_ref = internal_source_ref
                ),
                value      = makeExpressionCall(
                    called     = ExpressionAttributeLookup(
                        source         = ExpressionTempVariableRef(
                            variable   = tmp_item_variable,
                            source_ref = internal_source_ref
                        ),
                        attribute_name = "__mro_entries__",
                        source_ref     = internal_source_ref
                    ),
                    args       = ExpressionMakeTuple(
                        elements   = (
                            ExpressionVariableRef(
                                variable   = args_variable,
                                source_ref = internal_source_ref
                            ),
                        ),
                        source_ref = internal_source_ref
                    ),
                    kw         = None,
                    source_ref = internal_source_ref
                ),
                source_ref = internal_source_ref
            ),
            source_ref = internal_source_ref
        ),
        no_branch  = StatementListOperationAppend(
            list_arg   = ExpressionTempVariableRef(
                variable   = tmp_result_variable,
                source_ref = internal_source_ref
            ),
            value      = ExpressionTempVariableRef(
                variable   = tmp_item_variable,
                source_ref = internal_source_ref
            ),
            source_ref = internal_source_ref
        ),
        source_ref = internal_source_ref
    )

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

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


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

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

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

    return result
def buildFunctionNode( provider, node, source_ref ):
    assert getKind( node ) == "FunctionDef"

    # Remove "exec" flag if any.
    source_ref = source_ref.getExecReference( False )

    function_statements, function_doc = extractDocFromBody( node )

    function_body = ExpressionFunctionBody(
        provider   = provider,
        name       = node.name,
        doc        = function_doc,
        parameters = buildParameterSpec( node.name, node, source_ref ),
        source_ref = source_ref
    )

    # Hack:
    function_body.parent = provider

    decorators = buildNodeList( provider, reversed( node.decorator_list ), source_ref )

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

    function_statements_body = buildStatementsNode(
        provider   = function_body,
        nodes      = function_statements,
        frame      = True,
        source_ref = source_ref
    )

    if function_body.isExpressionFunctionBody() and function_body.isGenerator():
        # TODO: raise generator exit?
        pass
    elif function_statements_body is None:
        function_statements_body = makeStatementsSequenceFromStatement(
            statement = StatementReturn(
                expression = ExpressionConstantRef(
                    constant   = None,
                    source_ref = source_ref.atInternal()
                ),
                source_ref = source_ref.atInternal()
            )
        )
    elif not function_statements_body.isStatementAborting():
        function_statements_body.setStatements(
            function_statements_body.getStatements() +
            (
                StatementReturn(
                    expression = ExpressionConstantRef(
                        constant   = None,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref.atInternal()
                ),
            )
        )

    function_body.setBody( function_statements_body )

    annotations = buildParameterAnnotations( provider, node, source_ref )

    decorated_body = ExpressionFunctionCreation(
        function_ref = ExpressionFunctionRef(
            function_body,
            source_ref = source_ref
        ),
        defaults     = defaults,
        kw_defaults  = kw_defaults,
        annotations  = annotations,
        source_ref   = source_ref
    )

    # Add the staticmethod decorator to __new__ methods if not provided.

    # CPython made these optional, but applies them to every class __new__. We add them
    # early, so our optimization will see it.
    if node.name == "__new__" and not decorators and \
         provider.isExpressionFunctionBody() and provider.isClassDictCreation():

        decorators = (
            ExpressionBuiltinRef(
                builtin_name = "staticmethod",
                source_ref   = source_ref
            ),
        )

    for decorator in decorators:
        decorated_body = ExpressionCallNoKeywords(
            called     = decorator,
            args       = ExpressionMakeTuple(
                elements    = ( decorated_body, ),
                source_ref = source_ref
            ),
            source_ref = decorator.getSourceReference()
        )

    return StatementAssignmentVariable(
        variable_ref = ExpressionTargetVariableRef(
            variable_name = node.name,
            source_ref    = source_ref
        ),
        source       = decorated_body,
        source_ref   = source_ref
    )
def buildFunctionNode(provider, node, source_ref):
    assert getKind(node) == "FunctionDef"

    function_statements, function_doc = extractDocFromBody(node)

    function_body = ExpressionFunctionBody(
        provider   = provider,
        name       = node.name,
        doc        = function_doc,
        parameters = buildParameterSpec(provider, node.name, node, source_ref),
        is_class   = False,
        source_ref = source_ref
    )

    decorators = buildNodeList(
        provider   = provider,
        nodes      = reversed(node.decorator_list),
        source_ref = source_ref
    )

    defaults = buildNodeList(
        provider   = provider,
        nodes      = node.args.defaults,
        source_ref = source_ref
    )

    kw_defaults = buildParameterKwDefaults(
        provider, node, function_body, source_ref
    )

    function_statements_body = buildStatementsNode(
        provider   = function_body,
        nodes      = function_statements,
        frame      = True,
        source_ref = source_ref
    )

    if function_body.isGenerator():
        # TODO: raise generator exit?
        pass
    elif function_statements_body is None:
        function_statements_body = makeStatementsSequenceFromStatement(
            statement = StatementReturn(
                expression = ExpressionConstantRef(
                    constant      = None,
                    user_provided = True,
                    source_ref    = source_ref
                ),
                source_ref = source_ref
            )
        )
    elif not function_statements_body.isStatementAborting():
        function_statements_body.setStatements(
            function_statements_body.getStatements() +
            (
                StatementReturn(
                    expression = ExpressionConstantRef(
                        constant      = None,
                        user_provided = True,
                        source_ref    = source_ref
                    ),
                    source_ref = source_ref
                ),
            )
        )

    if function_statements_body.isStatementsFrame():
        function_statements_body = makeStatementsSequenceFromStatement(
            statement = function_statements_body
        )

    function_body.setBody(
        function_statements_body
    )

    annotations = buildParameterAnnotations(provider, node, source_ref)

    function_creation = ExpressionFunctionCreation(
        function_ref = ExpressionFunctionRef(
            function_body,
            source_ref = source_ref
        ),
        defaults     = defaults,
        kw_defaults  = kw_defaults,
        annotations  = annotations,
        source_ref   = source_ref
    )

    # Add the staticmethod decorator to __new__ methods if not provided.

    # CPython made these optional, but applies them to every class __new__. We
    # add them early, so our optimization will see it.
    if node.name == "__new__" and not decorators and \
         provider.isExpressionFunctionBody() and provider.isClassDictCreation():

        decorators = (
            ExpressionBuiltinRef(
                builtin_name = "staticmethod",
                source_ref   = source_ref
            ),
        )

    decorated_function = function_creation
    for decorator in decorators:
        decorated_function = ExpressionCallNoKeywords(
            called     = decorator,
            args       = ExpressionMakeTuple(
                elements   = (decorated_function,),
                source_ref = source_ref
            ),
            source_ref = decorator.getSourceReference()
        )


    result = StatementAssignmentVariable(
        variable_ref = ExpressionTargetVariableRef(
            variable_name = mangleName(node.name, provider),
            source_ref    = source_ref
        ),
        source       = decorated_function,
        source_ref   = source_ref
    )

    if Utils.python_version >= 340:
        function_body.qualname_setup = result.getTargetVariableRef()

    return result
Example #16
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 _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)

    if start_value is not None:
        container_tmp = function_body.allocateTempVariable(None, "result")

        statements = [
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=container_tmp.makeReference(function_body),
                    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(function_body),
                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(function_body),
            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 count, qual in enumerate(reversed(node.generators)):
        tmp_iter_variable = function_body.allocateTempVariable(
            temp_scope=None, name="contraction_iter_%d" % count)

        tmp_value_variable = function_body.allocateTempVariable(
            temp_scope=None, name="iter_value_%d" % count)

        # The first iterated value is to be calculated outside of the function
        # and will be given as a parameter "_iterated", the others are built
        # inside the function.
        if qual is node.generators[0]:
            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(function_body),
                    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(
                                function_body),
                            source_ref=source_ref),
                        source=ExpressionBuiltinNext1(
                            value=ExpressionTempVariableRef(
                                variable=tmp_iter_variable.makeReference(
                                    function_body),
                                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,
                temp_provider=function_body,
                node=qual.target,
                source=ExpressionTempVariableRef(
                    variable=tmp_value_variable.makeReference(function_body),
                    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=mergeStatements(loop_statements),
                source_ref=source_ref),
                          source_ref=source_ref))

        nested_statements.append(
            StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_iter_variable.makeReference(function_body),
                source_ref=source_ref),
                                 tolerant=False,
                                 source_ref=source_ref))

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

    statements.append(current_body)

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

    function_body.setBody(
        StatementsFrame(statements=mergeStatements(statements),
                        guard_mode="pass_through"
                        if emit_class is not ExpressionYield else "generator",
                        var_names=(),
                        arg_count=0,
                        kw_only_count=0,
                        has_starlist=False,
                        has_stardict=False,
                        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)
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 getListUnpackingHelper():
    helper_name = "_unpack_list"

    result = ExpressionFunctionBody(
        provider=getInternalModule(),
        name=helper_name,
        doc=None,
        parameters=ParameterSpec(
            name=helper_name, normal_args=(), list_star_arg="args", dict_star_arg=None, default_count=0, kw_only_args=()
        ),
        flags=set(),
        source_ref=internal_source_ref,
    )

    temp_scope = None

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

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

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

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

    tried = makeStatementsSequenceFromStatements(
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(variable=tmp_iter_variable, source_ref=internal_source_ref),
            source=ExpressionBuiltinIter1(
                value=ExpressionVariableRef(
                    variable_name="args", variable=args_variable, source_ref=internal_source_ref
                ),
                source_ref=internal_source_ref,
            ),
            source_ref=internal_source_ref,
        ),
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(variable=tmp_result_variable, source_ref=internal_source_ref),
            source=ExpressionConstantRef(constant=[], source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
        StatementLoop(body=loop_body, source_ref=internal_source_ref),
        StatementReturn(
            expression=ExpressionTempVariableRef(variable=tmp_result_variable, source_ref=internal_source_ref),
            source_ref=internal_source_ref,
        ),
    )

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

    return result
def _buildClassNode2(provider, node, source_ref):
    class_statements, class_doc = extractDocFromBody(node)

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

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

    body = buildStatementsNode(
        provider   = function_body,
        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 implicitly, 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().getFullName(),
                source_ref    = source_ref,
                user_provided = True
            ),
            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,
                    user_provided = True
                ),
                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 implicitly, at the end
    # returns its locals and cannot have other return statements contained.

    function_body.setBody(body)

    temp_scope = provider.allocateTempScope("class_creation")

    tmp_bases = provider.allocateTempVariable(temp_scope, "bases")
    tmp_class_dict = provider.allocateTempVariable(temp_scope, "class_dict")
    tmp_metaclass = provider.allocateTempVariable(temp_scope, "metaclass")
    tmp_class = provider.allocateTempVariable(temp_scope, "class")

    statements = [
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases,
                source_ref = source_ref
            ),
            source       = makeSequenceCreationOrConstant(
                sequence_kind = "tuple",
                elements      = buildNodeList(
                    provider, node.bases, source_ref
                ),
                source_ref    = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_dict,
                source_ref = source_ref
            ),
            source       =   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     = (),
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass,
                source_ref = source_ref
            ),
            source       = ExpressionConditional(
                condition      =  ExpressionComparison(
                    comparator = "In",
                    left       = ExpressionConstantRef(
                        constant      = "__metaclass__",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    right      = ExpressionTempVariableRef(
                        variable   = tmp_class_dict,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                yes_expression = ExpressionDictOperationGet(
                    dicte      = ExpressionTempVariableRef(
                        variable   = tmp_class_dict,
                        source_ref = source_ref
                    ),
                    key        = ExpressionConstantRef(
                        constant      = "__metaclass__",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    source_ref = source_ref
                ),
                no_expression  = ExpressionSelectMetaclass(
                    metaclass  = None,
                    bases      = ExpressionTempVariableRef(
                        variable   = tmp_bases,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref
                ),
                source_ref     = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class,
                source_ref = source_ref
            ),
            source       = ExpressionCallNoKeywords(
                called     = ExpressionTempVariableRef(
                    variable   = tmp_metaclass,
                    source_ref = source_ref
                ),
                args       = ExpressionMakeTuple(
                    elements   = (
                        ExpressionConstantRef(
                            constant      = node.name,
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_bases,
                            source_ref = source_ref
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_class_dict,
                            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,
                    source_ref = source_ref
                ),
                source       = ExpressionCallNoKeywords(
                    called     = decorator,
                    args       = ExpressionMakeTuple(
                        elements   = (
                            ExpressionTempVariableRef(
                                variable   = tmp_class,
                                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,
                source_ref = source_ref
            ),
            source_ref   = source_ref
        )
    )

    final = (
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_dict,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass,
                source_ref = source_ref
            ),
            tolerant     = True,
            source_ref   = source_ref
        )
    )

    return makeTryFinallyStatement(
        tried      = statements,
        final      = final,
        source_ref = source_ref
    )
Example #21
0
def _buildContractionNode(provider, node, name, emit_class, start_value,
                          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.

    # TODO: No function ought to be necessary.
    function_body = ExpressionFunctionBody(provider=provider,
                                           name=name,
                                           doc=None,
                                           parameters=ParameterSpec(
                                               ps_name=name,
                                               ps_normal_args=(".0", ),
                                               ps_list_star_arg=None,
                                               ps_dict_star_arg=None,
                                               ps_default_count=0,
                                               ps_kw_only_args=()),
                                           flags=set(),
                                           source_ref=source_ref)

    iter_tmp = function_body.getVariableForAssignment(variable_name=".0")
    assert iter_tmp.isParameterVariable()

    code_object = CodeObjectSpec(
        co_name=name,
        co_kind="Generator" if emit_class is ExpressionYield else "Function",
        co_varnames=function_body.getParameters().getParameterNames(),
        co_argcount=len(function_body.getParameters().getParameterNames()),
        co_kwonlyargcount=0,
        co_has_starlist=False,
        co_has_stardict=False,
    )

    if emit_class is ExpressionYield:
        code_body = ExpressionGeneratorObjectBody(provider=function_body,
                                                  name="<genexpr>",
                                                  flags=set(),
                                                  source_ref=source_ref)

        iter_tmp = code_body.getVariableForReference(variable_name=".0")
        assert iter_tmp.isLocalVariable()

        function_body.setBody(
            makeStatementsSequenceFromStatement(statement=StatementReturn(
                expression=ExpressionMakeGeneratorObject(
                    generator_ref=ExpressionFunctionRef(
                        function_body=code_body, source_ref=source_ref),
                    code_object=code_object,
                    source_ref=source_ref),
                source_ref=source_ref)))
    else:
        code_body = function_body

    if start_value is not None:
        container_tmp = code_body.allocateTempVariable(
            temp_scope=None, name="contraction_result")
    else:
        container_tmp = None

    statements, release_statements = _buildContractionBodyNode(
        function_body=code_body,
        provider=provider,
        node=node,
        emit_class=emit_class,
        iter_tmp=iter_tmp,
        temp_scope=None,
        start_value=start_value,
        container_tmp=container_tmp,
        assign_provider=False,
        source_ref=source_ref,
    )

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

    statements = (makeTryFinallyStatement(
        provider=function_body,
        tried=statements,
        final=release_statements,
        source_ref=source_ref.atInternal()), )

    if emit_class is ExpressionYield:
        guard_mode = "generator"
    else:
        guard_mode = "full"

    code_body.setBody(
        makeStatementsSequenceFromStatement(statement=StatementsFrame(
            statements=mergeStatements(statements, False),
            guard_mode=guard_mode,
            code_object=code_object,
            source_ref=source_ref)))

    return ExpressionFunctionCall(function=ExpressionFunctionCreation(
        function_ref=ExpressionFunctionRef(function_body=function_body,
                                           source_ref=source_ref),
        code_object=code_object,
        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)
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.

    # 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

    iterator_var_name = ".0"

    function_body = ExpressionFunctionBody(
        provider=provider,
        name=name,
        doc=None,
        parameters=ParameterSpec(
            name="contraction",
            normal_args=(iterator_var_name,),
            list_star_arg=None,
            dict_star_arg=None,
            default_count=0,
            kw_only_args=(),
        ),
        source_ref=source_ref,
    )

    if start_value is not None:
        container_tmp = function_body.allocateTempVariable(temp_scope=None, name="contraction_result")
    else:
        container_tmp = None

    outer_iter_ref = ExpressionVariableRef(variable_name=iterator_var_name, source_ref=source_ref)

    statements, del_statements = _buildContractionBodyNode(
        function_body=function_body,
        assign_provider=assign_provider,
        provider=provider,
        node=node,
        emit_class=emit_class,
        outer_iter_ref=outer_iter_ref,
        temp_scope=None,
        start_value=start_value,
        container_tmp=container_tmp,
        source_ref=source_ref,
    )

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

    statements = (makeTryFinallyStatement(tried=statements, final=del_statements, source_ref=source_ref.atInternal()),)

    function_body.setBody(
        makeStatementsSequenceFromStatement(
            statement=StatementsFrame(
                statements=statements,
                guard_mode="pass_through" if emit_class is not ExpressionYield else "generator",
                var_names=(),
                arg_count=0,
                kw_only_count=0,
                has_starlist=False,
                has_stardict=False,
                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,
    )
Example #23
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 _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
    )

    if start_value is not None:
        container_tmp = function_body.allocateTempVariable( None, "result" )

        statements = [
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = container_tmp.makeReference( function_body ),
                    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( function_body ),
                    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( function_body ),
                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 count, qual in enumerate(reversed( node.generators)):
        tmp_iter_variable = function_body.allocateTempVariable(
            temp_scope = None,
            name       = "contraction_iter_%d" % count
        )

        tmp_value_variable = function_body.allocateTempVariable(
            temp_scope = None,
            name       = "iter_value_%d" % count
        )

        # The first iterated value is to be calculated outside of the function
        # and will be given as a parameter "_iterated", the others are built
        # inside the function.
        if qual is node.generators[0]:
            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(
                        function_body
                    ),
                    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(
                                function_body
                            ),
                            source_ref = source_ref
                        ),
                        source     = ExpressionBuiltinNext1(
                            value      = ExpressionTempVariableRef(
                                variable   = tmp_iter_variable.makeReference(
                                    function_body
                                ),
                                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,
                temp_provider = function_body,
                node          = qual.target,
                source        = ExpressionTempVariableRef(
                    variable   = tmp_value_variable.makeReference(
                        function_body
                    ),
                    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 = mergeStatements(loop_statements),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        )

        nested_statements.append(
            StatementDelVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_iter_variable.makeReference(
                        function_body
                    ),
                    source_ref = source_ref
                ),
                tolerant   = False,
                source_ref = source_ref
            )
        )

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

    statements.append(current_body)

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

    function_body.setBody(
        StatementsFrame(
            statements    = mergeStatements(statements),
            guard_mode    = "pass_through"
                              if emit_class is not ExpressionYield else
                            "generator",
            var_names     = (),
            arg_count     = 0,
            kw_only_count = 0,
            has_starlist  = False,
            has_stardict  = False,
            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
    )
Example #25
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 buildFunctionNode(provider, node, source_ref):
    assert getKind(node) == "FunctionDef"

    function_statements, function_doc = extractDocFromBody(node)

    function_body = ExpressionFunctionBody(
        provider   = provider,
        name       = node.name,
        doc        = function_doc,
        parameters = buildParameterSpec(node.name, node, source_ref),
        source_ref = source_ref
    )

    # Hack:
    function_body.parent = provider

    decorators = buildNodeList(
        provider   = provider,
        nodes      = reversed(node.decorator_list),
        source_ref = source_ref
    )

    defaults = buildNodeList(
        provider   = provider,
        nodes      = node.args.defaults,
        source_ref = source_ref
    )

    kw_defaults = buildParameterKwDefaults(
        provider, node, function_body, source_ref
    )

    pushIndicatorVariable(Ellipsis)

    function_statements_body = buildStatementsNode(
        provider   = function_body,
        nodes      = function_statements,
        frame      = True,
        source_ref = source_ref
    )

    popIndicatorVariable()

    if function_body.isGenerator():
        # TODO: raise generator exit?
        pass
    elif function_statements_body is None:
        function_statements_body = makeStatementsSequenceFromStatement(
            statement = StatementReturn(
                expression = ExpressionConstantRef(
                    constant   = None,
                    source_ref = source_ref.atInternal()
                ),
                source_ref = source_ref.atInternal()
            )
        )
    elif not function_statements_body.isStatementAborting():
        function_statements_body.setStatements(
            function_statements_body.getStatements() +
            (
                StatementReturn(
                    expression = ExpressionConstantRef(
                        constant   = None,
                        source_ref = source_ref
                    ),
                    source_ref = source_ref.atInternal()
                ),
            )
        )

    function_body.setBody(
        function_statements_body
    )

    annotations = buildParameterAnnotations(provider, node, source_ref)

    function_creation = ExpressionFunctionCreation(
        function_ref = ExpressionFunctionRef(
            function_body,
            source_ref = source_ref
        ),
        defaults     = defaults,
        kw_defaults  = kw_defaults,
        annotations  = annotations,
        source_ref   = source_ref
    )

    # Add the staticmethod decorator to __new__ methods if not provided.

    # CPython made these optional, but applies them to every class __new__. We
    # add them early, so our optimization will see it.
    if node.name == "__new__" and not decorators and \
         provider.isExpressionFunctionBody() and provider.isClassDictCreation():

        decorators = (
            ExpressionBuiltinRef(
                builtin_name = "staticmethod",
                source_ref   = source_ref
            ),
        )

    decorated_function = function_creation
    for decorator in decorators:
        decorated_function = ExpressionCallNoKeywords(
            called     = decorator,
            args       = ExpressionMakeTuple(
                elements   = (decorated_function,),
                source_ref = source_ref
            ),
            source_ref = decorator.getSourceReference()
        )


    result = StatementAssignmentVariable(
        variable_ref = ExpressionTargetVariableRef(
            variable_name = node.name,
            source_ref    = source_ref
        ),
        source       = decorated_function,
        source_ref   = source_ref
    )

    if Utils.python_version >= 340:
        function_body.qualname_setup = result.getTargetVariableRef()

    return result
def getSetUnpackingHelper():
    helper_name = "_unpack_set"

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

    temp_scope = None

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

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

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

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

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

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

    return result
def buildFunctionWithParsing(provider, function_kind, name, function_doc, flags,
                             node, source_ref):
    # This contains a complex re-formulation for nested parameter functions.
    # pylint: disable=R0914

    kind = getKind(node)

    assert kind in ("FunctionDef", "Lambda", "AsyncFunctionDef"), "unsupported for kind " + kind

    def extractArg(arg):
        if arg is None:
            return None
        elif type(arg) is str:
            return mangleName(arg, provider)
        elif getKind(arg) == "Name":
            return mangleName(arg.id, provider)
        elif getKind(arg) == "arg":
            return mangleName(arg.arg, provider)
        elif getKind(arg) == "Tuple":
            # These are to be re-formulated on the outside.
            assert False
        else:
            assert False, getKind(arg)

    special_args = {}

    def extractNormalArgs(args):
        normal_args = []

        for arg in args:
            if type(arg) is not str and getKind(arg) == "Tuple":
                special_arg_name = ".%d" % (len(special_args) + 1)

                special_args[special_arg_name] = arg.elts
                normal_args.append(special_arg_name)
            else:
                normal_args.append(extractArg(arg))

        return normal_args

    normal_args = extractNormalArgs(node.args.args)

    parameters = ParameterSpec(
        ps_name          = name,
        ps_normal_args   = normal_args,
        ps_kw_only_args  = [
            extractArg(arg)
            for arg in
            node.args.kwonlyargs
            ]
              if python_version >= 300 else
            [],
        ps_list_star_arg = extractArg(node.args.vararg),
        ps_dict_star_arg = extractArg(node.args.kwarg),
        ps_default_count = len(node.args.defaults)
    )

    message = parameters.checkValid()

    if message is not None:
        SyntaxErrors.raiseSyntaxError(
            message,
            source_ref
        )

    code_object = CodeObjectSpec(
        co_name           = name,
        co_kind           = function_kind,
        co_varnames       = parameters.getParameterNames(),
        co_argcount       = parameters.getArgumentCount(),
        co_kwonlyargcount = parameters.getKwOnlyParameterCount(),
        co_has_starlist   = parameters.getStarListArgumentName() is not None,
        co_has_stardict   = parameters.getStarDictArgumentName() is not None
    )

    outer_body = ExpressionFunctionBody(
        provider   = provider,
        name       = name,
        flags      = flags,
        doc        = function_doc,
        parameters = parameters,
        source_ref = source_ref
    )

    if special_args:
        inner_name = name.strip("<>") + "$inner"
        inner_arg_names = []
        iter_vars = []

        values = []

        statements = []

        def unpackFrom(source, arg_names):
            accesses = []

            sub_special_index = 0

            iter_var = outer_body.allocateTempVariable(None, "arg_iter_%d" % len(iter_vars))
            iter_vars.append(iter_var)

            statements.append(
                StatementAssignmentVariable(
                    variable_ref = ExpressionTargetTempVariableRef(
                        variable   = iter_var,
                        source_ref = source_ref
                    ),
                    source       = ExpressionBuiltinIter1(
                        value      = source,
                        source_ref = source_ref
                    ),
                    source_ref   = source_ref
                )
            )

            for element_index, arg_name in enumerate(arg_names):
                if getKind(arg_name) == "Name":
                    inner_arg_names.append(arg_name.id)

                    arg_var = outer_body.allocateTempVariable(None, "tmp_" + arg_name.id)

                    statements.append(
                        StatementAssignmentVariable(
                            variable_ref = ExpressionTargetTempVariableRef(
                                variable   = arg_var,
                                source_ref = source_ref
                            ),
                            source       = ExpressionSpecialUnpack(
                                value      = ExpressionTempVariableRef(
                                    variable   = iter_var,
                                    source_ref = source_ref
                                ),
                                count      = element_index + 1,
                                expected   = len(arg_names),
                                source_ref = source_ref
                            ),
                            source_ref   = source_ref
                        )
                    )

                    accesses.append(
                        ExpressionTempVariableRef(
                            variable   = arg_var,
                            source_ref = source_ref
                        )
                    )
                elif getKind(arg_name) == "Tuple":
                    accesses.extend(
                        unpackFrom(
                            source    = ExpressionSpecialUnpack(
                                value      = ExpressionTempVariableRef(
                                    variable   = iter_var,
                                    source_ref = source_ref
                                ),
                                count      = element_index + 1,
                                expected   = len(arg_names),
                                source_ref = source_ref
                            ),
                            arg_names = arg_name.elts
                        )
                    )

                    sub_special_index += 1
                else:
                    assert False, arg_name

            statements.append(
                StatementSpecialUnpackCheck(
                    iterator   = ExpressionTempVariableRef(
                        variable   = iter_var,
                        source_ref = source_ref
                    ),
                    count      = len(arg_names),
                    source_ref = source_ref
                )
            )

            return accesses

        for arg_name in parameters.getParameterNames():
            if arg_name.startswith('.'):
                source = ExpressionVariableRef(
                    variable_name = arg_name,
                    source_ref    = source_ref
                )

                values.extend(
                    unpackFrom(source, special_args[arg_name])
                )
            else:
                values.append(
                    ExpressionVariableRef(
                        variable_name = arg_name,
                        source_ref    = source_ref
                    )
                )

                inner_arg_names.append(arg_name)

        inner_parameters = ParameterSpec(
            ps_name          = inner_name,
            ps_normal_args   = inner_arg_names,
            ps_kw_only_args  = (),
            ps_list_star_arg = None,
            ps_dict_star_arg = None,
            ps_default_count = None
        )

        function_body = ExpressionFunctionBody(
            provider   = outer_body,
            name       = inner_name,
            flags      = flags,
            doc        = function_doc,
            parameters = inner_parameters,
            source_ref = source_ref
        )

        statements.append(
            StatementReturn(
                ExpressionFunctionCall(
                    function   = ExpressionFunctionCreation(
                        function_ref = ExpressionFunctionRef(
                            function_body = function_body,
                            source_ref    = source_ref
                        ),
                        code_object  = code_object,
                        defaults     = (),
                        kw_defaults  = None,
                        annotations  = None,
                        source_ref   = source_ref
                    ),
                    values     = values,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        )

        outer_body.setBody(
            makeStatementsSequenceFromStatement(
                statement = makeTryFinallyStatement(
                    provider,
                    tried      = statements,
                    final      = [
                        StatementReleaseVariable(
                            variable   = variable,
                            source_ref = source_ref
                        )
                        for variable in
                        outer_body.getTempVariables()
                    ]   ,
                    source_ref = source_ref,
                    public_exc = False
                )
            )
        )
    else:
        function_body = outer_body

    return outer_body, function_body, code_object
Example #29
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)
Example #30
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)

    # We need a scope for the temporary variables, and they might be closured.
    temp_scope = provider.allocateTempScope(
        name          = "class_creation",
        allow_closure = True
    )

    tmp_bases = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "bases"
    )
    tmp_class_decl_dict = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "class_decl_dict"
    )
    tmp_metaclass = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "metaclass"
    )
    tmp_prepared = provider.allocateTempVariable(
        temp_scope = temp_scope,
        name       = "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: This allows some APIs to work although this is not yet officially a
    # child yet.
    class_creation_function.parent = provider

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

    source_ref_orig = source_ref
    source_ref = source_ref.atInternal()

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

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

    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,
                    user_provided = True
                ),
                source_ref   = source_ref.atInternal()
            )
        )

    # The "__qualname__" attribute is new in Python 3.3.
    if Utils.python_version >= 330:
        qualname = class_creation_function.getFunctionQualname()

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

    if Utils.python_version >= 340 and False: # TODO: Temporarily reverted:
        tmp_class = class_creation_function.allocateTempVariable(
            temp_scope = None,
            name       = "__class__"
        )

        class_target_variable_ref = ExpressionTargetTempVariableRef(
            variable   = tmp_class.makeReference(class_creation_function),
            source_ref = source_ref
        )
        class_variable_ref = ExpressionTempVariableRef(
            variable   = tmp_class.makeReference(class_creation_function),
            source_ref = source_ref
        )
    else:
        class_target_variable_ref = ExpressionTargetVariableRef(
            variable_name = "__class__",
            source_ref    = source_ref
        )
        class_variable_ref = ExpressionVariableRef(
            variable_name = "__class__",
            source_ref    = source_ref
        )

    statements += [
        body,
        StatementAssignmentVariable(
            variable_ref = class_target_variable_ref,
            source       = ExpressionCall(
                called     = ExpressionTempVariableRef(
                    variable   = tmp_metaclass.makeReference(provider),
                    source_ref = source_ref
                ),
                args       = makeSequenceCreationOrConstant(
                    sequence_kind = "tuple",
                    elements      = (
                        ExpressionConstantRef(
                            constant      = node.name,
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        ExpressionTempVariableRef(
                            variable   = tmp_bases.makeReference(provider),
                            source_ref = source_ref
                        ),
                        ExpressionBuiltinLocals(
                            source_ref = source_ref
                        )
                    ),
                    source_ref    = source_ref
                ),
                kw         = ExpressionTempVariableRef(
                    variable   = tmp_class_decl_dict.makeReference(provider),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref   = source_ref
        ),
        StatementReturn(
            expression = class_variable_ref,
            source_ref = source_ref
        )
    ]

    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( provider ),
                source_ref = source_ref
            ),
            source       = makeSequenceCreationOrConstant(
                sequence_kind = "tuple",
                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(provider),
                source_ref = source_ref
            ),
            source       = makeDictCreationOrConstant(
                keys      = [
                    ExpressionConstantRef(
                        constant      = keyword.arg,
                        source_ref    = source_ref,
                        user_provided = True
                    )
                    for keyword in
                    node.keywords
                ],
                values = [
                    buildNode(provider, keyword.value, source_ref)
                    for keyword in
                    node.keywords
                ],
                lazy_order = False,
                source_ref = source_ref
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass.makeReference(provider),
                source_ref = source_ref
            ),
            source       = ExpressionSelectMetaclass(
                metaclass = ExpressionConditional(
                    condition = ExpressionComparison(
                        comparator = "In",
                        left       = ExpressionConstantRef(
                            constant      = "metaclass",
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        right      = ExpressionTempVariableRef(
                            variable   = tmp_class_decl_dict.makeReference(
                                provider
                            ),
                            source_ref = source_ref
                        ),
                        source_ref = source_ref
                    ),
                    yes_expression = ExpressionDictOperationGet(
                        dicte      = ExpressionTempVariableRef(
                            variable   = tmp_class_decl_dict.makeReference(
                                provider
                            ),
                            source_ref = source_ref
                        ),
                        key        = ExpressionConstantRef(
                            constant      = "metaclass",
                            source_ref    = source_ref,
                            user_provided = True
                        ),
                        source_ref = source_ref
                    ),
                    no_expression  = ExpressionConditional(
                        condition      = ExpressionTempVariableRef(
                            variable   = tmp_bases.makeReference(provider),
                            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(
                                        provider
                                    ),
                                    source_ref = source_ref
                                ),
                                subscript  = ExpressionConstantRef(
                                    constant      = 0,
                                    source_ref    = source_ref,
                                    user_provided = True
                                ),
                                source_ref = source_ref
                            ),
                            source_ref = source_ref
                        ),
                        source_ref     = source_ref
                    ),
                    source_ref     = source_ref
                ),
                bases     = ExpressionTempVariableRef(
                    variable   = tmp_bases.makeReference(provider),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            source_ref = source_ref_orig
        ),
        StatementConditional(
            condition  = ExpressionComparison(
                comparator = "In",
                left       = ExpressionConstantRef(
                    constant      = "metaclass",
                    source_ref    = source_ref,
                    user_provided = True
                ),
                right      = ExpressionTempVariableRef(
                    variable   = tmp_class_decl_dict.makeReference(
                        provider
                    ),
                    source_ref = source_ref
                ),
                source_ref = source_ref
            ),
            no_branch  = None,
            yes_branch = makeStatementsSequenceFromStatement(
                statement = StatementDictOperationRemove(
                    dicte = ExpressionTempVariableRef(
                        variable   = tmp_class_decl_dict.makeReference(
                            provider
                        ),
                        source_ref = source_ref
                    ),
                    key   = ExpressionConstantRef(
                        constant      = "metaclass",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    source_ref = source_ref
                )
            ),
            source_ref = source_ref
        ),
        StatementAssignmentVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_prepared.makeReference(
                    provider
                ),
                source_ref = source_ref
            ),
            source       = ExpressionConditional(
                condition = ExpressionBuiltinHasattr(
                    object     = ExpressionTempVariableRef(
                        variable   = tmp_metaclass.makeReference(
                            provider
                        ),
                        source_ref = source_ref
                    ),
                    name       = ExpressionConstantRef(
                        constant      = "__prepare__",
                        source_ref    = source_ref,
                        user_provided = True
                    ),
                    source_ref = source_ref
                ),
                no_expression = ExpressionConstantRef(
                    constant      = {},
                    source_ref    = source_ref,
                    user_provided = True
                ),
                yes_expression = ExpressionCall(
                    called     = ExpressionAttributeLookup(
                        expression     = ExpressionTempVariableRef(
                            variable   = tmp_metaclass.makeReference(
                                provider
                            ),
                            source_ref = source_ref
                        ),
                        attribute_name = "__prepare__",
                        source_ref     = source_ref
                    ),
                    args       = ExpressionMakeTuple(
                        elements   = (
                            ExpressionConstantRef(
                                constant      = node.name,
                                source_ref    = source_ref,
                                user_provided = True
                            ),
                            ExpressionTempVariableRef(
                                variable   = tmp_bases.makeReference(
                                    provider
                                ),
                                source_ref = source_ref
                            )
                        ),
                        source_ref = source_ref
                    ),
                    kw         = ExpressionTempVariableRef(
                        variable   = tmp_class_decl_dict.makeReference(
                            provider
                        ),
                        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
        ),
    )

    final = (
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_bases.makeReference(provider),
                source_ref = source_ref
            ),
            tolerant   = True,
            source_ref = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_class_decl_dict.makeReference(provider),
                source_ref = source_ref
            ),
            tolerant   = True,
            source_ref = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_metaclass.makeReference(provider),
                source_ref = source_ref
            ),
            tolerant   = True,
            source_ref = source_ref
        ),
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_prepared.makeReference(provider),
                source_ref = source_ref
            ),
            tolerant   = True,
            source_ref = source_ref
        )
    )

    return makeTryFinallyStatement(
        tried      = statements,
        final      = final,
        source_ref = source_ref
    )
def buildAsyncFunctionNode(provider, node, source_ref):
    # We are creating a function here that creates coroutine objects, with
    # many details each, pylint: disable=R0914
    assert getKind(node) == "AsyncFunctionDef"

    function_statements, function_doc = extractDocFromBody(node)

    creator_function_body = ExpressionFunctionBody(
        provider   = provider,
        name       = node.name,
        doc        = function_doc,
        parameters = buildParameterSpec(provider, node.name, node, source_ref),
        is_class   = False,
        source_ref = source_ref
    )

    function_body = ExpressionCoroutineBody(
        provider   = creator_function_body,
        name       = node.name,
        source_ref = source_ref
    )

    decorators = buildNodeList(
        provider   = provider,
        nodes      = reversed(node.decorator_list),
        source_ref = source_ref
    )

    defaults = buildNodeList(
        provider   = provider,
        nodes      = node.args.defaults,
        source_ref = source_ref
    )

    function_statements_body = buildStatementsNode(
        provider   = function_body,
        nodes      = function_statements,
        frame      = True,
        source_ref = source_ref
    )

    function_statements_body = _insertFinalReturnStatement(
        function_statements_body = function_statements_body,
        source_ref               = source_ref
    )

    if function_statements_body.isStatementsFrame():
        function_statements_body = makeStatementsSequenceFromStatement(
            statement = function_statements_body
        )

    function_body.setBody(
        function_statements_body
    )

    annotations = buildParameterAnnotations(provider, node, source_ref)

    kw_defaults = buildParameterKwDefaults(
        provider      = provider,
        node          = node,
        function_body = creator_function_body,
        source_ref    = source_ref
    )

    creator_function_body.setBody(
        makeStatementsSequenceFromStatement(
            statement = StatementReturn(
                expression = ExpressionCoroutineCreation(
                    coroutine_body = function_body,
                    source_ref     = source_ref
                ),
                source_ref = source_ref
            )
        )
    )

    function_creation = ExpressionFunctionCreation(
        function_ref = ExpressionFunctionRef(
            function_body = creator_function_body,
            source_ref    = source_ref
        ),
        defaults     = defaults,
        kw_defaults  = kw_defaults,
        annotations  = annotations,
        source_ref   = source_ref
    )

    decorated_function = function_creation
    for decorator in decorators:
        decorated_function = ExpressionCallNoKeywords(
            called     = decorator,
            args       = ExpressionMakeTuple(
                elements   = (decorated_function,),
                source_ref = source_ref
            ),
            source_ref = decorator.getSourceReference()
        )


    result = StatementAssignmentVariable(
        variable_ref = ExpressionTargetVariableRef(
            variable_name = mangleName(node.name, provider),
            source_ref    = source_ref
        ),
        source       = decorated_function,
        source_ref   = source_ref
    )

    function_body.qualname_setup = result.getTargetVariableRef()

    return result
def buildFunctionWithParsing(
    provider, function_kind, name, function_doc, flags, node, source_ref
):
    # This contains a complex re-formulation for nested parameter functions.
    # pylint: disable=too-many-locals

    kind = getKind(node)
    assert kind in ("FunctionDef", "Lambda", "AsyncFunctionDef"), (
        "unsupported for kind " + kind
    )

    def extractArg(arg):
        if arg is None:
            return None
        elif type(arg) is str:
            return mangleName(arg, provider)
        elif getKind(arg) == "Name":
            return mangleName(arg.id, provider)
        elif getKind(arg) == "arg":
            return mangleName(arg.arg, provider)
        elif getKind(arg) == "Tuple":
            # These are to be re-formulated on the outside.
            assert False
        else:
            assert False, getKind(arg)

    special_args = {}

    def extractNormalArgs(args):
        normal_args = []

        for arg in args:
            if type(arg) is not str and getKind(arg) == "Tuple":
                special_arg_name = ".%d" % (len(special_args) + 1)

                special_args[special_arg_name] = arg.elts
                normal_args.append(special_arg_name)
            else:
                normal_args.append(extractArg(arg))

        return normal_args

    parameters = ParameterSpec(
        ps_name=name,
        ps_normal_args=extractNormalArgs(node.args.args),
        ps_pos_only_args=[extractArg(arg) for arg in node.args.posonlyargs]
        if python_version >= 0x380
        else (),
        ps_kw_only_args=[extractArg(arg) for arg in node.args.kwonlyargs]
        if python_version >= 0x300
        else (),
        ps_list_star_arg=extractArg(node.args.vararg),
        ps_dict_star_arg=extractArg(node.args.kwarg),
        ps_default_count=len(node.args.defaults),
    )

    message = parameters.checkParametersValid()

    if message is not None:
        raiseSyntaxError(message, source_ref.atColumnNumber(node.col_offset))

    parent_module = provider.getParentModule()

    code_object = CodeObjectSpec(
        co_name=name,
        co_kind=function_kind,
        co_varnames=parameters.getParameterNames(),
        co_freevars=(),
        co_argcount=parameters.getArgumentCount(),
        co_posonlyargcount=parameters.getPosOnlyParameterCount(),
        co_kwonlyargcount=parameters.getKwOnlyParameterCount(),
        co_has_starlist=parameters.getStarListArgumentName() is not None,
        co_has_stardict=parameters.getStarDictArgumentName() is not None,
        co_filename=parent_module.getRunTimeFilename(),
        co_lineno=source_ref.getLineNumber(),
        future_spec=parent_module.getFutureSpec(),
    )

    outer_body = ExpressionFunctionBody(
        provider=provider,
        name=name,
        code_object=code_object,
        flags=flags,
        doc=function_doc,
        parameters=parameters,
        auto_release=None,
        source_ref=source_ref,
    )

    # Wrap if necessary for special nested arguments.
    if special_args:
        code_body = _wrapFunctionWithSpecialNestedArgs(
            name=name,
            outer_body=outer_body,
            parameters=parameters,
            special_args=special_args,
            source_ref=source_ref,
        )

    else:
        code_body = outer_body

    return outer_body, code_body, code_object
Example #33
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