commands after the current position are getting ignored now - with failed import tests

This commit is contained in:
David Halter
2012-05-01 15:45:01 +02:00
parent 453e003153
commit 80f2a3518d
5 changed files with 57 additions and 20 deletions

View File

@@ -29,6 +29,16 @@ def clear_caches():
m.clear() m.clear()
def get_defined_names_for_position(obj, position):
names = obj.get_defined_names()
if not position:
return names
names_new = []
for n in names:
if (n.line_nr, n.indent) <= position:
names_new.append(n)
return names_new
def memoize(default=None): def memoize(default=None):
""" """
This is a typical memoization decorator, BUT there is one difference: This is a typical memoization decorator, BUT there is one difference:
@@ -292,7 +302,7 @@ class ArrayElement(object):
return "<%s of %s>" % (self.__class__.__name__, self.name) return "<%s of %s>" % (self.__class__.__name__, self.name)
def get_names_for_scope(scope, star_search=True): 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
@@ -304,7 +314,7 @@ def get_names_for_scope(scope, star_search=True):
# 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 += scope.get_defined_names() compl += get_def
scope = scope.parent scope = scope.parent
# add builtins to the global scope # add builtins to the global scope
@@ -318,8 +328,9 @@ def get_names_for_scope(scope, star_search=True):
return compl return compl
def get_scopes_for_name(scope, name, search_global=False): def get_scopes_for_name(scope, name, position=None, search_global=False):
""" """
: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.
:rtype: list :rtype: list
""" """
@@ -394,9 +405,13 @@ def get_scopes_for_name(scope, name, search_global=False):
return result return result
if search_global: if search_global:
names = get_names_for_scope(scope) names = get_names_for_scope(scope, position=position)
else: else:
names = scope.get_defined_names() if position:
names = get_defined_names_for_position(scope, position)
else:
names = scope.get_defined_names()
print ' ln', position
return remove_statements(filter_name(names)) return remove_statements(filter_name(names))
@@ -469,12 +484,11 @@ def follow_statement(stmt, scope=None, seek_name=None):
:param stmt: contains a statement :param stmt: contains a statement
:param scope: contains a scope. If not given, takes the parent of stmt. :param scope: contains a scope. If not given, takes the parent of stmt.
""" """
debug.dbg('follow_stmt', stmt, 'in', stmt.parent, scope, seek_name)
if scope is None: if scope is None:
scope = stmt.get_parent_until(parsing.Function, Execution, scope = stmt.get_parent_until(parsing.Function, Execution,
parsing.Class, Instance, parsing.Class, Instance,
InstanceElement) InstanceElement)
debug.dbg('follow_stmt', stmt, 'in', stmt.parent, scope, seek_name) debug.dbg('follow_stmt', stmt, 'in', scope, seek_name)
call_list = stmt.get_assignment_calls() call_list = stmt.get_assignment_calls()
debug.dbg('calls', call_list, call_list.values) debug.dbg('calls', call_list, call_list.values)
@@ -516,6 +530,7 @@ def follow_call(scope, call):
""" Follow a call is following a function, variable, string, etc. """ """ Follow a call is following a function, variable, string, etc. """
path = call.generate_call_list() path = call.generate_call_list()
position = (call.parent_stmt.line_nr, call.parent_stmt.indent)
current = next(path) current = next(path)
if isinstance(current, parsing.Array): if isinstance(current, parsing.Array):
result = [Array(current)] result = [Array(current)]
@@ -532,17 +547,19 @@ def follow_call(scope, call):
# make instances of those number/string objects # make instances of those number/string objects
scopes = [Instance(s) for s in scopes] scopes = [Instance(s) for s in scopes]
else: else:
scopes = get_scopes_for_name(scope, current, search_global=True) # this is the first global lookup
scopes = get_scopes_for_name(scope, current, position=position,
search_global=True)
result = strip_imports(scopes) result = strip_imports(scopes)
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) result = follow_paths(path, result, position=position)
return result return result
def follow_paths(path, results): def follow_paths(path, results, position=None):
results_new = [] results_new = []
try: try:
if results: if results:
@@ -551,13 +568,13 @@ def follow_paths(path, results):
else: else:
iter_paths = [path] iter_paths = [path]
for i, r in enumerate(results): for i, r in enumerate(results):
results_new += follow_path(iter_paths[i], r) results_new += follow_path(iter_paths[i], r, position=position)
except StopIteration: except StopIteration:
return results return results
return results_new return results_new
def follow_path(path, scope): def follow_path(path, scope, position=None):
""" """
Takes a generator and tries to complete the path. Takes a generator and tries to complete the path.
""" """
@@ -585,8 +602,10 @@ def follow_path(path, scope):
result = [] result = []
else: else:
# TODO check magic class methods and return them also # TODO check magic class methods and return them also
result = strip_imports(get_scopes_for_name(scope, current)) # this is the typical lookup while chaining things
return follow_paths(path, result) result = strip_imports(get_scopes_for_name(scope, current,
position=position))
return follow_paths(path, result, position=position)
def follow_import(_import): def follow_import(_import):

