Ejemplo n.º 1
0
Archivo: api.py Proyecto: omab/dotfiles
 def __init__(self, source, line, column, source_path,
                              source_encoding='utf-8'):
     debug.reset_time()
     source = modules.source_to_unicode(source, source_encoding)
     self.pos = line, column
     self.module = modules.ModuleWithCursor(source_path, source=source,
                                                         position=self.pos)
     self.source_path = source_path
     debug.speed('init')
Ejemplo n.º 2
0
 def __init__(self, source, line, column, source_path,
                              source_encoding='utf-8'):
     api_classes._clear_caches()
     debug.reset_time()
     self.source = modules.source_to_unicode(source, source_encoding)
     self.pos = line, column
     self._module = modules.ModuleWithCursor(source_path,
                                     source=self.source, position=self.pos)
     self._source_path = source_path
     self.source_path = None if source_path is None \
                                 else os.path.abspath(source_path)
     debug.speed('init')
Ejemplo n.º 3
0
 def __init__(self, source, line, column, source_path,
              source_encoding='utf-8'):
     debug.reset_time()
     try:
         source = unicode(source, source_encoding, 'replace')
         # Use 'replace' over 'ignore' to hold code structure.
     except TypeError:  # `source` is already a unicode object
         pass
     self.pos = line, column
     self.module = modules.ModuleWithCursor(source_path, source=source,
                                                         position=self.pos)
     self.source_path = source_path
     debug.speed('init')
Ejemplo n.º 4
0
 def __init__(self,
              source,
              line,
              column,
              source_path,
              source_encoding='utf-8'):
     debug.reset_time()
     try:
         source = unicode(source, source_encoding, 'replace')
         # Use 'replace' over 'ignore' to hold code structure.
     except TypeError:  # `source` is already a unicode object
         pass
     self.pos = line, column
     self.module = modules.ModuleWithCursor(source_path,
                                            source=source,
                                            position=self.pos)
     self.source_path = source_path
     debug.speed('init')
Ejemplo n.º 5
0
Archivo: api.py Proyecto: omab/dotfiles
    def _prepare_goto(self, goto_path, is_like_search=False):
        """ Base for complete, goto and get_definition. Basically it returns
        the resolved scopes under cursor. """
        debug.dbg('start: %s in %s' % (goto_path, self.parser.user_scope))

        user_stmt = self.parser.user_stmt
        debug.speed('parsed')
        if not user_stmt and len(goto_path.split('\n')) > 1:
            # If the user_stmt is not defined and the goto_path is multi line,
            # something's strange. Most probably the backwards tokenizer
            # matched to much.
            return []

        if isinstance(user_stmt, parsing.Import):
            scopes = [self._get_on_import_stmt(is_like_search)[0]]
        else:
            # just parse one statement, take it and evaluate it
            stmt = self._get_under_cursor_stmt(goto_path)
            scopes = evaluate.follow_statement(stmt)
        return scopes
Ejemplo n.º 6
0
    def _prepare_goto(self, goto_path, is_like_search=False):
        """ Base for complete, goto and get_definition. Basically it returns
        the resolved scopes under cursor. """
        debug.dbg('start: %s in %s' % (goto_path, self.parser.scope))

        user_stmt = self.parser.user_stmt
        debug.speed('parsed')
        if not user_stmt and len(goto_path.split('\n')) > 1:
            # If the user_stmt is not defined and the goto_path is multi line,
            # something's strange. Most probably the backwards tokenizer
            # matched to much.
            return []

        if isinstance(user_stmt, parsing.Import):
            scopes = [self._get_on_import_stmt(is_like_search)[0]]
        else:
            # just parse one statement, take it and evaluate it
            stmt = self._get_under_cursor_stmt(goto_path)
            scopes = evaluate.follow_statement(stmt)
        return scopes
