completion tests

This commit is contained in:
David Halter
2012-03-17 14:31:01 +01:00
parent b2a77acff6
commit 6b8551c917
4 changed files with 97 additions and 68 deletions

View File

@@ -2,14 +2,26 @@ import parsing
def get_names_for_scope(scope): def get_names_for_scope(scope):
""" Get all completions possible for the current scope. """ """ Get all completions possible for the current scope. """
comp = [] 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:
comp += scope.get_set_vars() compl += scope.get_set_vars()
scope = scope.parent scope = scope.parent
return comp return compl
# default: name in scope
# point: chaining
# execution: -> eval returns default & ?
def follow_statement(scope, stmt):
arr = stmt.get_assignment_calls()
return call
def follow_array(scope, array):
return
def follow_path(scope, path): def follow_path(scope, path):
@@ -18,17 +30,17 @@ def follow_path(scope, path):
recursive! recursive!
:returns: list(Scope) :returns: list(Scope)
""" """
comp = get_names_for_scope(scope) compl = get_names_for_scope(scope)
print path, comp print path, compl
path = list(path) path = list(path)
name = path.pop(0) name = path.pop(0)
scopes = [] scopes = []
# make the full comparison, because the names have to match exactly # make the full comparison, because the names have to match exactly
comp = [c for c in comp if [name] == list(c.names)] compl = [c for c in compl if [name] == list(c.names)]
# TODO differentiate between the different comp input (some are overridden) # TODO differentiate between the different comp input (some are overridden)
for c in comp: for c in compl:
p_class = c.parent.__class__ p_class = c.parent.__class__
if p_class == parsing.Class or p_class == parsing.Scope: if p_class == parsing.Class or p_class == parsing.Scope:
scopes.append(c.parent) scopes.append(c.parent)

View File

@@ -171,7 +171,7 @@ def complete(source, row, column, file_callback=None):
:type row: int :type row: int
:param col: The column to complete in. :param col: The column to complete in.
:type col: int :type col: int
:return: list :return: list of completion objects
:rtype: list :rtype: list
""" """
row = 84 row = 84
@@ -198,9 +198,14 @@ def complete(source, row, column, file_callback=None):
result = [] result = []
if path: if path:
name = path.pop() name = path.pop()
if path: if path:
# just parse one statement
r = parsing.PyFuzzyParser(".".join(path))
print 'p', r.top.get_code(), r.top.statements[0]
evaluate.follow_statement(scope, r.top.statements[0])
exit()
scopes = evaluate.follow_path(scope, tuple(path)) scopes = evaluate.follow_path(scope, tuple(path))
dbg('possible scopes', scopes) dbg('possible scopes', scopes)
@@ -208,6 +213,9 @@ def complete(source, row, column, file_callback=None):
for s in scopes: for s in scopes:
compl += s.get_defined_names() compl += s.get_defined_names()
else:
compl = evaluate.get_names_for_scope(scope)
dbg('possible-compl', compl) dbg('possible-compl', compl)
# make a partial comparison, because the other options have to # make a partial comparison, because the other options have to

View File

@@ -39,10 +39,6 @@ import cStringIO
import re import re
class TokenNotFoundError(Exception):
pass
class ParserError(Exception): class ParserError(Exception):
pass pass
@@ -502,19 +498,18 @@ class Statement(Simple):
most of the statements won't need this data anyway. This is something most of the statements won't need this data anyway. This is something
'like' a lazy execution. 'like' a lazy execution.
""" """
result = None result = Array(Array.EMPTY)
has_assignment = False
level = 0 level = 0
is_chain = False is_chain = False
for tok_temp in self.token_list: for tok_temp in self.token_list:
print 'tok', tok_temp #print 'tok', tok_temp
try: try:
token_type, tok, indent = tok_temp token_type, tok, indent = tok_temp
if '=' in tok and not tok in ['>=', '<=', '==', '!=']: if level == 0 and \
'=' in tok and not tok in ['>=', '<=', '==', '!=']:
# This means, there is an assignment here. # This means, there is an assignment here.
# TODO there may be multiple assignments: a = b = 1 # TODO there may be multiple assignments: a = b = 1
has_assignment = True
# initialize the first item # initialize the first item
result = Array(Array.EMPTY) result = Array(Array.EMPTY)
@@ -523,7 +518,6 @@ class Statement(Simple):
# the token is a Name, which has already been parsed # the token is a Name, which has already been parsed
tok = tok_temp tok = tok_temp
if has_assignment:
brackets = {'(': Array.EMPTY, '[': Array.LIST, '{': Array.SET} brackets = {'(': Array.EMPTY, '[': Array.LIST, '{': Array.SET}
is_call = isinstance(result, Call) is_call = isinstance(result, Call)
if isinstance(tok, Name): if isinstance(tok, Name):
@@ -534,7 +528,6 @@ class Statement(Simple):
else: else:
result.add_to_current_field(call) result.add_to_current_field(call)
result = call result = call
print 'asdf', result, result.parent
elif tok in brackets.keys(): elif tok in brackets.keys():
level += 1 level += 1
result = Array(brackets[tok], result) result = Array(brackets[tok], result)
@@ -557,7 +550,6 @@ class Statement(Simple):
result.arr_type = Array.TUPLE result.arr_type = Array.TUPLE
elif tok in [')', '}', ']']: elif tok in [')', '}', ']']:
level -= 1 level -= 1
print 'asdf2', result, result.parent
result = result.parent result = result.parent
else: else:
# TODO catch numbers and strings -> token_type and make # TODO catch numbers and strings -> token_type and make
@@ -566,9 +558,10 @@ class Statement(Simple):
result = result.parent result = result.parent
result.add_to_current_field(tok) result.add_to_current_field(tok)
if not has_assignment: if isinstance(result, Call):
raise TokenNotFoundError("You are requesting the result of an " # if the last added object was a name, the result will not be the
"assignment, where the token cannot be found") # top tree.
result = result.parent
if level != 0: if level != 0:
raise ParserError("Brackets don't match: %s. This is not normal " raise ParserError("Brackets don't match: %s. This is not normal "
"behaviour. Please submit a bug" % level) "behaviour. Please submit a bug" % level)
@@ -635,6 +628,18 @@ class Array(object):
else: else:
return self.values return self.values
def __repr__(self):
if self.arr_type == self.EMPTY:
temp = 'empty'
elif self.arr_type == self.TUPLE:
temp = 'tuple'
elif self.arr_type == self.DICT:
temp = 'dict'
elif self.arr_type == self.SET:
temp = 'set'
return "<%s: %s of %s>" % \
(self.__class__.__name__, temp, self.parent)
class Call(object): class Call(object):
""" The statement object of functions, to """ """ The statement object of functions, to """
@@ -660,6 +665,10 @@ class Call(object):
self.executions.append(call) self.executions.append(call)
return call return call
def __repr__(self):
return "<%s: %s of %s>" % \
(self.__class__.__name__, self.name, self.parent)
class Name(Simple): class Name(Simple):
""" """
@@ -706,7 +715,7 @@ class PyFuzzyParser(object):
""" """
def __init__(self, code, user_line=None): def __init__(self, code, user_line=None):
self.user_line = user_line self.user_line = user_line
self.code = code self.code = code + '\n' # end with \n, because the parser needs it
# initialize global Scope # initialize global Scope
self.top = Scope(0, 0) self.top = Scope(0, 0)

View File

@@ -136,5 +136,5 @@ class c1():
c1.c2.\ c1().c2.\
c c