Exemple #1
0
Fichier : api.py Projet : tkf/jedi
    def get_definition(self):
        """
        Returns the definitions of a the path under the cursor. This is
        not a goto function! This follows complicated paths and returns the
        end, not the first definition.

        :return: list of Definition objects, which are basically scopes.
        :rtype: list
        """
        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

        goto_path = self.module.get_path_under_cursor()

        context = self.module.get_context()
        if next(context) in ('class', 'def'):
            scopes = set([self.module.parser.user_scope])
        elif not goto_path:
            op = self.module.get_operator_under_cursor()
            scopes = set([keywords.get_operator(op, self.pos)] if op else [])
        else:
            scopes = set(self._prepare_goto(goto_path))

        scopes = resolve_import_paths(scopes)

        # add keywords
        scopes |= keywords.get_keywords(string=goto_path, pos=self.pos)

        d = set([Definition(s) for s in scopes])
        return sorted(d, key=lambda x: (x.module_path, x.start_pos))
Exemple #2
0
    def _goto(self, add_import_name=False):
        """
        Used for goto and related_names.
        """
        goto_path = self.module.get_path_under_cursor()
        context = self.module.get_context()
        if next(context) in ('class', 'def'):
            user_scope = self.parser.user_scope
            definitions = set([user_scope.name])
            search_name = str(user_scope.name)
        elif isinstance(self.parser.user_stmt, parsing.Import):
            s, name_part = self._get_on_import_stmt()
            try:
                definitions = [s.follow(is_goto=True)[0]]
            except IndexError:
                definitions = []
            search_name = str(name_part)

            if add_import_name:
                import_name = self.parser.user_stmt.get_defined_names()
                # imports have only one name
                if name_part == import_name[0].names[-1]:
                    definitions.append(import_name[0])
        else:
            stmt = self._get_under_cursor_stmt(goto_path)
            definitions, search_name = evaluate.goto(stmt)
        return definitions, search_name
Exemple #3
0
    def _goto(self, add_import_name=False):
        """
        Used for goto and related_names.
        :param add_import_name: TODO add description
        """
        def follow_inexistent_imports(defs):
            """ Imports can be generated, e.g. following
            `multiprocessing.dummy` generates an import dummy in the
            multiprocessing module. The Import doesn't exist -> follow.
            """
            definitions = set(defs)
            for d in defs:
                if isinstance(d.parent, parsing.Import) \
                                        and d.start_pos == (0, 0):
                    i = imports.ImportPath(d.parent).follow(is_goto=True)
                    definitions.remove(d)
                    definitions |= follow_inexistent_imports(i)
            return definitions

        goto_path = self._module.get_path_under_cursor()
        context = self._module.get_context()
        user_stmt = self._parser.user_stmt
        if next(context) in ('class', 'def'):
            user_scope = self._parser.user_scope
            definitions = set([user_scope.name])
            search_name = unicode(user_scope.name)
        elif isinstance(user_stmt, parsing.Import):
            s, name_part = self._get_on_import_stmt()
            try:
                definitions = [s.follow(is_goto=True)[0]]
            except IndexError:
                definitions = []
            search_name = unicode(name_part)

            if add_import_name:
                import_name = user_stmt.get_defined_names()
                # imports have only one name
                if name_part == import_name[0].names[-1]:
                    definitions.append(import_name[0])
        else:
            stmt = self._get_under_cursor_stmt(goto_path)
            defs, search_name = evaluate.goto(stmt)
            definitions = follow_inexistent_imports(defs)
            if isinstance(user_stmt, parsing.Statement):
                if user_stmt.get_assignment_calls().start_pos > self.pos:
                    # The cursor must be after the start, otherwise the
                    # statement is just an assignee.
                    definitions = [user_stmt]
        return definitions, search_name
Exemple #4
0
    def _goto(self, add_import_name=False):
        """
        Used for goto and related_names.
        :param add_import_name: TODO add description
        """
        def follow_inexistent_imports(defs):
            """ Imports can be generated, e.g. following
            `multiprocessing.dummy` generates an import dummy in the
            multiprocessing module. The Import doesn't exist -> follow.
            """
            definitions = set(defs)
            for d in defs:
                if isinstance(d.parent, parsing.Import) \
                                        and d.start_pos == (0, 0):
                    i = imports.ImportPath(d.parent).follow(is_goto=True)
                    definitions.remove(d)
                    definitions |= follow_inexistent_imports(i)
            return definitions

        goto_path = self._module.get_path_under_cursor()
        context = self._module.get_context()
        user_stmt = self._parser.user_stmt
        if next(context) in ('class', 'def'):
            user_scope = self._parser.user_scope
            definitions = set([user_scope.name])
            search_name = unicode(user_scope.name)
        elif isinstance(user_stmt, parsing.Import):
            s, name_part = self._get_on_import_stmt()
            try:
                definitions = [s.follow(is_goto=True)[0]]
            except IndexError:
                definitions = []
            search_name = unicode(name_part)

            if add_import_name:
                import_name = user_stmt.get_defined_names()
                # imports have only one name
                if name_part == import_name[0].names[-1]:
                    definitions.append(import_name[0])
        else:
            stmt = self._get_under_cursor_stmt(goto_path)
            defs, search_name = evaluate.goto(stmt)
            definitions = follow_inexistent_imports(defs)
            if isinstance(user_stmt, parsing.Statement):
                if user_stmt.get_assignment_calls().start_pos > self.pos:
                    # The cursor must be after the start, otherwise the
                    # statement is just an assignee.
                    definitions = [user_stmt]
        return definitions, search_name
