mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
Implement inline refactorings
This commit is contained in:
@@ -562,7 +562,8 @@ class Script(object):
|
||||
"""
|
||||
Inlines a variable under the cursor.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
names = [d._name for d in self.get_references(line, column, include_builtins=True)]
|
||||
return refactoring.inline(self._grammar, names)
|
||||
|
||||
def reorder_imports(self):
|
||||
"""
|
||||
|
||||
@@ -125,3 +125,60 @@ def rename(grammar, definitions, new_name):
|
||||
fmap = file_tree_name_map.setdefault(d.module_path, {})
|
||||
fmap[tree_name] = tree_name.prefix + new_name
|
||||
return Refactoring(grammar, file_tree_name_map, file_renames)
|
||||
|
||||
|
||||
def inline(grammar, names):
|
||||
if not names:
|
||||
raise RefactoringError("There's no name under the cursor")
|
||||
if any(n.api_type == 'module' for n in names):
|
||||
raise RefactoringError("Cannot inline imports or modules.")
|
||||
if any(n.tree_name is None for n in names):
|
||||
raise RefactoringError("Cannot inline builtins.")
|
||||
|
||||
definitions = [n for n in names if n.tree_name.is_definition()]
|
||||
if len(definitions) == 0:
|
||||
raise RefactoringError("No definition found to inline.")
|
||||
if len(definitions) > 1:
|
||||
raise RefactoringError("Cannot inline a name with multiple definitions.")
|
||||
|
||||
tree_name = definitions[0].tree_name
|
||||
|
||||
expr_stmt = tree_name.get_definition()
|
||||
if expr_stmt.type != 'expr_stmt':
|
||||
type_ = dict(
|
||||
funcdef='a function',
|
||||
classdef='a class',
|
||||
).get(expr_stmt.type, expr_stmt.type)
|
||||
raise RefactoringError("Cannot inline %s" % type_)
|
||||
|
||||
if len(expr_stmt.get_defined_names(include_setitem=True)) > 1:
|
||||
raise RefactoringError("Cannot inline a statement with multiple definitions")
|
||||
|
||||
rhs = expr_stmt.get_rhs()
|
||||
replace_code = rhs.get_code(include_prefix=False)
|
||||
|
||||
references = [n for n in names if not n.tree_name.is_definition()]
|
||||
file_to_node_changes = {}
|
||||
for name in references:
|
||||
path = name.get_root_context().py__file__()
|
||||
s = replace_code
|
||||
if rhs.type == 'testlist_star_expr':
|
||||
s = '(' + replace_code + ')'
|
||||
file_to_node_changes.setdefault(path, {})[name.tree_name] = \
|
||||
name.tree_name.prefix + s
|
||||
|
||||
path = definitions[0].get_root_context().py__file__()
|
||||
file_to_node_changes.setdefault(path, {})[expr_stmt] = \
|
||||
_remove_indent_and_newline_of_prefix(expr_stmt.get_first_leaf().prefix)
|
||||
return Refactoring(grammar, file_to_node_changes)
|
||||
|
||||
|
||||
def _remove_indent_and_newline_of_prefix(prefix):
|
||||
r"""
|
||||
Removes the last indentation of a prefix, e.g. " \n \n " becomes " \n \n".
|
||||
"""
|
||||
lines = split_lines(prefix, keepends=True)[:-1]
|
||||
if lines and lines[-1].endswith('\n'):
|
||||
# Remove the newline
|
||||
lines[-1] = lines[-1][:-1]
|
||||
return ''.join(lines)
|
||||
|
||||
@@ -1,20 +1,28 @@
|
||||
# -------------------------------------------------- simple-1
|
||||
# -------------------------------------------------- simple
|
||||
def test():
|
||||
#? 4
|
||||
a = (30 + b, c) + 1
|
||||
return test(100, a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- /home/dave/source/jedi/test/refactor/inline.py
|
||||
+++ /home/dave/source/jedi/test/refactor/inline.py
|
||||
@@ -1,5 +1,4 @@
|
||||
def test():
|
||||
#? 4
|
||||
return test(100, (30 + b, c) + 1)
|
||||
|
||||
|
||||
# -------------------------------------------------- simple-2
|
||||
- a = (30 + b, c) + 1
|
||||
- return test(100, a)
|
||||
+ return test(100, (30 + b, c) + 1)
|
||||
# -------------------------------------------------- tuple
|
||||
if 1:
|
||||
#? 4
|
||||
a = 1, 2
|
||||
return test(100, a)
|
||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
--- /home/dave/source/jedi/test/refactor/inline.py
|
||||
+++ /home/dave/source/jedi/test/refactor/inline.py
|
||||
@@ -1,5 +1,4 @@
|
||||
if 1:
|
||||
#? 4
|
||||
return test(100, (1, 2))
|
||||
- a = 1, 2
|
||||
- return test(100, a)
|
||||
+ return test(100, (1, 2))
|
||||
|
||||
Reference in New Issue
Block a user