diff --git a/evaluate.py b/evaluate.py index 85a9fc9e..d06738d0 100644 --- a/evaluate.py +++ b/evaluate.py @@ -30,6 +30,49 @@ class Arr(object): raise StopIteration +class Instance(object): + """ This class is used to evaluate instances. """ + def __init__(self, cl): + self.cl = cl + + def get_instance_vars(self): + """ + Get the instance vars of a class. This includes the vars of all + classes + """ + n = [] + for s in self.cl.subscopes: + try: + # get the self name, if there's one + self_name = s.params[0].used_vars[0].names[0] + except: + pass + else: + for n2 in s.get_set_vars(): + # Only names with the selfname are being added. + # It is also important, that they have a len() of 2, + # because otherwise, they are just something else + if n2.names[0] == self_name and len(n2.names) == 2: + n.append(n2) + n += self.cl.get_set_vars() + return n + + +class Execution(object): + """ This class is used to evaluate functions and their returns. """ + def __init__(self, function): + self.cl = function + + def get_return_vars(self): + """ + Get the instance vars of a class. This includes the vars of all + classes + """ + n = [] + n += self.function.get_set_vars() + return n + + def get_names_for_scope(scope): """ Get all completions possible for the current scope. """ compl = [] @@ -41,6 +84,19 @@ def get_names_for_scope(scope): scope = scope.parent return compl +def get_scopes_for_name(scope, name, search_global=False): + """ + :return: List of Names. Their parents are the scopes, they are defined in. + :rtype: list + """ + if search_global: + names = get_names_for_scope(scope) + else: + names = scope.get_set_vars() + + result = [c.parent for c in names if [name] == list(c.names)] + return result + # default: name in scope # point: chaining @@ -50,12 +106,18 @@ def follow_statement(scope, stmt): print arr path = arr.generate_call_list() - path, path_print = itertools.tee(path) - print '\n\ncalls:' - for c in path_print: - print c + if debug_function: + path, path_print = itertools.tee(path) + dbg('') + dbg('') + dbg('calls:') + for c in path_print: + dbg(c) + + dbg('') + dbg('') + dbg('follow:') - print '\n\nfollow' current = next(path) result = [] if isinstance(current, parsing.Array): @@ -71,7 +133,7 @@ def follow_statement(scope, stmt): elif current.arr_type == parsing.Array.DICT: result.append(__builtin__.dict()) else: - print current + result = get_scopes_for_name(scope, current, search_global=True) pass print result @@ -96,12 +158,36 @@ def follow_paths(path, results): return results_new -def follow_path(path, result): +def follow_path(path, input): current = next(path) - #result = [] + print 'follow', input, current + result = [] - result = follow_paths(path, result) - return result + if isinstance(current, parsing.Array): + # this must be an execution, either () or [] + if current.arr_type == parsing.Array.LIST: + print 'dini mami' + result = [] # TODO eval lists + else: + # input must be a class or func -> make an instance or execution + if isinstance(input, parsing.Class): + result.append(Instance(input)) + else: + result.append(Execution(input)) + else: + if isinstance(input, parsing.Function): + # TODO check default function methods and return them + result = [] + else: + # TODO check default class methods and return them also + if isinstance(input, Instance): + result = input.get_instance_vars() + elif isinstance(input, Execution): + result = input.get_return_vars() + else: + result = get_scopes_for_name(input, current) + + return follow_paths(path, result) def follow_array(scope, array): diff --git a/functions.py b/functions.py index 0902730e..800f062d 100644 --- a/functions.py +++ b/functions.py @@ -178,6 +178,7 @@ def complete(source, row, column, file_callback=None): column = 17 row = 140 + row = 144 column = 200 f = File(source=source, row=row) scope = f.parser.user_scope diff --git a/parsing.py b/parsing.py index faf5cd98..cc607fbd 100644 --- a/parsing.py +++ b/parsing.py @@ -257,24 +257,6 @@ class Class(Scope): str += "pass\n" return str - def get_instance_set_vars(self): - n = [] - for s in self.subscopes: - try: - # get the self name, if there's one - self_name = s.params[0].used_vars[0].names[0] - except: - pass - else: - for n2 in s.get_set_vars(): - # Only names with the selfname are being added. - # It is also important, that they have a len() of 2, - # because otherwise, they are just something else - if n2.names[0] == self_name and len(n2.names) == 2: - n.append(n2) - n += super(Class, self).get_set_vars() - return n - class Function(Scope): """ diff --git a/test.py b/test.py index 31f5a76b..78b53367 100644 --- a/test.py +++ b/test.py @@ -140,3 +140,5 @@ class c1(): c, 1, c3()) [0].pop() c = "a".join([1,2]) + +c = c1().c3()[0]