forked from VimPlug/jedi
Finally get rid of NameFinder
This commit is contained in:
@@ -76,8 +76,8 @@ class HelperValueMixin(object):
|
|||||||
"""
|
"""
|
||||||
if name_context is None:
|
if name_context is None:
|
||||||
name_context = self
|
name_context = self
|
||||||
names, f = self._goto(name_or_str, name_context, analysis_errors)
|
names = self.goto(name_or_str, name_context, analysis_errors)
|
||||||
values = f.find(names, attribute_lookup=True)
|
values = ValueSet.from_sets(name.infer() for name in names)
|
||||||
if not values:
|
if not values:
|
||||||
n = name_or_str.value if isinstance(name_or_str, Name) else name_or_str
|
n = name_or_str.value if isinstance(name_or_str, Name) else name_or_str
|
||||||
values = self.py__getattribute__alternatives(n)
|
values = self.py__getattribute__alternatives(n)
|
||||||
@@ -87,21 +87,17 @@ class HelperValueMixin(object):
|
|||||||
from jedi.inference import analysis
|
from jedi.inference import analysis
|
||||||
analysis.add_attribute_error(
|
analysis.add_attribute_error(
|
||||||
name_context, self, name_or_str)
|
name_context, self, name_or_str)
|
||||||
|
debug.dbg('context.names_to_types: %s -> %s', names, values)
|
||||||
return values
|
return values
|
||||||
|
|
||||||
def goto(self, *args, **kwargs):
|
def goto(self, name_or_str, name_context=None, analysis_errors=True):
|
||||||
return self._goto(*args, **kwargs)[0]
|
|
||||||
|
|
||||||
def _goto(self, name_or_str, name_context=None, analysis_errors=True):
|
|
||||||
if name_context is None:
|
if name_context is None:
|
||||||
name_context = self
|
name_context = self
|
||||||
from jedi.inference import finder
|
from jedi.inference import finder
|
||||||
f = finder.NameFinder(self, name_context, name_or_str,
|
|
||||||
analysis_errors=analysis_errors)
|
|
||||||
filters = self._get_value_filters(name_or_str)
|
filters = self._get_value_filters(name_or_str)
|
||||||
names = f.filter_name(filters)
|
names = finder.filter_name(filters, name_or_str)
|
||||||
debug.dbg('Context.goto %s in (%s): %s', name_or_str, self, names)
|
debug.dbg('Context.goto %s in (%s): %s', name_or_str, self, names)
|
||||||
return names, f
|
return names
|
||||||
|
|
||||||
def py__await__(self):
|
def py__await__(self):
|
||||||
await_value_set = self.py__getattribute__(u"__await__")
|
await_value_set = self.py__getattribute__(u"__await__")
|
||||||
|
|||||||
@@ -6,7 +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.inference.base_value import NO_VALUES, ValueSet
|
||||||
from jedi.parser_utils import get_parent_scope
|
from jedi.parser_utils import get_parent_scope
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi import parser_utils
|
from jedi import parser_utils
|
||||||
@@ -24,17 +24,13 @@ class AbstractContext(object):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def goto(self, name_or_str, position):
|
def goto(self, name_or_str, position):
|
||||||
return self._goto(name_or_str, position)[0]
|
|
||||||
|
|
||||||
def _goto(self, name_or_str, position):
|
|
||||||
from jedi.inference import finder
|
from jedi.inference import finder
|
||||||
f = finder.NameFinder(self, self, name_or_str, position)
|
|
||||||
filters = _get_global_filters_for_name(
|
filters = _get_global_filters_for_name(
|
||||||
self, name_or_str if isinstance(name_or_str, Name) else None, position,
|
self, name_or_str if isinstance(name_or_str, Name) else None, position,
|
||||||
)
|
)
|
||||||
names = f.filter_name(filters)
|
names = finder.filter_name(filters, name_or_str)
|
||||||
debug.dbg('Context.goto %s in (%s): %s', name_or_str, self, names)
|
debug.dbg('Context.goto %s in (%s): %s', name_or_str, self, names)
|
||||||
return names, f
|
return names
|
||||||
|
|
||||||
def py__getattribute__(self, name_or_str, name_context=None, position=None,
|
def py__getattribute__(self, name_or_str, name_context=None, position=None,
|
||||||
analysis_errors=True):
|
analysis_errors=True):
|
||||||
@@ -43,7 +39,7 @@ 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 = self.goto(name_or_str, position)
|
||||||
|
|
||||||
string_name = name_or_str.value if isinstance(name_or_str, Name) else name_or_str
|
string_name = name_or_str.value if isinstance(name_or_str, Name) else name_or_str
|
||||||
|
|
||||||
@@ -75,12 +71,15 @@ class AbstractContext(object):
|
|||||||
else:
|
else:
|
||||||
values = found_predefined_types
|
values = found_predefined_types
|
||||||
else:
|
else:
|
||||||
values = f.find(names, attribute_lookup=False)
|
values = ValueSet.from_sets(name.infer() for name in names)
|
||||||
|
|
||||||
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." % string_name)
|
message = ("NameError: name '%s' is not defined." % string_name)
|
||||||
analysis.add(name_context, 'name-error', name_or_str, message)
|
analysis.add(name_context, 'name-error', name_or_str, message)
|
||||||
|
|
||||||
|
debug.dbg('context.names_to_types: %s -> %s', names, values)
|
||||||
if values:
|
if values:
|
||||||
return values
|
return values
|
||||||
return self._check_for_additional_knowledge(name_or_str, name_context, position)
|
return self._check_for_additional_knowledge(name_or_str, name_context, position)
|
||||||
|
|||||||
@@ -15,52 +15,30 @@ Unfortunately every other thing is being ignored (e.g. a == '' would be easy to
|
|||||||
check for -> a is a string). There's big potential in these checks.
|
check for -> a is a string). There's big potential in these checks.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from parso.python import tree
|
|
||||||
from parso.tree import search_ancestor
|
from parso.tree import search_ancestor
|
||||||
from jedi import debug
|
from parso.python.tree import Name
|
||||||
|
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
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
|
||||||
from jedi.inference.base_value import ValueSet, NO_VALUES
|
from jedi.inference.base_value import NO_VALUES
|
||||||
from jedi.parser_utils import is_scope
|
from jedi.parser_utils import is_scope
|
||||||
|
|
||||||
|
|
||||||
class NameFinder(object):
|
def filter_name(filters, name_or_str):
|
||||||
def __init__(self, context, name_context, name_or_str,
|
"""
|
||||||
position=None, analysis_errors=True):
|
Searches names that are defined in a scope (the different
|
||||||
# Make sure that it's not just a syntax tree node.
|
``filters``), until a name fits.
|
||||||
self._context = context
|
"""
|
||||||
self._name_context = name_context
|
string_name = name_or_str.value if isinstance(name_or_str, Name) else name_or_str
|
||||||
self._name = name_or_str
|
names = []
|
||||||
if isinstance(name_or_str, tree.Name):
|
for filter in filters:
|
||||||
self._string_name = name_or_str.value
|
names = filter.get(string_name)
|
||||||
else:
|
if names:
|
||||||
self._string_name = name_or_str
|
break
|
||||||
self._position = position
|
|
||||||
self._analysis_errors = analysis_errors
|
|
||||||
|
|
||||||
def find(self, names, attribute_lookup):
|
return list(names)
|
||||||
"""
|
|
||||||
:params bool attribute_lookup: Tell to logic if we're accessing the
|
|
||||||
attribute or the contents of e.g. a function.
|
|
||||||
"""
|
|
||||||
values = ValueSet.from_sets(name.infer() for name in names)
|
|
||||||
debug.dbg('finder._names_to_types: %s -> %s', names, values)
|
|
||||||
return values
|
|
||||||
|
|
||||||
def filter_name(self, filters):
|
|
||||||
"""
|
|
||||||
Searches names that are defined in a scope (the different
|
|
||||||
``filters``), until a name fits.
|
|
||||||
"""
|
|
||||||
names = []
|
|
||||||
for filter in filters:
|
|
||||||
names = filter.get(self._string_name)
|
|
||||||
if names:
|
|
||||||
break
|
|
||||||
|
|
||||||
return list(names)
|
|
||||||
|
|
||||||
|
|
||||||
def check_flow_information(value, flow, search_name, pos):
|
def check_flow_information(value, flow, search_name, pos):
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ from jedi.inference import arguments
|
|||||||
from jedi.inference.value import ClassValue, FunctionValue
|
from jedi.inference.value import ClassValue, FunctionValue
|
||||||
from jedi.inference.value import iterable
|
from jedi.inference.value import iterable
|
||||||
from jedi.inference.value import TreeInstance
|
from jedi.inference.value import TreeInstance
|
||||||
from jedi.inference.finder import NameFinder
|
from jedi.inference.finder import filter_name
|
||||||
from jedi.inference.helpers import is_string, is_literal, is_number
|
from jedi.inference.helpers import is_string, is_literal, is_number
|
||||||
from jedi.inference.compiled.access import COMPARISON_OPERATORS
|
from jedi.inference.compiled.access import COMPARISON_OPERATORS
|
||||||
from jedi.inference.cache import inference_state_method_cache
|
from jedi.inference.cache import inference_state_method_cache
|
||||||
@@ -570,11 +570,11 @@ def tree_name_to_values(inference_state, context, tree_name):
|
|||||||
node = tree_name.parent
|
node = tree_name.parent
|
||||||
if node.type == 'global_stmt':
|
if node.type == 'global_stmt':
|
||||||
c = context.create_context(tree_name)
|
c = context.create_context(tree_name)
|
||||||
finder = NameFinder(c, c, tree_name.value)
|
|
||||||
# For global_stmt lookups, we only need the first possible scope,
|
# For global_stmt lookups, we only need the first possible scope,
|
||||||
# which means the function itself.
|
# which means the function itself.
|
||||||
filters = [next(c.get_filters())]
|
filters = [next(c.get_filters())]
|
||||||
return finder.find(finder.filter_name(filters), attribute_lookup=False)
|
names = filter_name(filters, tree_name)
|
||||||
|
return ValueSet.from_sets(name.infer() for name in names)
|
||||||
elif node.type not in ('import_from', 'import_name'):
|
elif node.type not in ('import_from', 'import_name'):
|
||||||
c = context.create_context(tree_name)
|
c = context.create_context(tree_name)
|
||||||
return infer_atom(c, tree_name)
|
return infer_atom(c, tree_name)
|
||||||
|
|||||||
Reference in New Issue
Block a user