ContextualizedName -> TreeNameDefinition

This commit is contained in:
Dave Halter
2019-09-05 00:15:38 +02:00
parent 4d332c32c0
commit aea2ddcbd8
4 changed files with 52 additions and 59 deletions

View File

@@ -75,7 +75,7 @@ from jedi.inference import recursion
from jedi.inference.cache import inference_state_function_cache from jedi.inference.cache import inference_state_function_cache
from jedi.inference import helpers from jedi.inference import helpers
from jedi.inference.names import TreeNameDefinition from jedi.inference.names import TreeNameDefinition
from jedi.inference.base_value import ContextualizedName, ContextualizedNode, \ from jedi.inference.base_value import ContextualizedNode, \
ValueSet, NO_VALUES, iterate_values ValueSet, NO_VALUES, iterate_values
from jedi.inference.value import ClassValue, FunctionValue from jedi.inference.value import ClassValue, FunctionValue
from jedi.inference.context import CompForContext from jedi.inference.context import CompForContext
@@ -256,8 +256,8 @@ class InferenceState(object):
container_types = context.infer_node(def_.children[3]) container_types = context.infer_node(def_.children[3])
cn = ContextualizedNode(context, def_.children[3]) cn = ContextualizedNode(context, def_.children[3])
for_types = iterate_values(container_types, cn) for_types = iterate_values(container_types, cn)
c_node = ContextualizedName(context, name) n = TreeNameDefinition(context, name)
return check_tuple_assignments(c_node, for_types) return check_tuple_assignments(n, for_types)
if type_ in ('import_from', 'import_name'): if type_ in ('import_from', 'import_name'):
return imports.infer_import(context, name) return imports.infer_import(context, name)
else: else:

View File

@@ -329,54 +329,6 @@ class ContextualizedNode(object):
return '<%s: %s in %s>' % (self.__class__.__name__, self.node, self.context) return '<%s: %s in %s>' % (self.__class__.__name__, self.node, self.context)
class ContextualizedName(ContextualizedNode):
# TODO merge with TreeNameDefinition?!
@property
def name(self):
return self.node
def assignment_indexes(self):
"""
Returns an array of tuple(int, node) of the indexes that are used in
tuple assignments.
For example if the name is ``y`` in the following code::
x, (y, z) = 2, ''
would result in ``[(1, xyz_node), (0, yz_node)]``.
When searching for b in the case ``a, *b, c = [...]`` it will return::
[(slice(1, -1), abc_node)]
"""
indexes = []
is_star_expr = False
node = self.node.parent
compare = self.node
while node is not None:
if node.type in ('testlist', 'testlist_comp', 'testlist_star_expr', 'exprlist'):
for i, child in enumerate(node.children):
if child == compare:
index = int(i / 2)
if is_star_expr:
from_end = int((len(node.children) - i) / 2)
index = slice(index, -from_end)
indexes.insert(0, (index, node))
break
else:
raise LookupError("Couldn't find the assignment.")
is_star_expr = False
elif node.type == 'star_expr':
is_star_expr = True
elif isinstance(node, (ExprStmt, SyncCompFor)):
break
compare = node
node = node.parent
return indexes
def _getitem(value, index_values, contextualized_node): def _getitem(value, index_values, contextualized_node):
# The actual getitem call. # The actual getitem call.
result = NO_VALUES result = NO_VALUES

View File

@@ -175,6 +175,46 @@ class TreeNameDefinition(AbstractTreeName):
return 'statement' return 'statement'
return self._API_TYPES.get(definition.type, 'statement') return self._API_TYPES.get(definition.type, 'statement')
def assignment_indexes(self):
"""
Returns an array of tuple(int, node) of the indexes that are used in
tuple assignments.
For example if the name is ``y`` in the following code::
x, (y, z) = 2, ''
would result in ``[(1, xyz_node), (0, yz_node)]``.
When searching for b in the case ``a, *b, c = [...]`` it will return::
[(slice(1, -1), abc_node)]
"""
indexes = []
is_star_expr = False
node = self.tree_name.parent
compare = self.tree_name
while node is not None:
if node.type in ('testlist', 'testlist_comp', 'testlist_star_expr', 'exprlist'):
for i, child in enumerate(node.children):
if child == compare:
index = int(i / 2)
if is_star_expr:
from_end = int((len(node.children) - i) / 2)
index = slice(index, -from_end)
indexes.insert(0, (index, node))
break
else:
raise LookupError("Couldn't find the assignment.")
is_star_expr = False
elif node.type == 'star_expr':
is_star_expr = True
elif node.type in ('expr_stmt', 'sync_comp_for'):
break
compare = node
node = node.parent
return indexes
class _ParamMixin(object): class _ParamMixin(object):
def maybe_positional_argument(self, include_star=True): def maybe_positional_argument(self, include_star=True):

