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._compatibility import next, hasattr, unicode
|
||||||
from jedi.parser import representation as pr
|
from jedi.parser import representation as pr
|
||||||
|
from jedi.parser.pytree import python_symbols
|
||||||
from jedi.parser.tokenize import Token
|
from jedi.parser.tokenize import Token
|
||||||
from jedi.parser import fast
|
from jedi.parser import fast
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
@@ -129,7 +130,7 @@ class Evaluator(object):
|
|||||||
if isinstance(stmt, FakeStatement):
|
if isinstance(stmt, FakeStatement):
|
||||||
return stmt.children # Already contains the results.
|
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
|
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.
|
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
|
return result
|
||||||
|
|
||||||
def eval_element(self, element):
|
def eval_element(self, element):
|
||||||
if isinstance(element, pr.Name):
|
if isinstance(element, (pr.Name, pr.Literal)):
|
||||||
stmt = element.get_parent_until(pr.ExprStmt)
|
return self.eval_atom(element)
|
||||||
return self.find_types(stmt.parent, element, stmt.start_pos,
|
elif element.type == python_symbols.power:
|
||||||
search_global=True)
|
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:
|
else:
|
||||||
raise NotImplementedError
|
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):
|
def eval_expression_list(self, expression_list):
|
||||||
"""
|
"""
|
||||||
`expression_list` can be either `pr.Array` or `list of 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)
|
return self.follow_path(path, result, scope)
|
||||||
|
|
||||||
@debug.increase_indent
|
@debug.increase_indent
|
||||||
def execute(self, obj, params=()):
|
def execute_old(self, obj, params=()):
|
||||||
if obj.isinstance(er.Function):
|
if obj.isinstance(er.Function):
|
||||||
obj = obj.get_decorated_func()
|
obj = obj.get_decorated_func()
|
||||||
|
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ class Name(_Leaf):
|
|||||||
self.start_pos[0], self.start_pos[1])
|
self.start_pos[0], self.start_pos[1])
|
||||||
|
|
||||||
def get_definition(self):
|
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):
|
class Literal(_Leaf):
|
||||||
@@ -1016,6 +1016,8 @@ class Statement(Simple, DocstringMixin):
|
|||||||
names.append(first.children[i])
|
names.append(first.children[i])
|
||||||
return names
|
return names
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
"""Get the names for the statement."""
|
"""Get the names for the statement."""
|
||||||
if self._set_vars is None:
|
if self._set_vars is None:
|
||||||
|
|
||||||
@@ -1040,6 +1042,14 @@ class Statement(Simple, DocstringMixin):
|
|||||||
search_calls(self.expression_list())
|
search_calls(self.expression_list())
|
||||||
return self._set_vars + self.as_names
|
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):
|
def get_names_dict(self):
|
||||||
"""The future of name resolution. Returns a dict(str -> Call)."""
|
"""The future of name resolution. Returns a dict(str -> Call)."""
|
||||||
dct = defaultdict(lambda: [])
|
dct = defaultdict(lambda: [])
|
||||||
|
|||||||
Reference in New Issue
Block a user