Ejemplo n.º 1
0
    def goto_assignments(self, follow_imports=False):
        """
        Return the first definition found, while optionally following imports.
        Multiple objects may be returned, because Python itself is a
        dynamic language, which means depending on an option you can have two
        different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        def filter_follow_imports(names, check):
            for name in names:
                if check(name):
                    for result in filter_follow_imports(name.goto(), check):
                        yield result
                else:
                    yield name

        names = self._goto()
        if follow_imports:

            def check(name):
                if isinstance(name, er.ModuleName):
                    return False
                return name.api_type == 'module'
        else:

            def check(name):
                return isinstance(name, imports.SubModuleName)

        names = filter_follow_imports(names, check)

        defs = [classes.Definition(self._evaluator, d) for d in set(names)]
        return helpers.sorted_definitions(defs)
Ejemplo n.º 2
0
    def usages(self, additional_module_paths=()):
        """
        Return :class:`classes.Definition` objects, which contain all
        names that point to the definition of the name under the cursor. This
        is very useful for refactoring (renaming), or to show all usages of a
        variable.

        .. todo:: Implement additional_module_paths

        :rtype: list of :class:`classes.Definition`
        """
        temp, settings.dynamic_flow_information = \
            settings.dynamic_flow_information, False
        try:
            user_stmt = self._parser.user_stmt()
            definitions = self._goto(add_import_name=True)
            if not definitions:
                # Without a definition for a name we cannot find references.
                return []

            if not isinstance(user_stmt, pr.Import):
                # import case is looked at with add_import_name option
                definitions = usages.usages_add_import_modules(
                    self._evaluator, definitions)

            module = set([d.get_parent_until() for d in definitions])
            module.add(self._parser.module())
            names = usages.usages(self._evaluator, definitions, module)

            for d in set(definitions):
                names.append(classes.Definition(self._evaluator, d))
        finally:
            settings.dynamic_flow_information = temp

        return helpers.sorted_definitions(set(names))
Ejemplo n.º 3
0
    def usages(self, additional_module_paths=()):
        """
        Return :class:`classes.Definition` objects, which contain all
        names that point to the definition of the name under the cursor. This
        is very useful for refactoring (renaming), or to show all usages of a
        variable.

        .. todo:: Implement additional_module_paths

        :rtype: list of :class:`classes.Definition`
        """
        temp, settings.dynamic_flow_information = \
            settings.dynamic_flow_information, False
        try:
            user_stmt = self._parser.user_stmt()
            definitions = self._goto(add_import_name=True)
            if not definitions:
                # Without a definition for a name we cannot find references.
                return []

            if not isinstance(user_stmt, pr.Import):
                # import case is looked at with add_import_name option
                definitions = usages.usages_add_import_modules(self._evaluator,
                                                               definitions)

            module = set([d.get_parent_until() for d in definitions])
            module.add(self._parser.module())
            names = usages.usages(self._evaluator, definitions, module)

            for d in set(definitions):
                names.append(classes.Definition(self._evaluator, d))
        finally:
            settings.dynamic_flow_information = temp

        return helpers.sorted_definitions(set(names))
    def _goto(self, line, column, follow_imports=False, follow_builtin_imports=False,
              only_stubs=False, prefer_stubs=False):
        tree_name = self._module_node.get_name_of_position((line, column))
        if tree_name is None:
            # Without a name we really just want to jump to the result e.g.
            # executed by `foo()`, if we the cursor is after `)`.
            return self.infer(line, column, only_stubs=only_stubs, prefer_stubs=prefer_stubs)
        name = self._get_module_context().create_name(tree_name)

        # Make it possible to goto the super class function/attribute
        # definitions, when they are overwritten.
        names = []
        if name.tree_name.is_definition() and name.parent_context.is_class():
            class_node = name.parent_context.tree_node
            class_value = self._get_module_context().create_value(class_node)
            mro = class_value.py__mro__()
            next(mro)  # Ignore the first entry, because it's the class itself.
            for cls in mro:
                names = cls.goto(tree_name.value)
                if names:
                    break

        if not names:
            names = list(name.goto())

        if follow_imports:
            names = helpers.filter_follow_imports(names)
        names = convert_names(
            names,
            only_stubs=only_stubs,
            prefer_stubs=prefer_stubs,
        )

        defs = [classes.Definition(self._inference_state, d) for d in set(names)]
        return helpers.sorted_definitions(defs)
Ejemplo n.º 5
0
    def goto_assignments(self, follow_imports=False):
        """
        Return the first definition found, while optionally following imports.
        Multiple objects may be returned, because Python itself is a
        dynamic language, which means depending on an option you can have two
        different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        def filter_follow_imports(names, check):
            for name in names:
                if check(name):
                    for result in filter_follow_imports(name.goto(), check):
                        yield result
                else:
                    yield name

        tree_name = self._module_node.get_name_of_position(self._pos)
        if tree_name is None:
            return []
        context = self._evaluator.create_context(self._get_module(), tree_name)
        names = list(self._evaluator.goto(context, tree_name))

        if follow_imports:
            def check(name):
                return name.is_import()
        else:
            def check(name):
                return isinstance(name, imports.SubModuleName)

        names = filter_follow_imports(names, check)

        defs = [classes.Definition(self._evaluator, d) for d in set(names)]
        return helpers.sorted_definitions(defs)
