1
0
forked from VimPlug/jedi

Processing atom and power nodes.

This commit is contained in:
Dave Halter
2014-10-15 13:40:56 +02:00
parent 485b8ae3da
commit 631aa0ea61
2 changed files with 73 additions and 7 deletions

View File

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

View File

@@ -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: [])