diff --git a/jedi/api.py b/jedi/api.py index 86e1feec..fa16d4ba 100644 --- a/jedi/api.py +++ b/jedi/api.py @@ -358,7 +358,7 @@ class Script(object): return None, 0 ass = helpers.fast_parent_copy(user_stmt.get_assignment_calls()) - call, index, stop = helpers.scan_array_for_pos(ass, self.pos) + call, index, stop = helpers.scan_array_for_pos(ass, self.pos, True) return call, index def check_cache(): diff --git a/jedi/helpers.py b/jedi/helpers.py index 99075ac1..154d3879 100644 --- a/jedi/helpers.py +++ b/jedi/helpers.py @@ -199,10 +199,11 @@ def generate_param_array(args_tuple, parent_stmt=None): return arr -def scan_array_for_pos(arr, pos): +def scan_array_for_pos(arr, pos, overwrite_after=False): """ - Returns the function Call that match search_name in an Array. - Makes changes to arr! + Returns the function Call that matches the position before `arr`. + This is somehow stupid, probably only the name of the function. + :param overwrite_after: Overwrite every statement after the found array. """ def check_arr_index(): positions = arr.arr_el_pos @@ -245,8 +246,9 @@ def scan_array_for_pos(arr, pos): parsing.Array.NOARRAY]: return start_s, index, False - reset.execution = None - reset.next = None + if overwrite_after: + reset.execution = None + reset.next = None return c or start_s, index, True s = s.next diff --git a/jedi/refactoring.py b/jedi/refactoring.py index 0e48f280..ecc18eab 100644 --- a/jedi/refactoring.py +++ b/jedi/refactoring.py @@ -3,6 +3,7 @@ import api import modules import difflib +import helpers class Refactoring(object): @@ -77,3 +78,46 @@ def rename(new_name, source, *args, **kwargs): process(current_path, old_lines, new_lines) return Refactoring(dct) + + +def extract(new_name, source, *args, **kwargs): + """ 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(source).splitlines() + old_lines = new_lines[:] + + script = api.Script(source, *args, **kwargs) + user_stmt = script._parser.user_stmt + + # TODO care for multiline extracts + dct = {} + if user_stmt: + indent = user_stmt.start_pos[0] + pos = script.pos + line_index = pos[0] - 1 + import parsing + assert isinstance(user_stmt, parsing.Statement) + call, index, stop = helpers.scan_array_for_pos( + user_stmt.get_assignment_calls(), pos) + assert isinstance(call, parsing.Call) + exe = call.execution + if exe: + s = exe.start_pos[0], exe.start_pos[1] + 1 + positions = [s] + call.execution.arr_el_pos + [exe.end_pos] + start_pos = positions[index] + end_pos = positions[index + 1][0], positions[index + 1][1] - 1 + print start_pos, end_pos + text = new_lines[start_pos[0] - 1][start_pos[1]:end_pos[1]] + print text + for l in range(start_pos[0], end_pos[0] - 1): + text + new_lines[start_pos[0]:end_pos[0]-1] + text = user_stmt.start_pos[1], user_stmt.end_pos[1] + new = "%s%s = %s" % (' ' * indent, new_name, text) + new_lines.insert(line_index, new) + dct[script.source_path] = script.source_path, old_lines, new_lines + return Refactoring(dct)