Ejemplo n.º 6
0
    def goto_definitions(self):
        """
        Return the definitions of a the path under the cursor.  goto function!
        This follows complicated paths and returns the end, not the first
        definition. The big difference between :meth:`goto_assignments` and
        :meth:`goto_definitions` is that :meth:`goto_assignments` doesn't
        follow imports and statements. Multiple objects may be returned,
        because Python itself is a dynamic language, which means depending on
        an option you can have two different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        leaf = self._get_module().name_for_position(self._pos)
        if leaf is None:
            leaf = self._get_module().get_leaf_for_position(self._pos)
            if leaf is None:
                return []
        definitions = helpers.evaluate_goto_definition(self._evaluator, leaf)

        names = [s.name for s in definitions]
        defs = [classes.Definition(self._evaluator, name) for name in names]
        # The additional set here allows the definitions to become unique in an
        # API sense. In the internals we want to separate more things than in
        # the API.
        return helpers.sorted_definitions(set(defs))
Ejemplo n.º 7
0
    def goto_assignments(self, follow_imports=False):
        """
        Return the first definition found, while optionally following imports.
        Multiple objects may be returned, because Python itself is a
        dynamic language, which means depending on an option you can have two
        different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        def filter_follow_imports(names):
            for name in names:
                definition = name.get_definition()
                if definition.type in ('import_name', 'import_from'):
                    imp = imports.ImportWrapper(self._evaluator, name)
                    for name in filter_follow_imports(imp.follow(is_goto=True)):
                        yield name
                else:
                    yield name

        names = self._goto()
        if follow_imports:
            names = filter_follow_imports(names)

        defs = [classes.Definition(self._evaluator, d) for d in set(names)]
        return helpers.sorted_definitions(defs)
Ejemplo n.º 8
0
    def goto_assignments(self, follow_imports=False):
        """
        Return the first definition found, while optionally following imports.
        Multiple objects may be returned, because Python itself is a
        dynamic language, which means depending on an option you can have two
        different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        def filter_follow_imports(names, check):
            for name in names:
                if check(name):
                    for result in filter_follow_imports(name.goto(), check):
                        yield result
                else:
                    yield name

        tree_name = self._module_node.get_name_of_position(self._pos)
        if tree_name is None:
            return []
        context = self._evaluator.create_context(self._get_module(), tree_name)
        names = list(self._evaluator.goto(context, tree_name))

        if follow_imports:
            def check(name):
                return name.is_import()
        else:
            def check(name):
                return isinstance(name, imports.SubModuleName)

        names = filter_follow_imports(names, check)

        defs = [classes.Definition(self._evaluator, d) for d in set(names)]
        return helpers.sorted_definitions(defs)
Ejemplo n.º 9
0
    def goto(self,
             line=None,
             column=None,
             *,
             follow_imports=False,
             follow_builtin_imports=False,
             only_stubs=False,
             prefer_stubs=False):
        """
        Goes to the name that defined the object under the cursor. Optionally
        you can follow imports.
        Multiple objects may be returned, depending on an if you can have two
        different versions of a function.

        :param follow_imports: The method will follow imports.
        :param follow_builtin_imports: If ``follow_imports`` is True will try
            to look up names in builtins (i.e. compiled or extension modules).
        :param only_stubs: Only return stubs for this method.
        :param prefer_stubs: Prefer stubs to Python objects for this method.
        :rtype: list of :class:`.Name`
        """
        tree_name = self._module_node.get_name_of_position((line, column))
        if tree_name is None:
            # Without a name we really just want to jump to the result e.g.
            # executed by `foo()`, if we the cursor is after `)`.
            return self.infer(line,
                              column,
                              only_stubs=only_stubs,
                              prefer_stubs=prefer_stubs)
        name = self._get_module_context().create_name(tree_name)

        # Make it possible to goto the super class function/attribute
        # definitions, when they are overwritten.
        names = []
        if name.tree_name.is_definition() and name.parent_context.is_class():
            class_node = name.parent_context.tree_node
            class_value = self._get_module_context().create_value(class_node)
            mro = class_value.py__mro__()
            next(mro)  # Ignore the first entry, because it's the class itself.
            for cls in mro:
                names = cls.goto(tree_name.value)
                if names:
                    break

        if not names:
            names = list(name.goto())

        if follow_imports:
            names = helpers.filter_follow_imports(names,
                                                  follow_builtin_imports)
        names = convert_names(
            names,
            only_stubs=only_stubs,
            prefer_stubs=prefer_stubs,
        )

        defs = [classes.Name(self._inference_state, d) for d in set(names)]
        # Avoid duplicates
        return list(set(helpers.sorted_definitions(defs)))
Ejemplo n.º 10
0
def usages_with_additional_modules(
    script: jedi.api.Script,
    additional_module_contexts: Tuple[ModuleContext] = ()):
    """
    Based on `jedi.api.Script.usages`, except `additional_modules` are also searched

    Forked from `jedi.api.Script.usages` on 2017-02-02.

    Return :class:`classes.Definition` objects, which contain all
    names that point to the definition of the name under the cursor. This
    is very useful for refactoring (renaming), or to show all usages of a
    variable.

    .. todo:: Implement additional_module_paths

    :rtype: list of :class:`classes.Definition`
    """
    from jedi import settings
    from jedi.api import usages
    from jedi.api import helpers
    from . import api_usages as alt_api_usages

    self = script

    temp, settings.dynamic_flow_information = \
        settings.dynamic_flow_information, False
    try:
        module_node = self._get_module_node()
        user_stmt = module_node.get_statement_for_position(self._pos)
        definition_names = self._goto()

        #assert not definition_names
        if not definition_names and isinstance(user_stmt, tree_Import):
            # For not defined imports (goto doesn't find something, we take
            # the name as a definition. This is enough, because every name
            # points to it.
            name = user_stmt.name_for_position(self._pos)
            if name is None:
                # Must be syntax
                return []
            definition_names = [TreeNameDefinition(self._get_module(), name)]

        if not definition_names:
            # Without a definition for a name we cannot find references.
            return []

        definition_names = usages.resolve_potential_imports(
            self._evaluator, definition_names)

        modules = set([d.get_root_context() for d in definition_names])
        modules.add(self._get_module())
        for additional_module_context in additional_module_contexts:
            modules.add(additional_module_context)
        definitions = alt_api_usages.usages(self._evaluator, definition_names,
                                            modules)
    finally:
        settings.dynamic_flow_information = temp

    return helpers.sorted_definitions(set(definitions))
Ejemplo n.º 11
0
 def _usages_in_module(include_builtins=True):
     tree_name = self._module_node.get_name_of_position(self._pos)
     if tree_name is None:
         # Must be syntax
         return []
     names = usages.usages_in_module(self._get_module(), tree_name)
     definitions = [classes.Definition(self._evaluator, n) for n in names]
     if not include_builtins:
         definitions = [d for d in definitions if not d.in_builtin_module()]
     return helpers.sorted_definitions(definitions)
Ejemplo n.º 12
0
        def _references(include_builtins=True):
            tree_name = self._module_node.get_name_of_position((line, column))
            if tree_name is None:
                # Must be syntax
                return []

            names = find_references(self._get_module_context(), tree_name)

            definitions = [classes.Definition(self._inference_state, n) for n in names]
            if not include_builtins:
                definitions = [d for d in definitions if not d.in_builtin_module()]
            return helpers.sorted_definitions(definitions)
Ejemplo n.º 13
0
        def _usages(include_builtins=True):
            tree_name = self._module_node.get_name_of_position(self._pos)
            if tree_name is None:
                # Must be syntax
                return []

            names = usages.usages(self._get_module(), tree_name)

            definitions = [classes.Definition(self._evaluator, n) for n in names]
            if not include_builtins:
                definitions = [d for d in definitions if not d.in_builtin_module()]
            return helpers.sorted_definitions(definitions)
Ejemplo n.º 14
0
    def goto_assignments(self):
        """
        Return the first definition found. Imports and statements aren't
        followed. Multiple objects may be returned, because Python itself is a
        dynamic language, which means depending on an option you can have two
        different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        results = self._goto()
        d = [classes.Definition(self._evaluator, d) for d in set(results)]
        return helpers.sorted_definitions(d)
