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 parsing
import evaluate import evaluate
import builtin
import helpers import helpers
import settings import settings
import debug
# This is something like the sys.path, but only for searching params. It means # This is something like the sys.path, but only for searching params. It means
# that this is the order in which Jedi searches params. # that this is the order in which Jedi searches params.
search_param_modules = ['.'] search_param_modules = ['.']
search_param_cache = {} search_param_cache = {}
def search_param_memoize(func): def search_param_memoize(func):
""" """
Is only good for search params memoize, respectively the closure, 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: if not settings.dynamic_array_additions:
return [] return []
def scan_array(arr, search_name): def scan_array(arr, search_name):
""" Returns the function Calls that match func_name """ """ Returns the function Calls that match func_name """
result = [] result = []
@@ -153,9 +154,27 @@ def _check_array_additions(compare_array, module, is_list):
position = c.parent_stmt().start_pos position = c.parent_stmt().start_pos
scope = c.parent_stmt().parent() scope = c.parent_stmt().parent()
e = evaluate.follow_call_path(backtrack_path, scope, position) found = evaluate.follow_call_path(backtrack_path, scope, position)
if not compare_array in e: if not compare_array in found:
# the `append`, etc. belong to other arrays # 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 continue
params = call_path[separate_index + 1] 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) result += evaluate.get_iterator_types(iterators)
return result 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 \ 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)
#print 'par', comp_arr_parent
possible_stmts = [] possible_stmts = []
result = [] result = []
for n in search_names: for n in search_names:
@@ -195,7 +225,7 @@ def check_array_instances(instance):
if not settings.dynamic_arrays_instances: if not settings.dynamic_arrays_instances:
return instance.var_args return instance.var_args
ai = ArrayInstance(instance) ai = ArrayInstance(instance)
return helpers.generate_param_array([ai]) return helpers.generate_param_array([ai], instance.var_args.parent_stmt())
class ArrayInstance(parsing.Base): class ArrayInstance(parsing.Base):
@@ -223,7 +253,13 @@ class ArrayInstance(parsing.Base):
temp = array.var_args[0][0] temp = array.var_args[0][0]
if isinstance(temp, ArrayInstance): if isinstance(temp, ArrayInstance):
#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
# TODO compare Modules
if self.var_args.start_pos != temp.var_args.start_pos:
items += temp.iter_content() items += temp.iter_content()
else:
debug.warning('ArrayInstance recursion', self.var_args)
print 'yippie'
continue continue
items += evaluate.get_iterator_types([array]) 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 Call the default method with the own instance (self implements all
the necessary functions). Add also the params. 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): def copy_properties(self, prop):
# Copy all these lists into this local function. # Copy all these lists into this local function.
@@ -691,6 +691,9 @@ class Execution(Executable):
def subscopes(self): def subscopes(self):
return self.copy_properties('subscopes') return self.copy_properties('subscopes')
def get_statement_for_position(self, pos):
return parsing.Scope.get_statement_for_position(self, pos)
def __repr__(self): def __repr__(self):
return "<%s of %s>" % \ return "<%s of %s>" % \
(self.__class__.__name__, self.base) (self.__class__.__name__, self.base)

View File

@@ -202,7 +202,13 @@ class Scope(Simple):
@Python3Method @Python3Method
def get_statement_for_position(self, pos): def get_statement_for_position(self, pos):
for s in self.statements: 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 return s
for s in self.subscopes: for s in self.subscopes:

View File

@@ -248,8 +248,81 @@ arr3[10]
#? float() str() int() set() #? float() str() int() set()
res[10] res[10]
# -----------------
# returns, special because the module dicts are not correct here.
# -----------------
def blub(): def blub():
a = [] a = []
a.append(1.0) a.append(1.0)
#? float() #? float()
a[0] 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): for c in Counter(3, 8):
#? int() #? int()
print c print c
# -----------------
# tuples
# -----------------
def gen():
if a:
yield 1, ""
else:
yield 2, 1.0
a, b = next(gen())
#? int()
a
#? str() float()
b