View File

@@ -9,7 +9,7 @@ from jedi._compatibility import force_unicode, unicode
from jedi import debug from jedi import debug
from jedi import parser_utils from jedi import parser_utils
from jedi.inference.base_value import ValueSet, NO_VALUES, ContextualizedNode, \ from jedi.inference.base_value import ValueSet, NO_VALUES, ContextualizedNode, \
ContextualizedName, iterator_to_value_set, iterate_values iterator_to_value_set, iterate_values
from jedi.inference.lazy_value import LazyTreeValue from jedi.inference.lazy_value import LazyTreeValue
from jedi.inference import compiled from jedi.inference import compiled
from jedi.inference import recursion from jedi.inference import recursion
@@ -25,6 +25,7 @@ from jedi.inference.compiled.access import COMPARISON_OPERATORS
from jedi.inference.cache import inference_state_method_cache from jedi.inference.cache import inference_state_method_cache
from jedi.inference.gradual.stub_value import VersionInfo from jedi.inference.gradual.stub_value import VersionInfo
from jedi.inference.gradual import annotation from jedi.inference.gradual import annotation
from jedi.inference.names import TreeNameDefinition
from jedi.inference.value.decorator import Decoratee from jedi.inference.value.decorator import Decoratee
from jedi.plugins import plugin_manager from jedi.plugins import plugin_manager
@@ -301,8 +302,8 @@ def _infer_expr_stmt(context, stmt, seek_name=None):
value_set = context.infer_node(rhs) value_set = context.infer_node(rhs)
if seek_name: if seek_name:
c_node = ContextualizedName(context, seek_name) n = TreeNameDefinition(context, seek_name)
value_set = check_tuple_assignments(c_node, value_set) value_set = check_tuple_assignments(n, value_set)
first_operator = next(stmt.yield_operators(), None) first_operator = next(stmt.yield_operators(), None)
is_setitem, subscriptlist = check_setitem(stmt) is_setitem, subscriptlist = check_setitem(stmt)
@@ -614,8 +615,8 @@ def tree_name_to_values(inference_state, context, tree_name):
contextualized_node=cn, contextualized_node=cn,
is_async=node.parent.type == 'async_stmt', is_async=node.parent.type == 'async_stmt',
) )
c_node = ContextualizedName(context, tree_name) n = TreeNameDefinition(context, tree_name)
types = check_tuple_assignments(c_node, for_types) types = check_tuple_assignments(n, for_types)
elif typ == 'expr_stmt': elif typ == 'expr_stmt':
types = _remove_statements(context, node, tree_name) types = _remove_statements(context, node, tree_name)
elif typ == 'with_stmt': elif typ == 'with_stmt':
@@ -687,13 +688,13 @@ def _apply_decorators(context, node):
return values return values
def check_tuple_assignments(contextualized_name, value_set): def check_tuple_assignments(name, value_set):
""" """
Checks if tuples are assigned. Checks if tuples are assigned.
""" """
lazy_value = None lazy_value = None
for index, node in contextualized_name.assignment_indexes(): for index, node in name.assignment_indexes():
cn = ContextualizedNode(contextualized_name.context, node) cn = ContextualizedNode(name.parent_context, node)
iterated = value_set.iterate(cn) iterated = value_set.iterate(cn)
if isinstance(index, slice): if isinstance(index, slice):
# For no star unpacking is not possible. # For no star unpacking is not possible.