1
0
forked from VimPlug/jedi

get rid of generate_param_array

This commit is contained in:
David Halter
2013-02-08 12:32:19 +01:00
parent d82b8d5e19
commit 94126edda8
3 changed files with 42 additions and 50 deletions

View File

@@ -82,7 +82,6 @@ import debug
import builtin import builtin
import imports import imports
import recursion import recursion
import helpers
import dynamic import dynamic
import docstrings import docstrings
@@ -416,9 +415,8 @@ def check_getattr(inst, name_str):
result = [] result = []
# str is important to lose the NamePart! # str is important to lose the NamePart!
name = pr.Call(str(name_str), pr.Call.STRING, (0, 0), inst) name = pr.Call(str(name_str), pr.Call.STRING, (0, 0), inst)
args = helpers.generate_param_array([name])
try: try:
result = inst.execute_subscope_by_name('__getattr__', args) result = inst.execute_subscope_by_name('__getattr__', [name])
except KeyError: except KeyError:
pass pass
if not result: if not result:
@@ -427,7 +425,7 @@ def check_getattr(inst, name_str):
# could be practical and the jedi would return wrong types. If # could be practical and the jedi would return wrong types. If
# you ever have something, let me know! # you ever have something, let me know!
try: try:
result = inst.execute_subscope_by_name('__getattribute__', args) result = inst.execute_subscope_by_name('__getattribute__', [name])
except KeyError: except KeyError:
pass pass
return result return result
@@ -663,8 +661,7 @@ def follow_call_path(path, scope, position):
debug.warning('unknown type:', current.type, current) debug.warning('unknown type:', current.type, current)
scopes = [] scopes = []
# Make instances of those number/string objects. # Make instances of those number/string objects.
arr = helpers.generate_param_array([current.name]) scopes = [er.Instance(s, [current.name]) for s in scopes]
scopes = [er.Instance(s, arr) for s in scopes]
result = imports.strip_imports(scopes) result = imports.strip_imports(scopes)
return follow_paths(path, result, scope, position=position) return follow_paths(path, result, scope, position=position)

View File

