diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 29e94540..5ead17a3 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -136,7 +136,6 @@ class Evaluator(object): if seek_name: types = finder.check_tuple_assignments(types, seek_name) - ass_details = stmt.assignment_details first_operation = stmt.first_operation() if first_operation not in ('=', None) and not isinstance(stmt, er.InstanceElement): # TODO don't check for this. # `=` is always the last character in aug assignments -> -1 diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index 3eb25bd4..cbbd3766 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -159,7 +159,7 @@ class NameFinder(object): # might still have conditions if defined outside of the # current scope. if isinstance(stmt, (pr.Param, pr.Import)) \ - or isinstance(name_list_scope, (pr.Lambda, pr.ListComprehension, er.Instance, InterpreterNamespace)) \ + or isinstance(name_list_scope, (pr.Lambda, er.Instance, InterpreterNamespace)) \ or isinstance(scope, compiled.CompiledObject): # Always reachable. names.append(name) @@ -248,6 +248,9 @@ class NameFinder(object): return True def _name_is_array_assignment(self, name, stmt): + return False + + # TODO DELETE this? or change it? if stmt.isinstance(pr.ExprStmt): def is_execution(calls): for c in calls: @@ -528,9 +531,6 @@ def get_names_of_scope(evaluator, scope, position=None, star_search=True, includ :rtype: [(pr.Scope, [pr.Name])] :return: Return an generator that yields a pair of scope and names. """ - if isinstance(scope, pr.ListComprehension): - position = scope.parent.start_pos - in_func_scope = scope non_flow = scope.get_parent_until(pr.Flow, reverse=True) while scope: @@ -554,9 +554,6 @@ def get_names_of_scope(evaluator, scope, position=None, star_search=True, includ for g in scope.scope_names_generator(position): yield g - if scope.isinstance(pr.ListComprehension): - # is a list comprehension - yield scope, scope.get_defined_names(is_internal_call=True) scope = scope.parent # This is used, because subscopes (Flow scopes) would distort the diff --git a/jedi/evaluate/helpers.py b/jedi/evaluate/helpers.py index b16449c7..5c8ffb3e 100644 --- a/jedi/evaluate/helpers.py +++ b/jedi/evaluate/helpers.py @@ -199,7 +199,8 @@ def search_call_signatures(user_stmt, position): # Now remove the part after the call. Including the array from the # statement. stmt_el = call - while isinstance(stmt_el, pr.StatementElement): + # TODO REMOVE this? or change? + while False and isinstance(stmt_el, pr.StatementElement): if stmt_el.next == arr: stmt_el.next = None break diff --git a/jedi/parser/representation.py b/jedi/parser/representation.py index ea5bd01f..4a737344 100644 --- a/jedi/parser/representation.py +++ b/jedi/parser/representation.py @@ -1294,56 +1294,13 @@ class Statement(Simple, DocstringMixin): :type start_pos: 2-tuple of int :param start_pos: Position (line, column) of the Statement. """ - __slots__ = ('_token_list', '_set_vars', 'as_names', '_expression_list', - '_assignment_details', '_names_are_set_vars', '_doc_token') - - def __init__old(self, children, parent=None,): - super(Statement, self).__init__(module, start_pos, end_pos, parent) - self._token_list = token_list - self._names_are_set_vars = names_are_set_vars - if set_name_parents: - for n in as_names: - n.parent = self.use_as_parent - self._doc_token = None - self._set_vars = None - self.as_names = list(as_names) - - # cache - self._assignment_details = [] - # For now just generate the expression list, even if its not needed. - # This will help to adapt a better new AST. - self.expression_list() + __slots__ = () def get_defined_names(self): return list(chain.from_iterable(_defined_names(self.children[i]) for i in range(0, len(self.children) - 2, 2) if '=' in self.children[i + 1].value)) - - """Get the names for the statement.""" - if self._set_vars is None: - - def search_calls(calls): - for call in calls: - if isinstance(call, Array) and call.type != Array.DICT: - for stmt in call: - search_calls(stmt.expression_list()) - elif isinstance(call, Call): - # Check if there's an execution in it, if so this is - # not a set_var. - if not call.next: - self._set_vars.append(call.name) - continue - - self._set_vars = [] - for calls, operation in self.assignment_details: - search_calls(calls) - - if not self.assignment_details and self._names_are_set_vars: - # In the case of Param, it's also a defining name without ``=`` - search_calls(self.expression_list()) - return self._set_vars + self.as_names - def get_rhs(self): """Returns the right-hand-side of the equals.""" return self.children[-1] @@ -1388,23 +1345,6 @@ class Statement(Simple, DocstringMixin): except IndexError: return None - @property - def assignment_details(self): - """ - Returns an array of tuples of the elements before the assignment. - - For example the following code:: - - x = (y, z) = 2, '' - - would result in ``[(Name(x), '='), (Array([Name(y), Name(z)]), '=')]``. - """ - return [] - - def set_expression_list(self, lst): - """It's necessary for some "hacks" to change the expression_list.""" - self._expression_list = lst - class ExprStmt(Statement): """ @@ -1418,14 +1358,6 @@ class ExprStmt(Statement): """ -class ArrayStmt(Statement): - """ - This class exists temporarily. Like ``ExprStatement``, this exists to - distinguish between real statements and stuff that is defined in those - statements. - """ - - class Param(Base): """ The class which shows definitions of params of classes and functions. @@ -1498,136 +1430,14 @@ class Param(Base): return '<%s: %s>' % (type(self).__name__, str(self.tfpdef) + default) -class StatementElement(Simple): - __slots__ = ('next', 'previous') - - def __init__(self, module, start_pos, end_pos, parent): - super(StatementElement, self).__init__(module, start_pos, end_pos, parent) - self.next = None - self.previous = None - - def set_next(self, call): - """ Adds another part of the statement""" - call.parent = self.parent - if self.next is not None: - self.next.set_next(call) - else: - self.next = call - call.previous = self - - def next_is_execution(self): - return Array.is_type(self.next, Array.TUPLE, Array.NOARRAY) - - def generate_call_path(self): - """ Helps to get the order in which statements are executed. """ - try: - yield self.name - except AttributeError: - yield self - if self.next is not None: - for y in self.next.generate_call_path(): - yield y - - -class Call(StatementElement): - __slots__ = ('name',) - - def __init__(self, module, name, start_pos, end_pos, parent=None): - super(Call, self).__init__(module, start_pos, end_pos, parent) - name.parent = self - self.name = name - - def names(self): - """ - Generate an array of string names. If a call is not just names, - raise an error. - """ - def check(call): - while call is not None: - if not isinstance(call, Call): # Could be an Array. - break - yield unicode(call.name) - call = call.next - - return list(check(self)) - - - def __repr__(self): - return "<%s: %s>" % (type(self).__name__, self.name) - - -class Array(StatementElement): - """ - Describes the different python types for an array, but also empty - statements. In the Python syntax definitions this type is named 'atom'. - http://docs.python.org/py3k/reference/grammar.html - Array saves sub-arrays as well as normal operators and calls to methods. - - :param array_type: The type of an array, which can be one of the constants - below. - :type array_type: int - """ - __slots__ = ('type', 'end_pos', 'values', 'keys') +class Array(object): + # TODO remove this. Just here because we need these names. NOARRAY = None # just brackets, like `1 * (3 + 2)` TUPLE = 'tuple' LIST = 'list' DICT = 'dict' SET = 'set' - def __init__(self, module, start_pos, arr_type=NOARRAY, parent=None): - super(Array, self).__init__(module, start_pos, (None, None), parent) - self.end_pos = None, None - self.type = arr_type - self.values = [] - self.keys = [] - - def add_statement(self, statement, is_key=False): - """Just add a new statement""" - statement.parent = self - if is_key: - self.type = self.DICT - self.keys.append(statement) - else: - self.values.append(statement) - - @staticmethod - def is_type(instance, *types): - """ - This is not only used for calls on the actual object, but for - ducktyping, to invoke this function with anything as `self`. - """ - try: - if instance.type in types: - return True - except AttributeError: - pass - return False - - def __len__(self): - return len(self.values) - - def __getitem__(self, key): - if self.type == self.DICT: - raise TypeError('no dicts allowed') - return self.values[key] - - def __iter__(self): - if self.type == self.DICT: - raise TypeError('no dicts allowed') - return iter(self.values) - - def items(self): - if self.type != self.DICT: - raise TypeError('only dicts allowed') - return zip(self.keys, self.values) - - def __repr__(self): - if self.type == self.NOARRAY: - typ = 'noarray' - else: - typ = self.type - return "<%s: %s%s>" % (type(self).__name__, typ, self.values) - class CompFor(Simple): def is_scope(self): @@ -1649,37 +1459,3 @@ class CompFor(Simple): def scope_names_generator(self, position): yield self, [] - - -class ListComprehension(ForFlow): - """ Helper class for list comprehensions """ - def __init__(self, module, stmt, middle, input, parent): - self.input = input - nested_lc = input.expression_list()[0] - if isinstance(nested_lc, ListComprehension): - # is nested LC - input = nested_lc.stmt - nested_lc.parent = self - - super(ListComprehension, self).__init__(module, [input], - 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): - nested_lc = self.input.expression_list()[0] - if isinstance(nested_lc, ListComprehension): - return nested_lc._get_most_inner_lc() - return self - - @property - def end_pos(self): - return self.stmt.end_pos - - def __repr__(self): - return "<%s: %s>" % (type(self).__name__, self.get_code())