Ejemplo n.º 15
0
Archivo: __init__.py Proyecto: ABob/vim
    def goto_assignments(self):
        """
        Return the first definition found. Imports and statements aren't
        followed. Multiple objects may be returned, because Python itself is a
        dynamic language, which means depending on an option you can have two
        different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        results = self._goto()
        d = [classes.Definition(self._evaluator, d) for d in set(results)]
        return helpers.sorted_definitions(d)
Ejemplo n.º 16
0
        def _references(include_builtins=True, scope='project'):
            if scope not in ('project', 'file'):
                raise ValueError('Only the scopes "file" and "project" are allowed')
            tree_name = self._module_node.get_name_of_position((line, column))
            if tree_name is None:
                # Must be syntax
                return []

            names = find_references(self._get_module_context(), tree_name, scope == 'file')

            definitions = [classes.Name(self._inference_state, n) for n in names]
            if not include_builtins or scope == 'file':
                definitions = [d for d in definitions if not d.in_builtin_module()]
            return helpers.sorted_definitions(definitions)
Ejemplo n.º 17
0
    def goto_definitions(self):
        """
        Return the definitions of a the path under the cursor.  goto function!
        This follows complicated paths and returns the end, not the first
        definition. The big difference between :meth:`goto_assignments` and
        :meth:`goto_definitions` is that :meth:`goto_assignments` doesn't
        follow imports and statements. Multiple objects may be returned,
        because Python itself is a dynamic language, which means depending on
        an option you can have two different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        def resolve_import_paths(scopes):
            for s in scopes.copy():
                if isinstance(s, imports.ImportPath):
                    scopes.remove(s)
                    scopes.update(resolve_import_paths(set(s.follow())))
            return scopes

        user_stmt = self._parser.user_stmt_with_whitespace()
        goto_path = self._user_context.get_path_under_cursor()
        context = self._user_context.get_context()
        definitions = set()
        if next(context) in ('class', 'def'):
            definitions = set([self._parser.user_scope()])
        else:
            # Fetch definition of callee, if there's no path otherwise.
            if not goto_path:
                (call,
                 _) = helpers.func_call_and_param_index(user_stmt, self._pos)
                if call is not None:
                    while call.next is not None:
                        call = call.next
                    # reset cursor position:
                    (row, col) = call.name.end_pos
                    pos = (row, max(col - 1, 0))
                    self._user_context = UserContext(self.source, pos)
                    # then try to find the path again
                    goto_path = self._user_context.get_path_under_cursor()

        if not definitions:
            if goto_path:
                definitions = set(self._prepare_goto(goto_path))

        definitions = resolve_import_paths(definitions)
        d = set([
            classes.Definition(self._evaluator, s) for s in definitions
            if s is not imports.ImportPath.GlobalNamespace
        ])
        return helpers.sorted_definitions(d)
