mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 14:34:31 +08:00
tried to clean up the mess of Instances and InstanceElements
This commit is contained in:
50
evaluate.py
50
evaluate.py
@@ -860,10 +860,8 @@ def get_defined_names_for_position(scope, position=None, start_scope=None):
|
|||||||
names = scope.get_defined_names()
|
names = scope.get_defined_names()
|
||||||
# Instances have special rules, always return all the possible completions,
|
# Instances have special rules, always return all the possible completions,
|
||||||
# because class variables are always valid and the `self.` variables, too.
|
# because class variables are always valid and the `self.` variables, too.
|
||||||
print scope, start_scope
|
if (not position or isinstance(scope, (Array, Instance))
|
||||||
if (not position or isinstance(scope, Array)
|
or start_scope != scope
|
||||||
or isinstance(scope, Instance)
|
|
||||||
or start_scope != scope
|
|
||||||
and isinstance(start_scope, (parsing.Function, Execution))):
|
and isinstance(start_scope, (parsing.Function, Execution))):
|
||||||
return names
|
return names
|
||||||
names_new = []
|
names_new = []
|
||||||
@@ -880,20 +878,20 @@ def get_names_for_scope(scope, position=None, star_search=True,
|
|||||||
The star search option is only here to provide an optimization. Otherwise
|
The star search option is only here to provide an optimization. Otherwise
|
||||||
the whole thing would probably start a little recursive madness.
|
the whole thing would probably start a little recursive madness.
|
||||||
"""
|
"""
|
||||||
start_scope = in_scope = scope
|
in_func_scope = scope
|
||||||
non_flow = scope.get_parent_until(parsing.Flow, reverse=True)
|
non_flow = scope.get_parent_until(parsing.Flow, reverse=True)
|
||||||
while scope:
|
while scope:
|
||||||
# `parsing.Class` is used, because the parent is never `Class`.
|
# `parsing.Class` is used, because the parent is never `Class`.
|
||||||
# Ignore the Flows, because the classes and functions care for that.
|
# Ignore the Flows, because the classes and functions care for that.
|
||||||
# InstanceElement of Class is ignored, if it is not the start scope.
|
# InstanceElement of Class is ignored, if it is not the start scope.
|
||||||
#print scope, start_scope
|
if not (scope != non_flow and scope.isinstance(parsing.Class)
|
||||||
if not (scope != start_scope and scope.isinstance(parsing.Class)
|
|
||||||
or scope.isinstance(parsing.Flow)
|
or scope.isinstance(parsing.Flow)
|
||||||
#or scope.isinstance(Instance) and scope != non_flow
|
or scope.isinstance(Instance)
|
||||||
|
and non_flow.isinstance(Function)
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
yield scope, get_defined_names_for_position(scope, position,
|
yield scope, get_defined_names_for_position(scope, position,
|
||||||
in_scope)
|
in_func_scope)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
raise MultiLevelStopIteration('StopIteration raised somewhere')
|
raise MultiLevelStopIteration('StopIteration raised somewhere')
|
||||||
if scope.isinstance(parsing.ForFlow) and scope.is_list_comp:
|
if scope.isinstance(parsing.ForFlow) and scope.is_list_comp:
|
||||||
@@ -904,11 +902,11 @@ def get_names_for_scope(scope, position=None, star_search=True,
|
|||||||
# This is used, because subscopes (Flow scopes) would distort the
|
# This is used, because subscopes (Flow scopes) would distort the
|
||||||
# results.
|
# results.
|
||||||
if scope and scope.isinstance(Function, parsing.Function, Execution):
|
if scope and scope.isinstance(Function, parsing.Function, Execution):
|
||||||
in_scope = scope
|
in_func_scope = scope
|
||||||
|
|
||||||
# Add star imports.
|
# Add star imports.
|
||||||
if star_search:
|
if star_search:
|
||||||
for s in imports.remove_star_imports(start_scope.get_parent_until()):
|
for s in imports.remove_star_imports(non_flow.get_parent_until()):
|
||||||
for g in get_names_for_scope(s, star_search=False):
|
for g in get_names_for_scope(s, star_search=False):
|
||||||
yield g
|
yield g
|
||||||
|
|
||||||
@@ -937,12 +935,18 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False):
|
|||||||
"""
|
"""
|
||||||
res_new = []
|
res_new = []
|
||||||
for r in result:
|
for r in result:
|
||||||
|
add = []
|
||||||
if r.isinstance(parsing.Statement):
|
if r.isinstance(parsing.Statement):
|
||||||
|
check_instance = None
|
||||||
|
if isinstance(r, InstanceElement) and r.is_class_var:
|
||||||
|
check_instance = r.instance
|
||||||
|
r = r.var
|
||||||
|
|
||||||
# Global variables handling.
|
# Global variables handling.
|
||||||
if r.is_global():
|
if r.is_global():
|
||||||
for token_name in r.token_list[1:]:
|
for token_name in r.token_list[1:]:
|
||||||
if isinstance(token_name, parsing.Name):
|
if isinstance(token_name, parsing.Name):
|
||||||
res_new += get_scopes_for_name(r.parent(),
|
add = get_scopes_for_name(r.parent(),
|
||||||
str(token_name))
|
str(token_name))
|
||||||
else:
|
else:
|
||||||
# generated objects are used within executions, where
|
# generated objects are used within executions, where
|
||||||
@@ -964,7 +968,14 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
scopes = follow_statement(r, seek_name=name_str)
|
scopes = follow_statement(r, seek_name=name_str)
|
||||||
res_new += remove_statements(scopes)
|
add += remove_statements(scopes)
|
||||||
|
|
||||||
|
if check_instance is not None:
|
||||||
|
# class renames
|
||||||
|
add = [InstanceElement(check_instance, a, True)
|
||||||
|
if isinstance(a, (Function, parsing.Function))
|
||||||
|
else a for a in add ]
|
||||||
|
res_new += add
|
||||||
else:
|
else:
|
||||||
if isinstance(r, parsing.Class):
|
if isinstance(r, parsing.Class):
|
||||||
r = Class(r)
|
r = Class(r)
|
||||||
@@ -1000,6 +1011,8 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False):
|
|||||||
"""
|
"""
|
||||||
result = []
|
result = []
|
||||||
no_break_scope = False
|
no_break_scope = False
|
||||||
|
#if isinstance(scope, InstanceElement) and scope.var == name.parent().parent():
|
||||||
|
#name = InstanceElement(scope.instance, name)
|
||||||
par = name.parent()
|
par = name.parent()
|
||||||
|
|
||||||
if par.isinstance(parsing.Flow):
|
if par.isinstance(parsing.Flow):
|
||||||
@@ -1046,10 +1059,9 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False):
|
|||||||
no_break_scope = True
|
no_break_scope = True
|
||||||
|
|
||||||
# TODO this makes self variables non-breakable. wanted?
|
# TODO this makes self variables non-breakable. wanted?
|
||||||
r = [n for n in par.get_set_vars()
|
#r = [n for n in par.get_set_vars()
|
||||||
if len(n) > 1 and str(n.names[-1] == name)]
|
# if len(n) > 1 and str(n.names[-1] == name)]
|
||||||
if isinstance(name, InstanceElement) and r \
|
if isinstance(name, InstanceElement):# and r:
|
||||||
and not name.is_class_var:
|
|
||||||
no_break_scope = True
|
no_break_scope = True
|
||||||
|
|
||||||
result.append(par)
|
result.append(par)
|
||||||
@@ -1301,10 +1313,6 @@ def follow_call(call):
|
|||||||
""" Follow a call is following a function, variable, string, etc. """
|
""" Follow a call is following a function, variable, string, etc. """
|
||||||
scope = call.parent_stmt().parent()
|
scope = call.parent_stmt().parent()
|
||||||
path = call.generate_call_path()
|
path = call.generate_call_path()
|
||||||
path = list(path)
|
|
||||||
#print 'p', scope, path
|
|
||||||
path = iter(path)
|
|
||||||
|
|
||||||
position = call.parent_stmt().start_pos
|
position = call.parent_stmt().start_pos
|
||||||
return follow_call_path(path, scope, position)
|
return follow_call_path(path, scope, position)
|
||||||
|
|
||||||
|
|||||||
@@ -101,11 +101,11 @@ class Simple(Base):
|
|||||||
@Python3Method
|
@Python3Method
|
||||||
def get_parent_until(self, classes=(), reverse=False):
|
def get_parent_until(self, classes=(), reverse=False):
|
||||||
""" Takes always the parent, until one class (not a Class) """
|
""" Takes always the parent, until one class (not a Class) """
|
||||||
if type(classes) != tuple:
|
if type(classes) not in (tuple, list):
|
||||||
classes = (classes,)
|
classes = (classes,)
|
||||||
scope = self
|
scope = self
|
||||||
while not scope.parent() is None:
|
while not scope.parent() is None:
|
||||||
if reverse != scope.isinstance(*classes):
|
if classes and reverse != scope.isinstance(*classes):
|
||||||
break
|
break
|
||||||
scope = scope.parent()
|
scope = scope.parent()
|
||||||
return scope
|
return scope
|
||||||
|
|||||||
Reference in New Issue
Block a user