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):
""" Get all completions possible for the current scope. """
comp = []
compl = []
start_scope = scope
while scope:
# class variables/functions are only availabe
if not isinstance(scope, parsing.Class) or scope == start_scope:
comp += scope.get_set_vars()
compl += scope.get_set_vars()
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):
@@ -18,17 +30,17 @@ def follow_path(scope, path):
recursive!
:returns: list(Scope)
"""
comp = get_names_for_scope(scope)
print path, comp
compl = get_names_for_scope(scope)
print path, compl
path = list(path)
name = path.pop(0)
scopes = []
# 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)
for c in comp:
for c in compl:
p_class = c.parent.__class__
if p_class == parsing.Class or p_class == parsing.Scope:
scopes.append(c.parent)

View File

@@ -171,7 +171,7 @@ def complete(source, row, column, file_callback=None):
:type row: int
:param col: The column to complete in.
:type col: int
:return: list
:return: list of completion objects
:rtype: list
"""
row = 84
@@ -198,15 +198,23 @@ def complete(source, row, column, file_callback=None):
result = []
if path:
name = path.pop()
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))
dbg('possible scopes', scopes)
compl = []
for s in scopes:
compl += s.get_defined_names()
dbg('possible scopes', scopes)
compl = []
for s in scopes:
compl += s.get_defined_names()
else:
compl = evaluate.get_names_for_scope(scope)
dbg('possible-compl', compl)

View File

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

View File

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