mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
Fix an extract case about "not"
This commit is contained in:
@@ -5,6 +5,7 @@ import difflib
|
|||||||
|
|
||||||
from parso import split_lines
|
from parso import split_lines
|
||||||
|
|
||||||
|
from jedi import debug
|
||||||
from jedi.api.exceptions import RefactoringError
|
from jedi.api.exceptions import RefactoringError
|
||||||
from jedi.common.utils import indent_block
|
from jedi.common.utils import indent_block
|
||||||
|
|
||||||
@@ -222,35 +223,48 @@ def inline(grammar, names):
|
|||||||
|
|
||||||
|
|
||||||
def extract_variable(grammar, path, module_node, new_name, pos, until_pos):
|
def extract_variable(grammar, path, module_node, new_name, pos, until_pos):
|
||||||
start_leaf = module_node.get_leaf_for_position(pos, include_prefixes=True)
|
start_node = module_node.get_leaf_for_position(pos, include_prefixes=True)
|
||||||
if start_leaf.type == 'operator':
|
|
||||||
next_leaf = start_leaf.get_next_leaf()
|
|
||||||
if next_leaf is not None and next_leaf.start_pos == pos:
|
|
||||||
start_leaf = next_leaf
|
|
||||||
if until_pos is None:
|
if until_pos is None:
|
||||||
node = start_leaf
|
if start_node.type == 'operator':
|
||||||
if node.type == 'operator':
|
next_leaf = start_node.get_next_leaf()
|
||||||
node = node.parent
|
if next_leaf is not None and next_leaf.start_pos == pos:
|
||||||
while node.parent.type in _EXTRACT_USE_PARENT:
|
start_node = next_leaf
|
||||||
node = node.parent
|
|
||||||
start_leaf
|
if _is_not_extractable_syntax(start_node):
|
||||||
nodes = [node]
|
start_node = start_node.parent
|
||||||
|
|
||||||
|
while start_node.parent.type in _EXTRACT_USE_PARENT:
|
||||||
|
start_node = start_node.parent
|
||||||
|
nodes = [start_node]
|
||||||
else:
|
else:
|
||||||
|
# Get the next leaf if we are at the end of a leaf
|
||||||
|
if start_node.end_pos == pos:
|
||||||
|
next_leaf = start_node.get_next_leaf()
|
||||||
|
if next_leaf is not None:
|
||||||
|
start_node = next_leaf
|
||||||
|
|
||||||
|
# Some syntax is not exactable, just use its parent
|
||||||
|
if _is_not_extractable_syntax(start_node):
|
||||||
|
start_node = start_node.parent
|
||||||
|
|
||||||
|
# Find the end
|
||||||
end_leaf = module_node.get_leaf_for_position(until_pos, include_prefixes=True)
|
end_leaf = module_node.get_leaf_for_position(until_pos, include_prefixes=True)
|
||||||
if end_leaf.start_pos > until_pos:
|
if end_leaf.start_pos > until_pos:
|
||||||
end_leaf = end_leaf.get_previous_leaf()
|
end_leaf = end_leaf.get_previous_leaf()
|
||||||
if end_leaf is None:
|
if end_leaf is None:
|
||||||
raise RefactoringError('Cannot extract anything from that')
|
raise RefactoringError('Cannot extract anything from that')
|
||||||
parent_node = start_leaf
|
|
||||||
|
parent_node = start_node
|
||||||
while parent_node.end_pos < end_leaf.end_pos:
|
while parent_node.end_pos < end_leaf.end_pos:
|
||||||
parent_node = parent_node.parent
|
parent_node = parent_node.parent
|
||||||
|
|
||||||
nodes = _remove_unwanted_expression_nodes(parent_node, pos, until_pos)
|
nodes = _remove_unwanted_expression_nodes(parent_node, pos, until_pos)
|
||||||
|
|
||||||
if any(node.type == 'name' and node.is_definition() for node in nodes):
|
if any(node.type == 'name' and node.is_definition() for node in nodes):
|
||||||
raise RefactoringError('Cannot extract a name that defines something')
|
raise RefactoringError('Cannot extract a name that defines something')
|
||||||
if nodes[0].type not in _VARIABLE_EXCTRACTABLE \
|
debug.dbg('Extracting nodes: %s', nodes)
|
||||||
or nodes[0].type == 'keyword' and nodes[0].value not in ('None', 'True', 'False'):
|
if nodes[0].type not in _VARIABLE_EXCTRACTABLE:
|
||||||
print(nodes)
|
|
||||||
raise RefactoringError('Cannot extract a "%s"' % nodes[0].type)
|
raise RefactoringError('Cannot extract a "%s"' % nodes[0].type)
|
||||||
|
|
||||||
definition = _get_parent_definition(nodes[0])
|
definition = _get_parent_definition(nodes[0])
|
||||||
@@ -317,9 +331,21 @@ def _remove_unwanted_expression_nodes(parent_node, pos, until_pos):
|
|||||||
end_index = i
|
end_index = i
|
||||||
if n.type == 'operator':
|
if n.type == 'operator':
|
||||||
end_index += 1
|
end_index += 1
|
||||||
|
|
||||||
|
# Something like `not foo or bar` should not be cut after not
|
||||||
|
for n in nodes[i:]:
|
||||||
|
if _is_not_extractable_syntax(n):
|
||||||
|
end_index += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
break
|
break
|
||||||
nodes = nodes[start_index:end_index + 1]
|
nodes = nodes[start_index:end_index + 1]
|
||||||
nodes[0:1] = _remove_unwanted_expression_nodes(nodes[0], pos, until_pos)
|
nodes[0:1] = _remove_unwanted_expression_nodes(nodes[0], pos, until_pos)
|
||||||
nodes[-1:] = _remove_unwanted_expression_nodes(nodes[-1], pos, until_pos)
|
nodes[-1:] = _remove_unwanted_expression_nodes(nodes[-1], pos, until_pos)
|
||||||
return nodes
|
return nodes
|
||||||
return [parent_node]
|
return [parent_node]
|
||||||
|
|
||||||
|
|
||||||
|
def _is_not_extractable_syntax(node):
|
||||||
|
return node.type == 'operator' \
|
||||||
|
or node.type == 'keyword' and node.value not in ('None', 'True', 'False')
|
||||||
|
|||||||
@@ -97,12 +97,12 @@ class Foo(x):
|
|||||||
#? 12 error {'new_name': 'x'}
|
#? 12 error {'new_name': 'x'}
|
||||||
def x(): pass
|
def x(): pass
|
||||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
Cannot extract a "keyword"
|
Cannot extract a "simple_stmt"
|
||||||
# -------------------------------------------------- keyword-continue
|
# -------------------------------------------------- keyword-continue
|
||||||
#? 5 error {'new_name': 'x'}
|
#? 5 error {'new_name': 'x'}
|
||||||
continue
|
continue
|
||||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
Cannot extract a "keyword"
|
Cannot extract a "simple_stmt"
|
||||||
# -------------------------------------------------- keyword-None
|
# -------------------------------------------------- keyword-None
|
||||||
if 1:
|
if 1:
|
||||||
#? 4 text {'new_name': 'x'}
|
#? 4 text {'new_name': 'x'}
|
||||||
@@ -219,3 +219,10 @@ Cannot extract a "if_stmt"
|
|||||||
x = foo = 4
|
x = foo = 4
|
||||||
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
Cannot extract a name that defines something
|
Cannot extract a name that defines something
|
||||||
|
# -------------------------------------------------- keyword-None
|
||||||
|
#? 4 text {'new_name': 'x', 'until_column': 7}
|
||||||
|
yy = not foo or bar
|
||||||
|
# ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
#? 4 text {'new_name': 'x', 'until_column': 7}
|
||||||
|
x = not foo
|
||||||
|
yy = x or bar
|
||||||
|
|||||||
Reference in New Issue
Block a user