A first implementation of call signatures.

This commit is contained in:
Dave Halter
2014-12-05 16:05:54 +01:00
parent ab254bbcba
commit 24903739f2
6 changed files with 22 additions and 16 deletions

View File

@@ -574,7 +574,7 @@ class Script(object):
:rtype: list of :class:`classes.CallSignature`
"""
user_stmt = self._parser.user_stmt_with_whitespace()
call, execution_arr, index = search_call_signatures(user_stmt, self._pos)
call, trailer, index = search_call_signatures(user_stmt, self._pos)
if call is None:
return []
@@ -585,14 +585,13 @@ class Script(object):
key_name = None
try:
detail = execution_arr[index].assignment_details[0]
except IndexError:
pass
else:
try:
key_name = unicode(detail[0][0].name)
# Access the trailers arglist node.
argument = trailer.children[0].children[index]
except (IndexError, AttributeError):
pass
else:
if argument.children[1] == '=':
key_name = argument.children[0]
return [classes.CallSignature(self._evaluator, o.name, call, index, key_name)
for o in origins if hasattr(o, 'py__call__')]

View File

@@ -675,7 +675,7 @@ class CallSignature(Definition):
def index(self):
"""
The Param index of the current call.
Returns None if the index doesn't is not defined.
Returns None if the index cannot be found in the curent call.
"""
if self._key_name is not None:
for i, param in enumerate(self.params):

View File

@@ -112,7 +112,7 @@ def cache_call_signatures(evaluator, call, source, user_pos, stmt):
module_path = stmt.get_parent_until().path
yield None if module_path is None else (module_path, before_bracket, stmt.start_pos)
yield evaluator.eval_call(call)
yield evaluator.eval_element(call)
def underscore_memoization(func):

View File

@@ -86,16 +86,18 @@ class CompiledObject(Base):
params_str, ret = self._parse_function_doc()
tokens = params_str.split(',')
params = []
module = SubModule(self.get_parent_until().name)
module = self.get_parent_until()
# it seems like start_pos/end_pos is always (0, 0) for a compiled
# object
start_pos, end_pos = (0, 0), (0, 0)
for p in tokens:
parts = [FakeName(part) for part in p.strip().split('=')]
if len(parts) >= 2:
parts.insert(1, Operator(module, '=', module, (0, 0)))
params.append(Param(module, parts, start_pos,
end_pos, builtin))
name = parts[0]
if len(parts) > 2:
default = parts[2]
else:
default = None
params.append(Param(name, module, default))
return params
def __repr__(self):

View File

@@ -203,10 +203,12 @@ def _call_signature_array_for_pos(stmt, pos):
def scan_node_for_call_signature(node, pos):
"""to something with call_signatures"""
if node.type == 'power' and node.start_pos < pos < node.end_pos:
for trailer in node.children[1:]:
for i, trailer in enumerate(node.children[1:], 1):
if trailer.type == 'trailer' and trailer.children[0] == '(' \
and trailer.children[0].start_pos < pos \
and pos <= trailer.children[-1].start_pos:
# Delete all the nodes including the current one
node.children[i:] = []
return node, trailer
for child in node.children:
node, trailer = scan_node_for_call_signature(child, pos)
@@ -226,7 +228,8 @@ def search_call_signatures(user_stmt, position):
# some parts will of the statement will be removed
user_stmt = deep_ast_copy(user_stmt)
print(scan_node_for_call_signature(user_stmt, position))
return scan_node_for_call_signature(user_stmt, position) + (0,)
print()
#arr, index, call = _call_signature_array_for_pos(user_stmt, position)
# Now remove the part after the call. Including the array from the

View File

@@ -18,6 +18,8 @@ class Arguments(pr.Base):
The argument_node is either a parser node or a list of evaluated
objects. Those evaluated objects may be lists of evaluated objects
themselves (one list for the first argument, one for the second, etc).
:param argument_node: May be an argument_node or a list of nodes.
"""
self.argument_node = argument_node
self._evaluator = evaluator