Exemplo n.º 1
0
    def get_return_types(self, check_yields=False):
        func = self.base

        if func.isinstance(LambdaWrapper):
            return self._evaluator.eval_element(self.children[-1])

        if func.listeners:
            # Feed the listeners, with the params.
            for listener in func.listeners:
                listener.execute(self._get_params())
            # If we do have listeners, that means that there's not a regular
            # execution ongoing. In this case Jedi is interested in the
            # inserted params, not in the actual execution of the function.
            return []

        if check_yields:
            types = []
            returns = self.yields
        else:
            returns = self.returns
            types = list(docstrings.find_return_types(self._evaluator, func))

        for r in returns:
            check = flow_analysis.break_check(self._evaluator, self, r)
            if check is flow_analysis.UNREACHABLE:
                debug.dbg('Return unreachable: %s', r)
            else:
                types += self._evaluator.eval_element(r.children[1])
            if check is flow_analysis.REACHABLE:
                debug.dbg('Return reachable: %s', r)
                break
        return types
    def get_return_types(self, check_yields=False):
        func = self.base

        if func.isinstance(LambdaWrapper):
            return self._evaluator.eval_element(self.children[-1])

        if func.listeners:
            # Feed the listeners, with the params.
            for listener in func.listeners:
                listener.execute(self._get_params())
            # If we do have listeners, that means that there's not a regular
            # execution ongoing. In this case Jedi is interested in the
            # inserted params, not in the actual execution of the function.
            return []

        if check_yields:
            types = []
            returns = self.yields
        else:
            returns = self.returns
            types = list(docstrings.find_return_types(self._evaluator, func))

        for r in returns:
            check = flow_analysis.break_check(self._evaluator, self, r)
            if check is flow_analysis.UNREACHABLE:
                debug.dbg('Return unreachable: %s', r)
            else:
                types += self._evaluator.eval_element(r.children[1])
            if check is flow_analysis.REACHABLE:
                debug.dbg('Return reachable: %s', r)
                break
        return types
Exemplo n.º 3
0
    def names_dict_lookup(self, names_dict, position):
        def get_param(scope, el):
            if isinstance(el.get_parent_until(pr.Param), pr.Param):
                return scope.param_by_name(str(el))
            return el

        search_str = str(self.name_str)
        try:
            names = names_dict[search_str]
            if not names:  # We want names, otherwise stop.
                return []
        except KeyError:
            return []

        names = filter_definition_names(names, self.name_str, position)

        name_scope = None
        # Only the names defined in the last position are valid definitions.
        last_names = []
        for name in reversed(sorted(names, key=lambda name: name.start_pos)):
            stmt = name.get_definition()
            name_scope = er.wrap(self._evaluator, stmt.get_parent_scope())

            if isinstance(self.scope, er.Instance) and not isinstance(
                    name_scope, er.Instance):
                # Instances should not be checked for positioning, because we
                # don't know in which order the functions are called.
                last_names.append(name)
                continue

            if isinstance(name_scope, compiled.CompiledObject):
                # Let's test this. TODO need comment. shouldn't this be
                # filtered before?
                last_names.append(name)
                continue

            if isinstance(name, compiled.CompiledName) \
                    or isinstance(name, er.InstanceName) and isinstance(name._origin_name, compiled.CompiledName):
                last_names.append(name)
                continue

            if isinstance(self.name_str, pr.Name):
                origin_scope = self.name_str.get_parent_until(pr.Scope,
                                                              reverse=True)
            else:
                origin_scope = None
            if isinstance(stmt.parent, compiled.CompiledObject):
                # TODO seriously? this is stupid.
                continue
            check = flow_analysis.break_check(self._evaluator, name_scope,
                                              stmt, origin_scope)
            if check is not flow_analysis.UNREACHABLE:
                last_names.append(name)
            if check is flow_analysis.REACHABLE:
                break

        if isinstance(name_scope, er.FunctionExecution):
            # Replace params
            return [get_param(name_scope, n) for n in last_names]
        return last_names