Ejemplo n.º 18
0
    def _goto(self,
              line,
              column,
              follow_imports=False,
              follow_builtin_imports=False,
              only_stubs=False,
              prefer_stubs=False):
        def filter_follow_imports(names):
            for name in names:
                if name.is_import():
                    new_names = list(filter_follow_imports(name.goto()))
                    found_builtin = False
                    if follow_builtin_imports:
                        for new_name in new_names:
                            if new_name.start_pos is None:
                                found_builtin = True

                    if found_builtin:
                        yield name
                    else:
                        for new_name in new_names:
                            yield new_name
                else:
                    yield name

        tree_name = self._module_node.get_name_of_position((line, column))
        if tree_name is None:
            # Without a name we really just want to jump to the result e.g.
            # executed by `foo()`, if we the cursor is after `)`.
            return self.infer(line,
                              column,
                              only_stubs=only_stubs,
                              prefer_stubs=prefer_stubs)
        name = self._get_module_context().create_name(tree_name)
        names = list(name.goto())

        if follow_imports:
            names = filter_follow_imports(names)
        names = convert_names(
            names,
            only_stubs=only_stubs,
            prefer_stubs=prefer_stubs,
        )

        defs = [
            classes.Definition(self._inference_state, d) for d in set(names)
        ]
        return helpers.sorted_definitions(defs)
Ejemplo n.º 19
0
    def goto_definitions(self):
        """
        Return the definitions of a the path under the cursor.  goto function!
        This follows complicated paths and returns the end, not the first
        definition. The big difference between :meth:`goto_assignments` and
        :meth:`goto_definitions` is that :meth:`goto_assignments` doesn't
        follow imports and statements. Multiple objects may be returned,
        because Python itself is a dynamic language, which means depending on
        an option you can have two different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        def resolve_import_paths(scopes):
            for s in scopes.copy():
                if isinstance(s, imports.ImportWrapper):
                    scopes.remove(s)
                    scopes.update(resolve_import_paths(set(s.follow())))
            return scopes

        goto_path = self._user_context.get_path_under_cursor()
        context = self._user_context.get_context()
        definitions = set()
        if next(context) in ('class', 'def'):
            definitions = set(
                [self._evaluator.wrap(self._parser.user_scope())])
        else:
            # Fetch definition of callee, if there's no path otherwise.
            if not goto_path:
                definitions = set(signature._definition
                                  for signature in self.call_signatures())

        if re.match('\w[\w\d_]*$', goto_path) and not definitions:
            user_stmt = self._parser.user_stmt()
            if user_stmt is not None and user_stmt.type == 'expr_stmt':
                for name in user_stmt.get_defined_names():
                    if name.start_pos <= self._pos <= name.end_pos:
                        # TODO scaning for a name and then using it should be
                        # the default.
                        definitions = set(
                            self._evaluator.goto_definition(name))

        if not definitions and goto_path:
            definitions = set(self._prepare_goto(goto_path))

        definitions = resolve_import_paths(definitions)
        names = [s.name for s in definitions]
        defs = [classes.Definition(self._evaluator, name) for name in names]
        return helpers.sorted_definitions(set(defs))
Ejemplo n.º 20
0
    def infer(self,
              line=None,
              column=None,
              *,
              only_stubs=False,
              prefer_stubs=False):
        """
        Return the definitions of under the cursor. It is basically a wrapper
        around Jedi's type inference.

        This method follows complicated paths and returns the end, not the
        first definition. The big difference between :meth:`goto` and
        :meth:`infer` is that :meth:`goto` doesn't
        follow imports and statements. Multiple objects may be returned,
        because depending on an option you can have two different versions of a
        function.

        :param only_stubs: Only return stubs for this method.
        :param prefer_stubs: Prefer stubs to Python objects for this method.
        :rtype: list of :class:`.Name`
        """
        pos = line, column
        leaf = self._module_node.get_name_of_position(pos)
        if leaf is None:
            leaf = self._module_node.get_leaf_for_position(pos)
            if leaf is None or leaf.type == 'string':
                return []
            if leaf.end_pos == (line, column) and leaf.type == 'operator':
                next_ = leaf.get_next_leaf()
                if next_.start_pos == leaf.end_pos \
                        and next_.type in ('number', 'string', 'keyword'):
                    leaf = next_

        context = self._get_module_context().create_context(leaf)

        values = helpers.infer(self._inference_state, context, leaf)
        values = convert_values(
            values,
            only_stubs=only_stubs,
            prefer_stubs=prefer_stubs,
        )

        defs = [classes.Name(self._inference_state, c.name) for c in values]
        # The additional set here allows the definitions to become unique in an
        # API sense. In the internals we want to separate more things than in
        # the API.
        return helpers.sorted_definitions(set(defs))
Ejemplo n.º 21
0
    def goto_definitions(self):
        """
        Return the definitions of a the path under the cursor.  goto function!
        This follows complicated paths and returns the end, not the first
        definition. The big difference between :meth:`goto_assignments` and
        :meth:`goto_definitions` is that :meth:`goto_assignments` doesn't
        follow imports and statements. Multiple objects may be returned,
        because Python itself is a dynamic language, which means depending on
        an option you can have two different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        def resolve_import_paths(scopes):
            for s in scopes.copy():
                if isinstance(s, imports.ImportPath):
                    scopes.remove(s)
                    scopes.update(resolve_import_paths(set(s.follow())))
            return scopes

        user_stmt = self._parser.user_stmt_with_whitespace()
        goto_path = self._user_context.get_path_under_cursor()
        context = self._user_context.get_context()
        definitions = set()
        if next(context) in ('class', 'def'):
            definitions = set([self._parser.user_scope()])
        else:
            # Fetch definition of callee, if there's no path otherwise.
            if not goto_path:
                (call, _) = helpers.func_call_and_param_index(user_stmt, self._pos)
                if call is not None:
                    while call.next is not None:
                        call = call.next
                    # reset cursor position:
                    (row, col) = call.name.end_pos
                    pos = (row, max(col - 1, 0))
                    self._user_context = UserContext(self.source, pos)
                    # then try to find the path again
                    goto_path = self._user_context.get_path_under_cursor()

        if not definitions:
            if goto_path:
                definitions = set(self._prepare_goto(goto_path))

        definitions = resolve_import_paths(definitions)
        d = set([classes.Definition(self._evaluator, s) for s in definitions
                 if s is not imports.ImportPath.GlobalNamespace])
        return helpers.sorted_definitions(d)
