forked from VimPlug/jedi
basic lambda implementation
This commit is contained in:
@@ -333,12 +333,12 @@ class Parser(object):
|
|||||||
# will even break in parentheses. This is true for typical flow
|
# will even break in parentheses. This is true for typical flow
|
||||||
# commands like def and class and the imports, which will never be used
|
# commands like def and class and the imports, which will never be used
|
||||||
# in a statement.
|
# in a statement.
|
||||||
breaks = ['\n', ':', ')']
|
breaks = set(['\n', ':', ')'])
|
||||||
always_break = [';', 'import', 'from', 'class', 'def', 'try', 'except',
|
always_break = [';', 'import', 'from', 'class', 'def', 'try', 'except',
|
||||||
'finally', 'while', 'return', 'yield']
|
'finally', 'while', 'return', 'yield']
|
||||||
not_first_break = ['del', 'raise']
|
not_first_break = ['del', 'raise']
|
||||||
if added_breaks:
|
if added_breaks:
|
||||||
breaks += added_breaks
|
breaks |= set(added_breaks)
|
||||||
|
|
||||||
tok_list = []
|
tok_list = []
|
||||||
while not (tok in always_break
|
while not (tok in always_break
|
||||||
@@ -356,7 +356,9 @@ class Parser(object):
|
|||||||
tok_list.append(n)
|
tok_list.append(n)
|
||||||
continue
|
continue
|
||||||
elif tok in ['lambda', 'for', 'in']:
|
elif tok in ['lambda', 'for', 'in']:
|
||||||
pass # don't parse these keywords, parse later in stmt.
|
# don't parse these keywords, parse later in stmt.
|
||||||
|
if tok == 'lambda':
|
||||||
|
breaks.remove(':')
|
||||||
elif token_type == tokenize.NAME:
|
elif token_type == tokenize.NAME:
|
||||||
n, token_type, tok = self._parse_dot_name(self.current)
|
n, token_type, tok = self._parse_dot_name(self.current)
|
||||||
# removed last entry, because we add Name
|
# removed last entry, because we add Name
|
||||||
|
|||||||
@@ -421,8 +421,9 @@ class Function(Scope):
|
|||||||
|
|
||||||
|
|
||||||
class Lambda(Function):
|
class Lambda(Function):
|
||||||
def __init__(self, module, params, start_pos):
|
def __init__(self, module, params, start_pos, parent):
|
||||||
super(Lambda, self).__init__(module, None, params, start_pos, None)
|
super(Lambda, self).__init__(module, None, params, start_pos, None)
|
||||||
|
self.parent = parent
|
||||||
|
|
||||||
def get_code(self, first_indent=False, indention=' '):
|
def get_code(self, first_indent=False, indention=' '):
|
||||||
params = ','.join([stmt.get_code() for stmt in self.params])
|
params = ','.join([stmt.get_code() for stmt in self.params])
|
||||||
@@ -852,7 +853,7 @@ class Statement(Simple):
|
|||||||
if not token_list:
|
if not token_list:
|
||||||
return None, tok
|
return None, tok
|
||||||
|
|
||||||
statement = Statement(self._sub_module, [], [], token_list,
|
statement = stmt_class(self._sub_module, [], [], token_list,
|
||||||
start_pos, end_pos, self.parent)
|
start_pos, end_pos, self.parent)
|
||||||
statement.used_vars = used_vars
|
statement.used_vars = used_vars
|
||||||
return statement, tok
|
return statement, tok
|
||||||
@@ -860,26 +861,28 @@ class Statement(Simple):
|
|||||||
def parse_lambda(token_iterator):
|
def parse_lambda(token_iterator):
|
||||||
params = []
|
params = []
|
||||||
start_pos = self.start_pos
|
start_pos = self.start_pos
|
||||||
tok = next(token_iterator)
|
while True:
|
||||||
while tok != ':':
|
param, tok = parse_stmt(token_iterator, added_breaks=[':'],
|
||||||
param, tok = parse_stmt(token_iterator,
|
stmt_class=Param)
|
||||||
added_breaks=[':', ','], stmt_class=Param)
|
|
||||||
if param is None:
|
if param is None:
|
||||||
break
|
break
|
||||||
params.append(param)
|
params.append(param)
|
||||||
|
if tok == ':':
|
||||||
|
break
|
||||||
if tok != ':':
|
if tok != ':':
|
||||||
return None, tok
|
return None
|
||||||
|
|
||||||
lambd = Lambda(self.module, params, start_pos)
|
# since lambda is a Function scope, it needs Scope parents
|
||||||
ret, tok = self._parse_statement(added_breaks=[','])
|
parent = self.get_parent_until(IsScope)
|
||||||
|
lambd = Lambda(self._sub_module, params, start_pos, parent)
|
||||||
|
|
||||||
|
ret, tok = parse_stmt(token_iterator)
|
||||||
if ret is not None:
|
if ret is not None:
|
||||||
ret.parent = lambd
|
ret.parent = lambd
|
||||||
lambd.returns.append(ret)
|
lambd.returns.append(ret)
|
||||||
lambd.parent = self.scope
|
|
||||||
lambd.end_pos = self.end_pos
|
lambd.end_pos = self.end_pos
|
||||||
return lambd
|
return lambd
|
||||||
|
|
||||||
|
|
||||||
def parse_list_comp(token_iterator, token_list, start_pos, end_pos):
|
def parse_list_comp(token_iterator, token_list, start_pos, end_pos):
|
||||||
def parse_stmt_or_arr(token_iterator, added_breaks=()):
|
def parse_stmt_or_arr(token_iterator, added_breaks=()):
|
||||||
stmt, tok = parse_stmt(token_iterator, added_breaks=added_breaks)
|
stmt, tok = parse_stmt(token_iterator, added_breaks=added_breaks)
|
||||||
@@ -980,7 +983,11 @@ class Statement(Simple):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
is_literal = token_type in [tokenize.STRING, tokenize.NUMBER]
|
is_literal = token_type in [tokenize.STRING, tokenize.NUMBER]
|
||||||
if isinstance(tok, Name) or is_literal:
|
if tok == 'lambda':
|
||||||
|
lambd = parse_lambda(token_iterator)
|
||||||
|
if lambd is not None:
|
||||||
|
result.append(lambd)
|
||||||
|
elif isinstance(tok, Name) or is_literal:
|
||||||
c_type = Call.NAME
|
c_type = Call.NAME
|
||||||
if is_literal:
|
if is_literal:
|
||||||
tok = literal_eval(tok)
|
tok = literal_eval(tok)
|
||||||
@@ -1032,9 +1039,9 @@ class Param(Statement):
|
|||||||
'parent_function')
|
'parent_function')
|
||||||
|
|
||||||
def __init__(self, module, set_vars, used_vars, token_list,
|
def __init__(self, module, set_vars, used_vars, token_list,
|
||||||
start_pos, end_pos):
|
start_pos, end_pos, parent=None):
|
||||||
super(Param, self).__init__(module, set_vars, used_vars, token_list,
|
super(Param, self).__init__(module, set_vars, used_vars, token_list,
|
||||||
start_pos, end_pos)
|
start_pos, end_pos, parent)
|
||||||
|
|
||||||
# this is defined by the parser later on, not at the initialization
|
# this is defined by the parser later on, not at the initialization
|
||||||
# it is the position in the call (first argument, second...)
|
# it is the position in the call (first argument, second...)
|
||||||
|
|||||||
Reference in New Issue
Block a user