forked from VimPlug/jedi
basic concept for get_assignment_calls
This commit is contained in:
@@ -743,11 +743,17 @@ class Statement(Simple):
|
|||||||
This is not really nice written, sorry for that. If you plan to replace
|
This is not really nice written, sorry for that. If you plan to replace
|
||||||
it and make it nicer, that would be cool :-)
|
it and make it nicer, that would be cool :-)
|
||||||
"""
|
"""
|
||||||
|
if self._assignment_calls_calculated:
|
||||||
|
return self._assignment_calls
|
||||||
|
|
||||||
brackets = {'(': Array.TUPLE, '[': Array.LIST, '{': Array.SET}
|
brackets = {'(': Array.TUPLE, '[': Array.LIST, '{': Array.SET}
|
||||||
closing_brackets = [')', '}', ']']
|
closing_brackets = [')', '}', ']']
|
||||||
|
|
||||||
def parse_array(token_iterator, array_type, start_pos):
|
def parse_array(token_iterator, array_type, start_pos, add_el=None):
|
||||||
arr = Array(start_pos, array_type)
|
arr = Array(start_pos, array_type)
|
||||||
|
if add_el is not None:
|
||||||
|
arr.add_statement(add_el)
|
||||||
|
|
||||||
maybe_dict = array_type == Array.SET
|
maybe_dict = array_type == Array.SET
|
||||||
while True:
|
while True:
|
||||||
statement, break_tok = parse_statement(token_iterator,
|
statement, break_tok = parse_statement(token_iterator,
|
||||||
@@ -755,6 +761,10 @@ class Statement(Simple):
|
|||||||
if statement is not None:
|
if statement is not None:
|
||||||
is_key = maybe_dict and break_tok == ':'
|
is_key = maybe_dict and break_tok == ':'
|
||||||
arr.add_statement(statement, is_key)
|
arr.add_statement(statement, is_key)
|
||||||
|
if not arr.values and maybe_dict:
|
||||||
|
# this is a really special case - empty brackets {} are
|
||||||
|
# always dictionaries and not sets.
|
||||||
|
arr.type = Array.DICT
|
||||||
return arr
|
return arr
|
||||||
|
|
||||||
def parse_statement(token_iterator, start_pos, maybe_dict=False):
|
def parse_statement(token_iterator, start_pos, maybe_dict=False):
|
||||||
@@ -764,6 +774,7 @@ class Statement(Simple):
|
|||||||
for i, tok_temp in token_iterator:
|
for i, tok_temp in token_iterator:
|
||||||
try:
|
try:
|
||||||
token_type, tok, start_tok_pos = tok_temp
|
token_type, tok, start_tok_pos = tok_temp
|
||||||
|
end_pos = start_pos[0], start_pos[1] + len(tok)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# the token is a Name, which has already been parsed
|
# the token is a Name, which has already been parsed
|
||||||
tok = tok_temp
|
tok = tok_temp
|
||||||
@@ -786,15 +797,12 @@ class Statement(Simple):
|
|||||||
statement.parent = self.parent
|
statement.parent = self.parent
|
||||||
return statement
|
return statement
|
||||||
|
|
||||||
if self._assignment_calls_calculated:
|
|
||||||
return self._assignment_calls
|
|
||||||
self._assignment_details = []
|
self._assignment_details = []
|
||||||
top = result = Array(self.start_pos, Array.NOARRAY, self)
|
result = []
|
||||||
level = 0
|
|
||||||
is_chain = False
|
is_chain = False
|
||||||
close_brackets = False
|
close_brackets = False
|
||||||
|
|
||||||
is_call = lambda: type(result) == Call
|
is_call = lambda: result and type(result[-1]) == Call
|
||||||
is_call_or_close = lambda: is_call() or close_brackets
|
is_call_or_close = lambda: is_call() or close_brackets
|
||||||
|
|
||||||
token_iterator = enumerate(self.token_list)
|
token_iterator = enumerate(self.token_list)
|
||||||
@@ -810,41 +818,22 @@ class Statement(Simple):
|
|||||||
tok = tok_temp
|
tok = tok_temp
|
||||||
token_type = None
|
token_type = None
|
||||||
start_pos = tok.start_pos
|
start_pos = tok.start_pos
|
||||||
except ValueError:
|
|
||||||
debug.warning("unkown value, shouldn't happen",
|
|
||||||
tok_temp, type(tok_temp))
|
|
||||||
raise
|
|
||||||
else:
|
else:
|
||||||
if level == 0 and tok.endswith('=') \
|
if tok.endswith('=') and not tok in ['>=', '<=', '==', '!=']:
|
||||||
and not tok in ['>=', '<=', '==', '!=']:
|
|
||||||
# This means, there is an assignment here.
|
# This means, there is an assignment here.
|
||||||
|
|
||||||
# Add assignments, which can be more than one
|
# Add assignments, which can be more than one
|
||||||
self._assignment_details.append((tok, top))
|
self._assignment_details.append((tok, result))
|
||||||
# All these calls wouldn't be important if nonlocal would
|
# nonlocal plz!
|
||||||
# exist. -> Initialize the first items again.
|
result = []
|
||||||
end_pos = start_pos[0], start_pos[1] + len(tok)
|
|
||||||
top = result = Array(end_pos, Array.NOARRAY, self)
|
|
||||||
level = 0
|
|
||||||
close_brackets = False
|
close_brackets = False
|
||||||
is_chain = False
|
is_chain = False
|
||||||
continue
|
continue
|
||||||
elif tok == 'as':
|
elif tok == 'as': # just ignore as
|
||||||
next(token_iterator, None)
|
next(token_iterator, None)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if level >= 0:
|
|
||||||
if tok in brackets.keys(): # brackets
|
|
||||||
level += 1
|
|
||||||
elif tok in closing_brackets:
|
|
||||||
level -= 1
|
|
||||||
if level == 0:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# here starts the statement creation madness!
|
|
||||||
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 isinstance(tok, Name) or is_literal:
|
||||||
_tok = tok
|
|
||||||
c_type = Call.NAME
|
c_type = Call.NAME
|
||||||
if is_literal:
|
if is_literal:
|
||||||
tok = literal_eval(tok)
|
tok = literal_eval(tok)
|
||||||
@@ -853,87 +842,38 @@ class Statement(Simple):
|
|||||||
elif token_type == tokenize.NUMBER:
|
elif token_type == tokenize.NUMBER:
|
||||||
c_type = Call.NUMBER
|
c_type = Call.NUMBER
|
||||||
|
|
||||||
|
call = Call(tok, c_type, start_pos, parent=result)
|
||||||
if is_chain:
|
if is_chain:
|
||||||
call = Call(tok, c_type, start_pos, parent=result)
|
result[-1].set_next(call)
|
||||||
result = result.set_next_chain_call(call)
|
|
||||||
is_chain = False
|
is_chain = False
|
||||||
close_brackets = False
|
close_brackets = False
|
||||||
else:
|
else:
|
||||||
if close_brackets:
|
result.append(call)
|
||||||
result = result.parent
|
elif tok in brackets.keys():
|
||||||
close_brackets = False
|
arr = parse_array(token_iterator, brackets[tok], start_pos)
|
||||||
if type(result) == Call:
|
|
||||||
result = result.parent
|
|
||||||
call = Call(tok, c_type, start_pos, parent=result)
|
|
||||||
result.add_to_current_field(call)
|
|
||||||
result = call
|
|
||||||
tok = _tok
|
|
||||||
elif tok in brackets.keys(): # brackets
|
|
||||||
level += 1
|
|
||||||
if is_call_or_close():
|
if is_call_or_close():
|
||||||
result = Array(start_pos, brackets[tok], parent=result)
|
result[-1].add_execution(arr)
|
||||||
result = result.parent.add_execution(result)
|
|
||||||
close_brackets = False
|
|
||||||
else:
|
else:
|
||||||
result = Array(start_pos, brackets[tok], parent=result)
|
result.append(arr)
|
||||||
result.parent.add_to_current_field(result)
|
|
||||||
elif tok == ':':
|
|
||||||
while is_call_or_close():
|
|
||||||
result = result.parent
|
|
||||||
close_brackets = False
|
|
||||||
if result.type == Array.LIST: # [:] lookups
|
|
||||||
result.add_to_current_field(tok)
|
|
||||||
else:
|
|
||||||
result.add_dictionary_key()
|
|
||||||
elif tok == '.':
|
|
||||||
if close_brackets and result.parent != top:
|
|
||||||
# only get out of the array, if it is a array execution
|
|
||||||
result = result.parent
|
|
||||||
close_brackets = False
|
|
||||||
is_chain = True
|
|
||||||
elif tok == ',':
|
|
||||||
while is_call_or_close():
|
|
||||||
result = result.parent
|
|
||||||
close_brackets = False
|
|
||||||
result.add_field((start_pos[0], start_pos[1] + 1))
|
|
||||||
# important - it cannot be empty anymore
|
|
||||||
if result.type == Array.NOARRAY:
|
|
||||||
result.type = Array.TUPLE
|
|
||||||
elif tok in closing_brackets:
|
|
||||||
while is_call_or_close():
|
|
||||||
result = result.parent
|
|
||||||
close_brackets = False
|
|
||||||
if tok == '}' and not len(result):
|
|
||||||
# this is a really special case - empty brackets {} are
|
|
||||||
# always dictionaries and not sets.
|
|
||||||
result.type = Array.DICT
|
|
||||||
level -= 1
|
|
||||||
result.end_pos = start_pos[0], start_pos[1] + 1
|
|
||||||
close_brackets = True
|
close_brackets = True
|
||||||
|
elif tok == '.':
|
||||||
|
if result and isinstance(result[-1], Call):
|
||||||
|
is_chain = True
|
||||||
|
elif tok == ',': # implies a tuple
|
||||||
|
# rewrite `result`, because now the whole thing is a tuple
|
||||||
|
add_el = parse_statement(iter(result), start_pos)
|
||||||
|
arr = parse_array(token_iterator, Array.TUPLE, start_pos,
|
||||||
|
add_el)
|
||||||
|
result = [arr]
|
||||||
else:
|
else:
|
||||||
while is_call_or_close():
|
close_brackets = False
|
||||||
result = result.parent
|
|
||||||
close_brackets = False
|
|
||||||
if tok != '\n':
|
if tok != '\n':
|
||||||
result.add_to_current_field(tok)
|
result.append(tok)
|
||||||
|
|
||||||
if level != 0:
|
|
||||||
debug.warning("Brackets don't match: %s."
|
|
||||||
"This is not normal behaviour." % level)
|
|
||||||
|
|
||||||
if self.token_list:
|
|
||||||
while result is not None:
|
|
||||||
try:
|
|
||||||
result.end_pos = start_pos[0], start_pos[1] + len(tok)
|
|
||||||
except TypeError:
|
|
||||||
result.end_pos = tok.end_pos
|
|
||||||
result = result.parent
|
|
||||||
else:
|
|
||||||
result.end_pos = self.end_pos
|
|
||||||
|
|
||||||
|
# TODO check
|
||||||
self._assignment_calls_calculated = True
|
self._assignment_calls_calculated = True
|
||||||
self._assignment_calls = top
|
self._assignment_calls = result
|
||||||
return top
|
return result
|
||||||
|
|
||||||
|
|
||||||
class Param(Statement):
|
class Param(Statement):
|
||||||
@@ -1011,7 +951,7 @@ class Call(Base):
|
|||||||
def parent_stmt(self, value):
|
def parent_stmt(self, value):
|
||||||
self._parent_stmt = value
|
self._parent_stmt = value
|
||||||
|
|
||||||
def set_next_chain_call(self, call):
|
def set_next(self, call):
|
||||||
""" Adds another part of the statement"""
|
""" Adds another part of the statement"""
|
||||||
self.next = call
|
self.next = call
|
||||||
call.parent = self.parent
|
call.parent = self.parent
|
||||||
|
|||||||
Reference in New Issue
Block a user