forked from VimPlug/jedi
Processing atom and power nodes.
This commit is contained in:
@@ -73,6 +73,7 @@ from itertools import tee, chain
|
||||
|
||||
from jedi._compatibility import next, hasattr, unicode
|
||||
from jedi.parser import representation as pr
|
||||
from jedi.parser.pytree import python_symbols
|
||||
from jedi.parser.tokenize import Token
|
||||
from jedi.parser import fast
|
||||
from jedi import debug
|
||||
@@ -129,7 +130,7 @@ class Evaluator(object):
|
||||
if isinstance(stmt, FakeStatement):
|
||||
return stmt.children # Already contains the results.
|
||||
|
||||
result = self.eval_element(stmt.children[0])
|
||||
result = self.eval_element(stmt.get_rhs())
|
||||
|
||||
ass_details = stmt.assignment_details
|
||||
if ass_details and ass_details[0][1] != '=' and not isinstance(stmt, er.InstanceElement): # TODO don't check for this.
|
||||
@@ -161,13 +162,68 @@ class Evaluator(object):
|
||||
return result
|
||||
|
||||
def eval_element(self, element):
|
||||
if isinstance(element, pr.Name):
|
||||
stmt = element.get_parent_until(pr.ExprStmt)
|
||||
return self.find_types(stmt.parent, element, stmt.start_pos,
|
||||
search_global=True)
|
||||
if isinstance(element, (pr.Name, pr.Literal)):
|
||||
return self.eval_atom(element)
|
||||
elif element.type == python_symbols.power:
|
||||
types = self.eval_atom(element.children[0])
|
||||
for trailer in element.children[1:]:
|
||||
if trailer == '**': # has a power operation.
|
||||
raise NotImplementedError
|
||||
types = self.eval_trailer(types, trailer)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
def eval_atom(self, atom):
|
||||
"""
|
||||
Basically to process ``atom`` nodes. The parser sometimes doesn't
|
||||
generate the node (because it has just one child). In that case an atom
|
||||
might be a name or a literal as well.
|
||||
"""
|
||||
if isinstance(atom, pr.Name):
|
||||
# This is the first global lookup.
|
||||
stmt = atom.get_parent_until(pr.ExprStmt)
|
||||
return self.find_types(stmt.parent, atom, stmt.start_pos,
|
||||
search_global=True)
|
||||
elif isinstance(atom, pr.Literal):
|
||||
return [compiled.create(self, atom.value)]
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
def eval_trailer(self, types, trailer):
|
||||
trailer_op, node = trailer.children[:2]
|
||||
new_types = []
|
||||
for typ in types:
|
||||
if trailer_op == '.':
|
||||
raise NotImplementedError
|
||||
elif trailer_op == '(':
|
||||
new_types += self.execute(typ, node)
|
||||
elif trailer_op == '[':
|
||||
raise NotImplementedError
|
||||
return new_types
|
||||
|
||||
@debug.increase_indent
|
||||
def execute(self, obj, params=()):
|
||||
if obj.isinstance(er.Function):
|
||||
obj = obj.get_decorated_func()
|
||||
|
||||
debug.dbg('execute: %s %s', obj, params)
|
||||
try:
|
||||
# Some stdlib functions like super(), namedtuple(), etc. have been
|
||||
# hard-coded in Jedi to support them.
|
||||
return stdlib.execute(self, obj, params)
|
||||
except stdlib.NotInStdLib:
|
||||
pass
|
||||
|
||||
try:
|
||||
func = obj.py__call__
|
||||
except AttributeError:
|
||||
debug.warning("no execution possible %s", obj)
|
||||
return []
|
||||
else:
|
||||
types = func(self, params)
|
||||
debug.dbg('execute result: %s in %s', types, obj)
|
||||
return types
|
||||
|
||||
def eval_expression_list(self, expression_list):
|
||||
"""
|
||||
`expression_list` can be either `pr.Array` or `list of list`.
|
||||
@@ -302,7 +358,7 @@ class Evaluator(object):
|
||||
return self.follow_path(path, result, scope)
|
||||
|
||||
@debug.increase_indent
|
||||
def execute(self, obj, params=()):
|
||||
def execute_old(self, obj, params=()):
|
||||
if obj.isinstance(er.Function):
|
||||
obj = obj.get_decorated_func()
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ class Name(_Leaf):
|
||||
self.start_pos[0], self.start_pos[1])
|
||||
|
||||
def get_definition(self):
|
||||
return self.parent.get_parent_until((ArrayStmt, StatementElement), reverse=True)
|
||||
return self.parent.get_parent_until((ArrayStmt, StatementElement, Node), reverse=True)
|
||||
|
||||
|
||||
class Literal(_Leaf):
|
||||
@@ -1016,6 +1016,8 @@ class Statement(Simple, DocstringMixin):
|
||||
names.append(first.children[i])
|
||||
return names
|
||||
return []
|
||||
|
||||
|
||||
"""Get the names for the statement."""
|
||||
if self._set_vars is None:
|
||||
|
||||
@@ -1040,6 +1042,14 @@ class Statement(Simple, DocstringMixin):
|
||||
search_calls(self.expression_list())
|
||||
return self._set_vars + self.as_names
|
||||
|
||||
def get_rhs(self):
|
||||
"""Returns the right-hand-side of the equals."""
|
||||
# TODO remove expr_stmt?
|
||||
if is_node(self.children[0], 'expr_stmt'):
|
||||
return self.children[0].children[-1]
|
||||
else:
|
||||
return self.children[0]
|
||||
|
||||
def get_names_dict(self):
|
||||
"""The future of name resolution. Returns a dict(str -> Call)."""
|
||||
dct = defaultdict(lambda: [])
|
||||
|
||||
Reference in New Issue
Block a user