def visit_Dict(self, node): # 1. create a scope using a counter # 2. Iterate keys and add them as children of the scope # 3. Iterate values and makes a points to connection with the keys current_scope = self.scope_manager.get_scope(self.current_ns) dict_counter = current_scope.inc_dict_counter() dict_name = utils.get_dict_name(dict_counter) dict_full_ns = utils.join_ns(self.current_ns, dict_name) # create a scope for the dict dict_scope = self.scope_manager.create_scope(dict_full_ns, current_scope) # Create a dict definition dict_def = self.def_manager.get(dict_full_ns) if not dict_def: dict_def = self.def_manager.create(dict_full_ns, utils.constants.NAME_DEF) # add it to the current scope current_scope.add_def(dict_name, dict_def) self.name_stack.append(dict_name) for key, value in zip(node.keys, node.values): if key: self.visit(key) if value: self.visit(value) decoded_key = self.decode_node(key) decoded_value = self.decode_node(value) # iterate decoded keys and values # to do the assignment operation for k in decoded_key: if isinstance(k, Definition): # get literal pointer names = k.get_lit_pointer().get() else: names = set() if isinstance(k, list): continue names.add(k) for name in names: # create a definition for the key if isinstance(name, int): name = utils.get_int_name(name) key_full_ns = utils.join_ns(dict_def.get_ns(), str(name)) key_def = self.def_manager.get(key_full_ns) if not key_def: key_def = self.def_manager.create( key_full_ns, utils.constants.NAME_DEF) dict_scope.add_def(str(name), key_def) for v in decoded_value: if isinstance(v, Definition): key_def.get_name_pointer().add(v.get_ns()) else: key_def.get_lit_pointer().add(v) self.name_stack.pop()
def visit_Dict(self, node): counter = self.scope_manager.get_scope(self.current_ns).inc_dict_counter() dict_name = utils.get_dict_name(counter) sc = self.scope_manager.get_scope(utils.join_ns(self.current_ns, dict_name)) if not sc: return self.name_stack.append(dict_name) sc.reset_counters() for key, val in zip(node.keys, node.values): if key: self.visit(key) if val: self.visit(val) self.name_stack.pop()
def decode_node(self, node): if isinstance(node, ast.Name): return [self.scope_manager.get_def(self.current_ns, node.id)] elif isinstance(node, ast.Call): decoded = self.decode_node(node.func) return_defs = [] for called_def in decoded: if not isinstance(called_def, Definition): continue return_ns = utils.constants.INVALID_NAME if called_def.get_type() == utils.constants.FUN_DEF: return_ns = utils.join_ns(called_def.get_ns(), utils.constants.RETURN_NAME) elif called_def.get_type() == utils.constants.CLS_DEF: return_ns = called_def.get_ns() defi = self.def_manager.get(return_ns) if defi: return_defs.append(defi) return return_defs elif isinstance(node, ast.Lambda): lambda_counter = self.scope_manager.get_scope(self.current_ns).get_lambda_counter() lambda_name = utils.get_lambda_name(lambda_counter) return [self.scope_manager.get_def(self.current_ns, lambda_name)] elif isinstance(node, ast.Tuple): decoded = [] for elt in node.elts: decoded.append(self.decode_node(elt)) return decoded elif isinstance(node, ast.BinOp): decoded_left = self.decode_node(node.left) decoded_right = self.decode_node(node.right) # return the non definition types if we're talking about a binop # since we only care about the type of the return (num, str, etc) if not isinstance(decoded_left, Definition): return decoded_left if not isinstance(decoded_right, Definition): return decoded_right elif isinstance(node, ast.Attribute): names = self._retrieve_attribute_names(node) defis = [] for name in names: defi = self.def_manager.get(name) if defi: defis.append(defi) return defis elif isinstance(node, ast.Num): return [node.n] elif isinstance(node, ast.Str): return [node.s] elif self._is_literal(node): return [node] elif isinstance(node, ast.Dict): dict_counter = self.scope_manager.get_scope(self.current_ns).get_dict_counter() dict_name = utils.get_dict_name(dict_counter) scope_def = self.scope_manager.get_def(self.current_ns, dict_name) return [self.scope_manager.get_def(self.current_ns, dict_name)] elif isinstance(node, ast.List): list_counter = self.scope_manager.get_scope(self.current_ns).get_list_counter() list_name = utils.get_list_name(list_counter) scope_def = self.scope_manager.get_def(self.current_ns, list_name) return [self.scope_manager.get_def(self.current_ns, list_name)] elif isinstance(node, ast.Subscript): names = self.retrieve_subscript_names(node) defis = [] for name in names: defi = self.def_manager.get(name) if defi: defis.append(defi) return defis return []