1
0
forked from VimPlug/jedi

add a Flow.previous attribute to be able to access the if flow from an else clause.

This commit is contained in:
Dave Halter
2014-08-05 11:17:18 +02:00
parent 54dce0e3b2
commit c44168f7ad
6 changed files with 29 additions and 9 deletions

View File

@@ -243,7 +243,7 @@ def save_parser(path, name, parser, pickling=True):
class ParserPickling(object): class ParserPickling(object):
version = 13 version = 14
""" """
Version number (integer) for file system cache. Version number (integer) for file system cache.

View File

@@ -0,0 +1,7 @@
NOT_REACHABLE = object()
REACHABLE = object()
UNSURE = object()
def break_check(scope):
return UNSURE

View File

@@ -47,7 +47,10 @@ def fast_parent_copy(obj):
elif isinstance(value, list): elif isinstance(value, list):
setattr(new_obj, key, list_rec(value)) setattr(new_obj, key, list_rec(value))
elif isinstance(value, pr.Simple): elif isinstance(value, pr.Simple):
setattr(new_obj, key, recursion(value)) try: # because of the circular Flow.previous/Flow.next
setattr(new_obj, key, new_elements[value])
except KeyError:
setattr(new_obj, key, recursion(value))
return new_obj return new_obj
def list_rec(list_obj): def list_rec(list_obj):

View File

@@ -26,6 +26,7 @@ from jedi.evaluate import iterable
from jedi.evaluate import docstrings from jedi.evaluate import docstrings
from jedi.evaluate import helpers from jedi.evaluate import helpers
from jedi.evaluate import param from jedi.evaluate import param
from jedi.evaluate import flow_analysis
class Executed(pr.IsScope): class Executed(pr.IsScope):
@@ -471,8 +472,14 @@ class FunctionExecution(Executed):
types = list(docstrings.find_return_types(self._evaluator, func)) types = list(docstrings.find_return_types(self._evaluator, func))
for r in self.returns: for r in self.returns:
if r is not None: if r is None:
continue
check = flow_analysis.break_check(r.parent.parent)
if check is not flow_analysis.NOT_REACHABLE:
types += self._evaluator.eval_statement(r) types += self._evaluator.eval_statement(r)
if check is flow_analysis.REACHABLE:
break
return types return types
@memoize_default(default=()) @memoize_default(default=())

View File

@@ -538,9 +538,9 @@ class Parser(object):
f = pr.Flow(self.module, command, inputs, first_pos) f = pr.Flow(self.module, command, inputs, first_pos)
if command in extended_flow: if command in extended_flow:
# the last statement has to be another part of # The last statement has to be another part of the flow
# the flow statement, because a dedent releases the # statement, because a dedent releases the main scope, so
# main scope, so just take the last statement. # just take the last statement.
try: try:
s = self._scope.statements[-1].set_next(f) s = self._scope.statements[-1].set_next(f)
except (AttributeError, IndexError): except (AttributeError, IndexError):
@@ -565,8 +565,9 @@ class Parser(object):
if stmt is not None: if stmt is not None:
stmt.parent = use_as_parent_scope stmt.parent = use_as_parent_scope
try: try:
func.statements.append(pr.KeywordStatement(tok_str, s, kw_stmt = pr.KeywordStatement(tok_str, s,
use_as_parent_scope, stmt)) use_as_parent_scope, stmt)
self._scope.statements.append(kw_stmt)
func.returns.append(stmt) func.returns.append(stmt)
# start_pos is the one of the return statement # start_pos is the one of the return statement
stmt.start_pos = s stmt.start_pos = s

View File

@@ -637,10 +637,11 @@ class Flow(Scope):
:param start_pos: Position (line, column) of the Flow statement. :param start_pos: Position (line, column) of the Flow statement.
:type start_pos: tuple(int, int) :type start_pos: tuple(int, int)
""" """
__slots__ = ('next', 'command', '_parent', 'inputs', 'set_vars') __slots__ = ('next', 'previous', 'command', '_parent', 'inputs', 'set_vars')
def __init__(self, module, command, inputs, start_pos): def __init__(self, module, command, inputs, start_pos):
self.next = None self.next = None
self.previous = None
self.command = command self.command = command
super(Flow, self).__init__(module, start_pos) super(Flow, self).__init__(module, start_pos)
self._parent = None self._parent = None
@@ -706,6 +707,7 @@ class Flow(Scope):
else: else:
self.next = next self.next = next
self.next.parent = self.parent self.next.parent = self.parent
self.next.previous = self
return next return next
def scope_names_generator(self, position=None): def scope_names_generator(self, position=None):