Ejemplo n.º 22
0
Archivo: __init__.py Proyecto: ABob/vim
    def goto_definitions(self):
        """
        Return the definitions of a the path under the cursor.  goto function!
        This follows complicated paths and returns the end, not the first
        definition. The big difference between :meth:`goto_assignments` and
        :meth:`goto_definitions` is that :meth:`goto_assignments` doesn't
        follow imports and statements. Multiple objects may be returned,
        because Python itself is a dynamic language, which means depending on
        an option you can have two different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        def resolve_import_paths(scopes):
            for s in scopes.copy():
                if isinstance(s, imports.ImportWrapper):
                    scopes.remove(s)
                    scopes.update(resolve_import_paths(set(s.follow())))
            return scopes

        goto_path = self._user_context.get_path_under_cursor()
        context = self._user_context.get_context()
        definitions = set()
        if next(context) in ('class', 'def'):
            definitions = set([self._evaluator.wrap(self._parser.user_scope())])
        else:
            # Fetch definition of callee, if there's no path otherwise.
            if not goto_path:
                definitions = set(signature._definition
                                  for signature in self.call_signatures())

        if re.match('\w[\w\d_]*$', goto_path) and not definitions:
            user_stmt = self._parser.user_stmt()
            if user_stmt is not None and user_stmt.type == 'expr_stmt':
                for name in user_stmt.get_defined_names():
                    if name.start_pos <= self._pos <= name.end_pos:
                        # TODO scaning for a name and then using it should be
                        # the default.
                        definitions = set(self._evaluator.goto_definition(name))

        if not definitions and goto_path:
            definitions = set(self._prepare_goto(goto_path))

        definitions = resolve_import_paths(definitions)
        names = [s.name for s in definitions]
        defs = [classes.Definition(self._evaluator, name) for name in names]
        return helpers.sorted_definitions(set(defs))
Ejemplo n.º 23
0
    def usages(self, additional_module_paths=()):
        """
        Return :class:`classes.Definition` objects, which contain all
        names that point to the definition of the name under the cursor. This
        is very useful for refactoring (renaming), or to show all usages of a
        variable.

        .. todo:: Implement additional_module_paths

        :rtype: list of :class:`classes.Definition`
        """
        temp, settings.dynamic_flow_information = \
            settings.dynamic_flow_information, False
        try:
            user_stmt = self._get_module().get_statement_for_position(
                self._pos)
            definitions = self._goto()
            if not definitions and isinstance(user_stmt, tree.Import):
                # For not defined imports (goto doesn't find something, we take
                # the name as a definition. This is enough, because every name
                # points to it.
                name = user_stmt.name_for_position(self._pos)
                if name is None:
                    # Must be syntax
                    return []
                definitions = [name]

            if not definitions:
                # Without a definition for a name we cannot find references.
                return []

            if not isinstance(user_stmt, tree.Import):
                # import case is looked at with add_import_name option
                definitions = usages.usages_add_import_modules(
                    self._evaluator, definitions)

            module = set([d.get_parent_until() for d in definitions])
            module.add(self._get_module())
            names = usages.usages(self._evaluator, definitions, module)

            for d in set(definitions):
                names.append(classes.Definition(self._evaluator, d))
        finally:
            settings.dynamic_flow_information = temp

        return helpers.sorted_definitions(set(names))
Ejemplo n.º 24
0
    def usages(self, additional_module_paths=()):
        """
        Return :class:`classes.Definition` objects, which contain all
        names that point to the definition of the name under the cursor. This
        is very useful for refactoring (renaming), or to show all usages of a
        variable.

        .. todo:: Implement additional_module_paths

        :rtype: list of :class:`classes.Definition`
        """
        temp, settings.dynamic_flow_information = \
            settings.dynamic_flow_information, False
        try:
            user_stmt = self._get_module().get_statement_for_position(
                self._pos)
            definitions = self._goto()
            if not definitions and isinstance(user_stmt, tree.Import):
                # For not defined imports (goto doesn't find something, we take
                # the name as a definition. This is enough, because every name
                # points to it.
                name = user_stmt.name_for_position(self._pos)
                if name is None:
                    # Must be syntax
                    return []
                definitions = [name]

            if not definitions:
                # Without a definition for a name we cannot find references.
                return []

            if not isinstance(user_stmt, tree.Import):
                # import case is looked at with add_import_name option
                definitions = usages.usages_add_import_modules(
                    self._evaluator, definitions)

            module = set([d.get_parent_until() for d in definitions])
            module.add(self._get_module())
            names = usages.usages(self._evaluator, definitions, module)

            for d in set(definitions):
                names.append(classes.Definition(self._evaluator, d))
        finally:
            settings.dynamic_flow_information = temp

        return helpers.sorted_definitions(set(names))
Ejemplo n.º 25
0
    def goto_assignments(self,
                         follow_imports=False,
                         follow_builtin_imports=False):
        """
        Return the first definition found, while optionally following imports.
        Multiple objects may be returned, because Python itself is a
        dynamic language, which means depending on an option you can have two
        different versions of a function.

        :param follow_imports: The goto call will follow imports.
        :param follow_builtin_imports: If follow_imports is True will decide if
            it follow builtin imports.
        :rtype: list of :class:`classes.Definition`
        """
        def filter_follow_imports(names, check):
            for name in names:
                if check(name):
                    new_names = list(filter_follow_imports(name.goto(), check))
                    found_builtin = False
                    if follow_builtin_imports:
                        for new_name in new_names:
                            if new_name.start_pos is None:
                                found_builtin = True

                    if found_builtin:
                        yield name
                    else:
                        for new_name in new_names:
                            yield new_name
                else:
                    yield name

        tree_name = self._module_node.get_name_of_position(self._pos)
        if tree_name is None:
            # Without a name we really just want to jump to the result e.g.
            # executed by `foo()`, if we the cursor is after `)`.
            return self.goto_definitions()
        context = self._evaluator.create_context(self._get_module(), tree_name)
        names = list(self._evaluator.goto(context, tree_name))

        if follow_imports:
            names = filter_follow_imports(names, lambda name: name.is_import())
        names = try_stub_to_actual_names(names, prefer_stub_to_compiled=True)

        defs = [classes.Definition(self._evaluator, d) for d in set(names)]
        return helpers.sorted_definitions(defs)
Ejemplo n.º 26
0
    def usages(self, additional_module_paths=()):
        """
        Return :class:`classes.Usage` objects, which contain all
        names that point to the definition of the name under the cursor. This
        is very useful for refactoring (renaming), or to show all usages of a
        variable.

        .. todo:: Implement additional_module_paths

        :rtype: list of :class:`classes.Usage`
        """
        temp, settings.dynamic_flow_information = \
            settings.dynamic_flow_information, False
        user_stmt = self._parser.user_stmt()
        definitions, search_name = self._goto(add_import_name=True)
        if isinstance(user_stmt, pr.Statement):
            c = user_stmt.expression_list()[0]
            if not isinstance(c, unicode) and self._pos < c.start_pos:
                # the search_name might be before `=`
                definitions = [
                    v for v in user_stmt.get_set_vars()
                    if unicode(v.names[-1]) == search_name
                ]
        if not isinstance(user_stmt, pr.Import):
            # import case is looked at with add_import_name option
            definitions = usages.usages_add_import_modules(
                self._evaluator, definitions, search_name)

        module = set([d.get_parent_until() for d in definitions])
        module.add(self._parser.module())
        names = usages.usages(self._evaluator, definitions, search_name,
                              module)

        for d in set(definitions):
            if isinstance(d, pr.Module):
                names.append(usages.Usage(self._evaluator, d, d))
            elif isinstance(d, er.Instance):
                # Instances can be ignored, because they have been created by
                # ``__getattr__``.
                pass
            else:
                names.append(usages.Usage(self._evaluator, d.names[-1], d))

        settings.dynamic_flow_information = temp
        return helpers.sorted_definitions(set(names))
Ejemplo n.º 27
0
    def usages(self, additional_module_paths=()):
        """
        Return :class:`classes.Definition` objects, which contain all
        names that point to the definition of the name under the cursor. This
        is very useful for refactoring (renaming), or to show all usages of a
        variable.

        .. todo:: Implement additional_module_paths

        :rtype: list of :class:`classes.Definition`
        """
        temp, settings.dynamic_flow_information = \
            settings.dynamic_flow_information, False
        try:
            module_node = self._get_module_node()
            user_stmt = get_statement_of_position(module_node, self._pos)
            definition_names = self._goto()
            if not definition_names and isinstance(user_stmt, tree.Import):
                # For not defined imports (goto doesn't find something, we take
                # the name as a definition. This is enough, because every name
                # points to it.
                name = user_stmt.get_name_of_position(self._pos)
                if name is None:
                    # Must be syntax
                    return []
                definition_names = [
                    TreeNameDefinition(self._get_module(), name)
                ]

            if not definition_names:
                # Without a definition for a name we cannot find references.
                return []

            definition_names = usages.resolve_potential_imports(
                self._evaluator, definition_names)

            modules = set([d.get_root_context() for d in definition_names])
            modules.add(self._get_module())
            definitions = usages.usages(self._evaluator, definition_names,
                                        modules)
        finally:
            settings.dynamic_flow_information = temp

        return helpers.sorted_definitions(set(definitions))
Ejemplo n.º 28
0
    def _goto_assignments(self,
                          follow_imports,
                          follow_builtin_imports,
                          only_stubs=False,
                          prefer_stubs=False):
        def filter_follow_imports(names, check):
            for name in names:
                if check(name):
                    new_names = list(filter_follow_imports(name.goto(), check))
                    found_builtin = False
                    if follow_builtin_imports:
                        for new_name in new_names:
                            if new_name.start_pos is None:
                                found_builtin = True

                    if found_builtin:
                        yield name
                    else:
                        for new_name in new_names:
                            yield new_name
                else:
                    yield name

        tree_name = self._module_node.get_name_of_position(self._pos)
        if tree_name is None:
            # Without a name we really just want to jump to the result e.g.
            # executed by `foo()`, if we the cursor is after `)`.
            return self.goto_definitions(only_stubs=only_stubs,
                                         prefer_stubs=prefer_stubs)
        context = self._evaluator.create_context(self._get_module(), tree_name)
        names = list(self._evaluator.goto(context, tree_name))

        if follow_imports:
            names = filter_follow_imports(names, lambda name: name.is_import())
        names = convert_names(
            names,
            only_stubs=only_stubs,
            prefer_stubs=prefer_stubs,
        )

        defs = [classes.Definition(self._evaluator, d) for d in set(names)]
        return helpers.sorted_definitions(defs)
Ejemplo n.º 29
0
    def usages(self, additional_module_paths=()):
        """
        Return :class:`classes.Definition` objects, which contain all
        names that point to the definition of the name under the cursor. This
        is very useful for refactoring (renaming), or to show all usages of a
        variable.

        .. todo:: Implement additional_module_paths

        :rtype: list of :class:`classes.Definition`
        """
        tree_name = self._module_node.get_name_of_position(self._pos)
        if tree_name is None:
            # Must be syntax
            return []

        names = usages.usages(self._get_module(), tree_name)

        definitions = [classes.Definition(self._evaluator, n) for n in names]
        return helpers.sorted_definitions(definitions)
Ejemplo n.º 30
0
    def usages(self, additional_module_paths=()):
        """
        Return :class:`classes.Definition` objects, which contain all
        names that point to the definition of the name under the cursor. This
        is very useful for refactoring (renaming), or to show all usages of a
        variable.

        .. todo:: Implement additional_module_paths

        :rtype: list of :class:`classes.Definition`
        """
        tree_name = self._get_module_node().get_name_of_position(self._pos)
        if tree_name is None:
            # Must be syntax
            return []

        names = usages.usages(self._get_module(), tree_name)

        definitions = [classes.Definition(self._evaluator, n) for n in names]
        return helpers.sorted_definitions(definitions)
Ejemplo n.º 31
0
    def goto_definitions(self):
        """
        Return the definitions of a the path under the cursor.  goto function!
        This follows complicated paths and returns the end, not the first
        definition. The big difference between :meth:`goto_assignments` and
        :meth:`goto_definitions` is that :meth:`goto_assignments` doesn't
        follow imports and statements. Multiple objects may be returned,
        because Python itself is a dynamic language, which means depending on
        an option you can have two different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        def resolve_import_paths(scopes):
            for s in scopes.copy():
                if isinstance(s, imports.ImportWrapper):
                    scopes.remove(s)
                    scopes.update(resolve_import_paths(set(s.follow())))
            return scopes

        user_stmt = self._parser.user_stmt_with_whitespace()
        goto_path = self._user_context.get_path_under_cursor()
        context = self._user_context.get_context()
        definitions = set()
        if next(context) in ('class', 'def'):
            definitions = set([er.wrap(self._evaluator, self._parser.user_scope())])
        else:
            # Fetch definition of callee, if there's no path otherwise.
            if not goto_path:
                call, _, _ = search_call_signatures(user_stmt, self._pos)
                if call is not None:
                    definitions = set(self._evaluator.eval_call(call))

        if not definitions:
            if goto_path:
                definitions = set(self._prepare_goto(goto_path))

        definitions = resolve_import_paths(definitions)
        names = [s.name for s in definitions
                 if s is not imports.ImportWrapper.GlobalNamespace]
        defs = [classes.Definition(self._evaluator, name) for name in names]
        return helpers.sorted_definitions(set(defs))
