mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 06:24: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)
|
names += inst.get_self_attributes(add_mro=False)
|
||||||
return names
|
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):
|
def get_subscope_by_name(self, name):
|
||||||
sub = self.base.get_subscope_by_name(name)
|
sub = self.base.get_subscope_by_name(name)
|
||||||
return get_instance_el(self._evaluator, self, sub, True)
|
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]
|
args = [obj, obj.base] if isinstance(obj, Instance) else [compiled.none_obj, obj]
|
||||||
return self.execute_subscope_by_name('__get__', *args)
|
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):
|
def scope_names_generator(self, position=None):
|
||||||
"""
|
"""
|
||||||
An Instance has two scopes: The scope with self names and the class
|
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)
|
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):
|
def get_instance_el(evaluator, instance, var, is_class_var=False):
|
||||||
"""
|
"""
|
||||||
Returns an InstanceElement if it makes sense, otherwise leaves the object
|
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):
|
if isinstance(var, pr.Name):
|
||||||
# TODO temp solution, remove later, Name should never get
|
# TODO temp solution, remove later, Name should never get
|
||||||
# here?
|
# here?
|
||||||
par = get_instance_el(evaluator, instance, var.parent, is_class_var)
|
parent = get_instance_el(evaluator, instance, var.parent)
|
||||||
name = pr.Name(unicode(var), var.start_pos)
|
return InstanceName(var, parent)
|
||||||
name.parent = par
|
|
||||||
return name
|
|
||||||
return var
|
return var
|
||||||
|
|
||||||
var = wrap(evaluator, var)
|
var = wrap(evaluator, var)
|
||||||
@@ -308,6 +372,9 @@ class InstanceElement(use_metaclass(CachedMetaClass, pr.Base)):
|
|||||||
return get_instance_el(self._evaluator, self.instance,
|
return get_instance_el(self._evaluator, self.instance,
|
||||||
self.var.get_rhs(), self.is_class_var)
|
self.var.get_rhs(), self.is_class_var)
|
||||||
|
|
||||||
|
def is_definition(self):
|
||||||
|
return self.var.is_definition()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def children(self):
|
def children(self):
|
||||||
# Copy and modify the array.
|
# Copy and modify the array.
|
||||||
|
|||||||
Reference in New Issue
Block a user