dynamic arrays in executions and instances should now work fully, some things got simplified, now it works.

This commit is contained in:
David Halter
2012-08-27 11:34:37 +02:00
parent 0d9a6282e7
commit 33e5850105
7 changed files with 67 additions and 28 deletions

View File

@@ -45,6 +45,7 @@ class ParamListener(object):
self.param_possibilities.append(params) self.param_possibilities.append(params)
@evaluate.memoize_default([])
def search_params(param): def search_params(param):
""" """
This is a dynamic search for params. If you try to complete a type: This is a dynamic search for params. If you try to complete a type:
@@ -123,6 +124,18 @@ def check_array_additions(array):
res = _check_array_additions(array, current_module, is_list) res = _check_array_additions(array, current_module, is_list)
return res return res
counter = 0
def dec(func):
def wrapper(*args, **kwargs):
global counter
a = args[0]._array.parent_stmt()
print ' '*counter + 'recursion,', a, id(a)
counter += 1
res = func(*args, **kwargs)
counter -= 1
print ' '*counter + 'end,', args[0]
return res
return wrapper
@evaluate.memoize_default([]) @evaluate.memoize_default([])
def _check_array_additions(compare_array, module, is_list): def _check_array_additions(compare_array, module, is_list):
@@ -170,26 +183,6 @@ def _check_array_additions(compare_array, module, is_list):
found = evaluate.follow_call_path(backtrack_path, scope, position) found = evaluate.follow_call_path(backtrack_path, scope, position)
settings.evaluate_special_assignments = True settings.evaluate_special_assignments = True
if not compare_array in found: if not compare_array in found:
# 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):
found_bases = []
for f in found:
base = get_execution_parent(f, parsing.Function)
found_bases.append(base)
if comp_arr_parent.base.base_func in found_bases:
stmt = comp_arr_parent. \
get_statement_for_position(c.start_pos)
if stmt is not None:
if evaluate.follow_statement.push_stmt(stmt):
# check recursion
continue
ass = stmt.get_assignment_calls()
new_calls = scan_array(ass, add_name)
result += check_calls(new_calls, add_name)
evaluate.follow_statement.pop_stmt()
continue continue
params = call_path[separate_index + 1] params = call_path[separate_index + 1]
@@ -215,24 +208,41 @@ def _check_array_additions(compare_array, module, is_list):
else: else:
# must be instance # must be instance
stmt = element.var_args.parent_stmt() stmt = element.var_args.parent_stmt()
if isinstance(stmt, evaluate.InstanceElement):
stop_classes = list(stop_classes) + [parsing.Function]
return stmt.get_parent_until(*stop_classes) return stmt.get_parent_until(*stop_classes)
search_names = ['append', 'extend', 'insert'] if is_list else \ search_names = ['append', 'extend', 'insert'] if is_list else \
['add', 'update'] ['add', 'update']
comp_arr_parent = get_execution_parent(compare_array, evaluate.Execution) comp_arr_parent = get_execution_parent(compare_array, evaluate.Execution)
possible_stmts = [] possible_stmts = []
result = [] res = []
for n in search_names: for n in search_names:
try: try:
possible_stmts += module.used_names[n] possible_stmts += module.used_names[n]
except KeyError: except KeyError:
continue continue
for stmt in possible_stmts: for stmt in possible_stmts:
ass = stmt.get_assignment_calls() # Check if the original scope is an execution. If it is, one
result += check_calls(scan_array(ass, n), n) # can search for the same statement, that is in the module
# dict. Executions are somewhat special in jedi, since they
return result # literally copy the contents of a function.
if isinstance(comp_arr_parent, evaluate.Execution):
stmt = comp_arr_parent. \
get_statement_for_position(stmt.start_pos)
if stmt is None:
continue
# InstanceElements are special, because they don't get copied,
# but have this wrapper around them.
if isinstance(comp_arr_parent, evaluate.InstanceElement):
stmt = evaluate.InstanceElement(comp_arr_parent.instance, stmt)
if evaluate.follow_statement.push_stmt(stmt):
# check recursion
continue
res += check_calls(scan_array(stmt.get_assignment_calls(), n), n)
evaluate.follow_statement.pop_stmt()
return res
def check_array_instances(instance): def check_array_instances(instance):
if not settings.dynamic_arrays_instances: if not settings.dynamic_arrays_instances:

View File

@@ -139,6 +139,8 @@ class Executable(parsing.Base):
class Instance(Executable): class Instance(Executable):
""" This class is used to evaluate instances. """ """ This class is used to evaluate instances. """
__metaclass__ = CachedMetaClass
def __init__(self, base, var_args=parsing.Array(None, None)): def __init__(self, base, var_args=parsing.Array(None, None)):
super(Instance, self).__init__(base, var_args) super(Instance, self).__init__(base, var_args)
if str(base.name) in ['list', 'set'] \ if str(base.name) in ['list', 'set'] \

View File

@@ -80,7 +80,7 @@ class Simple(Base):
def get_parent_until(self, *classes): def get_parent_until(self, *classes):
""" Takes always the parent, until one class (not a Class) """ """ Takes always the parent, until one class (not a Class) """
scope = self scope = self
while not (scope.parent() is None or scope.__class__ in classes): while not (scope.parent() is None or scope.isinstance(*classes)):
scope = scope.parent() scope = scope.parent()
return scope return scope

View File

@@ -231,5 +231,5 @@ tuple({1})[0]
tuple((1,))[0] tuple((1,))[0]
# implementation detail for lists, should not be visible # implementation detail for lists, should not be visible
#? [] ##? []
list().__iterable list().__iterable

View File

@@ -404,3 +404,17 @@ E.t(1)
e.u(1) e.u(1)
#? str() #? str()
E.u(1) E.u(1)
# -----------------
# recursions
# -----------------
def Recursion():
def recurse(self):
self.a = self.a
self.b = self.b.recurse()
#?
Recursion().a
#?
Recursion().b

View File

@@ -316,12 +316,23 @@ class C():
a[0] a[0]
return a return a
def class_arr(self, el):
self.a = []
self.a.append(el)
#? int()
self.a[0]
return self.a
#? int() #? int()
C().blub(1)[0] C().blub(1)[0]
#? float() #? float()
C().blub2(1)[0] C().blub2(1)[0]
#? int()
C().a[0]
#? int()
C().class_arr(1)[0]
# ----------------- # -----------------
# array recursions # array recursions
# ----------------- # -----------------

View File

@@ -198,6 +198,8 @@ def test_dir(completion_test_dir, thirdparty=False):
summary.append(s) summary.append(s)
# Sorry I didn't use argparse here. It's because argparse is not in the
# stdlib in 2.5.
args = sys.argv[1:] args = sys.argv[1:]
try: try:
i = args.index('--thirdparty') i = args.index('--thirdparty')