mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 22:14:27 +08:00
names_dicts for instances.
This commit is contained in:
@@ -182,6 +182,44 @@ class Instance(use_metaclass(CachedMetaClass, Executed)):
|
||||
names += inst.get_self_attributes(add_mro=False)
|
||||
return names
|
||||
|
||||
def _self_names_dict(self, add_mro=True):
|
||||
names = {}
|
||||
# This loop adds the names of the self object, copies them and removes
|
||||
# the self.
|
||||
for sub in self.base.subscopes:
|
||||
if isinstance(sub, pr.Class):
|
||||
continue
|
||||
# Get the self name, if there's one.
|
||||
self_name = self._get_func_self_name(sub)
|
||||
if self_name is None:
|
||||
continue
|
||||
|
||||
if sub.name.value == '__init__' and not self.is_generated:
|
||||
# ``__init__`` is special because the params need are injected
|
||||
# this way. Therefore an execution is necessary.
|
||||
if not sub.get_decorators():
|
||||
# __init__ decorators should generally just be ignored,
|
||||
# because to follow them and their self variables is too
|
||||
# complicated.
|
||||
sub = self._get_method_execution(sub)
|
||||
for name_list in sub.names_dict.values():
|
||||
for name in name_list:
|
||||
if name.value == self_name and name.prev_sibling() is None:
|
||||
trailer = name.next_sibling()
|
||||
if pr.is_node(trailer, 'trailer') \
|
||||
and len(trailer.children) == 2:
|
||||
name = trailer.children[1] # After dot.
|
||||
if name.is_definition():
|
||||
arr = names.setdefault(name.value, [])
|
||||
arr.append(get_instance_el(self._evaluator, self, name))
|
||||
|
||||
if add_mro and False: # TODO ADD!!!!
|
||||
for s in self.base.py__mro__(self._evaluator)[1:]:
|
||||
if not isinstance(s, compiled.CompiledObject):
|
||||
for inst in self._evaluator.execute(s):
|
||||
names += inst.get_self_attributes(add_mro=False)
|
||||
return names
|
||||
|
||||
def get_subscope_by_name(self, name):
|
||||
sub = self.base.get_subscope_by_name(name)
|
||||
return get_instance_el(self._evaluator, self, sub, True)
|
||||
@@ -197,6 +235,13 @@ class Instance(use_metaclass(CachedMetaClass, Executed)):
|
||||
args = [obj, obj.base] if isinstance(obj, Instance) else [compiled.none_obj, obj]
|
||||
return self.execute_subscope_by_name('__get__', *args)
|
||||
|
||||
@memoize_default([])
|
||||
def names_dicts(self):
|
||||
yield self._self_names_dict()
|
||||
|
||||
for names_dict in self.base.names_dicts():
|
||||
yield LazyInstanceDict(self._evaluator, self, names_dict)
|
||||
|
||||
def scope_names_generator(self, position=None):
|
||||
"""
|
||||
An Instance has two scopes: The scope with self names and the class
|
||||
@@ -245,6 +290,27 @@ class Instance(use_metaclass(CachedMetaClass, Executed)):
|
||||
self.var_args, dec)
|
||||
|
||||
|
||||
class LazyInstanceDict(object):
|
||||
def __init__(self, evaluator, instance, dct):
|
||||
self._evaluator = evaluator
|
||||
self._instance = instance
|
||||
self._dct = dct
|
||||
|
||||
def __getitem__(self, name):
|
||||
return [get_instance_el(self._evaluator, self._instance, var, True)
|
||||
for var in self._dct[name]]
|
||||
|
||||
|
||||
class InstanceName(pr.Name):
|
||||
def __init__(self, origin_name, parent):
|
||||
super(InstanceName, self).__init__(origin_name.value, origin_name.start_pos)
|
||||
self._origin_name = origin_name
|
||||
self.parent = parent
|
||||
|
||||
def is_definition(self):
|
||||
return self._origin_name.is_definition()
|
||||
|
||||
|
||||
def get_instance_el(evaluator, instance, var, is_class_var=False):
|
||||
"""
|
||||
Returns an InstanceElement if it makes sense, otherwise leaves the object
|
||||
@@ -255,10 +321,8 @@ def get_instance_el(evaluator, instance, var, is_class_var=False):
|
||||
if isinstance(var, pr.Name):
|
||||
# TODO temp solution, remove later, Name should never get
|
||||
# here?
|
||||
par = get_instance_el(evaluator, instance, var.parent, is_class_var)
|
||||
name = pr.Name(unicode(var), var.start_pos)
|
||||
name.parent = par
|
||||
return name
|
||||
parent = get_instance_el(evaluator, instance, var.parent)
|
||||
return InstanceName(var, parent)
|
||||
return var
|
||||
|
||||
var = wrap(evaluator, var)
|
||||
@@ -308,6 +372,9 @@ class InstanceElement(use_metaclass(CachedMetaClass, pr.Base)):
|
||||
return get_instance_el(self._evaluator, self.instance,
|
||||
self.var.get_rhs(), self.is_class_var)
|
||||
|
||||
def is_definition(self):
|
||||
return self.var.is_definition()
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
# Copy and modify the array.
|
||||
|
||||
Reference in New Issue
Block a user