Ejemplo n.º 7
0
Archivo: api.py Proyecto: omab/dotfiles
    def complete(self):
        """
        An auto completer for python files.

        :return: list of Completion objects, sorted by name and __ comes last.
        :rtype: list
        """
        def follow_imports_if_possible(name):
            # TODO remove this, or move to another place (not used)
            par = name.parent
            if isinstance(par, parsing.Import) and not \
                        isinstance(self.parser.user_stmt, parsing.Import):
                new = imports.ImportPath(par).follow(is_goto=True)
                # Only remove the old entry if a new one has been found.
                #print par, new, par.parent
                if new:
                    try:
                        return new
                    except AttributeError:  # .name undefined
                        pass
            return [name]

        debug.speed('complete start')
        path = self.module.get_path_until_cursor()
        if re.search('^\.|\.\.$', path):
            return []
        path, dot, like = self._get_completion_parts(path)

        try:
            scopes = list(self._prepare_goto(path, True))
        except NotFoundError:
            scopes = []
            scope_generator = evaluate.get_names_for_scope(
                                            self.parser.user_scope, self.pos)
            completions = []
            for scope, name_list in scope_generator:
                for c in name_list:
                    completions.append((c, scope))
        else:
            completions = []
            debug.dbg('possible scopes', scopes)
            for s in scopes:
                if s.isinstance(evaluate.Function):
                    names = s.get_magic_method_names()
                else:
                    if isinstance(s, imports.ImportPath):
                        if like == 'import':
                            l = self.module.get_line(self.pos[0])[:self.pos[1]]
                            if not l.endswith('import import'):
                                continue
                        names = s.get_defined_names(on_import_stmt=True)
                    else:
                        names = s.get_defined_names()

                for c in names:
                    completions.append((c, s))

        if not dot:  # named_params have no dots
            call_def = self.get_in_function_call()
            if call_def:
                if not call_def.module.is_builtin():
                    for p in call_def.params:
                        completions.append((p.get_name(), p))

            # Do the completion if there is no path before and no import stmt.
            if (not scopes or not isinstance(scopes[0], imports.ImportPath)) \
                        and not path:
                # add keywords
                bs = builtin.Builtin.scope
                completions += ((k, bs) for k in keywords.get_keywords(
                                                                    all=True))

        needs_dot = not dot and path

        comps = []
        for c, s in set(completions):
            n = c.names[-1]
            if settings.case_insensitive_completion \
                    and n.lower().startswith(like.lower()) \
                    or n.startswith(like):
                if not evaluate.filter_private_variable(s,
                                                    self.parser.user_stmt, n):
                    new = api_classes.Completion(c, needs_dot,
                                                    len(like), s)
                    comps.append(new)

        debug.speed('complete end')

        return sorted(comps, key=lambda x: (x.word.startswith('__'),
                                            x.word.startswith('_'),
                                            x.word.lower()))
Ejemplo n.º 8
0
Archivo: api.py Proyecto: omab/dotfiles
    def get_in_function_call(self):
        """
        Return the function, that the cursor is in, e.g.:
        >>> isinstance(| # | <-- cursor is here

        This would return the `isinstance` function. In contrary:
        >>> isinstance()| # | <-- cursor is here

        This would return `None`.
        """
        def check_user_stmt(user_stmt):
            if user_stmt is None \
                        or not isinstance(user_stmt, parsing.Statement):
                return None, 0
            ass = helpers.fast_parent_copy(user_stmt.get_assignment_calls())

            call, index, stop = helpers.scan_array_for_pos(ass, self.pos)
            return call, index

        def check_cache():
            """ Do the parsing with a part parser, therefore reduce ressource
            costs.
            TODO this is not working with multi-line docstrings, improve.
            """
            if self.source_path is None:
                return None, 0

            try:
                timestamp, parser = builtin.CachedModule.cache[
                                                            self.source_path]
            except KeyError:
                return None, 0
            part_parser = self.module.get_part_parser()
            user_stmt = part_parser.user_stmt
            call, index = check_user_stmt(user_stmt)
            if call:
                old_stmt = parser.module.get_statement_for_position(self.pos)
                if old_stmt is None:
                    return None, 0
                old_call, old_index = check_user_stmt(old_stmt)
                if old_call:
                    # compare repr because that should definitely be the same.
                    # Otherwise the whole thing is out of sync.
                    if repr(old_call) == repr(call):
                        # return the index of the part_parser
                        return old_call, index
                return None, 0
            else:
                raise NotFoundError()

        debug.speed('func_call start')
        try:
            call, index = check_cache()
        except NotFoundError:
            return None
        debug.speed('func_call parsed')

        if call is None:
            # This is a backup, if the above is not successful.
            user_stmt = self.parser.user_stmt
            call, index = check_user_stmt(user_stmt)
            if call is None:
                return None

        debug.speed('func_call user_stmt')
        with common.scale_speed_settings(settings.scale_get_in_function_call):
            origins = evaluate.follow_call(call)
        debug.speed('func_call followed')

        if len(origins) == 0:
            return None
        # just take entry zero, because we need just one.
        executable = origins[0]

        return api_classes.CallDef(executable, index, call)
