generators used to get names

This commit is contained in:
David Halter
2012-05-02 13:43:45 +02:00
parent 80f2a3518d
commit 532c78b024
5 changed files with 43 additions and 36 deletions

View File

@@ -78,7 +78,7 @@ class Parser(object):
except KeyError: except KeyError:
code = self._generate_code(self.module) code = self._generate_code(self.module)
try: try:
self._parser = parsing.PyFuzzyParser(code) self._parser = parsing.PyFuzzyParser(code, self.name)
except: except:
debug.warning('not possible to resolve', self.name, code) debug.warning('not possible to resolve', self.name, code)
#open('builtin_fail', 'w').write(code) #open('builtin_fail', 'w').write(code)

View File

@@ -140,7 +140,7 @@ class Instance(Executable):
except: except:
return None return None
def get_set_vars(self): def get_defined_names(self):
""" """
Get the instance vars of a class. This includes the vars of all Get the instance vars of a class. This includes the vars of all
classes classes
@@ -169,9 +169,6 @@ class Instance(Executable):
names.append(var) names.append(var)
return names return names
def get_defined_names(self):
return self.get_set_vars()
def __repr__(self): def __repr__(self):
return "<%s of %s (params: %s)>" % \ return "<%s of %s (params: %s)>" % \
(self.__class__.__name__, self.base, len(self.params or [])) (self.__class__.__name__, self.base, len(self.params or []))
@@ -306,29 +303,26 @@ def get_names_for_scope(scope, position=None, star_search=True):
""" """
Get all completions possible for the current scope. Get all completions possible for the current scope.
The star search option is only here to provide an optimization. Otherwise The star search option is only here to provide an optimization. Otherwise
the whole thing would make a little recursive maddness the whole thing would probably start a little recursive madness.
""" """
compl = []
start_scope = scope start_scope = scope
while scope: while scope:
# class variables/functions are only availabe # class variables/functions are only availabe
if (not isinstance(scope, parsing.Class) or scope == start_scope) \ if (not isinstance(scope, parsing.Class) or scope == start_scope) \
and not isinstance(scope, parsing.Flow): and not isinstance(scope, parsing.Flow):
compl += get_def yield get_defined_names_for_position(scope, position)
scope = scope.parent scope = scope.parent
# add builtins to the global scope
compl += builtin.Builtin.scope.get_defined_names()
# add star imports # add star imports
if star_search: if star_search:
for s in remove_star_imports(start_scope.get_parent_until()): for s in remove_star_imports(start_scope.get_parent_until()):
compl += get_names_for_scope(s, star_search=False) for name_list in get_names_for_scope(s, star_search=False):
#print 'gnfs', scope, compl yield name_list
return compl
# add builtins to the global scope
yield builtin.Builtin.scope.get_defined_names()
def get_scopes_for_name(scope, name, position=None, search_global=False): def get_scopes_for_name(scope, name_str, position=None, search_global=False):
""" """
:param position: Position of the last statement ->tuple of line, indent :param position: Position of the last statement ->tuple of line, indent
:return: List of Names. Their parents are the scopes, they are defined in. :return: List of Names. Their parents are the scopes, they are defined in.
@@ -353,19 +347,19 @@ def get_scopes_for_name(scope, name, position=None, search_global=False):
res_new += get_scopes_for_name(r.parent, res_new += get_scopes_for_name(r.parent,
str(token_name)) str(token_name))
else: else:
scopes = follow_statement(r, seek_name=name) scopes = follow_statement(r, seek_name=name_str)
res_new += remove_statements(scopes) res_new += remove_statements(scopes)
else: else:
res_new.append(r) res_new.append(r)
debug.dbg('sfn remove, new: %s, old: %s' % (res_new, result)) debug.dbg('sfn remove, new: %s, old: %s' % (res_new, result))
return res_new return res_new
def filter_name(scopes): def filter_name(scope_generator):
# the name is already given in the parent function # the name is already given in the parent function
def handle_non_arrays(): def handle_non_arrays(name):
result = [] result = []
par = scope.parent par = name.parent
if isinstance(par, parsing.Flow): if isinstance(par, parsing.Flow):
if par.command == 'for': if par.command == 'for':
# take the first statement (for has always only # take the first statement (for has always only
@@ -376,7 +370,7 @@ def get_scopes_for_name(scope, name, position=None, search_global=False):
for_vars = array.get_index_types() for_vars = array.get_index_types()
if len(par.set_vars) > 1: if len(par.set_vars) > 1:
var_arr = par.set_stmt.get_assignment_calls() var_arr = par.set_stmt.get_assignment_calls()
result += assign_tuples(var_arr, for_vars, name) result += assign_tuples(var_arr, for_vars, name_str)
else: else:
result += for_vars result += for_vars
else: else:
@@ -387,7 +381,7 @@ def get_scopes_for_name(scope, name, position=None, search_global=False):
# this is where self gets added - this happens at another # this is where self gets added - this happens at another
# place, if the params are clear. But some times the class is # place, if the params are clear. But some times the class is
# not known. Therefore set self. # not known. Therefore set self.
#print '\nselfadd', par, scope, scope.parent, par.parent, par.parent.parent #print '\nselfadd', par, name, name.parent, par.parent, par.parent.parent
result.append(Instance(par.parent.parent)) result.append(Instance(par.parent.parent))
result.append(par) result.append(par)
else: else:
@@ -395,13 +389,18 @@ def get_scopes_for_name(scope, name, position=None, search_global=False):
return result return result
result = [] result = []
for scope in scopes: for name_list in scope_generator:
if [name] == list(scope.names): for name in name_list:
if isinstance(scope, ArrayElement): if name_str == name.get_code():
result.append(scope) if isinstance(name, ArrayElement):
else: print 'dini mueter, wieso?', name
result += handle_non_arrays() result.append(name)
debug.dbg('sfn filter', name, result) else:
result += handle_non_arrays(name)
# if there are results, ignore the other scopes
if result:
break
debug.dbg('sfn filter', name_str, result)
return result return result
if search_global: if search_global:
@@ -411,7 +410,8 @@ def get_scopes_for_name(scope, name, position=None, search_global=False):
names = get_defined_names_for_position(scope, position) names = get_defined_names_for_position(scope, position)
else: else:
names = scope.get_defined_names() names = scope.get_defined_names()
print ' ln', position names = [names].__iter__()
#print ' ln', position
return remove_statements(filter_name(names)) return remove_statements(filter_name(names))
@@ -552,6 +552,10 @@ def follow_call(scope, call):
search_global=True) search_global=True)
result = strip_imports(scopes) result = strip_imports(scopes)
if result != scopes:
# reset the position, when imports where stripped
position = None
debug.dbg('call before result %s, current %s, scope %s' debug.dbg('call before result %s, current %s, scope %s'
% (result, current, scope)) % (result, current, scope))
result = follow_paths(path, result, position=position) result = follow_paths(path, result, position=position)

