forked from VimPlug/jedi
most evaluate representation classes probably receive the evaluator instance now
This commit is contained in:
@@ -255,10 +255,12 @@ class Evaluator(object):
|
|||||||
r = func.var.params[r.position_nr]
|
r = func.var.params[r.position_nr]
|
||||||
|
|
||||||
# add docstring knowledge
|
# add docstring knowledge
|
||||||
doc_params = docstrings.follow_param(r)
|
"""
|
||||||
|
doc_params = docstrings.follow_param(r) TODO ENABLE
|
||||||
if doc_params:
|
if doc_params:
|
||||||
res_new += doc_params
|
res_new += doc_params
|
||||||
continue
|
continue
|
||||||
|
"""
|
||||||
|
|
||||||
if not r.is_generated:
|
if not r.is_generated:
|
||||||
res_new += dynamic.search_params(r)
|
res_new += dynamic.search_params(r)
|
||||||
@@ -267,7 +269,7 @@ class Evaluator(object):
|
|||||||
if c in ('*', '**'):
|
if c in ('*', '**'):
|
||||||
t = 'tuple' if c == '*' else 'dict'
|
t = 'tuple' if c == '*' else 'dict'
|
||||||
res_new = [er.Instance(
|
res_new = [er.Instance(
|
||||||
self.find_name(builtin.Builtin.scope, t)[0])
|
self, self.find_name(builtin.Builtin.scope, t)[0])
|
||||||
]
|
]
|
||||||
if not r.assignment_details:
|
if not r.assignment_details:
|
||||||
# this means that there are no default params,
|
# this means that there are no default params,
|
||||||
@@ -284,7 +286,7 @@ class Evaluator(object):
|
|||||||
|
|
||||||
if check_instance is not None:
|
if check_instance is not None:
|
||||||
# class renames
|
# class renames
|
||||||
add = [er.InstanceElement(check_instance, a, True)
|
add = [er.InstanceElement(self, check_instance, a, True)
|
||||||
if isinstance(a, (er.Function, pr.Function))
|
if isinstance(a, (er.Function, pr.Function))
|
||||||
else a for a in add]
|
else a for a in add]
|
||||||
res_new += add
|
res_new += add
|
||||||
@@ -346,7 +348,7 @@ class Evaluator(object):
|
|||||||
if isinstance(scope, er.InstanceElement):
|
if isinstance(scope, er.InstanceElement):
|
||||||
inst = scope.instance
|
inst = scope.instance
|
||||||
else:
|
else:
|
||||||
inst = er.Instance(er.Class(until()))
|
inst = er.Instance(self, er.Class(self, until()))
|
||||||
inst.is_generated = True
|
inst.is_generated = True
|
||||||
result.append(inst)
|
result.append(inst)
|
||||||
elif par.isinstance(pr.Statement):
|
elif par.isinstance(pr.Statement):
|
||||||
@@ -543,7 +545,7 @@ class Evaluator(object):
|
|||||||
result += self.follow_statement(call.stmt)
|
result += self.follow_statement(call.stmt)
|
||||||
else:
|
else:
|
||||||
if isinstance(call, pr.Lambda):
|
if isinstance(call, pr.Lambda):
|
||||||
result.append(er.Function(call))
|
result.append(er.Function(self, call))
|
||||||
# With things like params, these can also be functions...
|
# With things like params, these can also be functions...
|
||||||
elif isinstance(call, pr.Base) and call.isinstance(
|
elif isinstance(call, pr.Base) and call.isinstance(
|
||||||
er.Function, er.Class, er.Instance, dynamic.ArrayInstance):
|
er.Function, er.Class, er.Instance, dynamic.ArrayInstance):
|
||||||
@@ -595,7 +597,7 @@ class Evaluator(object):
|
|||||||
# for pr.Literal
|
# for pr.Literal
|
||||||
scopes = self.find_name(builtin.Builtin.scope, current.type_as_string())
|
scopes = self.find_name(builtin.Builtin.scope, current.type_as_string())
|
||||||
# Make instances of those number/string objects.
|
# Make instances of those number/string objects.
|
||||||
scopes = [er.Instance(s, (current.value,)) for s in scopes]
|
scopes = [er.Instance(self, s, (current.value,)) for s in scopes]
|
||||||
result = imports.strip_imports(self, scopes)
|
result = imports.strip_imports(self, scopes)
|
||||||
|
|
||||||
return self.follow_paths(path, result, scope, position=position)
|
return self.follow_paths(path, result, scope, position=position)
|
||||||
@@ -662,7 +664,7 @@ class Evaluator(object):
|
|||||||
return self.follow_paths(path, set(result), call_scope, position=position)
|
return self.follow_paths(path, set(result), call_scope, position=position)
|
||||||
|
|
||||||
def execute(self, scope, params, evaluate_generator=False):
|
def execute(self, scope, params, evaluate_generator=False):
|
||||||
return er.Execution(scope, params).get_return_types(evaluate_generator)
|
return er.Execution(self, scope, params).get_return_types(evaluate_generator)
|
||||||
|
|
||||||
def goto(self, stmt, call_path=None):
|
def goto(self, stmt, call_path=None):
|
||||||
if call_path is None:
|
if call_path is None:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def memoize_default(default, cache_is_in_self=False):
|
def memoize_default(default, cache_is_in_self=False, first_arg_is_evaluator=False):
|
||||||
""" This is a typical memoization decorator, BUT there is one difference:
|
""" This is a typical memoization decorator, BUT there is one difference:
|
||||||
To prevent recursion it sets defaults.
|
To prevent recursion it sets defaults.
|
||||||
|
|
||||||
@@ -17,6 +17,8 @@ def memoize_default(default, cache_is_in_self=False):
|
|||||||
def wrapper(obj, *args, **kwargs):
|
def wrapper(obj, *args, **kwargs):
|
||||||
if cache_is_in_self:
|
if cache_is_in_self:
|
||||||
cache = obj.memoize_cache
|
cache = obj.memoize_cache
|
||||||
|
elif first_arg_is_evaluator: # needed for meta classes
|
||||||
|
cache = args[0].memoize_cache
|
||||||
else:
|
else:
|
||||||
cache = obj._evaluator.memoize_cache
|
cache = obj._evaluator.memoize_cache
|
||||||
|
|
||||||
@@ -24,7 +26,7 @@ def memoize_default(default, cache_is_in_self=False):
|
|||||||
memo = cache[function]
|
memo = cache[function]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
memo = {}
|
memo = {}
|
||||||
cache[function] = function
|
cache[function] = memo
|
||||||
|
|
||||||
key = (args, frozenset(kwargs.items()))
|
key = (args, frozenset(kwargs.items()))
|
||||||
if key in memo:
|
if key in memo:
|
||||||
@@ -39,10 +41,11 @@ def memoize_default(default, cache_is_in_self=False):
|
|||||||
|
|
||||||
|
|
||||||
class CachedMetaClass(type):
|
class CachedMetaClass(type):
|
||||||
""" This is basically almost the same than the decorator above, it just
|
|
||||||
caches class initializations. I haven't found any other way, so I do it
|
|
||||||
with meta classes.
|
|
||||||
"""
|
"""
|
||||||
@memoize_default(None)
|
This is basically almost the same than the decorator above, it just caches
|
||||||
|
class initializations. I haven't found any other way, so I'm doing it with
|
||||||
|
meta classes.
|
||||||
|
"""
|
||||||
|
@memoize_default(None, first_arg_is_evaluator=True)
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
return super(CachedMetaClass, self).__call__(*args, **kwargs)
|
return super(CachedMetaClass, self).__call__(*args, **kwargs)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class Executable(pr.IsScope):
|
|||||||
:param var_args: The param input array, consist of `pr.Array` or list.
|
:param var_args: The param input array, consist of `pr.Array` or list.
|
||||||
"""
|
"""
|
||||||
def __init__(self, evaluator, base, var_args=()):
|
def __init__(self, evaluator, base, var_args=()):
|
||||||
self.evaluator = evaluator
|
self._evaluator = evaluator
|
||||||
self.base = base
|
self.base = base
|
||||||
self.var_args = var_args
|
self.var_args = var_args
|
||||||
|
|
||||||
@@ -74,8 +74,8 @@ class Instance(use_metaclass(CachedMetaClass, Executable)):
|
|||||||
|
|
||||||
@memoize_default(None)
|
@memoize_default(None)
|
||||||
def _get_method_execution(self, func):
|
def _get_method_execution(self, func):
|
||||||
func = InstanceElement(self, func, True)
|
func = InstanceElement(self._evaluator, self, func, True)
|
||||||
return Execution(func, self.var_args)
|
return Execution(self._evaluator, func, self.var_args)
|
||||||
|
|
||||||
def _get_func_self_name(self, func):
|
def _get_func_self_name(self, func):
|
||||||
"""
|
"""
|
||||||
@@ -96,7 +96,7 @@ class Instance(use_metaclass(CachedMetaClass, Executable)):
|
|||||||
"""
|
"""
|
||||||
n = copy.copy(name)
|
n = copy.copy(name)
|
||||||
n.names = n.names[1:]
|
n.names = n.names[1:]
|
||||||
names.append(InstanceElement(self, n))
|
names.append(InstanceElement(self._evaluator, self, n))
|
||||||
|
|
||||||
names = []
|
names = []
|
||||||
# This loop adds the names of the self object, copies them and removes
|
# This loop adds the names of the self object, copies them and removes
|
||||||
@@ -125,17 +125,17 @@ class Instance(use_metaclass(CachedMetaClass, Executable)):
|
|||||||
add_self_dot_name(n)
|
add_self_dot_name(n)
|
||||||
|
|
||||||
for s in self.base.get_super_classes():
|
for s in self.base.get_super_classes():
|
||||||
names += Instance(s)._get_self_attributes()
|
names += Instance(self._evaluator, s)._get_self_attributes()
|
||||||
|
|
||||||
return names
|
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 InstanceElement(self, sub, True)
|
return InstanceElement(self._evaluator, self, sub, True)
|
||||||
|
|
||||||
def execute_subscope_by_name(self, name, args=()):
|
def execute_subscope_by_name(self, name, args=()):
|
||||||
method = self.get_subscope_by_name(name)
|
method = self.get_subscope_by_name(name)
|
||||||
return Execution(method, args).get_return_types()
|
return Execution(self._evaluator, method, args).get_return_types()
|
||||||
|
|
||||||
def get_descriptor_return(self, obj):
|
def get_descriptor_return(self, obj):
|
||||||
""" Throws a KeyError if there's no method. """
|
""" Throws a KeyError if there's no method. """
|
||||||
@@ -154,7 +154,7 @@ class Instance(use_metaclass(CachedMetaClass, Executable)):
|
|||||||
|
|
||||||
class_names = self.base.instance_names()
|
class_names = self.base.instance_names()
|
||||||
for var in class_names:
|
for var in class_names:
|
||||||
names.append(InstanceElement(self, var, True))
|
names.append(InstanceElement(self._evaluator, self, var, True))
|
||||||
return names
|
return names
|
||||||
|
|
||||||
def scope_generator(self):
|
def scope_generator(self):
|
||||||
@@ -167,7 +167,7 @@ class Instance(use_metaclass(CachedMetaClass, Executable)):
|
|||||||
names = []
|
names = []
|
||||||
class_names = self.base.instance_names()
|
class_names = self.base.instance_names()
|
||||||
for var in class_names:
|
for var in class_names:
|
||||||
names.append(InstanceElement(self, var, True))
|
names.append(InstanceElement(self._evaluator, self, var, True))
|
||||||
yield self, names
|
yield self, names
|
||||||
|
|
||||||
def get_index_types(self, index=None):
|
def get_index_types(self, index=None):
|
||||||
@@ -195,9 +195,9 @@ class InstanceElement(use_metaclass(CachedMetaClass, pr.Base)):
|
|||||||
InstanceElement is a wrapper for any object, that is used as an instance
|
InstanceElement is a wrapper for any object, that is used as an instance
|
||||||
variable (e.g. self.variable or class methods).
|
variable (e.g. self.variable or class methods).
|
||||||
"""
|
"""
|
||||||
def __init__(self, instance, var, is_class_var=False):
|
def __init__(self, evaluator, instance, var, is_class_var=False):
|
||||||
if isinstance(var, pr.Function):
|
if isinstance(var, pr.Function):
|
||||||
var = Function(var)
|
var = Function(evaluator, var)
|
||||||
elif isinstance(var, pr.Class):
|
elif isinstance(var, pr.Class):
|
||||||
var = Class(var)
|
var = Class(var)
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
@@ -213,7 +213,7 @@ class InstanceElement(use_metaclass(CachedMetaClass, pr.Base)):
|
|||||||
and par == self.instance.base.base:
|
and par == self.instance.base.base:
|
||||||
par = self.instance
|
par = self.instance
|
||||||
elif not isinstance(par, pr.Module):
|
elif not isinstance(par, pr.Module):
|
||||||
par = InstanceElement(self.instance, par, self.is_class_var)
|
par = InstanceElement(self.instance._evaluator, self.instance, par, self.is_class_var)
|
||||||
return par
|
return par
|
||||||
|
|
||||||
def get_parent_until(self, *args, **kwargs):
|
def get_parent_until(self, *args, **kwargs):
|
||||||
@@ -228,13 +228,13 @@ class InstanceElement(use_metaclass(CachedMetaClass, pr.Base)):
|
|||||||
|
|
||||||
def get_commands(self):
|
def get_commands(self):
|
||||||
# Copy and modify the array.
|
# Copy and modify the array.
|
||||||
return [InstanceElement(self.instance, command, self.is_class_var)
|
return [InstanceElement(self.instance._evaluator, self.instance, command, self.is_class_var)
|
||||||
if not isinstance(command, unicode) else command
|
if not isinstance(command, unicode) else command
|
||||||
for command in self.var.get_commands()]
|
for command in self.var.get_commands()]
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for el in self.var.__iter__():
|
for el in self.var.__iter__():
|
||||||
yield InstanceElement(self.instance, el, self.is_class_var)
|
yield InstanceElement(self.instance._evaluator, self.instance, el, self.is_class_var)
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
return getattr(self.var, name)
|
return getattr(self.var, name)
|
||||||
@@ -352,12 +352,12 @@ class Function(use_metaclass(CachedMetaClass, pr.IsScope)):
|
|||||||
debug.warning('multiple decorators found', self.base_func,
|
debug.warning('multiple decorators found', self.base_func,
|
||||||
dec_results)
|
dec_results)
|
||||||
# Create param array.
|
# Create param array.
|
||||||
old_func = Function(f, is_decorated=True)
|
old_func = Function(self._evaluator, f, is_decorated=True)
|
||||||
if instance is not None and decorator.isinstance(Function):
|
if instance is not None and decorator.isinstance(Function):
|
||||||
old_func = InstanceElement(instance, old_func)
|
old_func = InstanceElement(self._evaluator, instance, old_func)
|
||||||
instance = None
|
instance = None
|
||||||
|
|
||||||
wrappers = Execution(decorator, (old_func,)).get_return_types()
|
wrappers = Execution(self._evaluator, decorator, (old_func,)).get_return_types()
|
||||||
if not len(wrappers):
|
if not len(wrappers):
|
||||||
debug.warning('no wrappers found', self.base_func)
|
debug.warning('no wrappers found', self.base_func)
|
||||||
return None
|
return None
|
||||||
@@ -369,7 +369,7 @@ class Function(use_metaclass(CachedMetaClass, pr.IsScope)):
|
|||||||
|
|
||||||
debug.dbg('decorator end', f)
|
debug.dbg('decorator end', f)
|
||||||
if f != self.base_func and isinstance(f, pr.Function):
|
if f != self.base_func and isinstance(f, pr.Function):
|
||||||
f = Function(f)
|
f = Function(self._evaluator, f)
|
||||||
return f
|
return f
|
||||||
|
|
||||||
def get_decorated_func(self, instance=None):
|
def get_decorated_func(self, instance=None):
|
||||||
@@ -380,7 +380,7 @@ class Function(use_metaclass(CachedMetaClass, pr.IsScope)):
|
|||||||
# If the decorator func is not found, just ignore the decorator
|
# If the decorator func is not found, just ignore the decorator
|
||||||
# function, because sometimes decorators are just really
|
# function, because sometimes decorators are just really
|
||||||
# complicated.
|
# complicated.
|
||||||
return Function(self.base_func, True)
|
return Function(self._evaluator, self.base_func, True)
|
||||||
return decorated_func
|
return decorated_func
|
||||||
|
|
||||||
def get_magic_method_names(self):
|
def get_magic_method_names(self):
|
||||||
@@ -473,12 +473,12 @@ class Execution(Executable):
|
|||||||
cls = Class(cls)
|
cls = Class(cls)
|
||||||
su = cls.get_super_classes()
|
su = cls.get_super_classes()
|
||||||
if su:
|
if su:
|
||||||
return [Instance(su[0])]
|
return [Instance(self._evaluator, su[0])]
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if base.isinstance(Class):
|
if base.isinstance(Class):
|
||||||
# There maybe executions of executions.
|
# There maybe executions of executions.
|
||||||
return [Instance(base, self.var_args)]
|
return [Instance(self._evaluator, base, self.var_args)]
|
||||||
elif isinstance(base, Generator):
|
elif isinstance(base, Generator):
|
||||||
return base.iter_content()
|
return base.iter_content()
|
||||||
else:
|
else:
|
||||||
@@ -508,7 +508,10 @@ class Execution(Executable):
|
|||||||
if func.is_generator and not evaluate_generator:
|
if func.is_generator and not evaluate_generator:
|
||||||
return [Generator(func, self.var_args)]
|
return [Generator(func, self.var_args)]
|
||||||
else:
|
else:
|
||||||
|
"""
|
||||||
stmts = docstrings.find_return_types(func)
|
stmts = docstrings.find_return_types(func)
|
||||||
|
"""
|
||||||
|
stmts=[]
|
||||||
for r in self.returns:
|
for r in self.returns:
|
||||||
if r is not None:
|
if r is not None:
|
||||||
stmts += self._evaluator.follow_statement(r)
|
stmts += self._evaluator.follow_statement(r)
|
||||||
@@ -727,7 +730,7 @@ class Execution(Executable):
|
|||||||
copied = helpers.fast_parent_copy(element)
|
copied = helpers.fast_parent_copy(element)
|
||||||
copied.parent = self._scope_copy(copied.parent)
|
copied.parent = self._scope_copy(copied.parent)
|
||||||
if isinstance(copied, pr.Function):
|
if isinstance(copied, pr.Function):
|
||||||
copied = Function(copied)
|
copied = Function(self._evaluator, copied)
|
||||||
objects.append(copied)
|
objects.append(copied)
|
||||||
return objects
|
return objects
|
||||||
|
|
||||||
@@ -781,7 +784,8 @@ class Execution(Executable):
|
|||||||
|
|
||||||
class Generator(use_metaclass(CachedMetaClass, pr.Base, Iterable)):
|
class Generator(use_metaclass(CachedMetaClass, pr.Base, Iterable)):
|
||||||
""" Cares for `yield` statements. """
|
""" Cares for `yield` statements. """
|
||||||
def __init__(self, func, var_args):
|
def __init__(self, evaluator, func, var_args):
|
||||||
|
# Need evaluator for `CachedMetaClass`.
|
||||||
super(Generator, self).__init__()
|
super(Generator, self).__init__()
|
||||||
self.func = func
|
self.func = func
|
||||||
self.var_args = var_args
|
self.var_args = var_args
|
||||||
@@ -807,7 +811,7 @@ class Generator(use_metaclass(CachedMetaClass, pr.Base, Iterable)):
|
|||||||
|
|
||||||
def iter_content(self):
|
def iter_content(self):
|
||||||
""" returns the content of __iter__ """
|
""" returns the content of __iter__ """
|
||||||
return Execution(self.func, self.var_args).get_return_types(True)
|
return Execution(self._evaluator, self.func, self.var_args).get_return_types(True)
|
||||||
|
|
||||||
def get_index_types(self, index=None):
|
def get_index_types(self, index=None):
|
||||||
debug.warning('Tried to get array access on a generator', self)
|
debug.warning('Tried to get array access on a generator', self)
|
||||||
@@ -897,7 +901,7 @@ class Array(use_metaclass(CachedMetaClass, pr.Base, Iterable)):
|
|||||||
"""
|
"""
|
||||||
# `array.type` is a string with the type, e.g. 'list'.
|
# `array.type` is a string with the type, e.g. 'list'.
|
||||||
scope = self._evaluator.find_name(builtin.Builtin.scope, self._array.type)[0]
|
scope = self._evaluator.find_name(builtin.Builtin.scope, self._array.type)[0]
|
||||||
scope = Instance(scope)
|
scope = Instance(self._evaluator, scope)
|
||||||
names = scope.get_defined_names()
|
names = scope.get_defined_names()
|
||||||
return [ArrayMethod(n) for n in names]
|
return [ArrayMethod(n) for n in names]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user