Ejemplo n.º 9
0
    def complete(self):
        """
        An auto completer for python files.

        :return: list of Completion objects, sorted by name and __ comes last.
        :rtype: list
        """
        def follow_imports_if_possible(name):
            # TODO remove this, or move to another place (not used)
            par = name.parent
            if isinstance(par, parsing.Import) and not \
                        isinstance(self.parser.user_stmt, parsing.Import):
                new = imports.ImportPath(par).follow(is_goto=True)
                # Only remove the old entry if a new one has been found.
                #print par, new, par.parent
                if new:
                    try:
                        return new
                    except AttributeError:  # .name undefined
                        pass
            return [name]

        debug.speed('complete start')
        path = self.module.get_path_until_cursor()
        path, dot, like = self._get_completion_parts(path)

        try:
            scopes = list(self._prepare_goto(path, True))
        except NotFoundError:
            scopes = []
            scope_generator = evaluate.get_names_for_scope(
                self.parser.user_scope, self.pos)
            completions = []
            for scope, name_list in scope_generator:
                for c in name_list:
                    completions.append((c, scope))
        else:
            completions = []
            debug.dbg('possible scopes', scopes)
            for s in scopes:
                if s.isinstance(evaluate.Function):
                    names = s.get_magic_method_names()
                else:
                    if isinstance(s, imports.ImportPath):
                        if like == 'import':
                            l = self.module.get_line(self.pos[0])[:self.pos[1]]
                            if not l.endswith('import import'):
                                continue
                        names = s.get_defined_names(on_import_stmt=True)
                    else:
                        names = s.get_defined_names()

                for c in names:
                    completions.append((c, s))

        if not dot:  # named_params have no dots
            call_def = self.get_in_function_call()
            if call_def:
                if not call_def.module.is_builtin():
                    for p in call_def.params:
                        completions.append((p.get_name(), p))

            # Do the completion if there is no path before and no import stmt.
            if (not scopes or not isinstance(scopes[0], imports.ImportPath)) \
                        and not path:
                # add keywords
                bs = builtin.Builtin.scope
                completions += ((k, bs)
                                for k in keywords.get_keywords(all=True))

        needs_dot = not dot and path

        comps = []
        for c, s in set(completions):
            n = c.names[-1]
            if settings.case_insensitive_completion \
                    and n.lower().startswith(like.lower()) \
                    or n.startswith(like):
                if not evaluate.filter_private_variable(
                        s, self.parser.user_stmt, n):
                    new = api_classes.Completion(c, needs_dot, len(like), s)
                    comps.append(new)

        debug.speed('complete end')

        return sorted(
            comps,
            key=lambda x:
            (x.word.startswith('__'), x.word.startswith('_'), x.word.lower()))