Exemple #5
0
    def get_definition(self):
        """
        Returns the definitions of a the path under the cursor. This is
        not a goto function! This follows complicated paths and returns the
        end, not the first definition.
        The big difference of goto and get_definition is that goto 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.

        :return: list of Definition objects, which are basically scopes.
        :rtype: list
        """
        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

        goto_path = self.module.get_path_under_cursor()

        context = self.module.get_context()
        if next(context) in ('class', 'def'):
            scopes = set([self.module.parser.user_scope])
        elif not goto_path:
            op = self.module.get_operator_under_cursor()
            scopes = set([keywords.get_operator(op, self.pos)] if op else [])
        else:
            scopes = set(self._prepare_goto(goto_path))

        scopes = resolve_import_paths(scopes)

        # add keywords
        scopes |= keywords.get_keywords(string=goto_path, pos=self.pos)

        d = set([
            api_classes.Definition(s) for s in scopes
            if not isinstance(s, imports.ImportPath._GlobalNamespace)
        ])
        return sorted(d, key=lambda x: (x.module_path, x.start_pos))
Exemple #6
0
    def get_definition(self):
        """
        Returns the definitions of a the path under the cursor. This is
        not a goto function! This follows complicated paths and returns the
        end, not the first definition.
        The big difference of goto and get_definition is that goto 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.

        :return: list of Definition objects, which are basically scopes.
        :rtype: list
        """
        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

        goto_path = self.module.get_path_under_cursor()

        context = self.module.get_context()
        if next(context) in ('class', 'def'):
            scopes = set([self.module.parser.user_scope])
        elif not goto_path:
            op = self.module.get_operator_under_cursor()
            scopes = set([keywords.get_operator(op, self.pos)] if op else [])
        else:
            scopes = set(self._prepare_goto(goto_path))

        scopes = resolve_import_paths(scopes)

        # add keywords
        scopes |= keywords.get_keywords(string=goto_path, pos=self.pos)

        d = set([api_classes.Definition(s) for s in scopes
                    if not isinstance(s, imports.ImportPath._GlobalNamespace)])
        return sorted(d, key=lambda x: (x.module_path, x.start_pos))
Exemple #7
0
    def __next__(self):
        if self.closed:
            raise MultiLevelStopIteration()
        try:
            self.current = next(self.gen)
        except tokenize.TokenError:
            # We just ignore this error, I try to handle it earlier - as
            # good as possible
            debug.warning('parentheses not closed error')
            return self.__next__()
        except IndentationError:
            # This is an error, that tokenize may produce, because the code
            # is not indented as it should. Here it just ignores this line
            # and restarts the parser.
            # (This is a rather unlikely error message, for normal code,
            # tokenize seems to be pretty tolerant)
            debug.warning('indentation error on line %s, ignoring it' %
                                                        self.current[2][0])
            # add the starting line of the last position
            self.line_offset += self.current[2][0]
            self.gen = PushBackIterator(tokenize.generate_tokens(
                                                                self.readline))
            return self.__next__()

        c = list(self.current)

        # stop if a new class or definition is started at position zero.
        breaks = ['def', 'class', '@']
        if self.stop_on_scope and c[1] in breaks and c[2][1] == 0:
            if self.first_scope:
                self.closed = True
                raise MultiLevelStopIteration()
            elif c[1] != '@':
                self.first_scope = True

        c[2] = self.line_offset + c[2][0], c[2][1]
        c[3] = self.line_offset + c[3][0], c[3][1]
        return c
Exemple #8
0
    def __next__(self):
        if self.closed:
            raise MultiLevelStopIteration()
        try:
            self.current = next(self.gen)
        except tokenize.TokenError:
            # We just ignore this error, I try to handle it earlier - as
            # good as possible
            debug.warning('parentheses not closed error')
            return self.__next__()
        except IndentationError:
            # This is an error, that tokenize may produce, because the code
            # is not indented as it should. Here it just ignores this line
            # and restarts the parser.
            # (This is a rather unlikely error message, for normal code,
            # tokenize seems to be pretty tolerant)
            debug.warning('indentation error on line %s, ignoring it' %
                          self.current[2][0])
            # add the starting line of the last position
            self.line_offset += self.current[2][0]
            self.gen = PushBackIterator(tokenize.generate_tokens(
                self.readline))
            return self.__next__()

        c = list(self.current)

        # stop if a new class or definition is started at position zero.
        breaks = ['def', 'class', '@']
        if self.stop_on_scope and c[1] in breaks and c[2][1] == 0:
            if self.first_scope:
                self.closed = True
                raise MultiLevelStopIteration()
            elif c[1] != '@':
                self.first_scope = True

        c[2] = self.line_offset + c[2][0], c[2][1]
        c[3] = self.line_offset + c[3][0], c[3][1]
        return c
Exemple #9
0
 def __next__(self):
     if self.pushes:
         return self.pushes.pop()
     else:
         return next(self.iterator)
Exemple #10
0
 def __next__(self):
     if self.pushes:
         return self.pushes.pop()
     else:
         return next(self.iterator)