1
0
forked from VimPlug/jedi

follow_paths -> follow_path, follow_path -> _follow_path

This commit is contained in:
Dave Halter
2013-12-28 15:00:04 +01:00
parent 46dd0a9abe
commit 75a1b6f8cb
5 changed files with 23 additions and 27 deletions

View File

@@ -38,13 +38,13 @@ kick in. The statement has not been resolved fully, but now we need to resolve
the datetime import. So it continues the datetime import. So it continues
- follow import, which happens in the :mod:`imports` module. - follow import, which happens in the :mod:`imports` module.
- now the same ``eval_call`` as above calls ``follow_paths`` to follow the - now the same ``eval_call`` as above calls ``follow_path`` to follow the
second part of the statement ``date``. second part of the statement ``date``.
- After ``follow_paths`` returns with the desired ``datetime.date`` class, the - After ``follow_path`` returns with the desired ``datetime.date`` class, the
result is being returned and the recursion finishes. result is being returned and the recursion finishes.
Now what would happen if we wanted ``datetime.date.foo.bar``? Just two more Now what would happen if we wanted ``datetime.date.foo.bar``? Just two more
calls to ``follow_paths`` (which calls itself with a recursion). What if the calls to ``follow_path`` (which calls itself with a recursion). What if the
import would contain another Statement like this:: import would contain another Statement like this::
from foo import bar from foo import bar
@@ -534,7 +534,7 @@ class Evaluator(object):
for s in call)) for s in call))
call_path = call.generate_call_path() call_path = call.generate_call_path()
next(call_path, None) # the first one has been used already next(call_path, None) # the first one has been used already
result += self.follow_paths(call_path, r, call.parent, result += self.follow_path(call_path, r, call.parent,
position=call.start_pos) position=call.start_pos)
elif isinstance(call, pr.ListComprehension): elif isinstance(call, pr.ListComprehension):
loop = evaluate_list_comprehension(call) loop = evaluate_list_comprehension(call)
@@ -601,35 +601,31 @@ class Evaluator(object):
scopes = [er.Instance(self, s, (current.value,)) for s in scopes] scopes = [er.Instance(self, s, (current.value,)) for s in scopes]
result = imports.strip_imports(self, scopes) result = imports.strip_imports(self, scopes)
return self.follow_paths(path, result, scope, position=position) return self.follow_path(path, result, scope, position=position)
def follow_paths(self, path, results, call_scope, position=None): def follow_path(self, path, types, call_scope, position=None):
""" """
In each result, `path` must be followed. Copies the path iterator. In each result, `path` must be followed. Copies the path iterator.
""" """
results_new = [] results_new = []
if results: iter_paths = itertools.tee(path, len(types))
if len(results) > 1:
iter_paths = itertools.tee(path, len(results))
else:
iter_paths = [path]
for i, r in enumerate(results): for i, type in enumerate(types):
fp = self.follow_path(iter_paths[i], r, call_scope, position=position) fp = self._follow_path(iter_paths[i], type, call_scope, position=position)
if fp is not None: if fp is not None:
results_new += fp results_new += fp
else: else:
# This means stop iteration. # This means stop iteration.
return results return types
return results_new return results_new
def follow_path(self, path, scope, call_scope, position=None): def _follow_path(self, path, scope, call_scope, position=None):
""" """
Uses a generator and tries to complete the path, e.g.:: Uses a generator and tries to complete the path, e.g.::
foo.bar.baz foo.bar.baz
`follow_path` is only responsible for completing `.bar.baz`, the rest is `_follow_path` is only responsible for completing `.bar.baz`, the rest is
done in the `follow_call` function. done in the `follow_call` function.
""" """
# current is either an Array or a Scope. # current is either an Array or a Scope.
@@ -637,7 +633,7 @@ class Evaluator(object):
current = next(path) current = next(path)
except StopIteration: except StopIteration:
return None return None
debug.dbg('follow_path: %s in scope %s' % (current, scope)) debug.dbg('_follow_path: %s in scope %s' % (current, scope))
result = [] result = []
if isinstance(current, pr.Array): if isinstance(current, pr.Array):
@@ -662,7 +658,7 @@ class Evaluator(object):
return [] return []
result = imports.strip_imports(self, self.find_name(scope, current, result = imports.strip_imports(self, self.find_name(scope, current,
position=position)) position=position))
return self.follow_paths(path, set(result), call_scope, position=position) return self.follow_path(path, set(result), call_scope, position=position)
def execute(self, scope, params, evaluate_generator=False): def execute(self, scope, params, evaluate_generator=False):
return er.Execution(self, scope, params).get_return_types(evaluate_generator) return er.Execution(self, scope, params).get_return_types(evaluate_generator)

View File

@@ -439,7 +439,7 @@ class Builtin(object):
parser = Parser(source, None) parser = Parser(source, None)
module = parser.module module = parser.module
module.parent = self.scope module.parent = self.scope
typ = evaluator.follow_path(iter(['FunctionType']), module, module) typ = evaluator.follow_path(iter(['FunctionType']), [module], module)
s = self._magic_function_scope = typ.pop() s = self._magic_function_scope = typ.pop()
return s return s

View File

@@ -187,7 +187,7 @@ def search_params(evaluator, param):
if compare in c: if compare in c:
# only if we have the correct function we execute # only if we have the correct function we execute
# it, otherwise just ignore it. # it, otherwise just ignore it.
evaluator.follow_paths(iter(last), s, scope) evaluator.follow_path(iter(last), s, scope)
return listener.param_possibilities return listener.param_possibilities

View File

@@ -208,7 +208,7 @@ class ImportPath(pr.Base):
# ``os.path``, because it's a very important one in Python # ``os.path``, because it's a very important one in Python
# that is being achieved by messing with ``sys.modules`` in # that is being achieved by messing with ``sys.modules`` in
# ``os``. # ``os``.
scopes = self._evaluator.follow_path(iter(rest), scope, scope) scopes = self._evaluator.follow_path(iter(rest), [scope], scope)
elif rest: elif rest:
if is_goto: if is_goto:
scopes = itertools.chain.from_iterable( scopes = itertools.chain.from_iterable(
@@ -216,7 +216,7 @@ class ImportPath(pr.Base):
for s in scopes) for s in scopes)
else: else:
scopes = itertools.chain.from_iterable( scopes = itertools.chain.from_iterable(
self._evaluator.follow_path(iter(rest), s, s) self._evaluator.follow_path(iter(rest), [s], s)
for s in scopes) for s in scopes)
scopes = list(scopes) scopes = list(scopes)

View File

@@ -456,7 +456,7 @@ class Execution(Executable):
if len(arr_name.var_args) != 1: if len(arr_name.var_args) != 1:
debug.warning('jedi getattr is too simple') debug.warning('jedi getattr is too simple')
key = arr_name.var_args[0] key = arr_name.var_args[0]
stmts += self._evaluator.follow_path(iter([key]), obj, base) stmts += self._evaluator.follow_path(iter([key]), [obj], base)
return stmts return stmts
elif func_name == 'type': elif func_name == 'type':
# otherwise it would be a metaclass # otherwise it would be a metaclass