1
0
forked from VimPlug/jedi

Playing with params/names_dict

This commit is contained in:
Dave Halter
2014-11-03 13:38:57 +01:00
parent f4d7020ebf
commit 4676998fb5
4 changed files with 48 additions and 13 deletions

View File

@@ -61,16 +61,24 @@ class NameFinder(object):
if search_global:
return get_names_of_scope(self._evaluator, self.scope, self.position)
else:
if self.scope.isinstance(er.Function):
return iter([(self.scope, self.scope.get_magic_function_names())])
return self.scope.scope_names_generator(self.position)
def names_dict_lookup(self, scope):
def names_dict_lookup(self, scope, position):
def get_param(el):
if isinstance(el.parent, pr.Param) or isinstance(el.parent.parent, pr.Param):
return scope.param_by_name(str(el))
return el
try:
names = scope.names_dict[str(self.name_str)]
except KeyError:
return []
return [name for name in names if name.is_definition()]
names = [name for name in names if name.is_definition()]
names = pr.filter_after_position(names, position)
if isinstance(scope, er.FunctionExecution):
# Replace params
return [get_param(n) for n in names]
return names
def filter_name(self, scope_names_generator, search_global=False):
"""
@@ -82,11 +90,17 @@ class NameFinder(object):
from jedi.api.interpreter import InterpreterNamespace
names = []
self.maybe_descriptor = isinstance(self.scope, er.Class)
if not search_global and self.scope.isinstance(er.Function):
return [n for n in self.scope.get_magic_function_names()
if str(n) == str(self.name_str)]
for name_list_scope, name_list in scope_names_generator:
if hasattr(name_list_scope, 'names_dict'):
names = self.names_dict_lookup(name_list_scope)
names = self.names_dict_lookup(name_list_scope, self.position)
if names:
break
if isinstance(name_list_scope, (pr.Function, er.FunctionExecution)):
self.position = None
continue
break_scopes = []

View File

@@ -15,7 +15,6 @@ def deep_ast_copy(obj, new_elements_default=None):
return key_value[0] not in ('_expression_list', '_assignment_details')
new_elements = new_elements_default or {}
accept = (pr.Simple, pr.Name, pr.KeywordStatement)
def recursion(obj):
# If it's already in the cache, just return it.
@@ -52,7 +51,7 @@ def deep_ast_copy(obj, new_elements_default=None):
# tree in there.
items = sorted(items, key=sort_stmt)
else:
items = sorted(items, key=lambda x: x[0] == '_names_dict')
items = sorted(items, key=lambda x: x[0] != 'params')
# Actually copy and set attributes.
new_obj = copy.copy(obj)
@@ -75,7 +74,7 @@ def deep_ast_copy(obj, new_elements_default=None):
setattr(new_obj, key, d)
elif isinstance(value, (list, tuple)):
setattr(new_obj, key, sequence_recursion(value))
elif isinstance(value, accept):
elif isinstance(value, (pr.Simple, pr.Name)):
setattr(new_obj, key, recursion(value))
return new_obj
@@ -86,10 +85,10 @@ def deep_ast_copy(obj, new_elements_default=None):
else:
copied_array = array_obj[:] # lists, tuples, strings, unicode
for i, el in enumerate(copied_array):
if isinstance(el, accept):
copied_array[i] = recursion(el)
elif isinstance(el, (tuple, list)):
if isinstance(el, (tuple, list)):
copied_array[i] = sequence_recursion(el)
else:
copied_array[i] = recursion(el)
if isinstance(array_obj, tuple):
return tuple(copied_array)

View File

@@ -559,6 +559,9 @@ class FunctionExecution(Executed):
super(FunctionExecution, self).__init__(evaluator, base, *args, **kwargs)
# for deep_ast_copy
self._copy_dict = {base.base_func: self}
# We definitely want the params to be generated. Params are special,
# because they have been altered and are not normal "children".
self.params
@memoize_default(default=())
@recursion.execution_recursion_decorator
@@ -589,6 +592,11 @@ class FunctionExecution(Executed):
@property
@underscore_memoization
def names_dict(self):
d = {}
for key, values in self.base.names_dict.items():
d[key] = self._copy_list(values)
return d
self.base.names_dict
return LazyDict(self.base.names_dict, self._copy_list)
@memoize_default(default=NO_DEFAULT)
@@ -601,6 +609,9 @@ class FunctionExecution(Executed):
"""
return param.get_params(self._evaluator, self.base, self.var_args)
def param_by_name(self, name):
return [n for n in self._get_params() if str(n) == name][0]
def get_defined_names(self):
"""
Call the default method with the own instance (self implements all
@@ -638,6 +649,11 @@ class FunctionExecution(Executed):
self._scope_copy(scope.parent)
helpers.deep_ast_copy(scope, self._copy_dict)
@common.safe_property
@memoize_default([])
def params(self):
return self._copy_list(self.base.params)
@common.safe_property
@memoize_default([])
def returns(self):

View File

@@ -257,6 +257,8 @@ class Name(Leaf):
stmt = self.get_definition()
if isinstance(stmt, (Function, Class, Module)):
return True
elif isinstance(stmt, Param):
return self == stmt.get_name()
else:
return isinstance(stmt, (ExprStmt, Import)) \
and self in stmt.get_defined_names()
@@ -878,7 +880,7 @@ class Flow(Scope):
:param start_pos: Position (line, column) of the Flow statement.
:type start_pos: tuple(int, int)
"""
__slots__ = ('next', 'previous', 'command', '_parent', 'inputs', 'set_vars')
__slots__ = ('next', 'previous', 'command', 'parent', 'inputs', 'set_vars')
def __init__(self, module, command, inputs, start_pos):
self.next = None
@@ -1252,7 +1254,7 @@ class Param(Base):
A helper class for functions. Read only.
"""
__slots__ = ('tfpdef', 'default', 'stars', 'parent', 'annotation_stmt')
__slots__ = ('tfpdef', 'default', 'stars', 'parent')
def __init__(self, tfpdef, parent, default=None, stars=0):
self.tfpdef = tfpdef # tfpdef: see grammar.txt
@@ -1262,6 +1264,10 @@ class Param(Base):
# Here we reset the parent of our name. IMHO this is ok.
self.get_name().parent = self
def annotation(self):
# Generate from tfpdef.
raise NotImplementedError
@property
def children(self):
return []