1
0
forked from VimPlug/jedi

Remove quite a bit of the old parser representation logic.

This commit is contained in:
Dave Halter
2014-11-23 19:26:30 +01:00
parent 0f21d38e2c
commit 9b54541cae
4 changed files with 9 additions and 236 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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())