mirror of
https://github.com/davidhalter/jedi.git
synced 2026-03-07 06:01:52 +08:00
catched recursions in a special array case
This commit is contained in:
32
dynamic.py
32
dynamic.py
@@ -156,25 +156,27 @@ def _check_array_additions(compare_array, module, is_list):
|
|||||||
scope = c.parent_stmt().parent()
|
scope = c.parent_stmt().parent()
|
||||||
found = evaluate.follow_call_path(backtrack_path, scope, position)
|
found = evaluate.follow_call_path(backtrack_path, scope, position)
|
||||||
if not compare_array in found:
|
if not compare_array in found:
|
||||||
# the `append`, etc. belong to other arrays
|
# Check if the original scope is an execution. If it is, one
|
||||||
|
# can search for the same statement, that is in the module
|
||||||
|
# dict. Executions are somewhat special in jedi, since they
|
||||||
|
# literally copy the contents of a function.
|
||||||
if isinstance(comp_arr_parent, evaluate.Execution):
|
if isinstance(comp_arr_parent, evaluate.Execution):
|
||||||
found_bases = []
|
found_bases = []
|
||||||
for f in found:
|
for f in found:
|
||||||
base = get_execution_parent(f, parsing.Function)
|
base = get_execution_parent(f, parsing.Function)
|
||||||
found_bases.append(base)
|
found_bases.append(base)
|
||||||
#for f in found_bases:
|
|
||||||
#print 'adsf', c.start_pos, found, found_bases
|
|
||||||
if comp_arr_parent.base.base_func in found_bases:
|
if comp_arr_parent.base.base_func in found_bases:
|
||||||
stmt = comp_arr_parent.\
|
stmt = comp_arr_parent. \
|
||||||
get_statement_for_position(c.start_pos)
|
get_statement_for_position(c.start_pos)
|
||||||
if stmt is not None:
|
if stmt is not None:
|
||||||
#print 'LA', stmt.parent(), stmt
|
if evaluate.follow_statement.push_stmt(stmt):
|
||||||
|
# check recursion
|
||||||
|
continue
|
||||||
ass = stmt.get_assignment_calls()
|
ass = stmt.get_assignment_calls()
|
||||||
result += check_calls(scan_array(ass, add_name),
|
new_calls = scan_array(ass, add_name)
|
||||||
add_name)
|
#print [c.start_pos for c in new_calls], stmt.start_pos
|
||||||
#print found_bases, comp_arr_parent.base.base_func
|
result += check_calls(new_calls, add_name)
|
||||||
#print found, found[0]._array.parent_stmt().parent()
|
evaluate.follow_statement.pop_stmt()
|
||||||
#print compare_array_parent.base
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
params = call_path[separate_index + 1]
|
params = call_path[separate_index + 1]
|
||||||
@@ -204,9 +206,7 @@ def _check_array_additions(compare_array, module, is_list):
|
|||||||
|
|
||||||
search_names = ['append', 'extend', 'insert'] if is_list else \
|
search_names = ['append', 'extend', 'insert'] if is_list else \
|
||||||
['add', 'update']
|
['add', 'update']
|
||||||
#print compare_array
|
|
||||||
comp_arr_parent = get_execution_parent(compare_array, evaluate.Execution)
|
comp_arr_parent = get_execution_parent(compare_array, evaluate.Execution)
|
||||||
#print 'par', comp_arr_parent
|
|
||||||
possible_stmts = []
|
possible_stmts = []
|
||||||
result = []
|
result = []
|
||||||
for n in search_names:
|
for n in search_names:
|
||||||
@@ -246,6 +246,9 @@ class ArrayInstance(parsing.Base):
|
|||||||
items = []
|
items = []
|
||||||
#print 'ic', self.var_args, self.var_args.parent_stmt()
|
#print 'ic', self.var_args, self.var_args.parent_stmt()
|
||||||
stmt = self.var_args.parent_stmt()
|
stmt = self.var_args.parent_stmt()
|
||||||
|
#if evaluate.follow_statement.push_stmt(stmt):
|
||||||
|
# check recursion
|
||||||
|
#return []
|
||||||
#if stmt.get_parent_until() == builtin.Builtin.scope:
|
#if stmt.get_parent_until() == builtin.Builtin.scope:
|
||||||
#evaluate.follow_statement.push(stmt)
|
#evaluate.follow_statement.push(stmt)
|
||||||
for array in evaluate.follow_call_list(self.var_args):
|
for array in evaluate.follow_call_list(self.var_args):
|
||||||
@@ -255,11 +258,15 @@ class ArrayInstance(parsing.Base):
|
|||||||
#print items, self, id(self.var_args), id(self.var_args.parent_stmt()), array
|
#print items, self, id(self.var_args), id(self.var_args.parent_stmt()), array
|
||||||
# prevent recursions
|
# prevent recursions
|
||||||
# TODO compare Modules
|
# TODO compare Modules
|
||||||
|
#if evaluate.follow_statement.push_stmt(stmt):
|
||||||
|
# check recursion
|
||||||
|
# continue
|
||||||
if self.var_args.start_pos != temp.var_args.start_pos:
|
if self.var_args.start_pos != temp.var_args.start_pos:
|
||||||
items += temp.iter_content()
|
items += temp.iter_content()
|
||||||
else:
|
else:
|
||||||
debug.warning('ArrayInstance recursion', self.var_args)
|
debug.warning('ArrayInstance recursion', self.var_args)
|
||||||
print 'yippie'
|
print 'yippie'
|
||||||
|
#evaluate.follow_statement.pop_stmt()
|
||||||
continue
|
continue
|
||||||
items += evaluate.get_iterator_types([array])
|
items += evaluate.get_iterator_types([array])
|
||||||
|
|
||||||
@@ -269,4 +276,5 @@ class ArrayInstance(parsing.Base):
|
|||||||
module = self.var_args.parent_stmt().get_parent_until()
|
module = self.var_args.parent_stmt().get_parent_until()
|
||||||
is_list = str(self.instance.name) == 'list'
|
is_list = str(self.instance.name) == 'list'
|
||||||
items += _check_array_additions(self.instance, module, is_list)
|
items += _check_array_additions(self.instance, module, is_list)
|
||||||
|
#evaluate.follow_statement.pop_stmt()
|
||||||
return items
|
return items
|
||||||
|
|||||||
57
helpers.py
57
helpers.py
@@ -15,51 +15,64 @@ class RecursionDecorator(object):
|
|||||||
self.current = None
|
self.current = None
|
||||||
|
|
||||||
def __call__(self, stmt, *args, **kwargs):
|
def __call__(self, stmt, *args, **kwargs):
|
||||||
r = RecursionNode(stmt, self.current)
|
if self.push_stmt(stmt):
|
||||||
|
|
||||||
# Don't check param instances, they are not causing recursions
|
|
||||||
# The same's true for the builtins, because the builtins are really
|
|
||||||
# simple.
|
|
||||||
if isinstance(stmt, parsing.Param) \
|
|
||||||
or (r.script == builtin.Builtin.scope and
|
|
||||||
stmt.start_pos[0] != 538000):
|
|
||||||
return self.func(stmt, *args, **kwargs)
|
|
||||||
if r.script == builtin.Builtin.scope:
|
|
||||||
print 'rec_catch', stmt, stmt.parent().parent()
|
|
||||||
#print stmt
|
|
||||||
|
|
||||||
if self._check_recursion(r):
|
|
||||||
debug.warning('catched recursion', stmt, args, kwargs)
|
|
||||||
return []
|
return []
|
||||||
parent, self.current = self.current, r
|
else:
|
||||||
result = self.func(stmt, *args, **kwargs)
|
result = self.func(stmt, *args, **kwargs)
|
||||||
self.current = parent
|
self.pop_stmt()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _check_recursion(self, new):
|
def push_stmt(self, stmt):
|
||||||
|
self.current = RecursionNode(stmt, self.current)
|
||||||
|
if self._check_recursion():
|
||||||
|
debug.warning('catched recursion', stmt)
|
||||||
|
self.pop_stmt()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def pop_stmt(self):
|
||||||
|
self.current = self.current.parent
|
||||||
|
|
||||||
|
def _check_recursion(self):
|
||||||
test = self.current
|
test = self.current
|
||||||
while True:
|
while True:
|
||||||
if new == test:
|
test = test.parent
|
||||||
|
if self.current == test:
|
||||||
return True
|
return True
|
||||||
if not test:
|
if not test:
|
||||||
return False
|
return False
|
||||||
test = test.parent
|
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.top = None
|
self.top = None
|
||||||
self.current = None
|
self.current = None
|
||||||
|
|
||||||
|
def node_statements(self):
|
||||||
|
result = []
|
||||||
|
n = self.current
|
||||||
|
while n:
|
||||||
|
result.append(n.stmt)
|
||||||
|
n = n.parent
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class RecursionNode(object):
|
class RecursionNode(object):
|
||||||
def __init__(self, stmt, parent):
|
def __init__(self, stmt, parent):
|
||||||
self.script = stmt.get_parent_until()
|
self.script = stmt.get_parent_until()
|
||||||
self.position = stmt.start_pos
|
self.position = stmt.start_pos
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
self.stmt = stmt
|
||||||
|
|
||||||
|
# Don't check param instances, they are not causing recursions
|
||||||
|
# The same's true for the builtins, because the builtins are really
|
||||||
|
# simple.
|
||||||
|
self.is_ignored = isinstance(stmt, parsing.Param) \
|
||||||
|
or (self.script == builtin.Builtin.scope)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if not other:
|
if not other:
|
||||||
return None
|
return None
|
||||||
return self.script == other.script and self.position == other.position
|
return self.script == other.script \
|
||||||
|
and self.position == other.position and not self.is_ignored
|
||||||
|
|
||||||
|
|
||||||
def fast_parent_copy(obj):
|
def fast_parent_copy(obj):
|
||||||
|
|||||||
@@ -299,6 +299,28 @@ def blub():
|
|||||||
|
|
||||||
#? int()
|
#? int()
|
||||||
blub()[0]
|
blub()[0]
|
||||||
|
# -----------------
|
||||||
|
# returns, the same for classes
|
||||||
|
# -----------------
|
||||||
|
class C():
|
||||||
|
def blub(self, b):
|
||||||
|
if 1:
|
||||||
|
a = []
|
||||||
|
a.append(b)
|
||||||
|
return a
|
||||||
|
|
||||||
|
def blub2(self):
|
||||||
|
""" mapper function """
|
||||||
|
a = self.blub(1.0)
|
||||||
|
#? float()
|
||||||
|
a[0]
|
||||||
|
return a
|
||||||
|
|
||||||
|
#? int()
|
||||||
|
C().blub(1)[0]
|
||||||
|
|
||||||
|
#? float()
|
||||||
|
C().blub2(1)[0]
|
||||||
|
|
||||||
# -----------------
|
# -----------------
|
||||||
# array recursions
|
# array recursions
|
||||||
@@ -314,15 +336,20 @@ list(a)[0]
|
|||||||
def first(a):
|
def first(a):
|
||||||
b = []
|
b = []
|
||||||
b.append(a)
|
b.append(a)
|
||||||
#b.extend(second(a))
|
b.extend(second(a))
|
||||||
return b
|
return list(b)
|
||||||
|
|
||||||
def second(a):
|
def second(a):
|
||||||
b = []
|
b = []
|
||||||
b.append(a)
|
|
||||||
b.extend(first(a))
|
b.extend(first(a))
|
||||||
b.extend(second(a))
|
|
||||||
return list(b)
|
return list(b)
|
||||||
|
|
||||||
#? float()
|
#? float()
|
||||||
first(1.0)[0]
|
first(1.0)[0]
|
||||||
|
|
||||||
|
def third():
|
||||||
|
b = []
|
||||||
|
b.extend(first())
|
||||||
|
return list(b)
|
||||||
|
#?
|
||||||
|
third()[0]
|
||||||
|
|||||||
Reference in New Issue
Block a user