View File

@@ -187,7 +187,10 @@ def complete(source, row, column, source_path):
try: try:
stmt = r.top.statements[0] stmt = r.top.statements[0]
except IndexError: except IndexError:
completions = evaluate.get_names_for_scope(scope) scope_generator = evaluate.get_names_for_scope(scope)
completions = []
for name_list in scope_generator:
completions += name_list
#for c in completions: #for c in completions:
# if isinstance(, parsing.Function): # if isinstance(, parsing.Function):
# print c.parent # print c.parent

View File

@@ -154,8 +154,8 @@ flow_test.; a12, (b12, c12) = (1,(list, "")); b12.
def globalfunc(): def globalfunc():
global globalvar, globalvar2 global globalvar, globalvar2
globalvar = 3 globalvar = 3
# completetion:
a8 = 3 a8 = 3
#a8 = "" a8 = set
a8.; sys.path. # completion:
a8.
a8=list a8=list

View File

@@ -35,7 +35,7 @@ def completion_test(source):
completions = functions.complete(source, line_nr, 999, completions = functions.complete(source, line_nr, 999,
completion_test_dir) completion_test_dir)
except: except:
print 'test @%s: %s' % (line_nr, line) print 'test @#%s: %s' % (line_nr-1, line)
print traceback.format_exc() print traceback.format_exc()
fails += 1 fails += 1
else: else:
@@ -43,8 +43,8 @@ def completion_test(source):
# TODO remove set! duplicates should not be normal # TODO remove set! duplicates should not be normal
comp_str = str(sorted(set([str(c) for c in completions]))) comp_str = str(sorted(set([str(c) for c in completions])))
if comp_str != correct: if comp_str != correct:
print 'Solution on @%s not correct, received %s, wanted %s'\ print 'Solution on @#%s not right, received %s, wanted %s'\
% (line_nr, comp_str, correct) % (line_nr - 1, comp_str, correct)
#print [(c.name, c.name.parent) for c in completions] #print [(c.name, c.name.parent) for c in completions]
fails += 1 fails += 1
correct = None correct = None