diff --git a/builtin.py b/builtin.py index d8ae01af..f17d9765 100644 --- a/builtin.py +++ b/builtin.py @@ -2,6 +2,7 @@ import re import debug import parsing +import __builtin__ class Parser(object): @@ -9,6 +10,7 @@ class Parser(object): 'floating point number': '0.0', 'string': '""', 'str': '""', + 'character': '"a"', 'integer': '0', 'int': '0', 'dictionary': '{}', @@ -56,7 +58,8 @@ class Parser(object): continue # this has a builtin_function_or_method exe = getattr(scope, n) - if type(exe).__name__ == 'builtin_function_or_method': + if type(exe).__name__ in ['method_descriptor', + 'builtin_function_or_method']: funcs[n] = exe elif type(exe) == type: classes[n] = exe @@ -80,7 +83,6 @@ class Parser(object): names = set(dir(scope)) - {'__file__', '__name__', '__doc__', '__path__', '__package__'} classes, funcs, stmts, members = get_types(names) - #print 'blub', get_types(names) # classes for name, cl in classes.iteritems(): @@ -109,16 +111,23 @@ class Parser(object): # variables for name, value in stmts.iteritems(): - if isinstance(value, str): - value = repr(value) - elif type(value) == file: + if type(value) == file: value = 'file' + elif type(value).__name__ in ['int', 'bool', 'float', + 'dict', 'list', 'tuple']: + value = repr(value) + else: + # get the type, if the type is not simple. + mod = type(value).__module__ + value = type(value).__name__ + '()' + if mod != '__builtin__': + value = '%s.%s' % (mod, value) code += '%s = %s\n' % (name, value) - import sys - #if depth == 0: - # sys.stdout.write(code) - # exit() + if depth == 10: + import sys + sys.stdout.write(code) + exit() return code @@ -130,15 +139,46 @@ def parse_function_doc(func): # TODO: things like utime(path, (atime, mtime)) and a(b [, b]) -> None params = [] doc = func.__doc__ - end = doc.index(')') - #print 'blubedi', doc - param_str = doc[doc.index('(') + 1:end] + + # get full string, parse round parentheses: def func(a, (b,c)) + try: + count = 0 + debug.dbg(func, func.__name__, doc) + start = doc.index('(') + for i, s in enumerate(doc[start:]): + if s == '(': + count += 1 + elif s == ')': + count -= 1 + if count == 0: + end = start + i + break + param_str = doc[start + 1:end] + + # remove square brackets, which show an optional param ( in Python = None) + def change_options(m): + args = m.group(1).split(',') + for i, a in enumerate(args): + if a and '=' not in a: + args[i] += '=None' + return ','.join(args) + while True: + (param_str, changes) = re.subn(r' ?\[([^\[\]]+)\]', + change_options, param_str) + if changes == 0: + break + except (ValueError, AttributeError): + debug.dbg('no brackets found - no param') + end = 0 + param_str = '' + try: index = doc.index('-> ', end, end + 7) - except ValueError: + except (ValueError, AttributeError): ret = 'pass' else: - pattern = re.compile(r'(,\n|[^\n])+') + # get result type, which can contain newlines + pattern = re.compile(r'(,\n|[^\n-])+') ret_str = pattern.match(doc, index + 3).group(0) ret = Parser.map_types.get(ret_str, ret_str) if ret == ret_str and ret not in ['None', 'object', 'tuple', 'set']: @@ -149,7 +189,7 @@ def parse_function_doc(func): """if current.arr_type == parsing.Array.EMPTY: # the normal case - no array type - print 'length', len(current) + debug.dbg('length', len(current)) elif current.arr_type == parsing.Array.LIST: result.append(__builtin__.list()) elif current.arr_type == parsing.Array.SET: @@ -159,3 +199,7 @@ elif current.arr_type == parsing.Array.TUPLE: elif current.arr_type == parsing.Array.DICT: result.append(__builtin__.dict()) """ + +class Builtin(object): + _builtins = Parser('__builtin__') + scope = _builtins.parser.top diff --git a/debug.py b/debug.py index 113037b8..8fbc8ebe 100644 --- a/debug.py +++ b/debug.py @@ -23,5 +23,5 @@ def print_to_stdout(level, *args): """ The default debug function """ print 'dbg:' if level == NOTICE else 'warning:', args -debug_function = print_to_stdout +debug_function = None ignored_modules = [] diff --git a/evaluate.py b/evaluate.py index ab63b403..ba5000db 100644 --- a/evaluate.py +++ b/evaluate.py @@ -9,6 +9,7 @@ import itertools import parsing import modules import debug +import builtin class Exec(object): @@ -103,6 +104,9 @@ def get_names_for_scope(scope): if not isinstance(scope, parsing.Class) or scope == start_scope: compl += scope.get_set_vars() scope = scope.parent + + # add builtins to the global scope + compl += builtin.Builtin.scope.get_set_vars() return compl @@ -159,7 +163,6 @@ def resolve_results(scopes): result = [] for s in scopes: if isinstance(s, parsing.Import): - print 'dini mueter, steile griech!' try: scope = follow_import(s) #for r in resolve_results([follow_import(s)]): diff --git a/ftest.py b/ftest.py index 6486fde4..974f3328 100755 --- a/ftest.py +++ b/ftest.py @@ -2,12 +2,13 @@ import functions -#functions.debug.debug_function -functions.debug.ignored_modules += ['parsing', 'functions'] +functions.debug.debug_function = functions.debug.print_to_stdout +functions.debug.ignored_modules += ['parsing', 'builtin'] functions.modules.module_find_path.insert(0, '.') with open('test.py') as f: code = f.read() -completions = functions.complete(code, 50, 20) +for i in range(1): + completions = functions.complete(code, 50, 20) print '\n', [c.names for c in completions] diff --git a/functions.py b/functions.py index d6ac71d0..4e3846be 100644 --- a/functions.py +++ b/functions.py @@ -171,8 +171,8 @@ def complete(source, row, column, file_callback=None): debug.dbg('-' * 70) debug.dbg(' ' * 62 + 'complete') debug.dbg('-' * 70) - print 'complete_scope', scope - print 'user_scope', f.parser.user_scope.get_simple_for_line(row) + debug.dbg('complete_scope', scope) + debug.dbg('user_scope', f.parser.user_scope.get_simple_for_line(row)) try: path = f.get_row_path(column) @@ -181,6 +181,7 @@ def complete(source, row, column, file_callback=None): debug.dbg(e) result = [] + print path if path and path[0]: # just parse one statement r = parsing.PyFuzzyParser(".".join(path)) diff --git a/parsing.py b/parsing.py index 98c04260..5be605eb 100644 --- a/parsing.py +++ b/parsing.py @@ -152,7 +152,6 @@ class Scope(Simple): for s in self.statements: if isinstance(s, Scope): i += s.get_imports() - print 'geti', i return i def add_global(self, name): @@ -810,6 +809,9 @@ class PyFuzzyParser(object): self.parse() + # delete code again, only the parser needs it + del self.code + def _parsedotname(self, pre_used_token=None): """ The dot name parser parses a name, variable or function and returns @@ -969,7 +971,7 @@ class PyFuzzyParser(object): if next == '(': super = self._parseparen() elif next != ':': - print "class: syntax error - %s@%s" % (cname, self.line_nr) + debug.dbg("class: syntax error - %s@%s" % (cname, self.line_nr)) return None return Class(cname, super, indent, start_line) diff --git a/test.py b/test.py index 20b46d32..b1039d11 100644 --- a/test.py +++ b/test.py @@ -130,7 +130,7 @@ import time class c1(): c2,c5 = c1(), c1().c3() def c3(self): - import tokenize as c4 #from parsing import Scope as c4 + import os as c4 #from parsing import Scope as c4 c5 = c4 c5 = 1 return c5+1+'asdf' @@ -139,10 +139,10 @@ class c1(): (c1().c2.\ c, 1, c3()) [0].pop() -c = "a".join([1,2]) c = c1().c3().sleep() asdf = c1; asdf2 = asdf b= asdf2 #import parsing as test c = b().c3() +c = "a".join([1,2])