Пример #1
0
def _rename(names, replace_str):
    """ For both rename and inline. """
    order = sorted(names, key=lambda x: (x.module_path, x.line, x.column),
                   reverse=True)

    def process(path, old_lines, new_lines):
        if new_lines is not None:  # goto next file, save last
            dct[path] = path, old_lines, new_lines

    dct = {}
    current_path = object()
    new_lines = old_lines = None
    for name in order:
        if name.in_builtin_module():
            continue
        if current_path != name.module_path:
            current_path = name.module_path

            process(current_path, old_lines, new_lines)
            if current_path is not None:
                # None means take the source that is a normal param.
                with open(current_path) as f:
                    source = f.read()

            new_lines = modules.source_to_unicode(source).splitlines()
            old_lines = new_lines[:]

        nr, indent = name.line, name.column
        line = new_lines[nr - 1]
        new_lines[nr - 1] = line[:indent] + replace_str + \
            line[indent + len(name.text):]
    process(current_path, old_lines, new_lines)
    return dct
Пример #2
0
    def __init__(self,
                 source,
                 line=None,
                 column=None,
                 path=None,
                 source_encoding='utf-8',
                 source_path=None):
        if source_path is not None:
            warnings.warn("Use path instead of source_path.",
                          DeprecationWarning)
            path = source_path

        lines = source.splitlines() or ['']
        if source and source[-1] == '\n':
            lines.append('')

        self._line = max(len(lines), 1) if line is None else line
        self._column = len(lines[-1]) if column is None else column

        api_classes._clear_caches()
        debug.reset_time()
        self.source = modules.source_to_unicode(source, source_encoding)
        self._pos = self._line, self._column
        self._module = modules.ModuleWithCursor(path,
                                                source=self.source,
                                                position=self._pos)
        self._source_path = path
        self.path = None if path is None else os.path.abspath(path)
        debug.speed('init')
Пример #3
0
def _rename(names, replace_str):
    """ For both rename and inline. """
    order = sorted(names,
                   key=lambda x: (x.module_path, x.start_pos),
                   reverse=True)

    def process(path, old_lines, new_lines):
        if new_lines is not None:  # goto next file, save last
            dct[path] = path, old_lines, new_lines

    dct = {}
    current_path = object()
    new_lines = old_lines = None
    for name in order:
        if name.in_builtin_module():
            continue
        if current_path != name.module_path:
            current_path = name.module_path

            process(current_path, old_lines, new_lines)
            if current_path is not None:
                # None means take the source that is a normal param.
                with open(current_path) as f:
                    source = f.read()

            new_lines = modules.source_to_unicode(source).splitlines()
            old_lines = new_lines[:]

        nr, indent = name.start_pos
        line = new_lines[nr - 1]
        new_lines[nr - 1] = line[:indent] + replace_str + \
                            line[indent + len(name.text):]
    process(current_path, old_lines, new_lines)
    return dct
Пример #4
0
    def __init__(self, source=None, line=None, column=None, path=None,
                 encoding='utf-8', source_path=None):
        if source_path is not None:
            warnings.warn("Use path instead of source_path.", DeprecationWarning)
            path = source_path

        if source is None:
            with open(path) as f:
                source = f.read()

        lines = source.splitlines() or ['']
        if source and source[-1] == '\n':
            lines.append('')

        self._line = max(len(lines), 1) if line is None else line
        if not (0 < self._line <= len(lines)):
            raise ValueError('`line` parameter is not in a valid range.')

        line_len = len(lines[self._line - 1])
        self._column = line_len if column is None else column
        if not (0 <= self._column <= line_len):
            raise ValueError('`column` parameter is not in a valid range.')

        api_classes._clear_caches()
        debug.reset_time()
        self.source = modules.source_to_unicode(source, encoding)
        self._pos = self._line, self._column
        self._module = modules.ModuleWithCursor(
            path, source=self.source, position=self._pos)
        self._source_path = path
        self.path = None if path is None else os.path.abspath(path)
        debug.speed('init')
Пример #5
0
def extract(script, new_name):
    """ The `args` / `kwargs` params are the same as in `api.Script`.
    :param operation: The refactoring operation to execute.
    :type operation: str
    :type source: str
    :return: list of changed lines/changed files
    """
    new_lines = modules.source_to_unicode(script.source).splitlines()
    old_lines = new_lines[:]

    user_stmt = script._parser.user_stmt

    # TODO care for multiline extracts
    dct = {}
    if user_stmt:
        pos = script.pos
        line_index = pos[0] - 1
        arr, index = helpers.array_for_pos(user_stmt, pos)
        if arr is not None:
            start_pos = arr[index].start_pos
            end_pos = arr[index].end_pos

            # take full line if the start line is different from end line
            e = end_pos[1] if end_pos[0] == start_pos[0] else None
            start_line = new_lines[start_pos[0] - 1]
            text = start_line[start_pos[1]:e]
            for l in range(start_pos[0], end_pos[0] - 1):
                text += '\n' + l
            if e is None:
                end_line = new_lines[end_pos[0] - 1]
                text += '\n' + end_line[:end_pos[1]]

            # remove code from new lines
            t = text.lstrip()
            del_start = start_pos[1] + len(text) - len(t)

            text = t.rstrip()
            del_end = len(t) - len(text)
            if e is None:
                new_lines[end_pos[0] - 1] = end_line[end_pos[1] - del_end:]
                e = len(start_line)
            else:
                e = e - del_end
            start_line = start_line[:del_start] + new_name + start_line[e:]
            new_lines[start_pos[0] - 1] = start_line
            new_lines[start_pos[0]:end_pos[0] - 1] = []

            # add parentheses in multiline case
            open_brackets = ['(', '[', '{']
            close_brackets = [')', ']', '}']
            if '\n' in text and not (text[0] in open_brackets and text[-1] ==
                                     close_brackets[open_brackets.index(text[0])]):
                text = '(%s)' % text

            # add new line before statement
            indent = user_stmt.start_pos[1]
            new = "%s%s = %s" % (' ' * indent, new_name, text)
            new_lines.insert(line_index, new)
    dct[script.path] = script.path, old_lines, new_lines
    return Refactoring(dct)
