forked from VimPlug/jedi
Fix most usage tests.
This commit is contained in:
+13
-11
@@ -34,6 +34,7 @@ from jedi.evaluate.param import try_iter_content
|
|||||||
from jedi.evaluate.helpers import get_module_names
|
from jedi.evaluate.helpers import get_module_names
|
||||||
from jedi.evaluate.sys_path import get_venv_path
|
from jedi.evaluate.sys_path import get_venv_path
|
||||||
from jedi.evaluate.iterable import unpack_tuple_to_dict
|
from jedi.evaluate.iterable import unpack_tuple_to_dict
|
||||||
|
from jedi.evaluate.filters import TreeNameDefinition
|
||||||
|
|
||||||
# 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
|
||||||
# can remove some "maximum recursion depth" errors.
|
# can remove some "maximum recursion depth" errors.
|
||||||
@@ -256,8 +257,8 @@ class Script(object):
|
|||||||
try:
|
try:
|
||||||
module_node = self._get_module_node()
|
module_node = self._get_module_node()
|
||||||
user_stmt = module_node.get_statement_for_position(self._pos)
|
user_stmt = module_node.get_statement_for_position(self._pos)
|
||||||
definitions = self._goto()
|
definition_names = self._goto()
|
||||||
if not definitions and isinstance(user_stmt, tree.Import):
|
if not definition_names and isinstance(user_stmt, tree.Import):
|
||||||
# For not defined imports (goto doesn't find something, we take
|
# For not defined imports (goto doesn't find something, we take
|
||||||
# the name as a definition. This is enough, because every name
|
# the name as a definition. This is enough, because every name
|
||||||
# points to it.
|
# points to it.
|
||||||
@@ -265,22 +266,23 @@ class Script(object):
|
|||||||
if name is None:
|
if name is None:
|
||||||
# Must be syntax
|
# Must be syntax
|
||||||
return []
|
return []
|
||||||
definitions = [name]
|
self._evaluator
|
||||||
|
definition_names = [TreeNameDefinition(self._get_module(), name)]
|
||||||
|
|
||||||
if not definitions:
|
if not definition_names:
|
||||||
# Without a definition for a name we cannot find references.
|
# Without a definition for a name we cannot find references.
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if not isinstance(user_stmt, tree.Import):
|
if not isinstance(user_stmt, tree.Import) and False:
|
||||||
# import case is looked at with add_import_name option
|
# import case is looked at with add_import_name option
|
||||||
definitions = usages.usages_add_import_modules(self._evaluator,
|
definition_names = usages.usages_add_import_modules(self._evaluator,
|
||||||
definitions)
|
definition_names)
|
||||||
|
|
||||||
module = set([d.get_parent_until() for d in definitions])
|
modules = set([d.get_root_context() for d in definition_names])
|
||||||
module.add(module_node)
|
modules.add(self._get_module())
|
||||||
names = usages.usages(self._evaluator, definitions, module)
|
names = usages.usages(self._evaluator, definition_names, modules)
|
||||||
|
|
||||||
for d in set(definitions):
|
for d in set(definition_names):
|
||||||
names.append(classes.Definition(self._evaluator, d))
|
names.append(classes.Definition(self._evaluator, d))
|
||||||
finally:
|
finally:
|
||||||
settings.dynamic_flow_information = temp
|
settings.dynamic_flow_information = temp
|
||||||
|
|||||||
+9
-10
@@ -2,6 +2,7 @@ from jedi._compatibility import unicode
|
|||||||
from jedi.api import classes
|
from jedi.api import classes
|
||||||
from jedi.parser import tree
|
from jedi.parser import tree
|
||||||
from jedi.evaluate import imports
|
from jedi.evaluate import imports
|
||||||
|
from jedi.evaluate.filters import TreeNameDefinition
|
||||||
|
|
||||||
|
|
||||||
def usages(evaluator, definition_names, mods):
|
def usages(evaluator, definition_names, mods):
|
||||||
@@ -14,23 +15,20 @@ def usages(evaluator, definition_names, mods):
|
|||||||
"""
|
"""
|
||||||
result = []
|
result = []
|
||||||
for d in definitions:
|
for d in definitions:
|
||||||
module = d.get_parent_until()
|
module = d.get_root_context()
|
||||||
result.append((module, d.start_pos))
|
result.append((module, d.start_pos))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
search_name = unicode(list(definition_names)[0])
|
search_name = list(definition_names)[0].string_name
|
||||||
compare_definitions = compare_array(definition_names)
|
compare_definitions = compare_array(definition_names)
|
||||||
mods |= set([d.get_parent_until() for d in definition_names])
|
mods = mods | set([d.get_root_context() for d in definition_names])
|
||||||
definitions = []
|
definitions = []
|
||||||
for m in imports.get_modules_containing_name(evaluator, mods, search_name):
|
for m in imports.get_modules_containing_name(evaluator, mods, search_name):
|
||||||
try:
|
for name_node in m.module_node.used_names.get(search_name, []):
|
||||||
check_names = m.used_names[search_name]
|
context = evaluator.create_context(m, name_node)
|
||||||
except KeyError:
|
result = evaluator.goto(context, name_node)
|
||||||
continue
|
|
||||||
for name in check_names:
|
|
||||||
|
|
||||||
result = evaluator.goto(name)
|
|
||||||
if [c for c in compare_array(result) if c in compare_definitions]:
|
if [c for c in compare_array(result) if c in compare_definitions]:
|
||||||
|
name = TreeNameDefinition(context, name_node)
|
||||||
definitions.append(classes.Definition(evaluator, name))
|
definitions.append(classes.Definition(evaluator, name))
|
||||||
# Previous definitions might be imports, so include them
|
# Previous definitions might be imports, so include them
|
||||||
# (because goto might return that import name).
|
# (because goto might return that import name).
|
||||||
@@ -42,6 +40,7 @@ def usages_add_import_modules(evaluator, definitions):
|
|||||||
""" Adds the modules of the imports """
|
""" Adds the modules of the imports """
|
||||||
new = set()
|
new = set()
|
||||||
for d in definitions:
|
for d in definitions:
|
||||||
|
print(d)
|
||||||
imp_or_stmt = d.get_definition()
|
imp_or_stmt = d.get_definition()
|
||||||
if isinstance(imp_or_stmt, tree.Import):
|
if isinstance(imp_or_stmt, tree.Import):
|
||||||
s = imports.ImportWrapper(context, d)
|
s = imports.ImportWrapper(context, d)
|
||||||
|
|||||||
@@ -74,7 +74,12 @@ def search_params(evaluator, parent_context, funcdef):
|
|||||||
evaluator.dynamic_params_depth += 1
|
evaluator.dynamic_params_depth += 1
|
||||||
try:
|
try:
|
||||||
debug.dbg('Dynamic param search in %s.', funcdef.name.value, color='MAGENTA')
|
debug.dbg('Dynamic param search in %s.', funcdef.name.value, color='MAGENTA')
|
||||||
function_executions = _search_function_executions(evaluator, funcdef)
|
module_context = parent_context.get_root_context()
|
||||||
|
function_executions = _search_function_executions(
|
||||||
|
evaluator,
|
||||||
|
module_context,
|
||||||
|
funcdef
|
||||||
|
)
|
||||||
if function_executions:
|
if function_executions:
|
||||||
zipped_params = zip(*(
|
zipped_params = zip(*(
|
||||||
function_execution.get_params()
|
function_execution.get_params()
|
||||||
@@ -92,15 +97,15 @@ def search_params(evaluator, parent_context, funcdef):
|
|||||||
|
|
||||||
@memoize_default([], evaluator_is_first_arg=True)
|
@memoize_default([], evaluator_is_first_arg=True)
|
||||||
@to_list
|
@to_list
|
||||||
def _search_function_executions(evaluator, funcdef):
|
def _search_function_executions(evaluator, module_context, funcdef):
|
||||||
"""
|
"""
|
||||||
Returns a list of param names.
|
Returns a list of param names.
|
||||||
"""
|
"""
|
||||||
from jedi.evaluate import representation as er
|
from jedi.evaluate import representation as er
|
||||||
|
|
||||||
def get_possible_nodes(module_node, func_name):
|
def get_possible_nodes(module_context, func_name):
|
||||||
try:
|
try:
|
||||||
names = module_node.used_names[func_name]
|
names = module_context.module_node.used_names[func_name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -110,7 +115,6 @@ def _search_function_executions(evaluator, funcdef):
|
|||||||
if trailer.type == 'trailer' and bracket == '(':
|
if trailer.type == 'trailer' and bracket == '(':
|
||||||
yield name, trailer
|
yield name, trailer
|
||||||
|
|
||||||
current_module_node = funcdef.get_parent_until()
|
|
||||||
func_name = unicode(funcdef.name)
|
func_name = unicode(funcdef.name)
|
||||||
compare_node = funcdef
|
compare_node = funcdef
|
||||||
if func_name == '__init__':
|
if func_name == '__init__':
|
||||||
@@ -122,10 +126,9 @@ def _search_function_executions(evaluator, funcdef):
|
|||||||
|
|
||||||
found_executions = False
|
found_executions = False
|
||||||
i = 0
|
i = 0
|
||||||
for module_node in imports.get_module_nodes_containing_name(
|
for for_mod_context in imports.get_modules_containing_name(
|
||||||
evaluator, [current_module_node], func_name):
|
evaluator, [module_context], func_name):
|
||||||
module_context = er.ModuleContext(evaluator, module_node)
|
for name, trailer in get_possible_nodes(for_mod_context, func_name):
|
||||||
for name, trailer in get_possible_nodes(module_node, func_name):
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
# This is a simple way to stop Jedi's dynamic param recursion
|
# This is a simple way to stop Jedi's dynamic param recursion
|
||||||
|
|||||||
+34
-25
@@ -455,9 +455,12 @@ def _load_module(evaluator, path=None, source=None, sys_path=None, parent_module
|
|||||||
sys_path = evaluator.sys_path
|
sys_path = evaluator.sys_path
|
||||||
|
|
||||||
cached = load_parser(path)
|
cached = load_parser(path)
|
||||||
module = load(source) if cached is None else cached.module
|
module_node = load(source) if cached is None else cached.module
|
||||||
|
if isinstance(module_node, compiled.CompiledObject):
|
||||||
|
return module_node
|
||||||
|
|
||||||
from jedi.evaluate.representation import ModuleContext
|
from jedi.evaluate.representation import ModuleContext
|
||||||
return ModuleContext(evaluator, module)
|
return ModuleContext(evaluator, module_node)
|
||||||
|
|
||||||
|
|
||||||
def add_module(evaluator, module_name, module):
|
def add_module(evaluator, module_name, module):
|
||||||
@@ -469,18 +472,22 @@ def add_module(evaluator, module_name, module):
|
|||||||
evaluator.modules[module_name] = module
|
evaluator.modules[module_name] = module
|
||||||
|
|
||||||
|
|
||||||
def get_module_nodes_containing_name(evaluator, module_nodes, name):
|
def get_modules_containing_name(evaluator, modules, name):
|
||||||
"""
|
"""
|
||||||
Search a name in the directories of modules.
|
Search a name in the directories of modules.
|
||||||
"""
|
"""
|
||||||
|
from jedi.evaluate import representation as er
|
||||||
|
|
||||||
def check_python_file(path):
|
def check_python_file(path):
|
||||||
try:
|
try:
|
||||||
return parser_cache[path].parser.module
|
parser_cache_item = parser_cache[path]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
return check_fs(path)
|
return check_fs(path)
|
||||||
except IOError:
|
except IOError:
|
||||||
return None
|
return None
|
||||||
|
else:
|
||||||
|
return er.ModuleContext(evaluator, parser_cache_item.parser.module)
|
||||||
|
|
||||||
def check_fs(path):
|
def check_fs(path):
|
||||||
with open(path, 'rb') as f:
|
with open(path, 'rb') as f:
|
||||||
@@ -492,27 +499,29 @@ def get_module_nodes_containing_name(evaluator, module_nodes, name):
|
|||||||
return module
|
return module
|
||||||
|
|
||||||
# skip non python modules
|
# skip non python modules
|
||||||
module_nodes = set(m for m in module_nodes if not isinstance(m, compiled.CompiledObject))
|
used_mod_paths = set()
|
||||||
mod_paths = set()
|
for m in modules:
|
||||||
for m in module_nodes:
|
used_mod_paths.add(m.py__file__())
|
||||||
mod_paths.add(m.path)
|
|
||||||
yield m
|
yield m
|
||||||
|
|
||||||
if settings.dynamic_params_for_other_modules:
|
if not settings.dynamic_params_for_other_modules:
|
||||||
paths = set(settings.additional_dynamic_modules)
|
return
|
||||||
for p in mod_paths:
|
|
||||||
if p is not None:
|
|
||||||
# We need abspath, because the seetings paths might not already
|
|
||||||
# have been converted to absolute paths.
|
|
||||||
d = os.path.dirname(os.path.abspath(p))
|
|
||||||
for entry in os.listdir(d):
|
|
||||||
if entry not in mod_paths:
|
|
||||||
if entry.endswith('.py'):
|
|
||||||
paths.add(d + os.path.sep + entry)
|
|
||||||
|
|
||||||
for p in sorted(paths):
|
paths = set(settings.additional_dynamic_modules)
|
||||||
# make testing easier, sort it - same results on every interpreter
|
for p in used_mod_paths:
|
||||||
c = check_python_file(p)
|
if p is not None:
|
||||||
if c is not None and c not in module_nodes and not isinstance(c, compiled.CompiledObject):
|
# We need abspath, because the seetings paths might not already
|
||||||
continue # TODO REENABLE
|
# have been converted to absolute paths.
|
||||||
yield c.module_node
|
d = os.path.dirname(os.path.abspath(p))
|
||||||
|
for file_name in os.listdir(d):
|
||||||
|
path = os.path.join(d, file_name)
|
||||||
|
if path not in used_mod_paths and path not in paths:
|
||||||
|
if file_name.endswith('.py'):
|
||||||
|
paths.add(path)
|
||||||
|
|
||||||
|
# Sort here to make issues less random.
|
||||||
|
for p in sorted(paths):
|
||||||
|
# make testing easier, sort it - same results on every interpreter
|
||||||
|
m = check_python_file(p)
|
||||||
|
if m is not None and not isinstance(m, compiled.CompiledObject):
|
||||||
|
yield m
|
||||||
|
|||||||
Reference in New Issue
Block a user