1
0
forked from VimPlug/jedi

goto / related_name fixed -> tests are passing again

This commit is contained in:
David Halter
2012-09-22 15:15:21 +02:00
parent 0c71a9d86a
commit 4735126f1b
5 changed files with 77 additions and 74 deletions
+35 -56
View File
@@ -237,16 +237,7 @@ class Script(object):
return [] return []
if isinstance(user_stmt, parsing.Import): if isinstance(user_stmt, parsing.Import):
import_names = user_stmt.get_all_import_names() scopes = [self._get_on_import_stmt(is_like_search)[0]]
count = 0
kill_count = -1
for i in import_names:
for name_part in i.names:
count += 1
if self.pos <= name_part.end_pos:
kill_count += 1
scopes = [imports.ImportPath(user_stmt, is_like_search,
kill_count=kill_count, direct_resolve=True)]
else: else:
# just parse one statement, take it and evaluate it # just parse one statement, take it and evaluate it
stmt = self._get_under_cursor_stmt(goto_path) stmt = self._get_under_cursor_stmt(goto_path)
@@ -303,80 +294,51 @@ class Script(object):
d = [Definition(d) for d in set(self._goto()[0])] d = [Definition(d) for d in set(self._goto()[0])]
return sorted(d, key=lambda x: (x.module_path, x.start_pos)) return sorted(d, key=lambda x: (x.module_path, x.start_pos))
def _goto(self, check_imports=True): def _goto(self, add_import_name=False):
user_stmt = self.parser.user_stmt
goto_path = self.module.get_path_under_cursor() goto_path = self.module.get_path_under_cursor()
context = self.module.get_context() context = self.module.get_context()
if next(context) in ('class', 'def'): if next(context) in ('class', 'def'):
user_scope = self.parser.user_scope user_scope = self.parser.user_scope
definitions = set([user_scope.name]) definitions = set([user_scope.name])
search_name = str(user_scope.name) search_name = str(user_scope.name)
elif check_imports and isinstance(self.parser.user_stmt, parsing.Import): elif isinstance(self.parser.user_stmt, parsing.Import):
import_names = user_stmt.get_all_import_names() s, name_part = self._get_on_import_stmt()
count = 0
kill_count = -1
for i in import_names:
for name_part in i.names:
count += 1
if self.pos <= name_part.end_pos:
kill_count += 1
s = imports.ImportPath(user_stmt, False, kill_count=kill_count,
direct_resolve=True)
try: try:
definitions = [s.follow(is_goto=True)[0]] definitions = [s.follow(is_goto=True)[0]]
except IndexError: except IndexError:
definitions = [] definitions = []
search_name = str(import_names[-1]) search_name = str(name_part)
if add_import_name:
import_name = self.parser.user_stmt.get_defined_names()
# imports have only one name
if name_part == import_name[0].names[-1]:
definitions.append(import_name[0])
else: else:
stmt = self._get_under_cursor_stmt(goto_path) stmt = self._get_under_cursor_stmt(goto_path)
definitions, search_name = evaluate.goto(stmt) definitions, search_name = evaluate.goto(stmt)
return definitions, search_name return definitions, search_name
def related_names(self): def related_names(self, additional_module_paths=[]):
""" """
Returns `dynamic.RelatedName` objects, which contain all names, that Returns `dynamic.RelatedName` objects, which contain all names, that
are defined by the same variable, function, class or import. are defined by the same variable, function, class or import.
This function can be used either to show all the usages of a variable This function can be used either to show all the usages of a variable
or for renaming purposes. or for renaming purposes.
TODO implement additional_module_paths
""" """
definitions, search_name = self._goto(check_imports=True) definitions, search_name = self._goto(add_import_name=True)
definitions = dynamic.related_name_add_import_modules(definitions) definitions = dynamic.related_name_add_import_modules(definitions)
module = set([d.get_parent_until() for d in definitions]) module = set([d.get_parent_until() for d in definitions])
module.add(self.parser.module) module.add(self.parser.module)
if definitions: names = dynamic.related_names(definitions, search_name, module)
names = dynamic.related_names(definitions, search_name, module)
else:
names = []
for d in definitions: for d in definitions:
if isinstance(d, parsing.Statement): if isinstance(d, parsing.Module):
def add_array(arr): names.append(dynamic.RelatedName(d, d))
calls = dynamic._scan_array(arr, search_name)
for call in calls:
for n in call.name.names:
if n == search_name:
names.append(dynamic.RelatedName(n, d))
for op, arr in d.assignment_details:
add_array(arr)
if not d.assignment_details:
add_array(d.get_assignment_calls())
elif isinstance(d, parsing.Import):
is_user = d == self.module.parser.user_stmt
check_names = [d.namespace, d.alias, d.from_ns] if is_user \
else d.get_defined_names()
for name in check_names:
if name:
for n in name.names:
if n.start_pos <= self.pos <= n.end_pos \
or not is_user:
names.append(dynamic.RelatedName(n, d))
elif isinstance(d, parsing.Name):
names.append(dynamic.RelatedName(d.names[0], d))
elif isinstance(d, parsing.Module):
names.append(dynamic.RelatedName(d.get_names(), d))
else: else:
names.append(dynamic.RelatedName(d.name.names[0], d)) names.append(dynamic.RelatedName(d.names[0], d))
return sorted(names, key=lambda x: (x.module_path, x.start_pos)) return sorted(names, key=lambda x: (x.module_path, x.start_pos))
@@ -453,6 +415,23 @@ class Script(object):
index -= re.search('^[ ,]*', after).group(0).count(',') index -= re.search('^[ ,]*', after).group(0).count(',')
return CallDef(executable, index, call) return CallDef(executable, index, call)
def _get_on_import_stmt(self, is_like_search=False):
user_stmt = self.parser.user_stmt
import_names = user_stmt.get_all_import_names()
count = 0
kill_count = -1
cur_name_part = None
for i in import_names:
for name_part in i.names:
count += 1
if self.pos <= name_part.end_pos:
kill_count += 1
cur_name_part = name_part
i = imports.ImportPath(user_stmt, is_like_search,
kill_count=kill_count, direct_resolve=True)
return i, cur_name_part
def _get_completion_parts(self, path): def _get_completion_parts(self, path):
""" """
Returns the parts for the completion Returns the parts for the completion
+26 -7
View File
@@ -358,6 +358,9 @@ def related_names(definitions, search_name, mods):
return result return result
if not definitions:
return set()
mods |= set([d.get_parent_until() for d in definitions]) mods |= set([d.get_parent_until() for d in definitions])
names = [] names = []
for m in get_directory_modules_for_name(mods, search_name): for m in get_directory_modules_for_name(mods, search_name):
@@ -369,23 +372,39 @@ def related_names(definitions, search_name, mods):
except KeyError: except KeyError:
continue continue
for stmt in stmts: for stmt in stmts:
print stmt if isinstance(stmt, parsing.Import):
for call in _scan_array(stmt.get_assignment_calls(), search_name): count = 0
names += check_call(call) 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 kill_count, name_part in imps:
i = imports.ImportPath(stmt, False,
kill_count=count - kill_count, direct_resolve=True)
f = i.follow(is_goto=True)
if set(f) & set(definitions):
names.append(RelatedName(name_part, stmt))
else:
ass = stmt.get_assignment_calls()
for call in _scan_array(ass, search_name):
names += check_call(call)
return names return names
def related_name_add_import_modules(definitions): def related_name_add_import_modules(definitions):
""" Adds the modules of the imports """ """ Adds the modules of the imports """
new = [] new = set()
for d in definitions: for d in definitions:
if isinstance(d.parent(), parsing.Import): if isinstance(d.parent(), parsing.Import):
# introduce kill_count for not fully used imports # TODO introduce kill_count for not fully used imports
s = imports.ImportPath(d.parent(), False, direct_resolve=True) s = imports.ImportPath(d.parent(), False, direct_resolve=True)
try: try:
new.append(s.follow(is_goto=True)[0]) new.add(s.follow(is_goto=True)[0])
except IndexError: except IndexError:
pass pass
return definitions + new return set(definitions) | new
+8 -7
View File
@@ -1148,6 +1148,14 @@ class PyFuzzyParser(object):
self._tokenize_end_pos[1]) self._tokenize_end_pos[1])
def _check_user_stmt(self, simple): def _check_user_stmt(self, simple):
if not isinstance(simple, Param):
for tok_name in self.module.temp_used_names:
try:
self.module.used_names[tok_name].add(simple)
except KeyError:
self.module.used_names[tok_name] = set([simple])
self.module.temp_used_names = []
if not self.user_position: if not self.user_position:
return return
# the position is right # the position is right
@@ -1517,13 +1525,6 @@ class PyFuzzyParser(object):
stmt = stmt_class(string, set_vars, used_funcs, used_vars, \ stmt = stmt_class(string, set_vars, used_funcs, used_vars, \
tok_list, first_pos, self.end_pos) tok_list, first_pos, self.end_pos)
self._check_user_stmt(stmt) self._check_user_stmt(stmt)
if not isinstance(stmt, Param):
for tok_name in self.module.temp_used_names:
try:
self.module.used_names[tok_name].add(stmt)
except KeyError:
self.module.used_names[tok_name] = set([stmt])
self.module.temp_used_names = []
if is_return: if is_return:
# add returns to the scope # add returns to the scope
func = self.scope.get_parent_until(Function) func = self.scope.get_parent_until(Function)
+1 -1
View File
@@ -116,7 +116,7 @@ func_with_import().sleep
# ----------------- # -----------------
#? ['sqlite3'] #? ['sqlite3']
import sqlite import sqlite3
#? ['classes'] #? ['classes']
import classes import classes
+7 -3
View File
@@ -62,10 +62,10 @@ def a(): pass
#< (65,7) (68,0) #< (65,7) (68,0)
import colorama import module_not_exists
#< (65,7) (68,0) #< (65,7) (68,0)
colorama module_not_exists
@@ -74,5 +74,9 @@ colorama
from import_tree import rename1 from import_tree import rename1
#< (78,8) (3,0) (4,20) (6,0) #< (78,8) (3,0) (4,20) (6,0) (81,32) (82,0) (6,0)
rename1.abc rename1.abc
#< (78,8) (3,0) (4,20) (6,0) (81,32) (82,0) (6,0)
from import_tree.rename1 import abc
abc