possible direction of branch checks for name resolution.

This commit is contained in:
Dave Halter
2014-08-10 13:17:37 +02:00
parent 483f5c14ee
commit f1711f8f9c
7 changed files with 45 additions and 9 deletions

View File

@@ -139,7 +139,7 @@ class Evaluator(object):
operator = copy.copy(_operator) operator = copy.copy(_operator)
operator.string = operator.string[:-1] operator.string = operator.string[:-1]
name = str(expr_list[0].name) name = str(expr_list[0].name)
parent = stmt.parent parent = stmt.parent.get_parent_until(pr.Flow, reverse=True)
if isinstance(parent, (pr.SubModule, fast.Module)): if isinstance(parent, (pr.SubModule, fast.Module)):
parent = er.ModuleWrapper(self, parent) parent = er.ModuleWrapper(self, parent)
left = self.find_types(parent, name, stmt.start_pos) left = self.find_types(parent, name, stmt.start_pos)

View File

@@ -27,6 +27,7 @@ from jedi.evaluate import iterable
from jedi.evaluate import imports from jedi.evaluate import imports
from jedi.evaluate import analysis from jedi.evaluate import analysis
from jedi.evaluate import precedence from jedi.evaluate import precedence
from jedi.evaluate import flow_analysis
class NameFinder(object): class NameFinder(object):
@@ -86,13 +87,30 @@ class NameFinder(object):
if unicode(self.name_str) != name.get_code(): if unicode(self.name_str) != name.get_code():
continue continue
scope = name.parent.parent stmt = name.parent
scope = stmt.parent
if scope in break_scopes: if scope in break_scopes:
continue continue
# Exclude `arr[1] =` from the result set. # Exclude `arr[1] =` from the result set.
if not self._name_is_array_assignment(name): if not self._name_is_array_assignment(name):
result.append(name) if False:
result.append(name)
else:
if isinstance(stmt, (pr.Param, pr.Import)) \
or isinstance(name_list_scope, (pr.ListComprehension, er.Instance)) \
or isinstance(scope, compiled.CompiledObject) \
or isinstance(stmt, pr.Statement) and stmt.is_global():
# Always reachable.
result.append(name)
else:
check = flow_analysis.break_check(self._evaluator,
name_list_scope,
er.wrap(self._evaluator, scope))
if check is not flow_analysis.UNREACHABLE:
result.append(name)
if check is flow_analysis.REACHABLE:
break
if result and self._is_name_break_scope(name): if result and self._is_name_break_scope(name):
if self._does_scope_break_immediately(scope, name_list_scope): if self._does_scope_break_immediately(scope, name_list_scope):

View File

@@ -33,6 +33,10 @@ UNSURE = Status(None, 'unsure')
def break_check(evaluator, base_scope, element_scope): def break_check(evaluator, base_scope, element_scope):
from jedi.evaluate.representation import wrap
base_scope = wrap(evaluator, base_scope)
element_scope = wrap(evaluator, element_scope)
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

@@ -123,6 +123,9 @@ class Array(use_metaclass(CachedMetaClass, pr.Base)):
self._evaluator = evaluator self._evaluator = evaluator
self._array = array self._array = array
def py__bool__(self):
return None # We don't know the length, because of appends.
@memoize_default(NO_DEFAULT) @memoize_default(NO_DEFAULT)
def get_index_types(self, index_array=()): def get_index_types(self, index_array=()):
""" """

View File

@@ -6,7 +6,6 @@ from jedi.evaluate import iterable
from jedi import common from jedi import common
from jedi.evaluate import helpers from jedi.evaluate import helpers
from jedi.evaluate import analysis from jedi.evaluate import analysis
from jedi.evaluate.compiled import CompiledObject
class ExecutedParam(pr.Param): class ExecutedParam(pr.Param):

View File

@@ -29,6 +29,18 @@ from jedi.evaluate import param
from jedi.evaluate import flow_analysis from jedi.evaluate import flow_analysis
def wrap(evaluator, element):
if isinstance(element, pr.Class):
return Class(evaluator, element)
elif isinstance(element, pr.Function):
return Function(evaluator, element)
elif isinstance(element, (pr.Module)) \
and not isinstance(element, ModuleWrapper):
return ModuleWrapper(evaluator, element)
else:
return element
class Executed(pr.IsScope): class Executed(pr.IsScope):
""" """
An instance is also an executable - because __init__ is called An instance is also an executable - because __init__ is called
@@ -203,7 +215,7 @@ def get_instance_el(evaluator, instance, var, is_class_var=False):
untouched. untouched.
""" """
if isinstance(var, (Instance, compiled.CompiledObject, pr.Operator, Token, if isinstance(var, (Instance, compiled.CompiledObject, pr.Operator, Token,
pr.Module)): pr.Module, FunctionExecution)):
return var return var
if isinstance(var, pr.Function): if isinstance(var, pr.Function):

View File

@@ -23,18 +23,18 @@ a(0):.
# if/else/elif # if/else/elif
# ----------------- # -----------------
if 1: if (random.choice([0, 1])):
1 1
elif(3): elif(random.choice([0, 1])):
a = 3 a = 3
else: else:
a = '' a = ''
#? int() str() #? int() str()
a a
def func(): def func():
if 1: if random.choice([0, 1]):
1 1
elif(3): elif(random.choice([0, 1])):
a = 3 a = 3
else: else:
a = '' a = ''