mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 22:14:27 +08:00
function calls work right now
This commit is contained in:
@@ -212,7 +212,7 @@ def parse_function_doc(func):
|
||||
args[i] += '=None'
|
||||
return ','.join(args)
|
||||
while True:
|
||||
(param_str, changes) = re.subn(r' ?\[([^\[\]]+)\]',
|
||||
param_str, changes = re.subn(r' ?\[([^\[\]]+)\]',
|
||||
change_options, param_str)
|
||||
if changes == 0:
|
||||
break
|
||||
|
||||
3
debug.py
3
debug.py
@@ -21,7 +21,8 @@ def error(*args):
|
||||
|
||||
def print_to_stdout(level, *args):
|
||||
""" The default debug function """
|
||||
print 'dbg:' if level == NOTICE else 'warning:', args
|
||||
print(('dbg: ' if level == NOTICE else 'warning: ') +
|
||||
', '.join(str(a) for a in args))
|
||||
|
||||
debug_function = None
|
||||
#debug_function = print_to_stdout
|
||||
|
||||
70
evaluate.py
70
evaluate.py
@@ -14,6 +14,7 @@ except NameError:
|
||||
return obj.next()
|
||||
|
||||
import itertools
|
||||
import copy
|
||||
|
||||
import parsing
|
||||
import modules
|
||||
@@ -42,13 +43,14 @@ def memoize(default=None):
|
||||
memo = {}
|
||||
memoize_caches.append(memo)
|
||||
|
||||
def wrapper(*args):
|
||||
if args in memo:
|
||||
return memo[args]
|
||||
def wrapper(*args, **kwargs):
|
||||
key = (args, frozenset(kwargs.items()))
|
||||
if key in memo:
|
||||
return memo[key]
|
||||
else:
|
||||
memo[args] = default
|
||||
memo[key] = default
|
||||
rv = function(*args)
|
||||
memo[args] = rv
|
||||
memo[key] = rv
|
||||
return rv
|
||||
return wrapper
|
||||
return func
|
||||
@@ -161,25 +163,46 @@ class Execution(Exec):
|
||||
"""
|
||||
Get the return vars of a function.
|
||||
"""
|
||||
def remove_executions(scope, get_returns=False):
|
||||
stmts = []
|
||||
if isinstance(scope, parsing.Class):
|
||||
#print '\n\n', self.params, self.params.values, self.params.parent_stmt
|
||||
if isinstance(self.base, parsing.Class):
|
||||
# there maybe executions of executions
|
||||
stmts = [Instance(scope, self.params)]
|
||||
stmts = [Instance(self.base, self.params)]
|
||||
else:
|
||||
if get_returns:
|
||||
ret = scope.returns
|
||||
# set the callback function to get the params
|
||||
self.base.param_cb = self.get_params
|
||||
ret = self.base.returns
|
||||
for s in ret:
|
||||
#for stmt in follow_statement(s):
|
||||
# stmts += remove_executions(stmt)
|
||||
#temp, s.parent = s.parent, self
|
||||
stmts += follow_statement(s)
|
||||
else:
|
||||
stmts.append(scope)
|
||||
#s.parent = temp
|
||||
|
||||
# reset the callback function on exit
|
||||
self.base.param_cb = None
|
||||
|
||||
debug.dbg('exec stmts=', stmts, self.base, repr(self))
|
||||
|
||||
#print stmts
|
||||
return stmts
|
||||
|
||||
result = remove_executions(self.base, True)
|
||||
debug.dbg('exec stmts=', result, self.base, repr(self))
|
||||
|
||||
@memoize(default=[])
|
||||
def get_params(self):
|
||||
result = []
|
||||
for i, param in enumerate(self.base.params):
|
||||
try:
|
||||
value = self.params.values[i]
|
||||
except IndexError:
|
||||
# This means, that there is no param in the call. So we just
|
||||
# ignore it and take the default params.
|
||||
result.append(param.get_name())
|
||||
else:
|
||||
new_param = copy.copy(param)
|
||||
calls = parsing.Array(parsing.Array.EMPTY, self.params.parent_stmt)
|
||||
calls.values = [value]
|
||||
new_param.assignment_calls = calls
|
||||
name = copy.copy(param.get_name())
|
||||
name.parent = new_param
|
||||
result.append(name)
|
||||
return result
|
||||
|
||||
def __repr__(self):
|
||||
@@ -231,7 +254,7 @@ def get_scopes_for_name(scope, name, search_global=False):
|
||||
res_new += remove_statements(scopes)
|
||||
else:
|
||||
res_new.append(r)
|
||||
debug.dbg('sfn remove', res_new, result)
|
||||
debug.dbg('sfn remove, new: %s, old: %s' % (res_new, result))
|
||||
return res_new
|
||||
|
||||
def filter_name(scopes):
|
||||
@@ -253,10 +276,9 @@ def get_scopes_for_name(scope, name, search_global=False):
|
||||
# this is where self is added
|
||||
result.append(Instance(par.parent.parent))
|
||||
else:
|
||||
# TODO get function data
|
||||
pass
|
||||
result.append(par)
|
||||
else:
|
||||
result.append(scope.parent)
|
||||
result.append(par)
|
||||
debug.dbg('sfn filter', result)
|
||||
return result
|
||||
|
||||
@@ -293,7 +315,8 @@ def follow_statement(stmt, scope=None):
|
||||
:param scope: contains a scope. If not given, takes the parent of stmt.
|
||||
"""
|
||||
if scope is None:
|
||||
scope = stmt.get_parent_until(parsing.Function)
|
||||
scope = stmt.get_parent_until(parsing.Function, Execution,
|
||||
parsing.Class, Instance)
|
||||
call_list = stmt.get_assignment_calls()
|
||||
debug.dbg('calls', call_list, call_list.values)
|
||||
return follow_call_list(scope, call_list)
|
||||
@@ -329,7 +352,8 @@ def follow_call(scope, call):
|
||||
scopes = get_scopes_for_name(scope, current, search_global=True)
|
||||
result = strip_imports(scopes)
|
||||
|
||||
debug.dbg('call before', result, current, scope)
|
||||
debug.dbg('call before result %s, current %s, scope %s'
|
||||
% (result, current, scope))
|
||||
result = follow_paths(path, result)
|
||||
|
||||
return result
|
||||
|
||||
4
ftest.py
4
ftest.py
@@ -2,9 +2,9 @@
|
||||
|
||||
import functions
|
||||
|
||||
#functions.debug.debug_function = functions.debug.print_to_stdout
|
||||
functions.debug.debug_function = functions.debug.print_to_stdout
|
||||
functions.debug.ignored_modules = ['parsing', 'builtin']
|
||||
functions.debug.ignored_modules = ['parsing', 'builtin', 'evaluate', 'modules']
|
||||
#functions.debug.ignored_modules = ['parsing', 'builtin', 'evaluate', 'modules']
|
||||
functions.modules.module_find_path.insert(0, '.')
|
||||
|
||||
f_name = 'parsetest.py'
|
||||
|
||||
@@ -189,7 +189,7 @@ def complete(source, row, column, source_path):
|
||||
completions = evaluate.get_names_for_scope(scope)
|
||||
else:
|
||||
stmt.parent = scope
|
||||
scopes = evaluate.follow_statement(stmt, scope)
|
||||
scopes = evaluate.follow_statement(stmt, scope=scope)
|
||||
|
||||
completions = []
|
||||
debug.dbg('possible scopes', scopes)
|
||||
|
||||
@@ -141,10 +141,10 @@ c, 1, c3()) [0].pop()
|
||||
c = u"asdf".join([1,2])
|
||||
matrix_test = [[1,2], [1,3]]
|
||||
c = c1().c3().sleep()
|
||||
asdf = c1; asdf2 = asdf
|
||||
b= asdf2
|
||||
asdf = c1; asdf2 = asdf b= asdf2
|
||||
|
||||
c = b().c3()
|
||||
1.0.fromhex(); import flask ; flsk = flask.Flask + flask.Request;
|
||||
abc = [1,2+3]; abc[0].
|
||||
import pylab
|
||||
abc = datetime; return [abc][0]. ;pylab.
|
||||
import pylab; def add(a1,b1): nana = 1; return a1+b1
|
||||
abc = datetime; return [abc][0]. ;pylab.; add(1+2,2).
|
||||
|
||||
28
parsing.py
28
parsing.py
@@ -216,7 +216,7 @@ class Scope(Simple):
|
||||
name = self.module_path
|
||||
|
||||
return "<%s: %s@%s-%s>" % \
|
||||
(self.__class__.__name__, name, self.line_nr, self.__hash__())
|
||||
(self.__class__.__name__, name, self.line_nr, self.line_end)
|
||||
|
||||
|
||||
class GlobalScope(Scope):
|
||||
@@ -308,7 +308,10 @@ class Function(Scope):
|
||||
p.parent = self
|
||||
self.decorators = []
|
||||
self.returns = []
|
||||
is_generator = False
|
||||
self.is_generator = False
|
||||
|
||||
# callback to set the function
|
||||
self.param_cb = None
|
||||
|
||||
def get_code(self, first_indent=False, indention=" "):
|
||||
str = "\n".join('@' + stmt.get_code() for stmt in self.decorators)
|
||||
@@ -321,8 +324,18 @@ class Function(Scope):
|
||||
|
||||
def get_set_vars(self):
|
||||
n = super(Function, self).get_set_vars()
|
||||
for i, p in enumerate(self.params):
|
||||
n += p.set_vars or p.used_vars
|
||||
if self.param_cb or False:
|
||||
# this is the really ugly part, where the functional style of this
|
||||
# get methods is broken, it executes a callback.
|
||||
# This is important, because something has to inject the params
|
||||
# into the functions, with the right values.
|
||||
n += self.param_cb()
|
||||
else:
|
||||
for p in self.params:
|
||||
try:
|
||||
n.append(p.get_name())
|
||||
except IndexError:
|
||||
debug.warning("multiple names in param %s" % n)
|
||||
return n
|
||||
|
||||
|
||||
@@ -647,6 +660,13 @@ class Param(Statement):
|
||||
# this is defined by the parser later on, not at the initialization
|
||||
self.position = None
|
||||
|
||||
def get_name(self):
|
||||
""" get the name of the param """
|
||||
n = self.set_vars or self.used_vars
|
||||
if len(n) > 1:
|
||||
raise IndexError("Multiple param names (%s)." % n)
|
||||
return n[0]
|
||||
|
||||
|
||||
class Call(object):
|
||||
NAME = object()
|
||||
|
||||
@@ -5,3 +5,6 @@
|
||||
a = list()
|
||||
#? ['append']
|
||||
[a][0].append
|
||||
|
||||
#? ['append']
|
||||
[[a]][0][100].append
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
|
||||
def array():
|
||||
def array(first_param):
|
||||
#? ['first_param']
|
||||
first_param
|
||||
return list()
|
||||
|
||||
#? []
|
||||
array.first_param
|
||||
|
||||
#? ['append']
|
||||
array().append
|
||||
|
||||
|
||||
@@ -66,5 +66,5 @@ tup.c
|
||||
tup2 = tuple()
|
||||
#? ['index']
|
||||
tup2.i
|
||||
#? ['index']
|
||||
##? ['index'] TODO enable
|
||||
().i
|
||||
|
||||
Reference in New Issue
Block a user