Ejemplo n.º 32
0
    def usages(self, additional_module_paths=()):
        """
        Return :class:`classes.Usage` objects, which contain all
        names that point to the definition of the name under the cursor. This
        is very useful for refactoring (renaming), or to show all usages of a
        variable.

        .. todo:: Implement additional_module_paths

        :rtype: list of :class:`classes.Usage`
        """
        temp, settings.dynamic_flow_information = \
            settings.dynamic_flow_information, False
        user_stmt = self._parser.user_stmt()
        definitions, search_name = self._goto(add_import_name=True)
        if isinstance(user_stmt, pr.Statement):
            c = user_stmt.expression_list()[0]
            if not isinstance(c, unicode) and self._pos < c.start_pos:
                # the search_name might be before `=`
                definitions = [v for v in user_stmt.get_set_vars()
                               if unicode(v.names[-1]) == search_name]
        if not isinstance(user_stmt, pr.Import):
            # import case is looked at with add_import_name option
            definitions = usages.usages_add_import_modules(self._evaluator, definitions, search_name)

        module = set([d.get_parent_until() for d in definitions])
        module.add(self._parser.module())
        names = usages.usages(self._evaluator, definitions, search_name, module)

        for d in set(definitions):
            if isinstance(d, pr.Module):
                names.append(usages.Usage(self._evaluator, d, d))
            elif isinstance(d, er.Instance):
                # Instances can be ignored, because they have been created by
                # ``__getattr__``.
                pass
            else:
                names.append(usages.Usage(self._evaluator, d.names[-1], d))

        settings.dynamic_flow_information = temp
        return helpers.sorted_definitions(set(names))