Exemplo n.º 4
0
    def get_return_types(self):
        func = self.base

        if func.listeners:
            # Feed the listeners, with the params.
            for listener in func.listeners:
                listener.execute(self._get_params())
            # If we do have listeners, that means that there's not a regular
            # execution ongoing. In this case Jedi is interested in the
            # inserted params, not in the actual execution of the function.
            return []

        types = list(docstrings.find_return_types(self._evaluator, func))
        for r in self.returns:
            if isinstance(r, pr.KeywordStatement):
                stmt = r.stmt
            else:
                stmt = r  # Lambdas

            if stmt is None:
                continue

            check = flow_analysis.break_check(self._evaluator, self, r.parent)
            if check is flow_analysis.UNREACHABLE:
                debug.dbg('Return unreachable: %s', r)
            else:
                types += self._evaluator.eval_statement(stmt)
            if check is flow_analysis.REACHABLE:
                debug.dbg('Return reachable: %s', r)
                break
        return types
Exemplo n.º 5
0
Arquivo: finder.py Projeto: Axure/jedi
    def names_dict_lookup(self, names_dict, position):
        def get_param(scope, el):
            if isinstance(el.get_parent_until(pr.Param), pr.Param):
                return scope.param_by_name(str(el))
            return el

        search_str = str(self.name_str)
        try:
            names = names_dict[search_str]
            if not names:  # We want names, otherwise stop.
                return []
        except KeyError:
            return []

        names = filter_definition_names(names, self.name_str, position)

        name_scope = None
        # Only the names defined in the last position are valid definitions.
        last_names = []
        for name in reversed(sorted(names, key=lambda name: name.start_pos)):
            stmt = name.get_definition()
            name_scope = er.wrap(self._evaluator, stmt.get_parent_scope())

            if isinstance(self.scope, er.Instance) and not isinstance(name_scope, er.Instance):
                # Instances should not be checked for positioning, because we
                # don't know in which order the functions are called.
                last_names.append(name)
                continue

            if isinstance(name_scope, compiled.CompiledObject):
                # Let's test this. TODO need comment. shouldn't this be
                # filtered before?
                last_names.append(name)
                continue

            if isinstance(name, compiled.CompiledName) \
                    or isinstance(name, er.InstanceName) and isinstance(name._origin_name, compiled.CompiledName):
                last_names.append(name)
                continue

            if isinstance(self.name_str, pr.Name):
                origin_scope = self.name_str.get_parent_until(pr.Scope, reverse=True)
            else:
                origin_scope = None
            if isinstance(stmt.parent, compiled.CompiledObject):
                # TODO seriously? this is stupid.
                continue
            check = flow_analysis.break_check(self._evaluator, name_scope,
                                              stmt, origin_scope)
            if check is not flow_analysis.UNREACHABLE:
                last_names.append(name)
            if check is flow_analysis.REACHABLE:
                break

        if isinstance(name_scope, er.FunctionExecution):
            # Replace params
            return [get_param(name_scope, n) for n in last_names]
        return last_names
