def retrieve_subscript_names(self, node): if not isinstance(node, ast.Subscript): raise Exception("The node is not an subcript") if not getattr(self, "closured", None): return set() if getattr(node.slice, "value", None) and self._is_literal(node.slice.value): sl_names = [node.slice.value] else: sl_names = self.decode_node(node.slice) val_names = self.decode_node(node.value) decoded_vals = set() keys = set() full_names = set() # get all names associated with this variable name for n in val_names: if n and isinstance(n, Definition) and self.closured.get(n.get_ns(), None): decoded_vals |= self.closured.get(n.get_ns()) for s in sl_names: if isinstance(s, Definition) and self.closured.get(s.get_ns(), None): # we care about the literals pointed by the name # not the namespaces, so retrieve the literals pointed for name in self.closured.get(s.get_ns()): defi = self.def_manager.get(name) if not defi: continue keys |= defi.get_lit_pointer().get() elif isinstance(s, str): keys.add(s) elif isinstance(s, int): keys.add(utils.get_int_name(s)) for d in decoded_vals: for key in keys: # check for existence of var name and key combination str_key = str(key) if isinstance(key, int): str_key = utils.get_int_name(key) full_ns = utils.join_ns(d, str_key) full_names.add(full_ns) return full_names
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_List(self, node): # Works similarly with dicts current_scope = self.scope_manager.get_scope(self.current_ns) list_counter = current_scope.inc_list_counter() list_name = utils.get_list_name(list_counter) list_full_ns = utils.join_ns(self.current_ns, list_name) # create a scope for the list list_scope = self.scope_manager.create_scope(list_full_ns, current_scope) # create a list definition list_def = self.def_manager.get(list_full_ns) if not list_def: list_def = self.def_manager.create(list_full_ns, utils.constants.NAME_DEF) current_scope.add_def(list_name, list_def) self.name_stack.append(list_name) for idx, elt in enumerate(node.elts): self.visit(elt) key_full_ns = utils.join_ns(list_def.get_ns(), utils.get_int_name(idx)) 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) decoded_elt = self.decode_node(elt) for v in decoded_elt: 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()