Ejemplo n.º 33
0
    def usages(self, additional_module_paths=()):
        """
        Return :class:`classes.Definition` objects, which contain all
        names that point to the definition of the name under the cursor. This
        is very useful for refactoring (renaming), or to show all usages of a
        variable.

        .. todo:: Implement additional_module_paths

        :rtype: list of :class:`classes.Definition`
        """
        temp, settings.dynamic_flow_information = \
            settings.dynamic_flow_information, False
        try:
            module_node = self._get_module_node()
            user_stmt = get_statement_of_position(module_node, self._pos)
            definition_names = self._goto()
            if not definition_names and isinstance(user_stmt, tree.Import):
                # For not defined imports (goto doesn't find something, we take
                # the name as a definition. This is enough, because every name
                # points to it.
                name = user_stmt.get_name_of_position(self._pos)
                if name is None:
                    # Must be syntax
                    return []
                definition_names = [TreeNameDefinition(self._get_module(), name)]

            if not definition_names:
                # Without a definition for a name we cannot find references.
                return []

            definition_names = usages.resolve_potential_imports(self._evaluator,
                                                                definition_names)

            modules = set([d.get_root_context() for d in definition_names])
            modules.add(self._get_module())
            definitions = usages.usages(self._evaluator, definition_names, modules)
        finally:
            settings.dynamic_flow_information = temp

        return helpers.sorted_definitions(set(definitions))
