1
0
forked from VimPlug/jedi

Fix issues with unreachable flows.

This benefits static analysis as well as autocompletion: Unreachable code (things like code within 'if 0:') should still be resolveable.
This commit is contained in:
Dave Halter
2014-09-03 00:05:37 +02:00
parent ea5b98905e
commit bcc84820fe
4 changed files with 37 additions and 3 deletions

View File

@@ -106,7 +106,8 @@ class NameFinder(object):
else: else:
check = flow_analysis.break_check(self._evaluator, check = flow_analysis.break_check(self._evaluator,
name_list_scope, name_list_scope,
er.wrap(self._evaluator, scope)) er.wrap(self._evaluator, scope),
self.scope)
if check is not flow_analysis.UNREACHABLE: if check is not flow_analysis.UNREACHABLE:
result.append(name) result.append(name)
if check is flow_analysis.REACHABLE: if check is flow_analysis.REACHABLE:

View File

@@ -32,11 +32,21 @@ UNREACHABLE = Status(False, 'unreachable')
UNSURE = Status(None, 'unsure') UNSURE = Status(None, 'unsure')
def break_check(evaluator, base_scope, element_scope): def break_check(evaluator, base_scope, element_scope, origin_scope=None):
from jedi.evaluate.representation import wrap from jedi.evaluate.representation import wrap
base_scope = wrap(evaluator, base_scope) base_scope = wrap(evaluator, base_scope)
element_scope = wrap(evaluator, element_scope) element_scope = wrap(evaluator, element_scope)
# Direct parents get resolved, we filter scopes that are separate branches.
# This makes sense for autocompletion and static analysis. For actual
# Python it doesn't matter, because we're talking about potentially
# unreachable code.
s = origin_scope
while s is not None:
if element_scope == s:
return REACHABLE
s = s.parent
reachable = REACHABLE reachable = REACHABLE
if isinstance(element_scope, Flow): if isinstance(element_scope, Flow):
if element_scope.command == 'else': if element_scope.command == 'else':

View File

@@ -182,3 +182,26 @@ isinst(1.0)
isinst(False) isinst(False)
#? int() #? int()
isinst('') isinst('')
# -----------------
# flows that are not reachable should be able to access parent scopes.
# -----------------
foobar = ''
if 0:
within_flow = 1.0
#? float()
within_flow
#? str()
foobar
if 0:
nested = 1
#? int()
nested
#? float()
within_flow
#? str()
foobar
#?
nested

View File

@@ -207,7 +207,7 @@ def test_signature_is_definition():
# Now compare all the attributes that a CallSignature must also have. # Now compare all the attributes that a CallSignature must also have.
for attr_name in dir(definition): for attr_name in dir(definition):
dont_scan = ['defined_names', 'line_nr', 'start_pos', 'documentation', dont_scan = ['defined_names', 'line_nr', 'start_pos', 'documentation',
'doc', 'parent'] 'doc', 'parent', 'goto_assignments']
if attr_name.startswith('_') or attr_name in dont_scan: if attr_name.startswith('_') or attr_name in dont_scan:
continue continue
attribute = getattr(definition, attr_name) attribute = getattr(definition, attr_name)