1
0
forked from VimPlug/jedi

change Execution usage to always use the decorator function

This commit is contained in:
David Halter
2013-08-10 21:40:36 +04:30
parent c35da04820
commit 085bddd6a1
2 changed files with 46 additions and 32 deletions

View File

@@ -38,11 +38,18 @@ class Executable(pr.IsScope):
self.var_args = var_args self.var_args = var_args
def get_parent_until(self, *args, **kwargs): def get_parent_until(self, *args, **kwargs):
return self.base.get_parent_until(*args, **kwargs) return self.decorated.get_parent_until(*args, **kwargs)
@property @property
def parent(self): def parent(self):
return self.base.parent return self.decorated.parent
@property
def decorated(self):
"""
Instance doesn't care about decorators and Execution overrides this
"""
return self.base
class Instance(use_metaclass(cache.CachedMetaClass, Executable)): class Instance(use_metaclass(cache.CachedMetaClass, Executable)):
@@ -393,14 +400,24 @@ class Execution(Executable):
else: else:
return [stmt] # just some arbitrary object return [stmt] # just some arbitrary object
@property
@cache.memoize_default()
def decorated(self):
"""Get the decorated version of the input"""
base = self.base
if self.base.isinstance(Function):
base = base.get_decorated_func()
return base
@cache.memoize_default(default=()) @cache.memoize_default(default=())
@recursion.ExecutionRecursionDecorator @recursion.ExecutionRecursionDecorator
def get_return_types(self, evaluate_generator=False): def get_return_types(self, evaluate_generator=False):
""" Get the return types of a function. """ """ Get the return types of a function. """
base = self.decorated
stmts = [] stmts = []
if self.base.parent == builtin.Builtin.scope \ if base.parent == builtin.Builtin.scope \
and not isinstance(self.base, (Generator, Array)): and not isinstance(base, (Generator, Array)):
func_name = str(self.base.name) func_name = str(base.name)
# some implementations of builtins: # some implementations of builtins:
if func_name == 'getattr': if func_name == 'getattr':
@@ -419,8 +436,7 @@ class Execution(Executable):
if len(arr_name.var_args) != 1: if len(arr_name.var_args) != 1:
debug.warning('jedi getattr is too simple') debug.warning('jedi getattr is too simple')
key = arr_name.var_args[0] key = arr_name.var_args[0]
stmts += evaluate.follow_path(iter([key]), obj, stmts += evaluate.follow_path(iter([key]), obj, base)
self.base)
return stmts return stmts
elif func_name == 'type': elif func_name == 'type':
# otherwise it would be a metaclass # otherwise it would be a metaclass
@@ -441,36 +457,35 @@ class Execution(Executable):
return [Instance(su[0])] return [Instance(su[0])]
return [] return []
if self.base.isinstance(Class): if base.isinstance(Class):
# There maybe executions of executions. # There maybe executions of executions.
stmts = [Instance(self.base, self.var_args)] stmts = [Instance(base, self.var_args)]
elif isinstance(self.base, Generator): elif isinstance(base, Generator):
return self.base.iter_content() return base.iter_content()
else: else:
try: try:
self.base.returns # Test if it is a function base.returns # Test if it is a function
except AttributeError: except AttributeError:
if hasattr(self.base, 'execute_subscope_by_name'): if hasattr(base, 'execute_subscope_by_name'):
try: try:
stmts = self.base.execute_subscope_by_name('__call__', stmts = base.execute_subscope_by_name('__call__',
self.var_args) self.var_args)
except KeyError: except KeyError:
debug.warning("no __call__ func available", self.base) debug.warning("no __call__ func available", base)
else: else:
debug.warning("no execution possible", self.base) debug.warning("no execution possible", base)
else: else:
stmts = self._get_function_returns(evaluate_generator) stmts = self._get_function_returns(base, evaluate_generator)
debug.dbg('exec result: %s in %s' % (stmts, self)) debug.dbg('exec result: %s in %s' % (stmts, self))
return imports.strip_imports(stmts) return imports.strip_imports(stmts)
def _get_function_returns(self, evaluate_generator): def _get_function_returns(self, func, evaluate_generator):
""" A normal Function execution """ """ A normal Function execution """
# Feed the listeners, with the params. # Feed the listeners, with the params.
for listener in self.base.listeners: for listener in func.listeners:
listener.execute(self.get_params()) listener.execute(self.get_params())
func = self.base.get_decorated_func()
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:
@@ -496,7 +511,7 @@ class Execution(Executable):
parent = self.var_args.parent parent = self.var_args.parent
start_pos = self.var_args.start_pos start_pos = self.var_args.start_pos
else: else:
parent = self.base parent = self.decorated
start_pos = 0, 0 start_pos = 0, 0
new_param = copy.copy(param) new_param = copy.copy(param)
@@ -524,15 +539,15 @@ class Execution(Executable):
result = [] result = []
start_offset = 0 start_offset = 0
if isinstance(self.base, InstanceElement): if isinstance(self.decorated, InstanceElement):
# Care for self -> just exclude it and add the instance # Care for self -> just exclude it and add the instance
start_offset = 1 start_offset = 1
self_name = copy.copy(self.base.params[0].get_name()) self_name = copy.copy(self.decorated.params[0].get_name())
self_name.parent = self.base.instance self_name.parent = self.decorated.instance
result.append(self_name) result.append(self_name)
param_dict = {} param_dict = {}
for param in self.base.params: for param in self.decorated.params:
param_dict[str(param.get_name())] = param param_dict[str(param.get_name())] = param
# There may be calls, which don't fit all the params, this just ignores # There may be calls, which don't fit all the params, this just ignores
# it. # it.
@@ -541,7 +556,7 @@ class Execution(Executable):
non_matching_keys = [] non_matching_keys = []
keys_used = set() keys_used = set()
keys_only = False keys_only = False
for param in self.base.params[start_offset:]: for param in self.decorated.params[start_offset:]:
# The value and key can both be null. There, the defaults apply. # The value and key can both be null. There, the defaults apply.
# args / kwargs will just be empty arrays / dicts, respectively. # args / kwargs will just be empty arrays / dicts, respectively.
# Wrong value count is just ignored. If you try to test cases that # Wrong value count is just ignored. If you try to test cases that
@@ -686,7 +701,7 @@ class Execution(Executable):
execution. execution.
""" """
# Copy all these lists into this local function. # Copy all these lists into this local function.
attr = getattr(self.base, prop) attr = getattr(self.decorated, prop)
objects = [] objects = []
for element in attr: for element in attr:
if element is None: if element is None:
@@ -702,7 +717,7 @@ class Execution(Executable):
def __getattr__(self, name): def __getattr__(self, name):
if name not in ['start_pos', 'end_pos', 'imports', '_sub_module']: if name not in ['start_pos', 'end_pos', 'imports', '_sub_module']:
raise AttributeError('Tried to access %s: %s. Why?' % (name, self)) raise AttributeError('Tried to access %s: %s. Why?' % (name, self))
return getattr(self.base, name) return getattr(self.decorated, name)
@cache.memoize_default() @cache.memoize_default()
@common.rethrow_uncaught @common.rethrow_uncaught
@@ -744,7 +759,7 @@ class Execution(Executable):
def __repr__(self): def __repr__(self):
return "<%s of %s>" % \ return "<%s of %s>" % \
(type(self).__name__, self.base) (type(self).__name__, self.decorated)
class Generator(use_metaclass(cache.CachedMetaClass, pr.Base)): class Generator(use_metaclass(cache.CachedMetaClass, pr.Base)):

View File

@@ -149,13 +149,12 @@ JustAClass.a()
class DecoratorWithoutCall(): class DecoratorWithoutCall():
def __init__(self, func): def __init__(self, func):
self.func = func self.func = func
def __call__(self):
return self.func()
@DecoratorWithoutCall @DecoratorWithoutCall
def f(): def f():
return 1 return 1
# cannot be resolved - should be ignored
@DecoratorWithoutCall(None) @DecoratorWithoutCall(None)
def g(): def g():
return 1 return 1