Ejemplo n.º 34
0
    def _goto_definitions(self, only_stubs=False, prefer_stubs=False):
        leaf = self._module_node.get_name_of_position(self._pos)
        if leaf is None:
            leaf = self._module_node.get_leaf_for_position(self._pos)
            if leaf is None:
                return []

        context = self._evaluator.create_context(self._get_module(), leaf)

        contexts = helpers.evaluate_goto_definition(self._evaluator, context, leaf)
        contexts = convert_contexts(
            contexts,
            only_stubs=only_stubs,
            prefer_stubs=prefer_stubs,
        )

        defs = [classes.Definition(self._evaluator, c.name) for c in contexts]
        # The additional set here allows the definitions to become unique in an
        # API sense. In the internals we want to separate more things than in
        # the API.
        return helpers.sorted_definitions(set(defs))
Ejemplo n.º 35
0
    def _infer(self, line, column, only_stubs=False, prefer_stubs=False):
        pos = line, column
        leaf = self._module_node.get_name_of_position(pos)
        if leaf is None:
            leaf = self._module_node.get_leaf_for_position(pos)
            if leaf is None or leaf.type == 'string':
                return []

        context = self._get_module_context().create_context(leaf)

        values = helpers.infer(self._inference_state, context, leaf)
        values = convert_values(
            values,
            only_stubs=only_stubs,
            prefer_stubs=prefer_stubs,
        )

        defs = [classes.Name(self._inference_state, c.name) for c in values]
        # The additional set here allows the definitions to become unique in an
        # API sense. In the internals we want to separate more things than in
        # the API.
        return helpers.sorted_definitions(set(defs))
Ejemplo n.º 36
0
    def goto_assignments(self, follow_imports=False):
        """
        Return the first definition found, while optionally following imports.
        Multiple objects may be returned, because Python itself is a
        dynamic language, which means depending on an option you can have two
        different versions of a function.

        :rtype: list of :class:`classes.Definition`
        """
        def filter_follow_imports(names):
            for name in names:
                if isinstance(name, (imports.ImportName, TreeNameDefinition)):
                    for context in name.infer():
                        yield context.name
                else:
                    yield name

        names = self._goto()
        if follow_imports:
            names = filter_follow_imports(names)

        defs = [classes.Definition(self._evaluator, d) for d in set(names)]
        return helpers.sorted_definitions(defs)