Exemplo n.º 6
0
    def filter_name(self, scope_names_generator):
        """
        Filters all variables of a scope (which are defined in the
        `scope_names_generator`), until the name fits.
        """
        # TODO Now this import is really ugly. Try to remove it.
        # It's possibly the only api dependency.
        from jedi.api.interpreter import InterpreterNamespace
        names = []
        self.maybe_descriptor = isinstance(self.scope, er.Class)
        for name_list_scope, name_list in scope_names_generator:
            break_scopes = []
            if not isinstance(name_list_scope, compiled.CompiledObject):
                # Here is the position stuff happening (sorting of variables).
                # Compiled objects don't need that, because there's only one
                # reference.
                name_list = sorted(name_list, key=lambda n: n.start_pos, reverse=True)

            for name in name_list:
                if unicode(self.name_str) != name.get_code():
                    continue

                stmt = name.get_definition()
                scope = stmt.parent
                if scope in break_scopes:
                    continue

                # Exclude `arr[1] =` from the result set.
                if not self._name_is_array_assignment(name, stmt):
                    # TODO we ignore a lot of elements here that should not be
                    #   ignored. But then again flow_analysis also stops when the
                    #   input scope is reached. This is not correct: variables
                    #   might still have conditions if defined outside of the
                    #   current scope.
                    if isinstance(stmt, (pr.Param, pr.Import)) \
                            or isinstance(name_list_scope, (pr.Lambda, pr.ListComprehension, er.Instance, InterpreterNamespace)) \
                            or isinstance(scope, compiled.CompiledObject) \
                            or isinstance(stmt, pr.ExprStmt) and stmt.is_global():
                        # Always reachable.
                        names.append(name)
                    else:
                        check = flow_analysis.break_check(self._evaluator,
                                                          name_list_scope,
                                                          er.wrap(self._evaluator, scope),
                                                          self.scope)
                        if check is not flow_analysis.UNREACHABLE:
                            names.append(name)
                        if check is flow_analysis.REACHABLE:
                            break

                if names and self._is_name_break_scope(stmt):
                    if self._does_scope_break_immediately(scope, name_list_scope):
                        break
                    else:
                        break_scopes.append(scope)
            if names:
                break

            if isinstance(self.scope, er.Instance):
                # After checking the dictionary of an instance (self
                # attributes), an attribute maybe a descriptor.
                self.maybe_descriptor = True

        scope_txt = (self.scope if self.scope == name_list_scope
                     else '%s-%s' % (self.scope, name_list_scope))
        debug.dbg('finder.filter_name "%s" in (%s): %s@%s', self.name_str,
                  scope_txt, u(names), self.position)
        return list(self._clean_names(names))
Exemplo n.º 7
0
    def names_dict_lookup(self, names_dict, position):
        def get_param(scope, el):
            if isinstance(el.get_parent_until(tree.Param), tree.Param):
                return scope.param_by_name(str(el))
            return el

        search_str = str(self.name_str)
        try:
            names = names_dict[search_str]
            if not names:  # We want names, otherwise stop.
                return []
        except KeyError:
            return []

        names = filter_definition_names(names, self.name_str, position)

        name_scope = None
        # Only the names defined in the last position are valid definitions.
        last_names = []
        for name in reversed(sorted(names, key=lambda name: name.start_pos)):
            stmt = name.get_definition()
            name_scope = self._evaluator.wrap(stmt.get_parent_scope())

            if isinstance(self.scope, er.Instance) and not isinstance(
                    name_scope, er.Instance):
                # Instances should not be checked for positioning, because we
                # don't know in which order the functions are called.
                last_names.append(name)
                continue

            if isinstance(name_scope, compiled.CompiledObject):
                # Let's test this. TODO need comment. shouldn't this be
                # filtered before?
                last_names.append(name)
                continue

            if isinstance(stmt, er.ModuleWrapper):
                # In case of REPL completion, we can infer modules names that
                # don't really have a definition (because they are really just
                # namespaces). In this case we can just add it.
                last_names.append(name)
                continue

            if isinstance(name, compiled.CompiledName) \
                    or isinstance(name, er.InstanceName) and isinstance(name._origin_name, compiled.CompiledName):
                last_names.append(name)
                continue

            if isinstance(self.name_str, tree.Name):
                origin_scope = self.name_str.get_parent_until(tree.Scope,
                                                              reverse=True)
                scope = self.name_str
                check = None
                while True:
                    scope = scope.parent
                    if scope.type in ("if_stmt", "for_stmt", "comp_for"):
                        try:
                            name_dict = self._evaluator.predefined_if_name_dict_dict[
                                scope]
                            types = set(name_dict[str(self.name_str)])
                        except KeyError:
                            continue
                        else:
                            if self.name_str.start_pos < scope.children[
                                    1].end_pos:
                                # It doesn't make any sense to check if
                                # statements in the if statement itself, just
                                # deliver types.
                                self._found_predefined_if_name = types
                            else:
                                check = flow_analysis.break_check(
                                    self._evaluator, self.scope, origin_scope)
                                if check is flow_analysis.UNREACHABLE:
                                    self._found_predefined_if_name = set()
                                else:
                                    self._found_predefined_if_name = types
                            break
                    if isinstance(scope, tree.IsScope) or scope is None:
                        break
            else:
                origin_scope = None

            if isinstance(stmt.parent, compiled.CompiledObject):
                # TODO seriously? this is stupid.
                continue
            check = flow_analysis.break_check(self._evaluator, name_scope,
                                              stmt, origin_scope)
            if check is not flow_analysis.UNREACHABLE:
                last_names.append(name)

            if check is flow_analysis.REACHABLE:
                break

        if isinstance(name_scope, er.FunctionExecution):
            # Replace params
            return [get_param(name_scope, n) for n in last_names]
        return last_names
