forked from VimPlug/jedi
@@ -330,17 +330,14 @@ def _get_call_signature_details_from_error_node(node, additional_children, posit
|
|||||||
|
|
||||||
def get_call_signature_details(module, position):
|
def get_call_signature_details(module, position):
|
||||||
leaf = module.get_leaf_for_position(position, include_prefixes=True)
|
leaf = module.get_leaf_for_position(position, include_prefixes=True)
|
||||||
|
# It's easier to deal with the previous token than the next one in this
|
||||||
|
# case.
|
||||||
if leaf.start_pos >= position:
|
if leaf.start_pos >= position:
|
||||||
# Whitespace / comments after the leaf count towards the previous leaf.
|
# Whitespace / comments after the leaf count towards the previous leaf.
|
||||||
leaf = leaf.get_previous_leaf()
|
leaf = leaf.get_previous_leaf()
|
||||||
if leaf is None:
|
if leaf is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if leaf == ')':
|
|
||||||
# TODO is this ok?
|
|
||||||
if leaf.end_pos == position:
|
|
||||||
leaf = leaf.get_next_leaf()
|
|
||||||
|
|
||||||
# Now that we know where we are in the syntax tree, we start to look at
|
# Now that we know where we are in the syntax tree, we start to look at
|
||||||
# parents for possible function definitions.
|
# parents for possible function definitions.
|
||||||
node = leaf.parent
|
node = leaf.parent
|
||||||
@@ -364,11 +361,17 @@ def get_call_signature_details(module, position):
|
|||||||
continue
|
continue
|
||||||
additional_children.insert(0, n)
|
additional_children.insert(0, n)
|
||||||
|
|
||||||
|
# Find a valid trailer
|
||||||
if node.type == 'trailer' and node.children[0] == '(':
|
if node.type == 'trailer' and node.children[0] == '(':
|
||||||
leaf = node.get_previous_leaf()
|
# Additionally we have to check that an ending parenthesis isn't
|
||||||
if leaf is None:
|
# interpreted wrong. There are two cases:
|
||||||
return None
|
# 1. Cursor before paren -> The current signature is good
|
||||||
return CallDetails(node.children[0], node.children, position)
|
# 2. Cursor after paren -> We need to skip the current signature
|
||||||
|
if not (leaf is node.children[-1] and position >= leaf.end_pos):
|
||||||
|
leaf = node.get_previous_leaf()
|
||||||
|
if leaf is None:
|
||||||
|
return None
|
||||||
|
return CallDetails(node.children[0], node.children, position)
|
||||||
|
|
||||||
node = node.parent
|
node = node.parent
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ just one.
|
|||||||
"""
|
"""
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from operator import add
|
from operator import add
|
||||||
from parso.python.tree import ExprStmt, SyncCompFor, Name
|
from parso.python.tree import Name
|
||||||
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi._compatibility import zip_longest, unicode
|
from jedi._compatibility import zip_longest, unicode
|
||||||
|
|||||||
@@ -491,6 +491,13 @@ _calls = [
|
|||||||
(code4, 'i(?b,*r,c', 1),
|
(code4, 'i(?b,*r,c', 1),
|
||||||
(code4, 'i(?*', 0),
|
(code4, 'i(?*', 0),
|
||||||
(code4, 'i(?**', (0, 1)),
|
(code4, 'i(?**', (0, 1)),
|
||||||
|
|
||||||
|
# Random
|
||||||
|
(code4, 'i(()', 0),
|
||||||
|
(code4, 'i((),', 1),
|
||||||
|
(code4, 'i([(),', 0),
|
||||||
|
(code4, 'i([(,', 1),
|
||||||
|
(code4, 'i(x,()', 1),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -625,3 +632,36 @@ def test_call_magic_method(Script):
|
|||||||
assert [p.name for p in sig.params] == ['self', 'baz']
|
assert [p.name for p in sig.params] == ['self', 'baz']
|
||||||
sig, = Script(code + 'X().__call__(').call_signatures()
|
sig, = Script(code + 'X().__call__(').call_signatures()
|
||||||
assert [p.name for p in sig.params] == ['baz']
|
assert [p.name for p in sig.params] == ['baz']
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('column', [6, 9])
|
||||||
|
def test_cursor_after_signature(Script, column):
|
||||||
|
source = dedent("""
|
||||||
|
def foo(*args):
|
||||||
|
pass
|
||||||
|
foo() # _
|
||||||
|
""")
|
||||||
|
|
||||||
|
script = Script(source, 4, column)
|
||||||
|
|
||||||
|
assert not script.call_signatures()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'code, line, column, name, index', [
|
||||||
|
('abs(()\ndef foo(): pass', 1, None, 'abs', 0),
|
||||||
|
('abs(chr() \ndef foo(): pass', 1, 10, 'abs', 0),
|
||||||
|
('abs(chr()\ndef foo(): pass', 1, None, 'abs', 0),
|
||||||
|
('abs(chr()\ndef foo(): pass', 1, 8, 'chr', 0),
|
||||||
|
('abs(chr()\ndef foo(): pass', 1, 7, 'abs', 0),
|
||||||
|
('abs(chr ( \nclass y: pass', 1, None, 'chr', 0),
|
||||||
|
('abs(chr ( \nclass y: pass', 1, 8, 'abs', 0),
|
||||||
|
('abs(chr ( \nclass y: pass', 1, 9, 'abs', 0),
|
||||||
|
('abs(chr ( \nclass y: pass', 1, 10, 'chr', 0),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def test_base_signatures(Script, code, line, column, name, index):
|
||||||
|
sig, = Script(code, line=line, column=column).call_signatures()
|
||||||
|
|
||||||
|
assert sig.name == name
|
||||||
|
assert sig.index == index
|
||||||
|
|||||||
Reference in New Issue
Block a user