possible to return dynamic arrays

This commit is contained in:
David Halter
2012-08-22 11:44:45 +02:00
parent 9c09de6245
commit d85184d387
5 changed files with 142 additions and 8 deletions

View File

@@ -8,16 +8,16 @@ working quite good.
import parsing
import evaluate
import builtin
import helpers
import settings
import debug
# This is something like the sys.path, but only for searching params. It means
# that this is the order in which Jedi searches params.
search_param_modules = ['.']
search_param_cache = {}
def search_param_memoize(func):
"""
Is only good for search params memoize, respectively the closure,
@@ -128,6 +128,7 @@ def _check_array_additions(compare_array, module, is_list):
"""
if not settings.dynamic_array_additions:
return []
def scan_array(arr, search_name):
""" Returns the function Calls that match func_name """
result = []
@@ -153,9 +154,27 @@ def _check_array_additions(compare_array, module, is_list):
position = c.parent_stmt().start_pos
scope = c.parent_stmt().parent()
e = evaluate.follow_call_path(backtrack_path, scope, position)
if not compare_array in e:
found = evaluate.follow_call_path(backtrack_path, scope, position)
if not compare_array in found:
# the `append`, etc. belong to other arrays
if isinstance(comp_arr_parent, evaluate.Execution):
found_bases = []
for f in found:
base = get_execution_parent(f, parsing.Function)
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:
stmt = comp_arr_parent.\
get_statement_for_position(c.start_pos)
if stmt is not None:
#print 'LA', stmt.parent(), stmt
ass = stmt.get_assignment_calls()
result += check_calls(scan_array(ass, add_name),
add_name)
#print found_bases, comp_arr_parent.base.base_func
#print found, found[0]._array.parent_stmt().parent()
#print compare_array_parent.base
continue
params = call_path[separate_index + 1]
@@ -175,8 +194,19 @@ def _check_array_additions(compare_array, module, is_list):
result += evaluate.get_iterator_types(iterators)
return result
def get_execution_parent(element, *stop_classes):
if isinstance(element, evaluate.Array):
stmt = element._array.parent_stmt()
else:
# must be instance
stmt = element.var_args.parent_stmt()
return stmt.get_parent_until(*stop_classes)
search_names = ['append', 'extend', 'insert'] if is_list else \
['add', 'update']
#print compare_array
comp_arr_parent = get_execution_parent(compare_array, evaluate.Execution)
#print 'par', comp_arr_parent
possible_stmts = []
result = []
for n in search_names:
@@ -195,7 +225,7 @@ def check_array_instances(instance):
if not settings.dynamic_arrays_instances:
return instance.var_args
ai = ArrayInstance(instance)
return helpers.generate_param_array([ai])
return helpers.generate_param_array([ai], instance.var_args.parent_stmt())
class ArrayInstance(parsing.Base):
@@ -223,7 +253,13 @@ class ArrayInstance(parsing.Base):
temp = array.var_args[0][0]
if isinstance(temp, ArrayInstance):
#print items, self, id(self.var_args), id(self.var_args.parent_stmt()), array
# prevent recursions
# TODO compare Modules
if self.var_args.start_pos != temp.var_args.start_pos:
items += temp.iter_content()
else:
debug.warning('ArrayInstance recursion', self.var_args)
print 'yippie'
continue
items += evaluate.get_iterator_types([array])

View File

@@ -653,7 +653,7 @@ class Execution(Executable):
Call the default method with the own instance (self implements all
the necessary functions). Add also the params.
"""
return self.get_params() + parsing.Scope._get_set_vars(self)
return self.get_params() + parsing.Scope.get_set_vars(self)
def copy_properties(self, prop):
# Copy all these lists into this local function.
@@ -691,6 +691,9 @@ class Execution(Executable):
def subscopes(self):
return self.copy_properties('subscopes')
def get_statement_for_position(self, pos):
return parsing.Scope.get_statement_for_position(self, pos)
def __repr__(self):
return "<%s of %s>" % \
(self.__class__.__name__, self.base)

View File

@@ -202,7 +202,13 @@ class Scope(Simple):
@Python3Method
def get_statement_for_position(self, pos):
for s in self.statements:
if s.start_pos <= pos < self.end_pos:
if isinstance(s, Flow):
p = s.get_statement_for_position(pos)
if s.next and not p:
p = s.next.get_statement_for_position(pos)
if p:
return p
elif s.start_pos <= pos < s.end_pos:
return s
for s in self.subscopes:

View File

@@ -248,8 +248,81 @@ arr3[10]
#? float() str() int() set()
res[10]
# -----------------
# returns, special because the module dicts are not correct here.
# -----------------
def blub():
a = []
a.append(1.0)
#? float()
a[0]
return a
#? float()
blub()[0]
# list with default
def blub():
a = list([1])
a.append(1.0)
return a
#? int() float()
blub()[0]
# empty list
def blub():
a = list()
a.append(1.0)
return a
#? float()
blub()[0]
# with if
def blub():
if 1:
a = []
a.append(1.0)
return a
#? float()
blub()[0]
# with else clause
def blub():
if 1:
1
else:
a = []
a.append(1)
return a
#? int()
blub()[0]
# -----------------
# array recursions
# -----------------
a = set([1.0])
a.update(a)
a.update([1])
#? float() int()
list(a)[0]
def first(a):
b = []
b.append(a)
#b.extend(second(a))
return b
def second(a):
b = []
b.append(a)
b.extend(first(a))
b.extend(second(a))
return list(b)
#? float()
first(1.0)[0]

View File

@@ -89,3 +89,19 @@ class Counter:
for c in Counter(3, 8):
#? int()
print c
# -----------------
# tuples
# -----------------
def gen():
if a:
yield 1, ""
else:
yield 2, 1.0
a, b = next(gen())
#? int()
a
#? str() float()
b