forked from VimPlug/jedi
fix list comprehensions. they were not implemented in a good way
This commit is contained in:
@@ -192,10 +192,6 @@ class Evaluator(object):
|
|||||||
next(call_path, None) # the first one has been used already
|
next(call_path, None) # the first one has been used already
|
||||||
return self.follow_path(call_path, r, element.parent)
|
return self.follow_path(call_path, r, element.parent)
|
||||||
elif isinstance(element, pr.ListComprehension):
|
elif isinstance(element, pr.ListComprehension):
|
||||||
#lc = element.get_most_inner_lc()
|
|
||||||
# Caveat: parents are being changed, but this doesn't matter,
|
|
||||||
# because nothing else uses it.
|
|
||||||
#element.stmt.parent = loop
|
|
||||||
return self.eval_statement(element.stmt)
|
return self.eval_statement(element.stmt)
|
||||||
elif isinstance(element, pr.Lambda):
|
elif isinstance(element, pr.Lambda):
|
||||||
return [er.Function(self, element)]
|
return [er.Function(self, element)]
|
||||||
|
|||||||
@@ -470,8 +470,8 @@ def get_names_of_scope(evaluator, scope, position=None, star_search=True, includ
|
|||||||
:rtype: [(pr.Scope, [pr.Name])]
|
:rtype: [(pr.Scope, [pr.Name])]
|
||||||
:return: Return an generator that yields a pair of scope and names.
|
:return: Return an generator that yields a pair of scope and names.
|
||||||
"""
|
"""
|
||||||
if isinstance(scope, iterable.ListComprehensionFlow):
|
if isinstance(scope, pr.ListComprehension):
|
||||||
position = scope.list_comprehension.parent.start_pos
|
position = scope.parent.start_pos
|
||||||
|
|
||||||
in_func_scope = scope
|
in_func_scope = scope
|
||||||
non_flow = scope.get_parent_until(pr.Flow, reverse=True)
|
non_flow = scope.get_parent_until(pr.Flow, reverse=True)
|
||||||
@@ -497,7 +497,7 @@ def get_names_of_scope(evaluator, scope, position=None, star_search=True, includ
|
|||||||
yield scope, _get_defined_names_for_position(scope, position, in_func_scope)
|
yield scope, _get_defined_names_for_position(scope, position, in_func_scope)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
reraise(common.MultiLevelStopIteration, sys.exc_info()[2])
|
reraise(common.MultiLevelStopIteration, sys.exc_info()[2])
|
||||||
if scope.isinstance(iterable.ListComprehensionFlow):
|
if scope.isinstance(pr.ListComprehension):
|
||||||
# is a list comprehension
|
# is a list comprehension
|
||||||
yield scope, scope.get_defined_names(is_internal_call=True)
|
yield scope, scope.get_defined_names(is_internal_call=True)
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ class _RecursionNode(object):
|
|||||||
if not other:
|
if not other:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
is_list_comp = lambda x: isinstance(x, iterable.ListComprehensionFlow)
|
is_list_comp = lambda x: isinstance(x, pr.ListComprehension)
|
||||||
return self.script == other.script \
|
return self.script == other.script \
|
||||||
and self.position == other.position \
|
and self.position == other.position \
|
||||||
and not is_list_comp(self.stmt.parent) \
|
and not is_list_comp(self.stmt.parent) \
|
||||||
|
|||||||
@@ -1483,20 +1483,22 @@ class Name(Simple):
|
|||||||
class ListComprehension(ForFlow):
|
class ListComprehension(ForFlow):
|
||||||
""" Helper class for list comprehensions """
|
""" Helper class for list comprehensions """
|
||||||
def __init__(self, module, stmt, middle, input, parent):
|
def __init__(self, module, stmt, middle, input, parent):
|
||||||
self.stmt = stmt
|
|
||||||
self.middle = middle
|
|
||||||
self.input = input
|
self.input = input
|
||||||
for s in middle, input:
|
|
||||||
s.parent = self
|
|
||||||
stmt.parent = self._get_most_inner_lc()
|
|
||||||
self.parent = parent
|
|
||||||
|
|
||||||
nested_lc = input.expression_list()[0]
|
nested_lc = input.expression_list()[0]
|
||||||
if isinstance(nested_lc, ListComprehension):
|
if isinstance(nested_lc, ListComprehension):
|
||||||
# is nested LC
|
# is nested LC
|
||||||
input = nested_lc.stmt
|
input = nested_lc.stmt
|
||||||
|
nested_lc.parent = self
|
||||||
|
|
||||||
super(ListComprehension, self).__init__(module, [input],
|
super(ListComprehension, self).__init__(module, [input],
|
||||||
stmt.start_pos, middle)
|
stmt.start_pos, middle)
|
||||||
|
self.parent = parent
|
||||||
|
self.stmt = stmt
|
||||||
|
self.middle = middle
|
||||||
|
for s in middle, input:
|
||||||
|
s.parent = self
|
||||||
|
# The stmt always refers to the most inner list comprehension.
|
||||||
|
stmt.parent = self._get_most_inner_lc()
|
||||||
|
|
||||||
def _get_most_inner_lc(self):
|
def _get_most_inner_lc(self):
|
||||||
nested_lc = self.input.expression_list()[0]
|
nested_lc = self.input.expression_list()[0]
|
||||||
@@ -1517,31 +1519,6 @@ class ListComprehension(ForFlow):
|
|||||||
return "%s for %s in %s" % tuple(code)
|
return "%s for %s in %s" % tuple(code)
|
||||||
|
|
||||||
|
|
||||||
def _evaluate_list_comprehension(lc, parent=None):
|
|
||||||
# create a for loop, which does the same as list comprehensions
|
|
||||||
input = lc.input
|
|
||||||
nested_lc = input.expression_list()[0]
|
|
||||||
if isinstance(nested_lc, ListComprehension):
|
|
||||||
# is nested LC
|
|
||||||
input = nested_lc.stmt
|
|
||||||
loop = ListComprehensionFlow(lc, input, parent)
|
|
||||||
|
|
||||||
if isinstance(nested_lc, ListComprehension):
|
|
||||||
loop = _evaluate_list_comprehension(nested_lc, loop)
|
|
||||||
return loop
|
|
||||||
|
|
||||||
|
|
||||||
class ListComprehensionFlow(ForFlow):
|
|
||||||
"""Fake implementation to pretend being a ForFlow."""
|
|
||||||
def __init__(self, list_comprehension, input, parent):
|
|
||||||
lc = list_comprehension
|
|
||||||
sup = super(ListComprehensionFlow, self)
|
|
||||||
module = list_comprehension.get_parent_until()
|
|
||||||
sup.__init__(module, [input], lc.parent.start_pos, lc.middle)
|
|
||||||
self.parent = parent or lc.get_parent_until(IsScope)
|
|
||||||
self.list_comprehension = list_comprehension
|
|
||||||
|
|
||||||
|
|
||||||
class Operator(Base):
|
class Operator(Base):
|
||||||
__slots__ = ('string', '_line', '_column')
|
__slots__ = ('string', '_line', '_column')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user