Finally get rid of call_of_leaf

This commit is contained in:
Dave Halter
2020-01-12 03:04:09 +01:00
parent a17d4d9e16
commit bd2ed8dbbd
4 changed files with 34 additions and 66 deletions

View File

@@ -99,15 +99,17 @@ def _check_isinstance_type(value, node, search_name):
args = TreeArguments(value.inference_state, value, arglist, trailer) args = TreeArguments(value.inference_state, value, arglist, trailer)
param_list = list(args.unpack()) param_list = list(args.unpack())
# Disallow keyword arguments # Disallow keyword arguments
if len(param_list) == 2: if len(param_list) == 2 and len(arglist.children) == 3:
(key1, lazy_value_object), (key2, lazy_value_cls) = param_list (key1, _), (key2, lazy_value_cls) = param_list
if key1 is None and key2 is None: if key1 is None and key2 is None:
call = helpers.call_of_leaf(search_name) call = _get_call_string(search_name)
is_instance_call = helpers.call_of_leaf(lazy_value_object.data) is_instance_call = _get_call_string(arglist.children[0])
# Do a simple get_code comparison. They should just have the # Do a simple get_code comparison of the strings . They should
# same code, and everything will be all right. # just have the same code, and everything will be all right.
normalize = value.inference_state.grammar._normalize # There are ways that this is not correct, if some stuff is
if normalize(is_instance_call) == normalize(call): # redefined in between. However here we don't care, because
# it's a heuristic that works pretty well.
if call == is_instance_call:
lazy_cls = lazy_value_cls lazy_cls = lazy_value_cls
if lazy_cls is None: if lazy_cls is None:
return None return None
@@ -120,3 +122,16 @@ def _check_isinstance_type(value, node, search_name):
else: else:
value_set |= cls_or_tup.execute_with_values() value_set |= cls_or_tup.execute_with_values()
return value_set return value_set
def _get_call_string(node):
if node.parent.type == 'atom_expr':
return _get_call_string(node.parent)
code = ''
leaf = node.get_first_leaf()
end = node.get_last_leaf().end_pos
while leaf.start_pos < end:
code += leaf.value
leaf = leaf.get_next_leaf()
return code

View File

@@ -110,49 +110,6 @@ def infer_call_of_leaf(context, leaf, cut_own_trailer=False):
return values return values
def call_of_leaf(leaf):
"""
Creates a "call" node that consist of all ``trailer`` and ``power``
objects. E.g. if you call it with ``append``::
list([]).append(3) or None
You would get a node with the content ``list([]).append`` back.
This generates a copy of the original ast node.
If you're using the leaf, e.g. the bracket `)` it will return ``list([])``.
"""
# TODO this is the old version of this call. Try to remove it.
trailer = leaf.parent
# The leaf may not be the last or first child, because there exist three
# different trailers: `( x )`, `[ x ]` and `.x`. In the first two examples
# we should not match anything more than x.
if trailer.type != 'trailer' or leaf not in (trailer.children[0], trailer.children[-1]):
if trailer.type == 'atom':
return trailer
return leaf
power = trailer.parent
index = power.children.index(trailer)
new_power = copy.copy(power)
new_power.children = list(new_power.children)
new_power.children[index + 1:] = []
if power.type == 'error_node':
start = index
while True:
start -= 1
if power.children[start].type != 'trailer':
break
transformed = tree.Node('power', power.children[start:])
transformed.parent = power.parent
return transformed
return power
def get_names_of_node(node): def get_names_of_node(node):
try: try:
children = node.children children = node.children

View File

@@ -99,3 +99,14 @@ class Test():
#? #?
isinstance(1, int()) isinstance(1, int())
# -----------------
# more complicated arguments
# -----------------
def ayyyyyye(obj):
if isinstance(obj.obj, str):
#?
obj.obj
#?
obj

View File

@@ -1,15 +0,0 @@
from textwrap import dedent
from jedi.inference import helpers
def test_call_of_leaf_in_brackets(Script):
s = dedent("""
x = 1
type(x)
""")
last_x = Script(s).names(references=True, definitions=False)[-1]
name = last_x._name.tree_name
call = helpers.call_of_leaf(name)
assert call == name