mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 06:44:46 +08:00
params of methods are now better handled, this is the first version, which i think would be useful for usage
This commit is contained in:
3
debug.py
3
debug.py
@@ -23,5 +23,6 @@ def print_to_stdout(level, *args):
|
||||
""" The default debug function """
|
||||
print 'dbg:' if level == NOTICE else 'warning:', args
|
||||
|
||||
debug_function = print_to_stdout
|
||||
debug_function = None
|
||||
#debug_function = print_to_stdout
|
||||
ignored_modules = []
|
||||
|
||||
24
evaluate.py
24
evaluate.py
@@ -21,10 +21,10 @@ def memoize(default=None):
|
||||
don't think, that there is a big speed difference, but there are many cases
|
||||
where recursion could happen (think about a = b; b = a).
|
||||
"""
|
||||
memo = {}
|
||||
def func(function):
|
||||
memo = {}
|
||||
|
||||
def wrapper(*args):
|
||||
print function, args
|
||||
if args in memo:
|
||||
return memo[args]
|
||||
else:
|
||||
@@ -166,6 +166,19 @@ def get_scopes_for_name(scope, name, search_global=False):
|
||||
# result += filter_name(i)
|
||||
#else:
|
||||
if [name] == list(scope.names):
|
||||
par = scope.parent
|
||||
if isinstance(par, parsing.Flow):
|
||||
# TODO get Flow data, which is defined by the loop (or
|
||||
# with)
|
||||
pass
|
||||
elif isinstance(par, parsing.Param):
|
||||
if isinstance(par.parent.parent, parsing.Class) \
|
||||
and par.position == 0:
|
||||
result.append(Instance(par.parent.parent))
|
||||
else:
|
||||
# TODO get function data
|
||||
pass
|
||||
else:
|
||||
result.append(scope.parent)
|
||||
debug.dbg('sfn filter', result)
|
||||
return result
|
||||
@@ -188,12 +201,12 @@ def strip_imports(scopes):
|
||||
if isinstance(s, parsing.Import):
|
||||
print 'dini mueter, steile griech!'
|
||||
try:
|
||||
scope = follow_import(s)
|
||||
new = follow_import(s)
|
||||
except modules.ModuleNotFound:
|
||||
debug.dbg('Module not found: ' + str(s))
|
||||
else:
|
||||
result.append(scope)
|
||||
result += strip_imports(i for i in scope.get_imports() if i.star)
|
||||
result.append(new)
|
||||
result += strip_imports(i for i in new.get_imports() if i.star)
|
||||
else:
|
||||
result.append(s)
|
||||
return result
|
||||
@@ -223,7 +236,6 @@ def follow_call(scope, call):
|
||||
path = call.generate_call_list()
|
||||
|
||||
current = next(path)
|
||||
print 'call', scope, call, current
|
||||
if isinstance(current, parsing.Array):
|
||||
result = [current]
|
||||
else:
|
||||
|
||||
4
ftest.py
4
ftest.py
@@ -9,6 +9,6 @@ functions.modules.module_find_path.insert(0, '.')
|
||||
with open('test.py') as f:
|
||||
code = f.read()
|
||||
for i in range(1):
|
||||
completions = functions.complete(code, 50, 20)
|
||||
completions = functions.complete(code, 50, 200)
|
||||
|
||||
print '\n', [c.names for c in completions]
|
||||
print '\n', [c.names[-1] for c in completions]
|
||||
|
||||
36
functions.py
36
functions.py
@@ -8,11 +8,6 @@ import debug
|
||||
__all__ = ['complete', 'complete_test', 'set_debug_function']
|
||||
|
||||
|
||||
class ParserError(LookupError):
|
||||
""" The exception that is thrown if some handmade parser fails. """
|
||||
pass
|
||||
|
||||
|
||||
class FileWithCursor(modules.File):
|
||||
"""
|
||||
Manages all files, that are parsed and caches them.
|
||||
@@ -118,44 +113,27 @@ def complete(source, row, column, file_callback=None):
|
||||
"""
|
||||
f = FileWithCursor('__main__', source=source, row=row)
|
||||
scope = f.parser.user_scope
|
||||
|
||||
# print a debug.dbg title
|
||||
debug.dbg('complete_scope', scope)
|
||||
|
||||
try:
|
||||
path = f.get_row_path(column)
|
||||
print path
|
||||
debug.dbg('completion_path', path)
|
||||
except ParserError as e:
|
||||
path = []
|
||||
debug.dbg(e)
|
||||
debug.dbg('completion_start: %s in %s' % (path, scope))
|
||||
|
||||
result = []
|
||||
if path and path[0]:
|
||||
# just parse one statement
|
||||
#debug.ignored_modules = ['builtin']
|
||||
# just parse one statement, take it and evaluate it
|
||||
r = parsing.PyFuzzyParser(path)
|
||||
#debug.ignored_modules = ['parsing', 'builtin']
|
||||
#print 'p', r.top.get_code().replace('\n', r'\n'), r.top.statements[0]
|
||||
scopes = evaluate.follow_statement(r.top.statements[0], scope)
|
||||
|
||||
#name = path.pop() # use this later
|
||||
compl = []
|
||||
debug.dbg('possible scopes')
|
||||
completions = []
|
||||
debug.dbg('possible scopes', scopes)
|
||||
for s in scopes:
|
||||
compl += s.get_defined_names()
|
||||
completions += s.get_defined_names()
|
||||
|
||||
#else:
|
||||
# compl = evaluate.get_names_for_scope(scope)
|
||||
|
||||
debug.dbg('possible-compl', compl)
|
||||
debug.dbg('possible-compl', completions)
|
||||
|
||||
# make a partial comparison, because the other options have to
|
||||
# be returned as well.
|
||||
result = compl
|
||||
#result = [c for c in compl if name in c.names[-1]]
|
||||
|
||||
return result
|
||||
return completions
|
||||
|
||||
|
||||
def complete_test(source, row, column, file_callback=None):
|
||||
|
||||
30
parsing.py
30
parsing.py
@@ -212,7 +212,8 @@ class Scope(Simple):
|
||||
return n
|
||||
|
||||
def get_defined_names(self):
|
||||
return [n for n in self.get_set_vars() if isinstance(n, Import) or len(n) == 1]
|
||||
return [n for n in self.get_set_vars() \
|
||||
if isinstance(n, Import) or len(n) == 1]
|
||||
|
||||
def is_empty(self):
|
||||
"""
|
||||
@@ -515,7 +516,6 @@ class Statement(Simple):
|
||||
close_brackets = False
|
||||
|
||||
debug.dbg('tok_list', self.token_list)
|
||||
print 'tok_list', self.token_list
|
||||
for i, tok_temp in enumerate(self.token_list):
|
||||
#print 'tok', tok_temp, result
|
||||
try:
|
||||
@@ -608,10 +608,23 @@ class Statement(Simple):
|
||||
"behaviour. Please submit a bug" % level)
|
||||
|
||||
self.assignment_calls = top
|
||||
print 'top', top.values, top.values[0][0].name, repr(top.values[0][0].name)
|
||||
return top
|
||||
|
||||
|
||||
class Param(Statement):
|
||||
"""
|
||||
The class which shows definitions of params of classes and functions.
|
||||
But this is not to define function calls.
|
||||
"""
|
||||
def __init__(self, code, set_vars, used_funcs, used_vars, token_list,
|
||||
indent, line_nr, line_end):
|
||||
super(Param, self).__init__(code, set_vars, used_funcs,
|
||||
used_vars, token_list, indent, line_nr, line_end)
|
||||
|
||||
# this is defined by the parser later on, not at the initialization
|
||||
self.position = None
|
||||
|
||||
|
||||
class Call(object):
|
||||
NAME = object()
|
||||
NUMBER = object()
|
||||
@@ -910,10 +923,14 @@ class PyFuzzyParser(object):
|
||||
"""
|
||||
names = []
|
||||
tok = None
|
||||
pos = 0
|
||||
while tok not in [')', ':']:
|
||||
stmt, tok = self._parse_statement(added_breaks=',')
|
||||
stmt, tok = self._parse_statement(added_breaks=',',
|
||||
stmt_class=Param)
|
||||
if stmt:
|
||||
stmt.position = pos
|
||||
names.append(stmt)
|
||||
pos += 1
|
||||
|
||||
return names
|
||||
|
||||
@@ -972,7 +989,8 @@ class PyFuzzyParser(object):
|
||||
|
||||
return Class(cname, super, indent, start_line)
|
||||
|
||||
def _parse_statement(self, pre_used_token=None, added_breaks=None):
|
||||
def _parse_statement(self, pre_used_token=None, added_breaks=None,
|
||||
stmt_class=Statement):
|
||||
"""
|
||||
Parses statements like:
|
||||
|
||||
@@ -1075,7 +1093,7 @@ class PyFuzzyParser(object):
|
||||
and self.last_token[1] == tokenize.STRING:
|
||||
self.scope.add_docstr(self.last_token[1])
|
||||
else:
|
||||
stmt = Statement(string, set_vars, used_funcs, used_vars,\
|
||||
stmt = stmt_class(string, set_vars, used_funcs, used_vars,\
|
||||
tok_list, indent, line_start, self.line_nr)
|
||||
if is_return:
|
||||
# add returns to the scope
|
||||
|
||||
Reference in New Issue
Block a user