Exemplo n.º 1
0
    def _analysis(self):
        self._evaluator.is_analysis = True
        self._evaluator.analysis_modules = [self._get_module()]
        try:
            for node in self._get_module().nodes_to_execute():
                if node.type in ('funcdef', 'classdef'):
                    if node.type == 'classdef':
                        continue
                        raise NotImplementedError
                    er.Function(self._evaluator, node).get_decorated_func()
                elif isinstance(node, tree.Import):
                    import_names = set(node.get_defined_names())
                    if node.is_nested():
                        import_names |= set(path[-1] for path in node.paths())
                    for n in import_names:
                        imports.ImportWrapper(self._evaluator, n).follow()
                elif node.type == 'expr_stmt':
                    types = self._evaluator.eval_element(node)
                    for testlist in node.children[:-1:2]:
                        # Iterate tuples.
                        unpack_tuple_to_dict(self._evaluator, types, testlist)
                else:
                    try_iter_content(self._evaluator.goto_definitions(node))
                self._evaluator.reset_recursion_limitations()

            ana = [a for a in self._evaluator.analysis if self.path == a.path]
            return sorted(set(ana), key=lambda x: x.line)
        finally:
            self._evaluator.is_analysis = False
Exemplo n.º 2
0
 def _eval_statement_element(self, element):
     if pr.Array.is_type(element, pr.Array.NOARRAY):
         r = list(
             itertools.chain.from_iterable(
                 self.eval_statement(s) for s in element))
         call_path = element.generate_call_path()
         next(call_path, None)  # the first one has been used already
         return self.follow_path(call_path, r, element.parent)
     elif isinstance(element, pr.ListComprehension):
         loop = _evaluate_list_comprehension(element)
         # Caveat: parents are being changed, but this doesn't matter,
         # because nothing else uses it.
         element.stmt.parent = loop
         return self.eval_statement(element.stmt)
     elif isinstance(element, pr.Lambda):
         return [er.Function(self, element)]
     # With things like params, these can also be functions...
     elif isinstance(element, pr.Base) and element.isinstance(
             er.Function, er.Class, er.Instance, iterable.ArrayInstance):
         return [element]
     # The string tokens are just operations (+, -, etc.)
     elif isinstance(element, compiled.CompiledObject):
         return [element]
     elif not isinstance(element, Token):
         return self.eval_call(element)
     else:
         return []
Exemplo n.º 3
0
    def _analysis(self):
        def check_types(types):
            for typ in types:
                try:
                    f = typ.iter_content
                except AttributeError:
                    pass
                else:
                    check_types(f())

        #statements = set(chain(*self._parser.module().used_names.values()))
        nodes, imp_names, decorated_funcs = \
            analysis.get_module_statements(self._parser.module())
        # Sort the statements so that the results are reproducible.
        for n in imp_names:
            imports.ImportWrapper(self._evaluator, n).follow()
        for node in sorted(nodes, key=lambda obj: obj.start_pos):
            #if not (isinstance(stmt.parent, pr.ForFlow) and stmt.parent.set_stmt == stmt):
            if node.type == 'expr_stmt':
                check_types(self._evaluator.eval_statement(node))
            else:
                check_types(self._evaluator.eval_element(node))

        for dec_func in decorated_funcs:
            er.Function(self._evaluator, dec_func).get_decorated_func()

        ana = [a for a in self._evaluator.analysis if self.path == a.path]
        return sorted(set(ana), key=lambda x: x.line)
Exemplo n.º 4
0
 def eval_statement_element(self, element):
     if pr.Array.is_type(element, pr.Array.NOARRAY):
         try:
             lst_cmp = element[0].expression_list()[0]
             if not isinstance(lst_cmp, pr.ListComprehension):
                 raise IndexError
         except IndexError:
             r = list(
                 itertools.chain.from_iterable(
                     self.eval_statement(s) for s in element))
         else:
             r = [iterable.GeneratorComprehension(self, lst_cmp)]
         call_path = element.generate_call_path()
         next(call_path, None)  # the first one has been used already
         return self.follow_path(call_path, r, element.parent)
     elif isinstance(element, pr.ListComprehension):
         return self.eval_statement(element.stmt)
     elif isinstance(element, pr.Lambda):
         return [er.Function(self, element)]
     # With things like params, these can also be functions...
     elif isinstance(element, pr.Base) and element.isinstance(
             er.Function, er.Class, er.Instance, iterable.ArrayInstance):
         return [element]
     # The string tokens are just operations (+, -, etc.)
     elif isinstance(element, compiled.CompiledObject):
         return [element]
     elif isinstance(element, Token):
         return []
     else:
         return self.eval_call(element)
Exemplo n.º 5
0
    def _names_to_types(self, names, resolve_decorator):
        types = []
        # Add isinstance and other if/assert knowledge.
        flow_scope = self.scope
        evaluator = self._evaluator
        while flow_scope:
            # TODO check if result is in scope -> no evaluation necessary
            n = check_flow_information(evaluator, flow_scope, self.name_str,
                                       self.position)
            if n:
                return n
            flow_scope = flow_scope.parent

        for name in names:
            typ = name.parent
            if typ.isinstance(pr.ForFlow):
                types += self._handle_for_loops(typ)
            elif isinstance(typ, pr.Param):
                types += self._eval_param(typ)
            elif typ.isinstance(pr.Statement):
                if typ.is_global():
                    # global keyword handling.
                    types += evaluator.find_types(typ.parent.parent, str(name))
                else:
                    types += self._remove_statements(typ)
            else:
                if isinstance(typ, pr.Class):
                    typ = er.Class(evaluator, typ)
                elif isinstance(typ, pr.Function):
                    typ = er.Function(evaluator, typ)
                if typ.isinstance(er.Function) and resolve_decorator:
                    typ = typ.get_decorated_func()
                types.append(typ)
        return types
Exemplo n.º 6
0
 def wrap(self, element):
     if isinstance(element, tree.Class):
         return er.Class(self, element)
     elif isinstance(element, tree.Function):
         if isinstance(element, tree.Lambda):
             return er.LambdaWrapper(self, element)
         else:
             return er.Function(self, element)
     elif isinstance(element, (tree.Module)) \
             and not isinstance(element, er.ModuleWrapper):
         return er.ModuleWrapper(self, element)
     else:
         return element
Exemplo n.º 7
0
    def _follow_statements_imports(self):
        stripped = self._definition
        if isinstance(stripped, pr.Name):
            stripped = stripped.parent
            # We should probably work in `Finder._names_to_types` here.
            if isinstance(stripped, pr.Function):
                stripped = er.Function(self._evaluator, stripped)
            elif isinstance(stripped, pr.Class):
                stripped = er.Class(self._evaluator, stripped)

        if stripped.isinstance(pr.Statement):
            return self._evaluator.eval_statement(stripped)
        elif stripped.isinstance(pr.Import):
            return imports.strip_imports(self._evaluator, [stripped])
        else:
            return [stripped]
Exemplo n.º 8
0
    def wrap(self, element):
        if isinstance(element,
                      (er.Wrapper, er.InstanceElement, er.ModuleWrapper,
                       er.FunctionExecution, er.Instance,
                       compiled.CompiledObject)) or element is None:
            # TODO this is so ugly, please refactor. id:211 gh:212
            return element

        if element.type == 'classdef':
            return er.Class(self, element)
        elif element.type == 'funcdef':
            return er.Function(self, element)
        elif element.type == 'lambda':
            return er.LambdaWrapper(self, element)
        elif element.type == 'file_input':
            return er.ModuleWrapper(self, element)
        else:
            return element