コード例 #1
0
ファイル: base.py プロジェクト: vitsalis/PyCG
    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
コード例 #2
0
    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()
コード例 #3
0
    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()