def iterate(): # `var_args` is typically an Array, and not a list. for stmt in self.var_args: if not isinstance(stmt, pr.Statement): if stmt is None: yield None, None continue old = stmt # generate a statement if it's not already one. module = builtin.Builtin.scope stmt = pr.Statement(module, [], (0, 0), None) stmt._commands = [old] # *args commands = stmt.get_commands() if not len(commands): continue if commands[0] == '*': arrays = evaluate.follow_call_list(commands[1:]) # *args must be some sort of an array, otherwise -> ignore for array in arrays: if isinstance(array, Array): for field_stmt in array: # yield from plz! yield None, field_stmt elif isinstance(array, Generator): for field_stmt in array.iter_content(): yield None, helpers.FakeStatement(field_stmt) # **kwargs elif commands[0] == '**': arrays = evaluate.follow_call_list(commands[1:]) for array in arrays: if isinstance(array, Array): for key_stmt, value_stmt in array.items(): # first index, is the key if syntactically correct call = key_stmt.get_commands()[0] if isinstance(call, pr.Name): yield call, value_stmt elif isinstance(call, pr.Call): yield call.name, value_stmt # Normal arguments (including key arguments). else: if stmt.assignment_details: key_arr, op = stmt.assignment_details[0] # named parameter if key_arr and isinstance(key_arr[0], pr.Call): yield key_arr[0].name, stmt else: yield None, stmt
def iterate(): # `var_args` is typically an Array, and not a list. for stmt in self.var_args: if not isinstance(stmt, pr.Statement): if stmt is None: yield None, None continue old = stmt # generate a statement if it's not already one. module = builtin.Builtin.scope stmt = pr.Statement(module, [], [], [], (0, 0), None) stmt._commands = [old] # *args commands = stmt.get_commands() if not len(commands): continue if commands[0] == '*': arrays = evaluate.follow_call_list(commands[1:]) # *args must be some sort of an array, otherwise -> ignore for array in arrays: if isinstance(array, Array): for field_stmt in array: # yield from plz! yield None, field_stmt elif isinstance(array, Generator): for field_stmt in array.iter_content(): yield None, helpers.FakeStatement(field_stmt) # **kwargs elif commands[0] == '**': arrays = evaluate.follow_call_list(commands[1:]) for array in arrays: if isinstance(array, Array): for key_stmt, value_stmt in array.items(): # first index, is the key if syntactically correct call = key_stmt.get_commands()[0] if isinstance(call, pr.Name): yield call, value_stmt elif type(call) is pr.Call: yield call.name, value_stmt # Normal arguments (including key arguments). else: if stmt.assignment_details: key_arr, op = stmt.assignment_details[0] # named parameter if key_arr and isinstance(key_arr[0], pr.Call): yield key_arr[0].name, stmt else: yield None, stmt
def iter_content(self): """ The index is here just ignored, because of all the appends, etc. lists/sets are too complicated too handle that. """ items = [] for array in evaluate.follow_call_list(self.var_args): if isinstance(array, evaluate.Instance) and len(array.var_args): temp = array.var_args[0][0] if isinstance(temp, ArrayInstance): # prevent recursions # TODO compare Modules if self.var_args.start_pos != temp.var_args.start_pos: items += temp.iter_content() else: debug.warning('ArrayInstance recursion', self.var_args) continue items += evaluate.get_iterator_types([array]) if self.var_args.parent_stmt is None: return [] # generated var_args should not be checked for arrays module = self.var_args.parent_stmt.get_parent_until() is_list = str(self.instance.name) == 'list' items += _check_array_additions(self.instance, module, is_list) return items
def check_calls(calls, add_name): """ Calls are processed here. The part before the call is searched and compared with the original Array. """ result = [] for c in calls: call_path = list(c.generate_call_path()) separate_index = call_path.index(add_name) if add_name == call_path[-1] or separate_index == 0: # this means that there is no execution -> [].append # or the keyword is at the start -> append() continue backtrack_path = iter(call_path[:separate_index]) position = c.start_pos scope = c.parent_stmt.parent found = evaluate.follow_call_path(backtrack_path, scope, position) if not compare_array in found: continue params = call_path[separate_index + 1] if not params.values: continue # no params: just ignore it if add_name in ['append', 'add']: result += evaluate.follow_call_list(params) elif add_name in ['insert']: try: second_param = params[1] except IndexError: continue else: result += evaluate.follow_call_list([second_param]) elif add_name in ['extend', 'update']: iterators = evaluate.follow_call_list(params) result += evaluate.get_iterator_types(iterators) return result