mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 06:24:27 +08:00
for function works with tuples now / refactoring
This commit is contained in:
59
evaluate.py
59
evaluate.py
@@ -219,7 +219,8 @@ def get_names_for_scope(scope, star_search=True):
|
|||||||
start_scope = scope
|
start_scope = scope
|
||||||
while scope:
|
while scope:
|
||||||
# class variables/functions are only availabe
|
# class variables/functions are only availabe
|
||||||
if not isinstance(scope, parsing.Class) or scope == start_scope:
|
if (not isinstance(scope, parsing.Class) or scope == start_scope) \
|
||||||
|
and not isinstance(scope, parsing.Flow):
|
||||||
compl += scope.get_defined_names()
|
compl += scope.get_defined_names()
|
||||||
scope = scope.parent
|
scope = scope.parent
|
||||||
|
|
||||||
@@ -249,8 +250,8 @@ def get_scopes_for_name(scope, name, search_global=False):
|
|||||||
res_new = []
|
res_new = []
|
||||||
for r in result:
|
for r in result:
|
||||||
if isinstance(r, parsing.Statement):
|
if isinstance(r, parsing.Statement):
|
||||||
|
# global variables handling
|
||||||
if r.is_global():
|
if r.is_global():
|
||||||
res_new += []
|
|
||||||
for token_name in r.token_list[1:]:
|
for token_name in r.token_list[1:]:
|
||||||
if isinstance(token_name, parsing.Name):
|
if isinstance(token_name, parsing.Name):
|
||||||
res_new += get_scopes_for_name(r.parent,
|
res_new += get_scopes_for_name(r.parent,
|
||||||
@@ -265,32 +266,42 @@ def get_scopes_for_name(scope, name, search_global=False):
|
|||||||
|
|
||||||
def filter_name(scopes):
|
def filter_name(scopes):
|
||||||
# the name is already given in the parent function
|
# the name is already given in the parent function
|
||||||
|
|
||||||
|
def handle_non_arrays():
|
||||||
|
result = []
|
||||||
|
par = scope.parent
|
||||||
|
if isinstance(par, parsing.Flow):
|
||||||
|
if par.command == 'for':
|
||||||
|
# take the first statement (for has always only
|
||||||
|
# one, remember `in`). And follow it. After that,
|
||||||
|
# get the types which are in the array
|
||||||
|
arrays = follow_statement(par.inits[0])
|
||||||
|
for array in arrays:
|
||||||
|
for_vars = array.get_index_types()
|
||||||
|
if len(par.set_vars) > 1:
|
||||||
|
var_arr = par.set_stmt.get_assignment_calls()
|
||||||
|
result += assign_tuples(var_arr, for_vars, name)
|
||||||
|
else:
|
||||||
|
result += for_vars
|
||||||
|
else:
|
||||||
|
debug.warning('Why are you here? %s' % par.command)
|
||||||
|
elif isinstance(par, parsing.Param) \
|
||||||
|
and isinstance(par.parent.parent, parsing.Class) \
|
||||||
|
and par.position == 0:
|
||||||
|
# this is where self gets added
|
||||||
|
result.append(Instance(par.parent.parent))
|
||||||
|
result.append(par)
|
||||||
|
else:
|
||||||
|
result.append(par)
|
||||||
|
return result
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
for scope in scopes:
|
for scope in scopes:
|
||||||
if [name] == list(scope.names):
|
if [name] == list(scope.names):
|
||||||
if isinstance(scope, ArrayElement):
|
if isinstance(scope, ArrayElement):
|
||||||
result.append(scope)
|
result.append(scope)
|
||||||
else:
|
else:
|
||||||
par = scope.parent
|
result += handle_non_arrays()
|
||||||
if isinstance(par, parsing.Flow):
|
|
||||||
if par.command == 'for':
|
|
||||||
# take the first statement (for has always only
|
|
||||||
# one, remember `in`). And follow it. After that,
|
|
||||||
# get the types which are in the array
|
|
||||||
arrays = follow_statement(par.inits[0])
|
|
||||||
# TODO for loops can have tuples as set_vars
|
|
||||||
for array in arrays:
|
|
||||||
result += array.get_index_types()
|
|
||||||
else:
|
|
||||||
debug.warning('Why are you here? %s' % par.command)
|
|
||||||
elif isinstance(par, parsing.Param) \
|
|
||||||
and isinstance(par.parent.parent, parsing.Class) \
|
|
||||||
and par.position == 0:
|
|
||||||
# this is where self gets added
|
|
||||||
result.append(Instance(par.parent.parent))
|
|
||||||
result.append(par)
|
|
||||||
else:
|
|
||||||
result.append(par)
|
|
||||||
debug.dbg('sfn filter', result)
|
debug.dbg('sfn filter', result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@@ -319,6 +330,7 @@ def strip_imports(scopes):
|
|||||||
result.append(s)
|
result.append(s)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def assign_tuples(tup, results, seek_name):
|
def assign_tuples(tup, results, seek_name):
|
||||||
"""
|
"""
|
||||||
This is a normal assignment checker. In python functions and other things
|
This is a normal assignment checker. In python functions and other things
|
||||||
@@ -359,6 +371,7 @@ def assign_tuples(tup, results, seek_name):
|
|||||||
result += eval_results(i)
|
result += eval_results(i)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@memoize(default=[])
|
@memoize(default=[])
|
||||||
def follow_statement(stmt, scope=None, seek_name=None):
|
def follow_statement(stmt, scope=None, seek_name=None):
|
||||||
"""
|
"""
|
||||||
@@ -388,7 +401,7 @@ def follow_call_list(scope, call_list):
|
|||||||
This can be either `parsing.Array` or `list`.
|
This can be either `parsing.Array` or `list`.
|
||||||
"""
|
"""
|
||||||
if parsing.Array.is_type(call_list, parsing.Array.TUPLE):
|
if parsing.Array.is_type(call_list, parsing.Array.TUPLE):
|
||||||
# Tuples can stand just alone without any braces. These would be
|
# Tuples can stand just alone without any braces. These would be
|
||||||
# recognized as separate calls, but actually are a tuple.
|
# recognized as separate calls, but actually are a tuple.
|
||||||
result = follow_call(scope, call_list)
|
result = follow_call(scope, call_list)
|
||||||
else:
|
else:
|
||||||
|
|||||||
2
ftest.py
2
ftest.py
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import functions
|
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']
|
||||||
#functions.debug.ignored_modules = ['parsing', 'builtin', 'evaluate', 'modules']
|
#functions.debug.ignored_modules = ['parsing', 'builtin', 'evaluate', 'modules']
|
||||||
functions.modules.module_find_path.insert(0, '.')
|
functions.modules.module_find_path.insert(0, '.')
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ def globalfunc():
|
|||||||
global globalvar, globalvar2
|
global globalvar, globalvar2
|
||||||
globalvar = 3
|
globalvar = 3
|
||||||
|
|
||||||
|
for abcde, efgh in [(1,"")]:
|
||||||
|
abcde.real
|
||||||
|
|
||||||
|
abcde.
|
||||||
|
|
||||||
globalvar.
|
|
||||||
|
|||||||
45
parsing.py
45
parsing.py
@@ -431,6 +431,14 @@ class Flow(Scope):
|
|||||||
next.parent = self.parent
|
next.parent = self.parent
|
||||||
return next
|
return next
|
||||||
|
|
||||||
|
class ForFlow(Flow):
|
||||||
|
"""
|
||||||
|
Used for the for loop, because there are two statement parts.
|
||||||
|
"""
|
||||||
|
def __init__(self, command, inits, indent, line_nr, set_stmt):
|
||||||
|
super(ForFlow, self).__init__(command, inits, indent, line_nr,
|
||||||
|
set_stmt.used_vars)
|
||||||
|
self.set_stmt = set_stmt
|
||||||
|
|
||||||
class Import(Simple):
|
class Import(Simple):
|
||||||
"""
|
"""
|
||||||
@@ -942,35 +950,6 @@ class PyFuzzyParser(object):
|
|||||||
names.append(tok)
|
names.append(tok)
|
||||||
return (names, token_type, tok, start_indent, start_line)
|
return (names, token_type, tok, start_indent, start_line)
|
||||||
|
|
||||||
def _parse_value_list(self, pre_used_token=None):
|
|
||||||
"""
|
|
||||||
A value list is a comma separated list. This is used for:
|
|
||||||
>>> for a,b,self.c in enumerate(test)
|
|
||||||
|
|
||||||
TODO there may be multiple "sub" value lists e.g. (a,(b,c)).
|
|
||||||
"""
|
|
||||||
value_list = []
|
|
||||||
if pre_used_token:
|
|
||||||
token_type, tok, indent = pre_used_token
|
|
||||||
n, token_type, tok, start_indent, start_line = \
|
|
||||||
self._parsedotname(tok)
|
|
||||||
if n:
|
|
||||||
temp = Name(n, start_indent, start_line, self.line_nr)
|
|
||||||
value_list.append()
|
|
||||||
|
|
||||||
token_type, tok, indent = self.next()
|
|
||||||
while tok != 'in' and token_type != tokenize.NEWLINE:
|
|
||||||
n, token_type, tok, start_indent, start_line = \
|
|
||||||
self._parsedotname(self.current)
|
|
||||||
if n:
|
|
||||||
temp = Name(n, start_indent, start_line, self.line_nr)
|
|
||||||
value_list.append(temp)
|
|
||||||
if tok == 'in':
|
|
||||||
break
|
|
||||||
|
|
||||||
token_type, tok, indent = self.next()
|
|
||||||
return (value_list, tok)
|
|
||||||
|
|
||||||
def _parseimportlist(self):
|
def _parseimportlist(self):
|
||||||
"""
|
"""
|
||||||
The parser for the imports. Unlike the class and function parse
|
The parser for the imports. Unlike the class and function parse
|
||||||
@@ -1329,12 +1308,12 @@ class PyFuzzyParser(object):
|
|||||||
self.freshscope = False
|
self.freshscope = False
|
||||||
#loops
|
#loops
|
||||||
elif tok == 'for':
|
elif tok == 'for':
|
||||||
value_list, tok = self._parse_value_list()
|
set_stmt, tok = self._parse_statement(added_breaks=['in'])
|
||||||
if tok == 'in':
|
if tok == 'in':
|
||||||
statement, tok = self._parse_statement()
|
statement, tok = self._parse_statement()
|
||||||
if tok == ':':
|
if tok == ':':
|
||||||
f = Flow('for', [statement], indent,
|
f = ForFlow('for', [statement], indent,
|
||||||
self.line_nr, value_list)
|
self.line_nr, set_stmt)
|
||||||
debug.dbg("new scope: flow for@%s" % (f.line_nr))
|
debug.dbg("new scope: flow for@%s" % (f.line_nr))
|
||||||
self.scope = self.scope.add_statement(f)
|
self.scope = self.scope.add_statement(f)
|
||||||
|
|
||||||
@@ -1352,7 +1331,7 @@ class PyFuzzyParser(object):
|
|||||||
if command == 'except' and tok in added_breaks:
|
if command == 'except' and tok in added_breaks:
|
||||||
# the except statement defines a var
|
# the except statement defines a var
|
||||||
# this is only true for python 2
|
# this is only true for python 2
|
||||||
path, token_type, tok, start_indent, start_line2 = \
|
path, token_type, tok, start_indent, start_line2 =\
|
||||||
self._parsedotname()
|
self._parsedotname()
|
||||||
n = Name(path, start_indent, start_line2,
|
n = Name(path, start_indent, start_line2,
|
||||||
self.line_nr)
|
self.line_nr)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ for a1 in 1,"":
|
|||||||
#? ['upper']
|
#? ['upper']
|
||||||
a1.upper
|
a1.upper
|
||||||
|
|
||||||
for a3, b3 in (1,""), (1,""):
|
for a3, b3 in (1,""), (1,""), (1,""):
|
||||||
#? ['real']
|
#? ['real']
|
||||||
a3.real
|
a3.real
|
||||||
#? []
|
#? []
|
||||||
|
|||||||
Reference in New Issue
Block a user