Пример #6
0
def extract(script, new_name):
    """ The `args` / `kwargs` params are the same as in `api.Script`.
    :param operation: The refactoring operation to execute.
    :type operation: str
    :type source: str
    :return: list of changed lines/changed files
    """
    new_lines = modules.source_to_unicode(script.source).splitlines()
    old_lines = new_lines[:]

    user_stmt = script._parser.user_stmt

    # TODO care for multiline extracts
    dct = {}
    if user_stmt:
        pos = script._pos
        line_index = pos[0] - 1
        arr, index = helpers.array_for_pos(user_stmt, pos)
        if arr is not None:
            start_pos = arr[index].start_pos
            end_pos = arr[index].end_pos

            # take full line if the start line is different from end line
            e = end_pos[1] if end_pos[0] == start_pos[0] else None
            start_line = new_lines[start_pos[0] - 1]
            text = start_line[start_pos[1]:e]
            for l in range(start_pos[0], end_pos[0] - 1):
                text += '\n' + l
            if e is None:
                end_line = new_lines[end_pos[0] - 1]
                text += '\n' + end_line[:end_pos[1]]

            # remove code from new lines
            t = text.lstrip()
            del_start = start_pos[1] + len(text) - len(t)

            text = t.rstrip()
            del_end = len(t) - len(text)
            if e is None:
                new_lines[end_pos[0] - 1] = end_line[end_pos[1] - del_end:]
                e = len(start_line)
            else:
                e = e - del_end
            start_line = start_line[:del_start] + new_name + start_line[e:]
            new_lines[start_pos[0] - 1] = start_line
            new_lines[start_pos[0]:end_pos[0] - 1] = []

            # add parentheses in multiline case
            open_brackets = ['(', '[', '{']
            close_brackets = [')', ']', '}']
            if '\n' in text and not (text[0] in open_brackets and text[-1] ==
                                     close_brackets[open_brackets.index(text[0])]):
                text = '(%s)' % text

            # add new line before statement
            indent = user_stmt.start_pos[1]
            new = "%s%s = %s" % (' ' * indent, new_name, text)
            new_lines.insert(line_index, new)
    dct[script.path] = script.path, old_lines, new_lines
    return Refactoring(dct)
Пример #7
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")
Пример #8
0
def defined_names(source, source_path=None, source_encoding="utf-8"):
    """
    Get all definitions in `source` sorted by its position.

    This functions can be used for listing functions, classes and
    data defined in a file.  This can be useful if you want to list
    them in "sidebar".  Each element in the returned list also has
    `defined_names` method which can be used to get sub-definitions
    (e.g., methods in class).

    :rtype: list of api_classes.Definition
    """
    parser = parsing.Parser(modules.source_to_unicode(source, source_encoding), module_path=source_path)
    return api_classes._defined_names(parser.scope)
Пример #9
0
Файл: api.py Проект: lvh/jedi
    def __init__(self, source, line=None, column=None, source_path=None,
                 source_encoding='utf-8'):
        lines = source.splitlines()
        line = len(lines) if line is None else line
        column = len(lines[-1]) if column is None else column

        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')
Пример #10
0
def inline(script):
    """
    :type script: api.Script
    """
    new_lines = modules.source_to_unicode(script.source).splitlines()

    dct = {}

    definitions = script.goto()
    with common.ignored(AssertionError):
        assert len(definitions) == 1
        stmt = definitions[0]._definition
        usages = script.usages()
        inlines = [
            r for r in usages
            if not stmt.start_pos <= r.start_pos <= stmt.end_pos
        ]
        inlines = sorted(inlines,
                         key=lambda x: (x.module_path, x.start_pos),
                         reverse=True)
        commands = stmt.get_commands()
        # don't allow multiline refactorings for now.
        assert stmt.start_pos[0] == stmt.end_pos[0]
        index = stmt.start_pos[0] - 1

        line = new_lines[index]
        replace_str = line[commands[0].start_pos[1]:stmt.end_pos[1] + 1]
        replace_str = replace_str.strip()
        # tuples need parentheses
        if commands and isinstance(commands[0], pr.Array):
            arr = commands[0]
            if replace_str[0] not in ['(', '[', '{'] and len(arr) > 1:
                replace_str = '(%s)' % replace_str

        # if it's the only assignment, remove the statement
        if len(stmt.set_vars) == 1:
            line = line[:stmt.start_pos[1]] + line[stmt.end_pos[1]:]

        dct = _rename(inlines, replace_str)
        # remove the empty line
        new_lines = dct[script.source_path][2]
        if line.strip():
            new_lines[index] = line
        else:
            new_lines.pop(index)

    return Refactoring(dct)
