1
0
forked from VimPlug/jedi

Finally get rid of NameFinder

This commit is contained in:
Dave Halter
2019-08-24 03:20:21 +02:00
parent c4b0b45a1d
commit c1d8454f0c
4 changed files with 32 additions and 59 deletions

View File

@@ -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__")

View File

@@ -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)

View File

@@ -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):

View File

@@ -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)