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()
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):
"""
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)
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.
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
if (not isinstance(scope, parsing.Class) or scope == start_scope) \
and not isinstance(scope, parsing.Flow):
compl += scope.get_defined_names()
compl += get_def
scope = scope.parent
# add builtins to the global scope
@@ -318,8 +328,9 @@ def get_names_for_scope(scope, star_search=True):
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.
:rtype: list
"""
@@ -394,9 +405,13 @@ def get_scopes_for_name(scope, name, search_global=False):
return result
if search_global:
names = get_names_for_scope(scope)
names = get_names_for_scope(scope, position=position)
else:
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))
@@ -469,12 +484,11 @@ def follow_statement(stmt, scope=None, seek_name=None):
:param stmt: contains a statement
: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:
scope = stmt.get_parent_until(parsing.Function, Execution,
parsing.Class, Instance,
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()
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. """
path = call.generate_call_list()
position = (call.parent_stmt.line_nr, call.parent_stmt.indent)
current = next(path)
if isinstance(current, parsing.Array):
result = [Array(current)]
@@ -532,17 +547,19 @@ def follow_call(scope, call):
# make instances of those number/string objects
scopes = [Instance(s) for s in scopes]
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)
debug.dbg('call before result %s, current %s, scope %s'
% (result, current, scope))
result = follow_paths(path, result)
result = follow_paths(path, result, position=position)
return result
def follow_paths(path, results):
def follow_paths(path, results, position=None):
results_new = []
try:
if results:
@@ -551,13 +568,13 @@ def follow_paths(path, results):
else:
iter_paths = [path]
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:
return results
return results_new
def follow_path(path, scope):
def follow_path(path, scope, position=None):
"""
Takes a generator and tries to complete the path.
"""
@@ -585,8 +602,10 @@ def follow_path(path, scope):
result = []
else:
# TODO check magic class methods and return them also
result = strip_imports(get_scopes_for_name(scope, current))
return follow_paths(path, result)
# this is the typical lookup while chaining things
result = strip_imports(get_scopes_for_name(scope, current,
position=position))
return follow_paths(path, result, position=position)
def follow_import(_import):

View File

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

View File

@@ -2,7 +2,7 @@
# test comment
import datetime
import datetime, os, sys
#from token import *
from time import sleep
from token import OP as OP_TEST, INDENT as INDENT_TEST
@@ -140,7 +140,7 @@ class c1():
return self.acp # self.bcp +
(c1().c2.\
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]]
c = c1().c3().sleep()
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
flow_test.; a12, (b12, c12) = (1,(list, "")); b12.
def globalfunc():
global globalvar, globalvar2
globalvar = 3
c1(1).c3(r"")
# completetion:
a8 = 3
#a8 = ""
a8.; sys.path.
a8=list

View File

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

View File

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