Ejemplo n.º 1
0
        def from_scope_node(scope_node, child_is_funcdef=None, is_nested=True, node_is_object=False):
            if scope_node == base_node:
                return base_context

            is_funcdef = scope_node.type in ('funcdef', 'lambdef')
            parent_scope = parser_utils.get_parent_scope(scope_node)
            parent_context = from_scope_node(parent_scope, child_is_funcdef=is_funcdef)

            if is_funcdef:
                if isinstance(parent_context, AnonymousInstance):
                    func = BoundMethod(
                        self, parent_context, parent_context.class_context,
                        parent_context.parent_context, scope_node
                    )
                else:
                    func = er.FunctionContext(
                        self,
                        parent_context,
                        scope_node
                    )
                if is_nested and not node_is_object:
                    return func.get_function_execution()
                return func
            elif scope_node.type == 'classdef':
                class_context = er.ClassContext(self, scope_node, parent_context)
                if child_is_funcdef:
                    # anonymous instance
                    return AnonymousInstance(self, parent_context, class_context)
                else:
                    return class_context
            elif scope_node.type == 'comp_for':
                if node.start_pos >= scope_node.children[-1].start_pos:
                    return parent_context
                return iterable.CompForContext.from_comp_for(parent_context, scope_node)
            raise Exception("There's a scope that was not managed.")
Ejemplo n.º 2
0
 def _eval_element_not_cached(self, context, element):
     debug.dbg('eval_element %s@%s', element, element.start_pos)
     types = set()
     typ = element.type
     if typ in ('name', 'number', 'string', 'atom'):
         types = self.eval_atom(context, element)
     elif typ == 'keyword':
         # For False/True/None
         if element.value in ('False', 'True', 'None'):
             types.add(compiled.builtin_from_name(self, element.value))
         # else: print e.g. could be evaluated like this in Python 2.7
     elif typ == 'lambdef':
         types = set([er.FunctionContext(self, context, element)])
     elif typ == 'expr_stmt':
         types = self.eval_statement(context, element)
     elif typ in ('power', 'atom_expr'):
         first_child = element.children[0]
         if not (first_child.type == 'keyword' and first_child.value == 'await'):
             types = self.eval_atom(context, first_child)
             for trailer in element.children[1:]:
                 if trailer == '**':  # has a power operation.
                     right = self.eval_element(context, element.children[2])
                     types = set(precedence.calculate(self, context, types, trailer, right))
                     break
                 types = self.eval_trailer(context, types, trailer)
     elif typ in ('testlist_star_expr', 'testlist',):
         # The implicit tuple in statements.
         types = set([iterable.SequenceLiteralContext(self, context, element)])
     elif typ in ('not_test', 'factor'):
         types = self.eval_element(context, element.children[-1])
         for operator in element.children[:-1]:
             types = set(precedence.factor_calculate(self, types, operator))
     elif typ == 'test':
         # `x if foo else y` case.
         types = (self.eval_element(context, element.children[0]) |
                  self.eval_element(context, element.children[-1]))
     elif typ == 'operator':
         # Must be an ellipsis, other operators are not evaluated.
         # In Python 2 ellipsis is coded as three single dot tokens, not
         # as one token 3 dot token.
         assert element.value in ('.', '...')
         types = set([compiled.create(self, Ellipsis)])
     elif typ == 'dotted_name':
         types = self.eval_atom(context, element.children[0])
         for next_name in element.children[2::2]:
             # TODO add search_global=True?
             types = unite(
                 typ.py__getattribute__(next_name, name_context=context)
                 for typ in types
             )
         types = types
     elif typ == 'eval_input':
         types = self._eval_element_not_cached(context, element.children[0])
     elif typ == 'annassign':
         types = pep0484._evaluate_for_annotation(context, element.children[1])
     else:
         types = precedence.calculate_children(self, context, element.children)
     debug.dbg('eval_element result %s', types)
     return types
Ejemplo n.º 3
0
    def parent(self):
        context = self._name.parent_context
        if context is None:
            return None

        if isinstance(context, er.FunctionExecutionContext):
            # TODO the function context should be a part of the function
            # execution context.
            context = er.FunctionContext(
                self._evaluator, context.parent_context, context.tree_node)
        return Definition(self._evaluator, context.name)
Ejemplo n.º 4
0
    def goto_definitions(self, context, name):
        def_ = name.get_definition()
        is_simple_name = name.parent.type not in ('power', 'trailer')
        if is_simple_name:
            if name.parent.type == 'classdef' and name.parent.name == name:
                return [er.ClassContext(self, name.parent, context)]
            elif name.parent.type == 'funcdef':
                return [er.FunctionContext(self, context, name.parent)]
            elif name.parent.type == 'file_input':
                raise NotImplementedError
            if def_.type == 'expr_stmt' and name in def_.get_defined_names():
                return self.eval_statement(context, def_, name)
            elif def_.type == 'for_stmt':
                container_types = self.eval_element(context, def_.children[3])
                for_types = iterable.py__iter__types(self, container_types,
                                                     def_.children[3])
                return finder.check_tuple_assignments(self, for_types, name)
            elif def_.type in ('import_from', 'import_name'):
                return imports.infer_import(context, name)

        return helpers.evaluate_call_of_leaf(context, name)
Ejemplo n.º 5
0
    def goto_definitions(self, context, name):
        def_ = name.get_definition(import_name_always=True)
        if def_ is not None:
            type_ = def_.type
            if type_ == 'classdef':
                return [er.ClassContext(self, name.parent, context)]
            elif type_ == 'funcdef':
                return [er.FunctionContext(self, context, name.parent)]

            if type_ == 'expr_stmt':
                is_simple_name = name.parent.type not in ('power', 'trailer')
                if is_simple_name:
                    return self.eval_statement(context, def_, name)
            if type_ == 'for_stmt':
                container_types = self.eval_element(context, def_.children[3])
                cn = ContextualizedNode(context, def_.children[3])
                for_types = iterable.py__iter__types(self, container_types, cn)
                c_node = ContextualizedName(context, name)
                return finder.check_tuple_assignments(self, c_node, for_types)
            if type_ in ('import_from', 'import_name'):
                return imports.infer_import(context, name)

        return helpers.evaluate_call_of_leaf(context, name)
Ejemplo n.º 6
0
def _apply_decorators(evaluator, context, node):
    """
    Returns the function, that should to be executed in the end.
    This is also the places where the decorators are processed.
    """
    if node.type == 'classdef':
        decoratee_context = er.ClassContext(evaluator,
                                            parent_context=context,
                                            classdef=node)
    else:
        decoratee_context = er.FunctionContext(evaluator,
                                               parent_context=context,
                                               funcdef=node)
    initial = values = set([decoratee_context])
    for dec in reversed(node.get_decorators()):
        debug.dbg('decorator: %s %s', dec, values)
        dec_values = context.eval_node(dec.children[1])
        trailer_nodes = dec.children[2:-1]
        if trailer_nodes:
            # Create a trailer and evaluate it.
            trailer = tree.PythonNode('trailer', trailer_nodes)
            trailer.parent = dec
            dec_values = evaluator.eval_trailer(context, dec_values, trailer)

        if not len(dec_values):
            debug.warning('decorator not found: %s on %s', dec, node)
            return initial

        values = unite(
            dec_value.execute(param.ValuesArguments([values]))
            for dec_value in dec_values)
        if not len(values):
            debug.warning('not possible to resolve wrappers found %s', node)
            return initial

        debug.dbg('decorator end %s', values)
    return values