forked from VimPlug/jedi
Move some static analysis details out of finder
This commit is contained in:
@@ -6,6 +6,7 @@ from parso.python.tree import Name
|
|||||||
|
|
||||||
from jedi.inference.filters import ParserTreeFilter, MergedFilter, \
|
from jedi.inference.filters import ParserTreeFilter, MergedFilter, \
|
||||||
GlobalNameFilter
|
GlobalNameFilter
|
||||||
|
from jedi.inference.base_value import NO_VALUES
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi import parser_utils
|
from jedi import parser_utils
|
||||||
|
|
||||||
@@ -42,12 +43,42 @@ class AbstractContext(object):
|
|||||||
if name_context is None:
|
if name_context is None:
|
||||||
name_context = self
|
name_context = self
|
||||||
names, f = self._goto(name_or_str, position)
|
names, f = self._goto(name_or_str, position)
|
||||||
values = f.find(names, attribute_lookup=False)
|
|
||||||
|
string_name = name_or_str.value if isinstance(name_or_str, Name) else name_or_str
|
||||||
|
|
||||||
|
# This paragraph is currently needed for proper branch type inference
|
||||||
|
# (static analysis).
|
||||||
|
found_predefined_types = None
|
||||||
|
if self.predefined_names and isinstance(name_or_str, Name):
|
||||||
|
node = name_or_str
|
||||||
|
while node is not None and not parser_utils.is_scope(node):
|
||||||
|
node = node.parent
|
||||||
|
if node.type in ("if_stmt", "for_stmt", "comp_for", 'sync_comp_for'):
|
||||||
|
try:
|
||||||
|
name_dict = self.predefined_names[node]
|
||||||
|
types = name_dict[string_name]
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
found_predefined_types = types
|
||||||
|
break
|
||||||
|
if found_predefined_types is not None and names:
|
||||||
|
from jedi.inference import flow_analysis
|
||||||
|
check = flow_analysis.reachability_check(
|
||||||
|
context=self,
|
||||||
|
value_scope=self.tree_node,
|
||||||
|
node=name_or_str,
|
||||||
|
)
|
||||||
|
if check is flow_analysis.UNREACHABLE:
|
||||||
|
values = NO_VALUES
|
||||||
|
else:
|
||||||
|
values = found_predefined_types
|
||||||
|
else:
|
||||||
|
values = f.find(names, attribute_lookup=False)
|
||||||
if not names and not values and analysis_errors:
|
if not names and not values and analysis_errors:
|
||||||
if isinstance(name_or_str, Name):
|
if isinstance(name_or_str, Name):
|
||||||
from jedi.inference import analysis
|
from jedi.inference import analysis
|
||||||
message = ("NameError: name '%s' is not defined."
|
message = ("NameError: name '%s' is not defined." % string_name)
|
||||||
% name_or_str if isinstance(name_or_str, Name) else name_or_str)
|
|
||||||
analysis.add(name_context, 'name-error', name_or_str, message)
|
analysis.add(name_context, 'name-error', name_or_str, message)
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ from parso.python import tree
|
|||||||
from parso.tree import search_ancestor
|
from parso.tree import search_ancestor
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
from jedi.inference import flow_analysis
|
|
||||||
from jedi.inference.arguments import TreeArguments
|
from jedi.inference.arguments import TreeArguments
|
||||||
from jedi.inference import helpers
|
from jedi.inference import helpers
|
||||||
from jedi.inference.value import iterable
|
from jedi.inference.value import iterable
|
||||||
@@ -46,33 +45,6 @@ class NameFinder(object):
|
|||||||
:params bool attribute_lookup: Tell to logic if we're accessing the
|
:params bool attribute_lookup: Tell to logic if we're accessing the
|
||||||
attribute or the contents of e.g. a function.
|
attribute or the contents of e.g. a function.
|
||||||
"""
|
"""
|
||||||
found_predefined_types = None
|
|
||||||
# This paragraph is currently needed for proper branch type inference
|
|
||||||
# (static analysis).
|
|
||||||
if self._context.predefined_names and isinstance(self._name, tree.Name):
|
|
||||||
node = self._name
|
|
||||||
while node is not None and not is_scope(node):
|
|
||||||
node = node.parent
|
|
||||||
if node.type in ("if_stmt", "for_stmt", "comp_for", 'sync_comp_for'):
|
|
||||||
try:
|
|
||||||
name_dict = self._context.predefined_names[node]
|
|
||||||
types = name_dict[self._string_name]
|
|
||||||
except KeyError:
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
found_predefined_types = types
|
|
||||||
break
|
|
||||||
|
|
||||||
if found_predefined_types is not None and names:
|
|
||||||
check = flow_analysis.reachability_check(
|
|
||||||
context=self._context,
|
|
||||||
value_scope=self._context.tree_node,
|
|
||||||
node=self._name,
|
|
||||||
)
|
|
||||||
if check is flow_analysis.UNREACHABLE:
|
|
||||||
return NO_VALUES
|
|
||||||
return found_predefined_types
|
|
||||||
|
|
||||||
values = ValueSet.from_sets(name.infer() for name in names)
|
values = ValueSet.from_sets(name.infer() for name in names)
|
||||||
debug.dbg('finder._names_to_types: %s -> %s', names, values)
|
debug.dbg('finder._names_to_types: %s -> %s', names, values)
|
||||||
if values:
|
if values:
|
||||||
|
|||||||
Reference in New Issue
Block a user