1
0
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:
Dave Halter
2014-08-18 22:25:55 +02:00
parent 7619bf27d1
commit 8006d6f190
7 changed files with 36 additions and 52 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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):