forked from VimPlug/jedi
Statement -> ExprStmt.
This commit is contained in:
@@ -334,7 +334,7 @@ class BaseDefinition(object):
|
|||||||
# Functions, classes and modules are already fixed definitions, we
|
# Functions, classes and modules are already fixed definitions, we
|
||||||
# cannot follow them anymore.
|
# cannot follow them anymore.
|
||||||
return [self]
|
return [self]
|
||||||
stmt_or_imp = self._name.get_parent_until((pr.Statement, pr.Import))
|
stmt_or_imp = self._name.get_parent_until((pr.ExprStmt, pr.Import))
|
||||||
call_path = call_path_for_name_part(stmt_or_imp, self._name)
|
call_path = call_path_for_name_part(stmt_or_imp, self._name)
|
||||||
names = self._evaluator.goto(stmt_or_imp, call_path)
|
names = self._evaluator.goto(stmt_or_imp, call_path)
|
||||||
return [Definition(self._evaluator, n) for n in names]
|
return [Definition(self._evaluator, n) for n in names]
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ def deep_ast_copy(obj, new_elements_default=None, check_first=False):
|
|||||||
new_obj = copy.copy(obj)
|
new_obj = copy.copy(obj)
|
||||||
new_elements[obj] = new_obj
|
new_elements[obj] = new_obj
|
||||||
|
|
||||||
if isinstance(obj, pr.Statement):
|
if isinstance(obj, pr.ExprStmt):
|
||||||
# Need to set _set_vars, otherwise the cache is not working
|
# Need to set _set_vars, otherwise the cache is not working
|
||||||
# correctly, don't know exactly why.
|
# correctly, don't know exactly why.
|
||||||
obj.get_defined_names()
|
obj.get_defined_names()
|
||||||
@@ -50,7 +50,7 @@ def deep_ast_copy(obj, new_elements_default=None, check_first=False):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if isinstance(obj, pr.Statement):
|
if isinstance(obj, pr.ExprStmt):
|
||||||
# We need to process something with priority for statements,
|
# We need to process something with priority for statements,
|
||||||
# because there are several references that don't walk the whole
|
# because there are several references that don't walk the whole
|
||||||
# tree in there.
|
# tree in there.
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class Arguments(pr.Base):
|
|||||||
named_index = None
|
named_index = None
|
||||||
new_args = []
|
new_args = []
|
||||||
for i, stmt in enumerate(var_args):
|
for i, stmt in enumerate(var_args):
|
||||||
if isinstance(stmt, pr.Statement):
|
if isinstance(stmt, pr.ExprStmt):
|
||||||
if named_index is None and stmt.assignment_details:
|
if named_index is None and stmt.assignment_details:
|
||||||
named_index = i
|
named_index = i
|
||||||
|
|
||||||
@@ -362,7 +362,7 @@ def _unpack_var_args(evaluator, var_args, func):
|
|||||||
|
|
||||||
# `var_args` is typically an Array, and not a list.
|
# `var_args` is typically an Array, and not a list.
|
||||||
for stmt in _reorder_var_args(var_args.iterate()):
|
for stmt in _reorder_var_args(var_args.iterate()):
|
||||||
if not isinstance(stmt, pr.Statement):
|
if not isinstance(stmt, pr.ExprStmt):
|
||||||
if stmt is None:
|
if stmt is None:
|
||||||
argument_list.append((None, []))
|
argument_list.append((None, []))
|
||||||
# TODO generate warning?
|
# TODO generate warning?
|
||||||
|
|||||||
@@ -367,6 +367,8 @@ class Parser(object):
|
|||||||
return "<%s: %s>" % (type(self).__name__, self.module)
|
return "<%s: %s>" % (type(self).__name__, self.module)
|
||||||
|
|
||||||
def _check_user_stmt(self, simple):
|
def _check_user_stmt(self, simple):
|
||||||
|
# TODO REMOVE (not used and called)
|
||||||
|
|
||||||
# this is not user checking, just update the used_names
|
# this is not user checking, just update the used_names
|
||||||
for tok_name in self.module.temp_used_names:
|
for tok_name in self.module.temp_used_names:
|
||||||
try:
|
try:
|
||||||
@@ -374,7 +376,7 @@ class Parser(object):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
self.module.used_names[tok_name] = set([simple])
|
self.module.used_names[tok_name] = set([simple])
|
||||||
self.module.temp_used_names = []
|
self.module.temp_used_names = []
|
||||||
if isinstance(simple, pt.Statement):
|
if isinstance(simple, pt.ExprStmt):
|
||||||
for name, calls in simple.get_names_dict().items():
|
for name, calls in simple.get_names_dict().items():
|
||||||
self._scope.add_name_calls(name, calls)
|
self._scope.add_name_calls(name, calls)
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ See also :attr:`Scope.subscopes` and :attr:`Scope.statements`.
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from inspect import cleandoc
|
from inspect import cleandoc
|
||||||
from collections import defaultdict
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
@@ -234,13 +233,13 @@ class Whitespace(LeafWithNewLines):
|
|||||||
"""Contains NEWLINE and ENDMARKER tokens."""
|
"""Contains NEWLINE and ENDMARKER tokens."""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Name(Leaf):
|
class Name(Leaf):
|
||||||
"""
|
"""
|
||||||
A string. Sometimes it is important to know if the string belongs to a name
|
A string. Sometimes it is important to know if the string belongs to a name
|
||||||
or not.
|
or not.
|
||||||
"""
|
"""
|
||||||
type = 'name'
|
type = 'name'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
@@ -335,6 +334,7 @@ class String(Literal):
|
|||||||
|
|
||||||
class Operator(Leaf):
|
class Operator(Leaf):
|
||||||
type = 'operator'
|
type = 'operator'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
@@ -358,6 +358,7 @@ class Operator(Leaf):
|
|||||||
|
|
||||||
class Keyword(Leaf):
|
class Keyword(Leaf):
|
||||||
type = 'keyword'
|
type = 'keyword'
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"""
|
"""
|
||||||
Make comparisons with strings easy.
|
Make comparisons with strings easy.
|
||||||
@@ -892,6 +893,7 @@ class Lambda(Function):
|
|||||||
Lambdas are basically trimmed functions, so give it the same interface.
|
Lambdas are basically trimmed functions, so give it the same interface.
|
||||||
"""
|
"""
|
||||||
type = 'lambda'
|
type = 'lambda'
|
||||||
|
|
||||||
def __init__(self, children):
|
def __init__(self, children):
|
||||||
super(Function, self).__init__(children)
|
super(Function, self).__init__(children)
|
||||||
self.listeners = set() # not used here, but in evaluation.
|
self.listeners = set() # not used here, but in evaluation.
|
||||||
@@ -914,6 +916,7 @@ class Flow(Simple):
|
|||||||
|
|
||||||
class IfStmt(Flow):
|
class IfStmt(Flow):
|
||||||
type = 'if_stmt'
|
type = 'if_stmt'
|
||||||
|
|
||||||
def check_nodes(self):
|
def check_nodes(self):
|
||||||
"""
|
"""
|
||||||
Returns all the `test` nodes that are defined as x, here:
|
Returns all the `test` nodes that are defined as x, here:
|
||||||
@@ -969,6 +972,7 @@ class TryStmt(Flow):
|
|||||||
|
|
||||||
class WithStmt(Flow):
|
class WithStmt(Flow):
|
||||||
type = 'with_stmt'
|
type = 'with_stmt'
|
||||||
|
|
||||||
def get_defined_names(self):
|
def get_defined_names(self):
|
||||||
names = []
|
names = []
|
||||||
for with_item in self.children[1:-2:2]:
|
for with_item in self.children[1:-2:2]:
|
||||||
@@ -1011,6 +1015,7 @@ class Import(Simple):
|
|||||||
|
|
||||||
class ImportFrom(Import):
|
class ImportFrom(Import):
|
||||||
type = 'import_from'
|
type = 'import_from'
|
||||||
|
|
||||||
def get_defined_names(self):
|
def get_defined_names(self):
|
||||||
return [alias or name for name, alias in self._as_name_tuples()]
|
return [alias or name for name, alias in self._as_name_tuples()]
|
||||||
|
|
||||||
@@ -1135,12 +1140,14 @@ class KeywordStatement(Simple):
|
|||||||
|
|
||||||
class AssertStmt(KeywordStatement):
|
class AssertStmt(KeywordStatement):
|
||||||
type = 'assert_stmt'
|
type = 'assert_stmt'
|
||||||
|
|
||||||
def assertion(self):
|
def assertion(self):
|
||||||
return self.children[1]
|
return self.children[1]
|
||||||
|
|
||||||
|
|
||||||
class GlobalStmt(KeywordStatement):
|
class GlobalStmt(KeywordStatement):
|
||||||
type = 'global_stmt'
|
type = 'global_stmt'
|
||||||
|
|
||||||
def get_defined_names(self):
|
def get_defined_names(self):
|
||||||
return self.children[1::2]
|
return self.children[1::2]
|
||||||
|
|
||||||
@@ -1174,22 +1181,8 @@ def _defined_names(current):
|
|||||||
return names
|
return names
|
||||||
|
|
||||||
|
|
||||||
class Statement(Simple, DocstringMixin):
|
class ExprStmt(Simple, DocstringMixin):
|
||||||
"""
|
type = 'expr_stmt'
|
||||||
This is the class for all the possible statements. Which means, this class
|
|
||||||
stores pretty much all the Python code, except functions, classes, imports,
|
|
||||||
and flow functions like if, for, etc.
|
|
||||||
|
|
||||||
:type token_list: list
|
|
||||||
:param token_list:
|
|
||||||
List of tokens or names. Each element is either an instance
|
|
||||||
of :class:`Name` or a tuple of token type value (e.g.,
|
|
||||||
:data:`tokenize.NUMBER`), token string (e.g., ``'='``), and
|
|
||||||
start position (e.g., ``(1, 0)``).
|
|
||||||
:type start_pos: 2-tuple of int
|
|
||||||
:param start_pos: Position (line, column) of the Statement.
|
|
||||||
"""
|
|
||||||
__slots__ = ()
|
|
||||||
|
|
||||||
def get_defined_names(self):
|
def get_defined_names(self):
|
||||||
return list(chain.from_iterable(_defined_names(self.children[i])
|
return list(chain.from_iterable(_defined_names(self.children[i])
|
||||||
@@ -1200,37 +1193,6 @@ class Statement(Simple, DocstringMixin):
|
|||||||
"""Returns the right-hand-side of the equals."""
|
"""Returns the right-hand-side of the equals."""
|
||||||
return self.children[-1]
|
return self.children[-1]
|
||||||
|
|
||||||
def get_names_dict(self):
|
|
||||||
"""The future of name resolution. Returns a dict(str -> Call)."""
|
|
||||||
dct = defaultdict(lambda: [])
|
|
||||||
|
|
||||||
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):
|
|
||||||
c = call
|
|
||||||
# Check if there's an execution in it, if so this is
|
|
||||||
# not a set_var.
|
|
||||||
while True:
|
|
||||||
if c.next is None or isinstance(c.next, Array):
|
|
||||||
break
|
|
||||||
c = c.next
|
|
||||||
dct[unicode(c.name)].append(call)
|
|
||||||
|
|
||||||
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())
|
|
||||||
|
|
||||||
for as_name in self.as_names:
|
|
||||||
dct[unicode(as_name)].append(Call(self._sub_module, as_name,
|
|
||||||
as_name.start_pos, as_name.end_pos, self))
|
|
||||||
return dct
|
|
||||||
|
|
||||||
def first_operation(self):
|
def first_operation(self):
|
||||||
"""
|
"""
|
||||||
Returns `+=`, `=`, etc or None if there is no operation.
|
Returns `+=`, `=`, etc or None if there is no operation.
|
||||||
@@ -1241,19 +1203,6 @@ class Statement(Simple, DocstringMixin):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class ExprStmt(Statement):
|
|
||||||
"""
|
|
||||||
This class exists temporarily, to be able to distinguish real statements
|
|
||||||
(``small_stmt`` in Python grammar) from the so called ``test`` parts, that
|
|
||||||
may be used to defined part of an array, but are never a whole statement.
|
|
||||||
|
|
||||||
The reason for this class is purely historical. It was easier to just use
|
|
||||||
Statement nested, than to create a new class for Test (plus Jedi's fault
|
|
||||||
tolerant parser just makes things very complicated).
|
|
||||||
"""
|
|
||||||
type = 'expr_stmt'
|
|
||||||
|
|
||||||
|
|
||||||
class Param(Base):
|
class Param(Base):
|
||||||
"""
|
"""
|
||||||
The class which shows definitions of params of classes and functions.
|
The class which shows definitions of params of classes and functions.
|
||||||
|
|||||||
Reference in New Issue
Block a user