Пример #11
0
def inline(script):
    """
    :type script: api.Script
    """
    new_lines = modules.source_to_unicode(script.source).splitlines()

    dct = {}

    definitions = script.goto()
    try:
        assert len(definitions) == 1
        stmt = definitions[0].definition
        related_names = script.related_names()
        inlines = [r for r in related_names
                        if not stmt.start_pos <= r.start_pos <= stmt.end_pos]
        inlines = sorted(inlines, key=lambda x: (x.module_path, x.start_pos),
                                                reverse=True)
        commands = stmt.get_commands()
        # don't allow multiline refactorings for now.
        assert stmt.start_pos[0] == stmt.end_pos[0]
        index = stmt.start_pos[0] - 1

        line = new_lines[index]
        replace_str = line[commands[0].start_pos[1]:stmt.end_pos[1] + 1]
        replace_str = replace_str.strip()
        # tuples need parentheses
        if commands and isinstance(commands[0], pr.Array):
            arr = commands[0]
            if replace_str[0] not in ['(', '[', '{'] and len(arr) > 1:
                replace_str = '(%s)' % replace_str

        # if it's the only assignment, remove the statement
        if len(stmt.set_vars) == 1:
            line = line[:stmt.start_pos[1]] + line[stmt.end_pos[1]:]

        dct = _rename(inlines, replace_str)
        # remove the empty line
        new_lines = dct[script.source_path][2]
        if line.strip():
            new_lines[index] = line
        else:
            new_lines.pop(index)

    except AssertionError:
        pass

    return Refactoring(dct)
Пример #12
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')
Пример #13
0
def defined_names(source, path=None, source_encoding='utf-8'):
    """
    Get all definitions in `source` sorted by its position.

    This functions can be used for listing functions, classes and
    data defined in a file.  This can be useful if you want to list
    them in "sidebar".  Each element in the returned list also has
    `defined_names` method which can be used to get sub-definitions
    (e.g., methods in class).

    :rtype: list of api_classes.Definition
    """
    parser = Parser(
        modules.source_to_unicode(source, source_encoding),
        module_path=path,
    )
    return api_classes._defined_names(parser.module)
Пример #14
0
    def __init__(self, source, line=None, column=None, path=None,
                 source_encoding='utf-8', source_path=None):
        if source_path is not None:
            warnings.warn("Use path instead of source_path.", DeprecationWarning)
            path = source_path

        lines = source.splitlines()
        if source and source[-1] == '\n':
            lines.append('')

        self._line = max(len(lines), 1) if line is None else line
        self._column = len(lines[-1]) if column is None else column

        api_classes._clear_caches()
        debug.reset_time()
        self.source = modules.source_to_unicode(source, source_encoding)
        self.pos = self._line, self._column
        self._module = modules.ModuleWithCursor(
            path, source=self.source, position=self.pos)
        self._source_path = path
        self.path = None if path is None else os.path.abspath(path)
        debug.speed('init')
Пример #15
0
    def __init__(self,
                 source=None,
                 line=None,
                 column=None,
                 path=None,
                 source_encoding='utf-8',
                 source_path=None):
        if source_path is not None:
            warnings.warn("Use path instead of source_path.",
                          DeprecationWarning)
            path = source_path

        if source is None:
            with open(path) as f:
                source = f.read()

        lines = source.splitlines() or ['']
        if source and source[-1] == '\n':
            lines.append('')

        self._line = max(len(lines), 1) if line is None else line
        if not (0 < self._line <= len(lines)):
            raise ValueError('`line` parameter is not in a valid range.')

        line_len = len(lines[self._line - 1])
        self._column = line_len if column is None else column
        if not (0 <= self._column <= line_len):
            raise ValueError('`column` parameter is not in a valid range.')

        api_classes._clear_caches()
        debug.reset_time()
        self.source = modules.source_to_unicode(source, source_encoding)
        self._pos = self._line, self._column
        self._module = modules.ModuleWithCursor(path,
                                                source=self.source,
                                                position=self._pos)
        self._source_path = path
        self.path = None if path is None else os.path.abspath(path)
        debug.speed('init')
Пример #16
0
 def check_fs(path):
     with open(path) as f:
         source = modules.source_to_unicode(f.read())
         if name in source:
             return modules.Module(path, source).parser.module
Пример #17
0
 def check_fs(path):
     with open(path) as f:
         source = modules.source_to_unicode(f.read())
         if name in source:
             return modules.Module(path, source).parser.module