mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 23:04:48 +08:00
refactor search_call_signatures. Now we don't need to set Call.next.parent in a strange way anymore and the whole thing seems to be more logical.
This commit is contained in:
@@ -379,7 +379,7 @@ class Script(object):
|
|||||||
else:
|
else:
|
||||||
# Fetch definition of callee, if there's no path otherwise.
|
# Fetch definition of callee, if there's no path otherwise.
|
||||||
if not goto_path:
|
if not goto_path:
|
||||||
(call, _) = search_call_signatures(user_stmt, self._pos)
|
(call, _, _) = search_call_signatures(user_stmt, self._pos)
|
||||||
if call is not None:
|
if call is not None:
|
||||||
while call.next is not None:
|
while call.next is not None:
|
||||||
call = call.next
|
call = call.next
|
||||||
@@ -559,22 +559,12 @@ class Script(object):
|
|||||||
:rtype: list of :class:`classes.CallSignature`
|
:rtype: list of :class:`classes.CallSignature`
|
||||||
"""
|
"""
|
||||||
user_stmt = self._parser.user_stmt_with_whitespace()
|
user_stmt = self._parser.user_stmt_with_whitespace()
|
||||||
call, index = search_call_signatures(user_stmt, self._pos)
|
call, execution_arr, index = search_call_signatures(user_stmt, self._pos)
|
||||||
if call is None:
|
if call is None:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
stmt_el = call
|
|
||||||
while isinstance(stmt_el.parent, pr.StatementElement):
|
|
||||||
# Go to parent literal/variable until not possible anymore. This
|
|
||||||
# makes it possible to return the whole expression.
|
|
||||||
stmt_el = stmt_el.parent
|
|
||||||
# We can change the execution since it's a new object
|
|
||||||
# (fast_parent_copy).
|
|
||||||
execution_arr, call.execution = call.execution, None
|
|
||||||
call.next = None
|
|
||||||
|
|
||||||
with common.scale_speed_settings(settings.scale_call_signatures):
|
with common.scale_speed_settings(settings.scale_call_signatures):
|
||||||
_callable = lambda: self._evaluator.eval_call(stmt_el)
|
_callable = lambda: self._evaluator.eval_call(call)
|
||||||
origins = cache.cache_call_signatures(_callable, self.source,
|
origins = cache.cache_call_signatures(_callable, self.source,
|
||||||
self._pos, user_stmt)
|
self._pos, user_stmt)
|
||||||
debug.speed('func_call followed')
|
debug.speed('func_call followed')
|
||||||
|
|||||||
@@ -78,50 +78,53 @@ def fast_parent_copy(obj):
|
|||||||
def call_signature_array_for_pos(stmt, pos):
|
def call_signature_array_for_pos(stmt, pos):
|
||||||
"""
|
"""
|
||||||
Searches for the array and position of a tuple.
|
Searches for the array and position of a tuple.
|
||||||
|
Returns a tuple of (array, index-in-the-array, call).
|
||||||
"""
|
"""
|
||||||
def search_array(arr, pos, origin_call=None):
|
def search_array(arr, pos, origin_call=None):
|
||||||
accepted_types = pr.Array.TUPLE, pr.Array.NOARRAY
|
accepted_types = pr.Array.TUPLE, pr.Array.NOARRAY
|
||||||
if arr.type == 'dict':
|
if arr.type == 'dict':
|
||||||
for stmt in arr.values + arr.keys:
|
for stmt in arr.values + arr.keys:
|
||||||
new_arr, index = call_signature_array_for_pos(stmt, pos)
|
tup = call_signature_array_for_pos(stmt, pos)
|
||||||
if new_arr is not None:
|
if tup[0] is not None:
|
||||||
return new_arr, index
|
return tup
|
||||||
else:
|
else:
|
||||||
for i, stmt in enumerate(arr):
|
for i, stmt in enumerate(arr):
|
||||||
new_arr, index = call_signature_array_for_pos(stmt, pos)
|
tup = call_signature_array_for_pos(stmt, pos)
|
||||||
if new_arr is not None:
|
if tup[0] is not None:
|
||||||
return new_arr, index
|
return tup
|
||||||
|
|
||||||
# TODO couldn't we merge with the len(arr) == 0 check?
|
# Since we need the index, we duplicate efforts (with empty
|
||||||
|
# arrays).
|
||||||
if arr.start_pos < pos <= stmt.end_pos:
|
if arr.start_pos < pos <= stmt.end_pos:
|
||||||
if arr.type in accepted_types and isinstance(origin_call, pr.Call):
|
if arr.type in accepted_types and isinstance(origin_call, pr.Call):
|
||||||
return arr, i
|
return arr, i, origin_call
|
||||||
|
|
||||||
if len(arr) == 0 and arr.start_pos < pos < arr.end_pos:
|
if len(arr) == 0 and arr.start_pos < pos < arr.end_pos:
|
||||||
if arr.type in accepted_types and isinstance(origin_call, pr.Call):
|
if arr.type in accepted_types and isinstance(origin_call, pr.Call):
|
||||||
return arr, 0
|
return arr, 0, origin_call
|
||||||
return None, 0
|
return None, 0, None
|
||||||
|
|
||||||
def search_call(call, pos, origin_call=None):
|
def search_call(call, pos, origin_call=None):
|
||||||
arr, index = None, 0
|
tup = None, 0, None
|
||||||
if call.next is not None:
|
if call.next is not None:
|
||||||
method = search_array if isinstance(call.next, pr.Array) else search_call
|
method = search_array if isinstance(call.next, pr.Array) else search_call
|
||||||
arr, index = method(call.next, pos, origin_call or call)
|
tup = method(call.next, pos, origin_call or call)
|
||||||
if not arr and call.execution is not None:
|
if not tup[0] and call.execution is not None:
|
||||||
arr, index = search_array(call.execution, pos, origin_call)
|
tup = search_array(call.execution, pos, origin_call)
|
||||||
return arr, index
|
return tup
|
||||||
|
|
||||||
if stmt.start_pos >= pos >= stmt.end_pos:
|
if stmt.start_pos >= pos >= stmt.end_pos:
|
||||||
return None, 0
|
return None, 0, None
|
||||||
|
|
||||||
|
tup = None, 0, None
|
||||||
for command in stmt.expression_list():
|
for command in stmt.expression_list():
|
||||||
arr = None
|
|
||||||
if isinstance(command, pr.Array):
|
if isinstance(command, pr.Array):
|
||||||
arr, index = search_array(command, pos)
|
tup = search_array(command, pos)
|
||||||
elif isinstance(command, pr.StatementElement):
|
elif isinstance(command, pr.StatementElement):
|
||||||
arr, index = search_call(command, pos, command)
|
tup = search_call(command, pos, command)
|
||||||
if arr is not None:
|
if tup[0] is not None:
|
||||||
return arr, index
|
break
|
||||||
return None, 0
|
return tup
|
||||||
|
|
||||||
|
|
||||||
def search_call_signatures(user_stmt, position):
|
def search_call_signatures(user_stmt, position):
|
||||||
@@ -129,16 +132,25 @@ def search_call_signatures(user_stmt, position):
|
|||||||
Returns the function Call that matches the position before.
|
Returns the function Call that matches the position before.
|
||||||
"""
|
"""
|
||||||
debug.speed('func_call start')
|
debug.speed('func_call start')
|
||||||
call, index = None, 0
|
call, arr, index = None, None, 0
|
||||||
if user_stmt is not None and isinstance(user_stmt, pr.Statement):
|
if user_stmt is not None and isinstance(user_stmt, pr.Statement):
|
||||||
# some parts will of the statement will be removed
|
# some parts will of the statement will be removed
|
||||||
user_stmt = fast_parent_copy(user_stmt)
|
user_stmt = fast_parent_copy(user_stmt)
|
||||||
arr, index = call_signature_array_for_pos(user_stmt, position)
|
arr, index, call = call_signature_array_for_pos(user_stmt, position)
|
||||||
if arr is not None:
|
|
||||||
call = arr.parent
|
# Now remove the part after the call. Including the array from the
|
||||||
|
# statement.
|
||||||
|
stmt_el = call
|
||||||
|
while isinstance(stmt_el, pr.StatementElement):
|
||||||
|
if stmt_el.execution == arr:
|
||||||
|
stmt_el.execution = None
|
||||||
|
stmt_el.next = None
|
||||||
|
break
|
||||||
|
|
||||||
|
stmt_el = stmt_el.next
|
||||||
|
|
||||||
debug.speed('func_call parsed')
|
debug.speed('func_call parsed')
|
||||||
return call, index
|
return call, arr, index
|
||||||
|
|
||||||
|
|
||||||
def scan_statement_for_calls(stmt, search_name, assignment_details=False):
|
def scan_statement_for_calls(stmt, search_name, assignment_details=False):
|
||||||
|
|||||||
@@ -1277,7 +1277,7 @@ class StatementElement(Simple):
|
|||||||
|
|
||||||
def set_next(self, call):
|
def set_next(self, call):
|
||||||
""" Adds another part of the statement"""
|
""" Adds another part of the statement"""
|
||||||
call.parent = self
|
call.parent = self.parent
|
||||||
if self.next is not None:
|
if self.next is not None:
|
||||||
self.next.set_next(call)
|
self.next.set_next(call)
|
||||||
else:
|
else:
|
||||||
@@ -1288,7 +1288,7 @@ class StatementElement(Simple):
|
|||||||
An execution is nothing else than brackets, with params in them, which
|
An execution is nothing else than brackets, with params in them, which
|
||||||
shows access on the internals of this name.
|
shows access on the internals of this name.
|
||||||
"""
|
"""
|
||||||
call.parent = self
|
call.parent = self.parent
|
||||||
if self.next is not None:
|
if self.next is not None:
|
||||||
self.next.set_execution(call)
|
self.next.set_execution(call)
|
||||||
elif self.execution is not None:
|
elif self.execution is not None:
|
||||||
|
|||||||
Reference in New Issue
Block a user