1
0
forked from VimPlug/jedi

move the usages stuff away from dynamic

This commit is contained in:
Dave Halter
2013-12-24 22:54:03 +01:00
parent 3c28b1907c
commit dd804dc4cb
2 changed files with 80 additions and 79 deletions

View File

@@ -700,3 +700,83 @@ def set_debug_function(func_cb=debug.print_to_stdout, warnings=True,
debug.enable_warning = warnings
debug.enable_notice = notices
debug.enable_speed = speed
# TODO move to a better place.
def usages(definitions, search_name, mods):
def compare_array(definitions):
""" `definitions` are being compared by module/start_pos, because
sometimes the id's of the objects change (e.g. executions).
"""
result = []
for d in definitions:
module = d.get_parent_until()
result.append((module, d.start_pos))
return result
def check_call(call):
result = []
follow = [] # There might be multiple search_name's in one call_path
call_path = list(call.generate_call_path())
for i, name in enumerate(call_path):
# name is `pr.NamePart`.
if name == search_name:
follow.append(call_path[:i + 1])
for f in follow:
follow_res, search = evaluate.goto(call.parent, f)
follow_res = usages_add_import_modules(follow_res, search)
compare_follow_res = compare_array(follow_res)
# compare to see if they match
if any(r in compare_definitions for r in compare_follow_res):
scope = call.parent
result.append(api_classes.Usage(search, scope))
return result
if not definitions:
return set()
compare_definitions = compare_array(definitions)
mods |= set([d.get_parent_until() for d in definitions])
names = []
for m in get_directory_modules_for_name(mods, search_name):
try:
stmts = m.used_names[search_name]
except KeyError:
continue
for stmt in stmts:
if isinstance(stmt, pr.Import):
count = 0
imps = []
for i in stmt.get_all_import_names():
for name_part in i.names:
count += 1
if name_part == search_name:
imps.append((count, name_part))
for used_count, name_part in imps:
i = imports.ImportPath(_evaluator, stmt, kill_count=count - used_count,
direct_resolve=True)
f = i.follow(is_goto=True)
if set(f) & set(definitions):
names.append(api_classes.Usage(name_part, stmt))
else:
for call in _scan_statement(stmt, search_name,
assignment_details=True):
names += check_call(call)
return names
def usages_add_import_modules(definitions, search_name):
""" Adds the modules of the imports """
new = set()
for d in definitions:
if isinstance(d.parent, pr.Import):
s = imports.ImportPath(_evaluator, d.parent, direct_resolve=True)
with common.ignored(IndexError):
new.add(s.follow(is_goto=True)[0])
return set(definitions) | new

View File

@@ -57,10 +57,8 @@ from jedi import cache
from jedi.parser import representation as pr
from jedi import modules
from jedi import settings
from jedi import common
from jedi import debug
from jedi.parser import fast as fast_parser
from jedi.evaluate import imports
from jedi.evaluate.cache import memoize_default
# This is something like the sys.path, but only for searching params. It means
@@ -449,83 +447,6 @@ class ArrayInstance(pr.Base):
return items
def usages(definitions, search_name, mods):
def compare_array(definitions):
""" `definitions` are being compared by module/start_pos, because
sometimes the id's of the objects change (e.g. executions).
"""
result = []
for d in definitions:
module = d.get_parent_until()
result.append((module, d.start_pos))
return result
def check_call(call):
result = []
follow = [] # There might be multiple search_name's in one call_path
call_path = list(call.generate_call_path())
for i, name in enumerate(call_path):
# name is `pr.NamePart`.
if name == search_name:
follow.append(call_path[:i + 1])
for f in follow:
follow_res, search = evaluate.goto(call.parent, f)
follow_res = usages_add_import_modules(follow_res, search)
compare_follow_res = compare_array(follow_res)
# compare to see if they match
if any(r in compare_definitions for r in compare_follow_res):
scope = call.parent
result.append(api_classes.Usage(search, scope))
return result
if not definitions:
return set()
compare_definitions = compare_array(definitions)
mods |= set([d.get_parent_until() for d in definitions])
names = []
for m in get_directory_modules_for_name(mods, search_name):
try:
stmts = m.used_names[search_name]
except KeyError:
continue
for stmt in stmts:
if isinstance(stmt, pr.Import):
count = 0
imps = []
for i in stmt.get_all_import_names():
for name_part in i.names:
count += 1
if name_part == search_name:
imps.append((count, name_part))
for used_count, name_part in imps:
i = imports.ImportPath(_evaluator, stmt, kill_count=count - used_count,
direct_resolve=True)
f = i.follow(is_goto=True)
if set(f) & set(definitions):
names.append(api_classes.Usage(name_part, stmt))
else:
for call in _scan_statement(stmt, search_name,
assignment_details=True):
names += check_call(call)
return names
def usages_add_import_modules(definitions, search_name):
""" Adds the modules of the imports """
new = set()
for d in definitions:
if isinstance(d.parent, pr.Import):
s = imports.ImportPath(_evaluator, d.parent, direct_resolve=True)
with common.ignored(IndexError):
new.add(s.follow(is_goto=True)[0])
return set(definitions) | new
def check_flow_information(flow, search_name, pos):
""" Try to find out the type of a variable just with the information that
is given by the flows: e.g. It is also responsible for assert checks.::