@@ -35,12 +35,12 @@ class DecoratorNotFound(LookupError):
class Executable(pr.Base): class Executable(pr.Base):
""" An instance is also an executable - because __init__ is called """ """
def __init__(self, base, var_args=None): An instance is also an executable - because __init__ is called
:param var_args: The param input array, consist of `pr.Array` or list.
"""
def __init__(self, base, var_args=[]):
self.base = base self.base = base
# The param input array.
if var_args is None:
var_args = pr.Array(None, None)
self.var_args = var_args self.var_args = var_args
def get_parent_until(self, *args, **kwargs): def get_parent_until(self, *args, **kwargs):
@@ -122,20 +122,15 @@ class Instance(use_metaclass(cache.CachedMetaClass, Executable)):
sub = self.base.get_subscope_by_name(name) sub = self.base.get_subscope_by_name(name)
return InstanceElement(self, sub, True) return InstanceElement(self, sub, True)
def execute_subscope_by_name(self, name, args=None): def execute_subscope_by_name(self, name, args=[]):
if args is None:
args = helpers.generate_param_array([])
method = self.get_subscope_by_name(name) method = self.get_subscope_by_name(name)
if args.parent_stmt is None:
args.parent_stmt = method
return Execution(method, args).get_return_types() return Execution(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. """
# Arguments in __get__ descriptors are obj, class. # Arguments in __get__ descriptors are obj, class.
# `method` is the new parent of the array, don't know if that's good. # `method` is the new parent of the array, don't know if that's good.
v = [obj, obj.base] if isinstance(obj, Instance) else [None, obj] args = [obj, obj.base] if isinstance(obj, Instance) else [None, obj]
args = helpers.generate_param_array(v)
return self.execute_subscope_by_name('__get__', args) return self.execute_subscope_by_name('__get__', args)
@cache.memoize_default([]) @cache.memoize_default([])
@@ -165,7 +160,7 @@ class Instance(use_metaclass(cache.CachedMetaClass, Executable)):
yield self, names yield self, names
def get_index_types(self, index=None): def get_index_types(self, index=None):
args = helpers.generate_param_array([] if index is None else [index]) args = [] if index is None else [index]
try: try:
return self.execute_subscope_by_name('__getitem__', args) return self.execute_subscope_by_name('__getitem__', args)
except KeyError: except KeyError:
@@ -340,9 +335,8 @@ class Function(use_metaclass(cache.CachedMetaClass, pr.Base)):
decorator = dec_results.pop() decorator = dec_results.pop()
# Create param array. # Create param array.
old_func = Function(f, is_decorated=True) old_func = Function(f, is_decorated=True)
params = helpers.generate_param_array([old_func], old_func)
wrappers = Execution(decorator, params).get_return_types() wrappers = Execution(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
@@ -389,6 +383,17 @@ class Execution(Executable):
multiple calls to functions and recursion has to be avoided. But this is multiple calls to functions and recursion has to be avoided. But this is
responsibility of the decorators. responsibility of the decorators.
""" """
def follow_var_arg(self, index):
try:
stmt = self.var_args[index]
except IndexError:
return []
else:
if isinstance(stmt, pr.Statement):
return evaluate.follow_statement(stmt)
else:
return [stmt] # just some arbitrary object
@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):
@@ -402,8 +407,8 @@ class Execution(Executable):
if func_name == 'getattr': if func_name == 'getattr':
# follow the first param # follow the first param
try: try:
objects = evaluate.follow_call_list([self.var_args[0]]) objects = self.follow_var_arg(0)
names = evaluate.follow_call_list([self.var_args[1]]) names = self.follow_var_arg(1)
except IndexError: except IndexError:
debug.warning('getattr() called with to few args.') debug.warning('getattr() called with to few args.')
return [] return []
@@ -421,11 +426,12 @@ class Execution(Executable):
elif func_name == 'type': elif func_name == 'type':
# otherwise it would be a metaclass # otherwise it would be a metaclass
if len(self.var_args) == 1: if len(self.var_args) == 1:
objects = evaluate.follow_call_list([self.var_args[0]]) objects = self.follow_var_arg(0)
return [o.base for o in objects if isinstance(o, Instance)] return [o.base for o in objects if isinstance(o, Instance)]
elif func_name == 'super': elif func_name == 'super':
# TODO make this able to detect multiple inheritance supers
accept = (pr.Function,) accept = (pr.Function,)
func = self.var_args.parent_stmt.get_parent_until(accept) func = self.var_args.get_parent_until(accept)
if func.isinstance(*accept): if func.isinstance(*accept):
cls = func.get_parent_until(accept + (pr.Class,), cls = func.get_parent_until(accept + (pr.Class,),
include_current=False) include_current=False)
@@ -597,20 +603,20 @@ class Execution(Executable):
""" """
def iterate(): def iterate():
# `var_args` is typically an Array, and not a list. # `var_args` is typically an Array, and not a list.
for var_arg in self.var_args: for stmt in self.var_args:
# empty var_arg if not isinstance(stmt, pr.Statement):
if len(var_arg) == 0: yield None, stmt
yield None, None
# *args # *args
elif var_arg[0] == '*': elif stmt.token_list[0] == '*':
arrays = evaluate.follow_call_list([var_arg[1:]]) arrays = evaluate.follow_call_list([stmt.token_list[1:]])
# *args must be some sort of an array, otherwise -> ignore
for array in arrays: for array in arrays:
if hasattr(array, 'get_contents'): if hasattr(array, 'get_contents'):
for field in array.get_contents(): for field in array.get_contents():
yield None, field yield None, field
# **kwargs # **kwargs
elif var_arg[0] == '**': elif stmt[0] == '**':
arrays = evaluate.follow_call_list([var_arg[1:]]) arrays = evaluate.follow_call_list([stmt.token_list[1:]])
for array in arrays: for array in arrays:
if hasattr(array, 'get_contents'): if hasattr(array, 'get_contents'):
for key, field in array.get_contents(): for key, field in array.get_contents():
@@ -623,11 +629,13 @@ class Execution(Executable):
yield name, field yield name, field
# Normal arguments (including key arguments). # Normal arguments (including key arguments).
else: else:
if len(var_arg) > 1 and var_arg[1] == '=': if stmt.assignment_detail:
# This is a named parameter (var_arg[0] is a Call). tok, key_arr = stmt.assignment_detail[0]
yield var_arg[0].name, var_arg[2:] # named parameter
if key_arr and isinstance(key_arr[0], pr.Call):
yield tok[0].name, stmt
else: else:
yield None, var_arg yield None, stmt
return iter(common.PushBackIterator(iterate())) return iter(common.PushBackIterator(iterate()))

View File

@@ -60,19 +60,6 @@ def fast_parent_copy(obj):
return recursion(obj) return recursion(obj)
def generate_param_array(args_tuple, parent_stmt=None):
""" This generates an array, that can be used as a param. """
values = []
for arg in args_tuple:
if arg is None:
values.append([])
else:
values.append([arg])
pos = None
arr = pr.Array(pos, pr.Array.TUPLE, parent_stmt, values=values)
return arr
def check_arr_index(arr, pos): def check_arr_index(arr, pos):
positions = arr.arr_el_pos positions = arr.arr_el_pos
for index, comma_pos in enumerate(positions): for index, comma_pos in enumerate(positions):