Ejemplo n.º 10
0
    def get_in_function_call(self):
        """
        Return the function, that the cursor is in, e.g.:
        >>> isinstance(| # | <-- cursor is here

        This would return the `isinstance` function. In contrary:
        >>> isinstance()| # | <-- cursor is here

        This would return `None`.
        """
        def check_user_stmt(user_stmt):
            if user_stmt is None \
                        or not isinstance(user_stmt, parsing.Statement):
                return None, 0
            ass = helpers.fast_parent_copy(user_stmt.get_assignment_calls())

            call, index, stop = helpers.scan_array_for_pos(ass, self.pos)
            return call, index

        def check_cache():
            """ Do the parsing with a part parser, therefore reduce ressource
            costs.
            TODO this is not working with multi-line docstrings, improve.
            """
            if self.source_path is None:
                return None, 0

            try:
                timestamp, parser = builtin.CachedModule.cache[
                    self.source_path]
            except KeyError:
                return None, 0
            part_parser = self.module.get_part_parser()
            user_stmt = part_parser.user_stmt
            call, index = check_user_stmt(user_stmt)
            if call:
                old_stmt = parser.module.get_statement_for_position(self.pos)
                if old_stmt is None:
                    return None, 0
                old_call, old_index = check_user_stmt(old_stmt)
                if old_call:
                    # compare repr because that should definitely be the same.
                    # Otherwise the whole thing is out of sync.
                    if repr(old_call) == repr(call):
                        # return the index of the part_parser
                        return old_call, index
                return None, 0
            else:
                raise NotFoundError()

        debug.speed('func_call start')
        try:
            call, index = check_cache()
        except NotFoundError:
            return None
        debug.speed('func_call parsed')

        if call is None:
            # This is a backup, if the above is not successful.
            user_stmt = self.parser.user_stmt
            call, index = check_user_stmt(user_stmt)
            if call is None:
                return None

        debug.speed('func_call user_stmt')
        with helpers.scale_speed_settings(settings.scale_get_in_function_call):
            origins = evaluate.follow_call(call)
        debug.speed('func_call followed')

        if len(origins) == 0:
            return None
        # just take entry zero, because we need just one.
        executable = origins[0]

        return api_classes.CallDef(executable, index, call)
Ejemplo n.º 11
0
    def get_in_function_call(self):
        """
        Return the function object of the call you're currently in.

        E.g. if the cursor is here::

            >>> abs(# <-- cursor is here

        This would return the ``abs`` function. On the other hand::

            >>> abs()# <-- cursor is here

        This would return ``None``.

        :rtype: :class:`api_classes.CallDef`
        """
        def check_user_stmt(user_stmt):
            if user_stmt is None \
                        or not isinstance(user_stmt, parsing.Statement):
                return None, 0
            ass = helpers.fast_parent_copy(user_stmt.get_assignment_calls())

            call, index, stop = helpers.search_function_call(ass, self.pos)
            return call, index

        def check_cache():
            """ Do the parsing with a part parser, therefore reduce ressource
            costs.
            TODO this is not working with multi-line docstrings, improve.
            """
            if self.source_path is None:
                return None, 0

            try:
                parser = cache.parser_cache[self.source_path].parser
            except KeyError:
                return None, 0
            part_parser = self._module.get_part_parser()
            user_stmt = part_parser.user_stmt
            call, index = check_user_stmt(user_stmt)
            if call:
                old_stmt = parser.module.get_statement_for_position(self.pos)
                if old_stmt is None:
                    return None, 0
                old_call, old_index = check_user_stmt(old_stmt)
                if old_call:
                    # compare repr because that should definitely be the same.
                    # Otherwise the whole thing is out of sync.
                    if repr(old_call) == repr(call):
                        # return the index of the part_parser
                        return old_call, index
                return None, 0
            else:
                raise NotFoundError()

        debug.speed('func_call start')
        call = None
        if settings.use_get_in_function_call_cache:
            try:
                call, index = check_cache()
            except NotFoundError:
                return None

        user_stmt = self._parser.user_stmt
        if call is None:
            # This is a backup, if the above is not successful.
            call, index = check_user_stmt(user_stmt)
            if call is None:
                return None
        debug.speed('func_call parsed')

        with common.scale_speed_settings(settings.scale_get_in_function_call):
            _callable = lambda: evaluate.follow_call(call)
            origins = cache.cache_get_in_function_call(_callable, user_stmt)
        debug.speed('func_call followed')

        if len(origins) == 0:
            return None
        # just take entry zero, because we need just one.
        executable = origins[0]

        return api_classes.CallDef(executable, index, call)