View File

@@ -192,6 +192,8 @@ def complete(source, row, column, source_path):
# if isinstance(, parsing.Function): # if isinstance(, parsing.Function):
# print c.parent # print c.parent
else: else:
stmt.line_nr = row
stmt.indent = column
stmt.parent = scope stmt.parent = scope
scopes = evaluate.follow_statement(stmt, scope=scope) scopes = evaluate.follow_statement(stmt, scope=scope)

View File

@@ -2,7 +2,7 @@
# test comment # test comment
import datetime import datetime, os, sys
#from token import * #from token import *
from time import sleep from time import sleep
from token import OP as OP_TEST, INDENT as INDENT_TEST from token import OP as OP_TEST, INDENT as INDENT_TEST
@@ -140,7 +140,7 @@ class c1():
return self.acp # self.bcp + return self.acp # self.bcp +
(c1().c2.\ (c1().c2.\
c, 1, c3()) [0].pop() c, 1, c3()) [0].pop()
c = u"asdf".join([1,2]) c = u"asdf".join([1,2]); c1(1).c3(r"")
matrix_test = [[1,2], [1,3]] matrix_test = [[1,2], [1,3]]
c = c1().c3().sleep() c = c1().c3().sleep()
asdf = c1; asdf2 = asdf b= asdf2 asdf = c1; asdf2 = asdf b= asdf2
@@ -151,10 +151,11 @@ abc = [1,2+3]; abc[0].
import pylab; def add(a1,b1): nana = 1; return a1+b1 import pylab; def add(a1,b1): nana = 1; return a1+b1
flow_test.; a12, (b12, c12) = (1,(list, "")); b12. flow_test.; a12, (b12, c12) = (1,(list, "")); b12.
def globalfunc(): def globalfunc():
global globalvar, globalvar2 global globalvar, globalvar2
globalvar = 3 globalvar = 3
# completetion:
c1(1).c3(r"") a8 = 3
#a8 = ""
a8.; sys.path.
a8=list

View File

@@ -27,6 +27,15 @@ class TestClass(object):
def ret(self, a1): def ret(self, a1):
return a1 return a1
# should not work
#? []
var_local
#? []
var_inst
#? []
var_func
# instance
inst = TestClass(1) inst = TestClass(1)
#? ['var_class', 'var_func', 'var_inst', 'var_local'] #? ['var_class', 'var_func', 'var_inst', 'var_local']

View File

@@ -14,6 +14,12 @@ float.is_int
#? ['is_integer'] #? ['is_integer']
1.0.is_integer 1.0.is_integer
#? ['upper']
"".upper
#? ['upper']
r"".upper
# ----------------- # -----------------
# lists # lists
# ----------------- # -----------------