forked from VimPlug/jedi
Change implementation of StatementElement.
Instead of having both next and execution as attributes, we now only have next, because it's an execution if there's an array.
This commit is contained in:
@@ -22,7 +22,7 @@ def usages(evaluator, definitions, search_name, mods):
|
||||
while not stmt.parent.is_scope():
|
||||
stmt = stmt.parent
|
||||
# New definition, call cannot be a part of stmt
|
||||
if len(call.name) == 1 and call.execution is None \
|
||||
if len(call.name) == 1 and call.next is None \
|
||||
and call.name in stmt.get_defined_names():
|
||||
# Class params are not definitions (like function params). They
|
||||
# are super classes, that need to be resolved.
|
||||
|
||||
@@ -243,7 +243,7 @@ def save_parser(path, name, parser, pickling=True):
|
||||
|
||||
class ParserPickling(object):
|
||||
|
||||
version = 14
|
||||
version = 15
|
||||
"""
|
||||
Version number (integer) for file system cache.
|
||||
|
||||
|
||||
@@ -161,7 +161,8 @@ def _check_for_exception_catch(evaluator, jedi_obj, exception, payload=None):
|
||||
assert len(expression_list) == 1
|
||||
call = expression_list[0]
|
||||
assert isinstance(call, pr.Call) and str(call.name) == 'hasattr'
|
||||
execution = call.execution
|
||||
assert call.next_is_execution()
|
||||
execution = call.next
|
||||
assert execution and len(execution) == 2
|
||||
|
||||
# check if the names match
|
||||
|
||||
@@ -187,7 +187,7 @@ class NameFinder(object):
|
||||
# Compare start_pos, because names may be different
|
||||
# because of executions.
|
||||
if c.name.start_pos == name.start_pos \
|
||||
and c.execution:
|
||||
and isinstance(c.next, pr.Array):
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -391,10 +391,10 @@ def _check_isinstance_type(evaluator, stmt, search_name_part):
|
||||
assert len(expression_list) == 1
|
||||
call = expression_list[0]
|
||||
assert isinstance(call, pr.Call) and str(call.name) == 'isinstance'
|
||||
assert bool(call.execution)
|
||||
assert call.next_is_execution()
|
||||
|
||||
# isinstance check
|
||||
isinst = call.execution.values
|
||||
isinst = call.next.values
|
||||
assert len(isinst) == 2 # has two params
|
||||
obj, classes = [statement.expression_list() for statement in isinst]
|
||||
assert len(obj) == 1
|
||||
|
||||
@@ -96,11 +96,11 @@ def call_signature_array_for_pos(stmt, pos):
|
||||
# Since we need the index, we duplicate efforts (with empty
|
||||
# arrays).
|
||||
if arr.start_pos < pos <= stmt.end_pos:
|
||||
if arr.type in accepted_types and isinstance(origin_call, pr.Call):
|
||||
if arr.type in accepted_types and origin_call:
|
||||
return arr, i, origin_call
|
||||
|
||||
if len(arr) == 0 and arr.start_pos < pos < arr.end_pos:
|
||||
if arr.type in accepted_types and isinstance(origin_call, pr.Call):
|
||||
if arr.type in accepted_types and origin_call:
|
||||
return arr, 0, origin_call
|
||||
return None, 0, None
|
||||
|
||||
@@ -109,8 +109,6 @@ def call_signature_array_for_pos(stmt, pos):
|
||||
if call.next is not None:
|
||||
method = search_array if isinstance(call.next, pr.Array) else search_call
|
||||
tup = method(call.next, pos, origin_call or call)
|
||||
if not tup[0] and call.execution is not None:
|
||||
tup = search_array(call.execution, pos, origin_call)
|
||||
return tup
|
||||
|
||||
if stmt.start_pos >= pos >= stmt.end_pos:
|
||||
@@ -142,11 +140,9 @@ def search_call_signatures(user_stmt, position):
|
||||
# statement.
|
||||
stmt_el = call
|
||||
while isinstance(stmt_el, pr.StatementElement):
|
||||
if stmt_el.execution == arr:
|
||||
stmt_el.execution = None
|
||||
if stmt_el.next == arr:
|
||||
stmt_el.next = None
|
||||
break
|
||||
|
||||
stmt_el = stmt_el.next
|
||||
|
||||
debug.speed('func_call parsed')
|
||||
@@ -178,13 +174,14 @@ def scan_statement_for_calls(stmt, search_name, assignment_details=False):
|
||||
elif isinstance(c, pr.Call):
|
||||
s_new = c
|
||||
while s_new is not None:
|
||||
n = s_new.name
|
||||
if isinstance(n, pr.Name) \
|
||||
and search_name in [str(x) for x in n.names]:
|
||||
result.append(c)
|
||||
if isinstance(s_new, pr.Array):
|
||||
result += scan_array(s_new, search_name)
|
||||
else:
|
||||
n = s_new.name
|
||||
if isinstance(n, pr.Name) \
|
||||
and search_name in [str(x) for x in n.names]:
|
||||
result.append(c)
|
||||
|
||||
if s_new.execution is not None:
|
||||
result += scan_array(s_new.execution, search_name)
|
||||
s_new = s_new.next
|
||||
elif isinstance(c, pr.ListComprehension):
|
||||
for s in c.stmt, c.middle, c.input:
|
||||
|
||||
@@ -71,17 +71,20 @@ def _paths_from_insert(module_path, exe):
|
||||
""" extract the inserted module path from an "sys.path.insert" statement
|
||||
"""
|
||||
exe_type, exe.type = exe.type, pr.Array.NOARRAY
|
||||
exe_pop = exe.values.pop(0)
|
||||
res = _execute_code(module_path, exe.get_code())
|
||||
exe.type = exe_type
|
||||
try:
|
||||
exe_pop = exe.values.pop(0)
|
||||
res = _execute_code(module_path, exe.get_code())
|
||||
finally:
|
||||
exe.type = exe_type
|
||||
exe.values.insert(0, exe_pop)
|
||||
return res
|
||||
|
||||
|
||||
def _paths_from_call_expression(module_path, call):
|
||||
""" extract the path from either "sys.path.append" or "sys.path.insert" """
|
||||
if call.execution is None:
|
||||
if not call.next_is_execution():
|
||||
return
|
||||
|
||||
n = call.name
|
||||
if not isinstance(n, pr.Name) or len(n.names) != 3:
|
||||
return
|
||||
@@ -89,7 +92,7 @@ def _paths_from_call_expression(module_path, call):
|
||||
if names[:2] != ['sys', 'path']:
|
||||
return
|
||||
cmd = names[2]
|
||||
exe = call.execution
|
||||
exe = call.next
|
||||
if cmd == 'insert' and len(exe) == 2:
|
||||
path = _paths_from_insert(module_path, exe)
|
||||
elif cmd == 'append' and len(exe) == 1:
|
||||
@@ -109,10 +112,8 @@ def _check_module(module):
|
||||
if len(expressions) == 1 and isinstance(expressions[0], pr.Call):
|
||||
sys_path.extend(
|
||||
_paths_from_call_expression(module.path, expressions[0]) or [])
|
||||
elif (
|
||||
hasattr(stmt, 'assignment_details') and
|
||||
len(stmt.assignment_details) == 1
|
||||
):
|
||||
elif hasattr(stmt, 'assignment_details') \
|
||||
and len(stmt.assignment_details) == 1:
|
||||
sys_path.extend(_paths_from_assignment(stmt) or [])
|
||||
return sys_path
|
||||
|
||||
|
||||
@@ -952,7 +952,8 @@ class Statement(Simple, DocstringMixin):
|
||||
# not a set_var.
|
||||
is_execution = False
|
||||
while c:
|
||||
if Array.is_type(c.execution, Array.TUPLE):
|
||||
# TODO use StatementElement.next_is_execution
|
||||
if Array.is_type(c.next, Array.TUPLE):
|
||||
is_execution = True
|
||||
c = c.next
|
||||
if is_execution:
|
||||
@@ -1194,7 +1195,7 @@ class Statement(Simple, DocstringMixin):
|
||||
token_iterator, brackets[tok.string], tok.start_pos
|
||||
)
|
||||
if result and isinstance(result[-1], StatementElement):
|
||||
result[-1].set_execution(arr)
|
||||
result[-1].set_next(arr)
|
||||
else:
|
||||
arr.parent = self
|
||||
result.append(arr)
|
||||
@@ -1264,7 +1265,7 @@ class Param(Statement):
|
||||
|
||||
|
||||
class StatementElement(Simple):
|
||||
__slots__ = ('parent', 'next', 'execution')
|
||||
__slots__ = ('parent', 'next')
|
||||
|
||||
def __init__(self, module, start_pos, end_pos, parent):
|
||||
super(StatementElement, self).__init__(module, start_pos, end_pos)
|
||||
@@ -1273,7 +1274,6 @@ class StatementElement(Simple):
|
||||
# be an array.
|
||||
self.parent = parent
|
||||
self.next = None
|
||||
self.execution = None
|
||||
|
||||
def set_next(self, call):
|
||||
""" Adds another part of the statement"""
|
||||
@@ -1283,18 +1283,8 @@ class StatementElement(Simple):
|
||||
else:
|
||||
self.next = call
|
||||
|
||||
def set_execution(self, call):
|
||||
"""
|
||||
An execution is nothing else than brackets, with params in them, which
|
||||
shows access on the internals of this name.
|
||||
"""
|
||||
call.parent = self.parent
|
||||
if self.next is not None:
|
||||
self.next.set_execution(call)
|
||||
elif self.execution is not None:
|
||||
self.execution.set_execution(call)
|
||||
else:
|
||||
self.execution = call
|
||||
def next_is_execution(self):
|
||||
return Array.is_type(self.next, Array.TUPLE, Array.NOARRAY)
|
||||
|
||||
def generate_call_path(self):
|
||||
""" Helps to get the order in which statements are executed. """
|
||||
@@ -1303,20 +1293,15 @@ class StatementElement(Simple):
|
||||
yield name_part
|
||||
except AttributeError:
|
||||
yield self
|
||||
if self.execution is not None:
|
||||
for y in self.execution.generate_call_path():
|
||||
yield y
|
||||
if self.next is not None:
|
||||
for y in self.next.generate_call_path():
|
||||
yield y
|
||||
|
||||
def get_code(self):
|
||||
s = ''
|
||||
if self.execution is not None:
|
||||
s += self.execution.get_code()
|
||||
if self.next is not None:
|
||||
s += '.' + self.next.get_code()
|
||||
return s
|
||||
s = '.' if isinstance(self, Array) else ''
|
||||
return s + self.next.get_code()
|
||||
return ''
|
||||
|
||||
|
||||
class Call(StatementElement):
|
||||
|
||||
Reference in New Issue
Block a user