fixed some bugs related to func param display

This commit is contained in:
David Halter
2012-09-15 17:33:18 +02:00
parent 24d86c72a0
commit 60e8f57c32
3 changed files with 42 additions and 12 deletions

43
api.py
View File

@@ -112,9 +112,10 @@ class Definition(dynamic.BaseOutput):
class CallDef(object): class CallDef(object):
def __init__(self, executable, index): def __init__(self, executable, index, call):
self.executable = executable self.executable = executable
self.index = index self.index = index
self.call = call
@property @property
def params(self): def params(self):
@@ -353,41 +354,63 @@ class Script(object):
return sorted(names, key=lambda x: (x.module_path, x.start_pos)) return sorted(names, key=lambda x: (x.module_path, x.start_pos))
def get_in_function_call(self): def get_in_function_call(self):
"""
Return the function, that the cursor is in, e.g.:
>>> isinstance(| # | <-- cursor is here
This would return the `isinstance` function. In contrary:
>>> isinstance()| # | <-- cursor is here
This would return `None`.
"""
def scan_array_for_pos(arr, pos): def scan_array_for_pos(arr, pos):
""" """
Returns the function Call that match search_name in an Array. Returns the function Call that match search_name in an Array.
""" """
index = None index = 0
call = None call = None
stop = False
for index, sub in enumerate(arr): for index, sub in enumerate(arr):
call = None call = None
for s in sub: for s in sub:
if isinstance(s, parsing.Array): if isinstance(s, parsing.Array):
new = scan_array_for_pos(s, pos) new = scan_array_for_pos(s, pos)
if new[0] is not None: if new[0] is not None:
call, index = new call, index, stop = new
if stop:
return call, index, stop
elif isinstance(s, parsing.Call): elif isinstance(s, parsing.Call):
while s is not None: while s is not None:
if s.start_pos >= pos: if s.start_pos >= pos:
return call, index return call, index, stop
if s.execution is not None: if s.execution is not None:
if s.execution.start_pos <= pos: if s.execution.start_pos <= pos:
call = s call = s
c, index = scan_array_for_pos(s.execution, c, index, stop = scan_array_for_pos(
pos) s.execution, pos)
if stop:
return c, index, stop
if c is not None: if c is not None:
call = c call = c
else: else:
return call, index return call, index, stop
print('E', pos, s.execution.end_pos)
if s.execution.end_pos is not None:
if pos < s.execution.end_pos:
return call, index, True
else:
return None, 0, True
s = s.next s = s.next
return call, index # The third return is just necessary for recursion inside, because
# it needs to know when to stop iterating.
return call, index, stop
user_stmt = self.parser.user_stmt user_stmt = self.parser.user_stmt
if user_stmt is None or not isinstance(user_stmt, parsing.Statement): if user_stmt is None or not isinstance(user_stmt, parsing.Statement):
return None return None
ass = user_stmt.get_assignment_calls() ass = user_stmt.get_assignment_calls()
call, index = scan_array_for_pos(ass, self.pos) call, index, stop = scan_array_for_pos(ass, self.pos)
if call is None: if call is None:
return None return None
@@ -399,7 +422,7 @@ class Script(object):
return None return None
# just take entry zero, because we need just one. # just take entry zero, because we need just one.
executable = origins[0] executable = origins[0]
return CallDef(executable, index) return CallDef(executable, index, call)
def _get_completion_parts(self, path): def _get_completion_parts(self, path):
""" """

View File

@@ -790,6 +790,7 @@ class Statement(Simple):
# always dictionaries and not sets. # always dictionaries and not sets.
result.type = Array.DICT result.type = Array.DICT
level -= 1 level -= 1
result.end_pos = start_pos[0], start_pos[1] + 1
close_brackets = True close_brackets = True
else: else:
while is_call_or_close(): while is_call_or_close():
@@ -943,6 +944,7 @@ class Array(Call):
self.values = values if values else [] self.values = values if values else []
self.keys = [] self.keys = []
self.end_pos = None
def add_field(self): def add_field(self):
""" """

View File

@@ -113,16 +113,21 @@ class TestRegression(unittest.TestCase):
def test_get_in_function_call(self): def test_get_in_function_call(self):
s = "isinstance(a, abs(" s = "isinstance(a, abs("
s2 = "isinstance(), " s2 = "isinstance(), "
s3 = "isinstance()."
check = lambda call_def, index: call_def and call_def.index == index check = lambda call_def, index: call_def and call_def.index == index
assert check(self.get_in_function_call(s, (1, 11)), 0) assert check(self.get_in_function_call(s, (1, 11)), 0)
assert check(self.get_in_function_call(s, (1, 14)), 1) assert check(self.get_in_function_call(s, (1, 14)), 1)
assert check(self.get_in_function_call(s, (1, 15)), 1) assert check(self.get_in_function_call(s, (1, 15)), 1)
assert check(self.get_in_function_call(s, (1, 18)), 0) assert check(self.get_in_function_call(s, (1, 18)), 0)
##assert check(self.get_in_function_call(s2, (1, 11)), 0) # TODO uncomment assert check(self.get_in_function_call(s2, (1, 11)), 0)
assert self.get_in_function_call(s2, (1, 12)) is None assert self.get_in_function_call(s2, (1, 12)) is None
assert self.get_in_function_call(s2) is None assert self.get_in_function_call(s2) is None
assert self.get_in_function_call(s3, (1, 12)) is None
assert self.get_in_function_call(s3) is None
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()