Exemplo n.º 8
0
    def names_dict_lookup(self, names_dict, position):
        def get_param(scope, el):
            if isinstance(el.get_parent_until(tree.Param), tree.Param):
                return scope.param_by_name(str(el))
            return el

        search_str = str(self.name_str)
        try:
            names = names_dict[search_str]
            if not names:  # We want names, otherwise stop.
                return []
        except KeyError:
            return []

        names = filter_definition_names(names, self.name_str, position)

        name_scope = None
        # Only the names defined in the last position are valid definitions.
        last_names = []
        for name in reversed(sorted(names, key=lambda name: name.start_pos)):
            stmt = name.get_definition()
            name_scope = self._evaluator.wrap(stmt.get_parent_scope())

            if isinstance(self.scope, er.Instance) and not isinstance(name_scope, er.Instance):
                # Instances should not be checked for positioning, because we
                # don't know in which order the functions are called.
                last_names.append(name)
                continue

            if isinstance(name_scope, compiled.CompiledObject):
                # Let's test this. TODO need comment. shouldn't this be
                # filtered before?
                last_names.append(name)
                continue

            if isinstance(stmt, er.ModuleWrapper):
                # In case of REPL completion, we can infer modules names that
                # don't really have a definition (because they are really just
                # namespaces). In this case we can just add it.
                last_names.append(name)
                continue

            if (
                isinstance(name, compiled.CompiledName)
                or isinstance(name, er.InstanceName)
                and isinstance(name._origin_name, compiled.CompiledName)
            ):
                last_names.append(name)
                continue

            if isinstance(self.name_str, tree.Name):
                origin_scope = self.name_str.get_parent_until(tree.Scope, reverse=True)
                scope = self.name_str
                check = None
                while True:
                    scope = scope.parent
                    if scope.type in ("if_stmt", "for_stmt", "comp_for"):
                        try:
                            name_dict = self._evaluator.predefined_if_name_dict_dict[scope]
                            types = set(name_dict[str(self.name_str)])
                        except KeyError:
                            continue
                        else:
                            if self.name_str.start_pos < scope.children[1].end_pos:
                                # It doesn't make any sense to check if
                                # statements in the if statement itself, just
                                # deliver types.
                                self._found_predefined_if_name = types
                            else:
                                check = flow_analysis.break_check(self._evaluator, self.scope, origin_scope)
                                if check is flow_analysis.UNREACHABLE:
                                    self._found_predefined_if_name = set()
                                else:
                                    self._found_predefined_if_name = types
                            break
                    if isinstance(scope, tree.IsScope) or scope is None:
                        break
            else:
                origin_scope = None

            if isinstance(stmt.parent, compiled.CompiledObject):
                # TODO seriously? this is stupid.
                continue
            check = flow_analysis.break_check(self._evaluator, name_scope, stmt, origin_scope)
            if check is not flow_analysis.UNREACHABLE:
                last_names.append(name)

            if check is flow_analysis.REACHABLE:
                break

        if isinstance(name_scope, er.FunctionExecution):
            # Replace params
            return [get_param(name_scope, n) for n in last_names]
        return last_names