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