1
0
forked from VimPlug/jedi

total rewrite of goto -> incomplete

This commit is contained in:
David Halter
2012-09-21 20:26:41 +02:00
parent abcc60624e
commit bfca702bf9
4 changed files with 57 additions and 21 deletions

View File

@@ -341,13 +341,14 @@ class Script(object):
e = evaluate.Function(self.module.parser.user_scope) e = evaluate.Function(self.module.parser.user_scope)
else: else:
e = evaluate.Class(self.module.parser.user_scope) e = evaluate.Class(self.module.parser.user_scope)
definitions = [e] definitions = [e.name]
elif isinstance(self.module.parser.user_stmt, #elif isinstance(self.module.parser.user_stmt,
(parsing.Param, parsing.Import)): #(parsing.Param, parsing.Import)):
definitions = [self.module.parser.user_stmt] #definitions = [self.module.parser.user_stmt]
else: else:
evaluate.goto_names = []
scopes = self._prepare_goto(goto_path) scopes = self._prepare_goto(goto_path)
definitions = evaluate.goto(scopes, search_name_new) definitions = evaluate.goto2(scopes, search_name_new)
module = set([d.get_parent_until() for d in definitions]) module = set([d.get_parent_until() for d in definitions])
module.add(self.module.parser.module) module.add(self.module.parser.module)

View File

@@ -341,26 +341,21 @@ def related_names(definitions, search_name, mods):
follow = [] # There might be multiple search_name's in one call_path follow = [] # There might be multiple search_name's in one call_path
call_path = list(call.generate_call_path()) call_path = list(call.generate_call_path())
for i, name in enumerate(call_path): for i, name in enumerate(call_path):
# name is `parsing.NamePart`.
if name == search_name: if name == search_name:
follow.append(call_path[:i + 1]) follow.append(call_path[:i + 1])
for f in follow: for f in follow:
scope = call.parent_stmt().parent() #print 's', evaluate.goto_names, scopes, search.start_pos
evaluate.statement_path = [] #follow_res = evaluate.goto(scopes, search, statement_path_offset=0,
position = call.parent_stmt().start_pos # follow_import=True)
if len(f) > 1: #follow_res = evaluate.goto2(scopes, search)
f, search = f[:-1], f[-1] follow_res, search = evaluate.goto3(f, call)
else:
search = None
scopes = evaluate.follow_call_path(iter(f), scope, position)
follow_res = evaluate.goto(scopes, search, statement_path_offset=0,
follow_import=True)
# compare to see if they match # compare to see if they match
if True in [r in definitions for r in follow_res]: if True in [r in definitions for r in follow_res]:
l = f[-1] # the NamePart object
scope = call.parent_stmt() scope = call.parent_stmt()
result.append(RelatedName(l, scope)) result.append(RelatedName(search, scope))
return result return result

View File

@@ -33,6 +33,7 @@ import dynamic
memoize_caches = [] memoize_caches = []
statement_path = [] statement_path = []
faked_scopes = [] faked_scopes = []
goto_names = None
class DecoratorNotFound(LookupError): class DecoratorNotFound(LookupError):
@@ -74,7 +75,7 @@ def clear_caches():
that should be completed after each completion finishes. The only things that should be completed after each completion finishes. The only things
that stays is the module cache (which is not deleted here). that stays is the module cache (which is not deleted here).
""" """
global memoize_caches, statement_path, faked_scopes global memoize_caches, statement_path, faked_scopes, goto_names
for m in memoize_caches: for m in memoize_caches:
m.clear() m.clear()
@@ -86,6 +87,7 @@ def clear_caches():
# the wrappers. # the wrappers.
statement_path = [] statement_path = []
faked_scopes = [] faked_scopes = []
goto_names = None
follow_statement.reset() follow_statement.reset()
@@ -978,7 +980,8 @@ def get_names_for_scope(scope, position=None, star_search=True,
yield builtin_scope, builtin_scope.get_defined_names() yield builtin_scope, builtin_scope.get_defined_names()
def get_scopes_for_name(scope, name_str, position=None, search_global=False): def get_scopes_for_name(scope, name_str, position=None, search_global=False,
is_goto=False):
""" """
This is the search function. The most important part to debug. This is the search function. The most important part to debug.
`remove_statements` and `filter_statements` really are the core part of `remove_statements` and `filter_statements` really are the core part of
@@ -1142,8 +1145,13 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False):
and isinstance(p.var, parsing.Class): and isinstance(p.var, parsing.Class):
p = p.var p = p.var
if name_str == name.get_code() and p not in break_scopes: if name_str == name.get_code() and p not in break_scopes:
if goto_names is not None:
goto_names.append(name)
r, no_break_scope = process(name) r, no_break_scope = process(name)
result += r if is_goto:
result.append(name)
else:
result += r
# for comparison we need the raw class # for comparison we need the raw class
s = scope.base if isinstance(scope, Class) else scope s = scope.base if isinstance(scope, Class) else scope
# this means that a definition was found and is not e.g. # this means that a definition was found and is not e.g.
@@ -1177,6 +1185,8 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False):
res_new.append(r) res_new.append(r)
return res_new return res_new
if goto_names:
return [] # goto has already been used.
if search_global: if search_global:
scope_generator = get_names_for_scope(scope, position=position) scope_generator = get_names_for_scope(scope, position=position)
else: else:
@@ -1191,6 +1201,8 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False):
names = get_defined_names_for_position(scope, position) names = get_defined_names_for_position(scope, position)
scope_generator = iter([(scope, names)]) scope_generator = iter([(scope, names)])
if is_goto:
return filter_name(scope_generator)
return descriptor_check(remove_statements(filter_name(scope_generator))) return descriptor_check(remove_statements(filter_name(scope_generator)))
@@ -1501,6 +1513,34 @@ def follow_path(path, scope, position=None):
return follow_paths(path, set(result), position=position) return follow_paths(path, set(result), position=position)
def goto3(call_path, call):
scope = call.parent_stmt().parent()
position = call.parent_stmt().start_pos
call_path, search = call_path[:-1], call_path[-1]
if call_path:
scopes = follow_call_path(iter(call_path), scope, position)
search_global = False
pos = None
else:
scopes = [scope]
pos = search.start_pos
search_global = True
follow_res = []
for s in scopes:
follow_res += get_scopes_for_name(s, search, pos,
search_global=search_global, is_goto=True)
print 'c', call, scope, follow_res
return follow_res, search
def goto2(scopes, search_name=None):
global goto_names
result = goto_names
if result == []:
print 'LALA', scopes
goto_names = None
return result
def goto(scopes, search_name=None, statement_path_offset=1, def goto(scopes, search_name=None, statement_path_offset=1,
follow_import=False): follow_import=False):
def follow_imports(names): def follow_imports(names):

View File

@@ -7,7 +7,7 @@ results always contain position informations.
def abc(): pass def abc(): pass
#< 0 (7,4) (10,0) (12,0) #< 0 (7,4) (10,0) (12,0)
abc.d.a.abc.d abc.d.a.bsaasd.abc.d
abc abc