forked from VimPlug/jedi
Filter names in a separate function so that it can be used for both completion and name lookups.
This commit is contained in:
@@ -34,7 +34,7 @@ from jedi.evaluate import compiled
|
|||||||
from jedi.evaluate import imports
|
from jedi.evaluate import imports
|
||||||
from jedi.evaluate.cache import memoize_default
|
from jedi.evaluate.cache import memoize_default
|
||||||
from jedi.evaluate.helpers import FakeName, get_module_names
|
from jedi.evaluate.helpers import FakeName, get_module_names
|
||||||
from jedi.evaluate.finder import get_names_of_scope, filter_private_variable
|
from jedi.evaluate.finder import get_names_of_scope, filter_definition_names
|
||||||
from jedi.evaluate import analysis
|
from jedi.evaluate import analysis
|
||||||
|
|
||||||
# Jedi uses lots and lots of recursion. By setting this a little bit higher, we
|
# Jedi uses lots and lots of recursion. By setting this a little bit higher, we
|
||||||
@@ -247,6 +247,7 @@ class Script(object):
|
|||||||
for names_dict in s.names_dicts(search_global=False):
|
for names_dict in s.names_dicts(search_global=False):
|
||||||
names += chain.from_iterable(names_dict.values())
|
names += chain.from_iterable(names_dict.values())
|
||||||
|
|
||||||
|
names = filter_definition_names(names)
|
||||||
for c in names:
|
for c in names:
|
||||||
completions.append((c, s))
|
completions.append((c, s))
|
||||||
return completions
|
return completions
|
||||||
|
|||||||
+28
-21
@@ -32,6 +32,28 @@ from jedi.evaluate import helpers
|
|||||||
from jedi.evaluate.cache import memoize_default
|
from jedi.evaluate.cache import memoize_default
|
||||||
|
|
||||||
|
|
||||||
|
def filter_definition_names(names, position=None):
|
||||||
|
# Just calculate the scope from the first
|
||||||
|
stmt = names[0].get_definition()
|
||||||
|
scope = stmt.get_parent_scope()
|
||||||
|
if isinstance(stmt, (pr.CompFor, pr.Lambda, pr.GlobalStmt)):
|
||||||
|
return names
|
||||||
|
|
||||||
|
# Private name mangling (compile.c) disallows access on names
|
||||||
|
# preceeded by two underscores `__` if used outside of the class. Names
|
||||||
|
# that also end with two underscores (e.g. __id__) are not affected.
|
||||||
|
names = list(names)
|
||||||
|
for name in names:
|
||||||
|
if name.value.startswith('__') and not name.value.endswith('__'):
|
||||||
|
if filter_private_variable(scope, name):
|
||||||
|
names.remove(name)
|
||||||
|
|
||||||
|
if not (isinstance(scope, er.FunctionExecution)
|
||||||
|
and isinstance(scope.base, er.LambdaWrapper)):
|
||||||
|
names = pr.filter_after_position(names, position)
|
||||||
|
return [name for name in names if name.is_definition()]
|
||||||
|
|
||||||
|
|
||||||
class NameFinder(object):
|
class NameFinder(object):
|
||||||
def __init__(self, evaluator, scope, name_str, position=None):
|
def __init__(self, evaluator, scope, name_str, position=None):
|
||||||
self._evaluator = evaluator
|
self._evaluator = evaluator
|
||||||
@@ -71,7 +93,7 @@ class NameFinder(object):
|
|||||||
return ((n, None) for n in self.scope.names_dicts(search_global))
|
return ((n, None) for n in self.scope.names_dicts(search_global))
|
||||||
|
|
||||||
def names_dict_lookup(self, names_dict, position):
|
def names_dict_lookup(self, names_dict, position):
|
||||||
def get_param(el):
|
def get_param(scope, el):
|
||||||
if isinstance(el.parent, pr.Param) or isinstance(el.parent.parent, pr.Param):
|
if isinstance(el.parent, pr.Param) or isinstance(el.parent.parent, pr.Param):
|
||||||
return scope.param_by_name(str(el))
|
return scope.param_by_name(str(el))
|
||||||
return el
|
return el
|
||||||
@@ -84,25 +106,9 @@ class NameFinder(object):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
#print(names[0].parent, names[0].get_definition().get_parent_scope())
|
names = filter_definition_names(names, position)
|
||||||
# Just calculate the scope from the first
|
|
||||||
stmt = names[0].get_definition()
|
|
||||||
scope = stmt.get_parent_scope()
|
|
||||||
if isinstance(stmt, (pr.CompFor, pr.Lambda, pr.GlobalStmt)):
|
|
||||||
return names
|
|
||||||
|
|
||||||
# Private name mangling (compile.c) disallows access on names
|
|
||||||
# preceeded by two underscores `__` if used outside of the class. Names
|
|
||||||
# that also end with two underscores (e.g. __id__) are not affected.
|
|
||||||
if search_str.startswith('__') and not search_str.endswith('__'):
|
|
||||||
if filter_private_variable(scope, self.name_str):
|
|
||||||
return []
|
|
||||||
|
|
||||||
if not (isinstance(scope, er.FunctionExecution)
|
|
||||||
and isinstance(scope.base, er.LambdaWrapper)):
|
|
||||||
names = pr.filter_after_position(names, position)
|
|
||||||
names = [name for name in names if name.is_definition()]
|
|
||||||
|
|
||||||
|
name_scope = None
|
||||||
# Only the names defined in the last position are valid definitions.
|
# Only the names defined in the last position are valid definitions.
|
||||||
last_names = []
|
last_names = []
|
||||||
for name in reversed(sorted(names, key=lambda name: name.start_pos)):
|
for name in reversed(sorted(names, key=lambda name: name.start_pos)):
|
||||||
@@ -140,9 +146,9 @@ class NameFinder(object):
|
|||||||
if check is flow_analysis.REACHABLE:
|
if check is flow_analysis.REACHABLE:
|
||||||
break
|
break
|
||||||
|
|
||||||
if isinstance(scope, er.FunctionExecution):
|
if isinstance(name_scope, er.FunctionExecution):
|
||||||
# Replace params
|
# Replace params
|
||||||
return [get_param(n) for n in last_names]
|
return [get_param(name_scope, n) for n in last_names]
|
||||||
return last_names
|
return last_names
|
||||||
|
|
||||||
def filter_name(self, names_dicts, search_global=False):
|
def filter_name(self, names_dicts, search_global=False):
|
||||||
@@ -651,6 +657,7 @@ def check_tuple_assignments(types, name):
|
|||||||
|
|
||||||
def filter_private_variable(scope, search_name):
|
def filter_private_variable(scope, search_name):
|
||||||
"""Check if a variable is defined inside the same class or outside."""
|
"""Check if a variable is defined inside the same class or outside."""
|
||||||
|
# TODO integrate this in the function that checks this.
|
||||||
instance = scope.get_parent_scope()
|
instance = scope.get_parent_scope()
|
||||||
coming_from = search_name
|
coming_from = search_name
|
||||||
while coming_from is not None and not isinstance(coming_from, pr.Class):
|
while coming_from is not None and not isinstance(coming_from, pr.Class):
|
||||||
|
|||||||
@@ -515,7 +515,6 @@ class Class(use_metaclass(CachedMetaClass, Wrapper)):
|
|||||||
yield self.names_dict
|
yield self.names_dict
|
||||||
else:
|
else:
|
||||||
for scope in self.py__mro__(self._evaluator):
|
for scope in self.py__mro__(self._evaluator):
|
||||||
print(scope)
|
|
||||||
yield scope.names_dict
|
yield scope.names_dict
|
||||||
|
|
||||||
def is_class(self):
|
def is_class(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user