⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 id.py

📁 编译工具
💻 PY
字号:
# -*- python -*-#                           Package   : omniidl# id.py                     Created on: 2000/4/6#			    Author    : David Scott (djs)##    Copyright (C) 1999 AT&T Laboratories Cambridge##  This file is part of omniidl.##  omniidl is free software; you can redistribute it and/or modify it#  under the terms of the GNU General Public License as published by#  the Free Software Foundation; either version 2 of the License, or#  (at your option) any later version.##  This program is distributed in the hope that it will be useful,#  but WITHOUT ANY WARRANTY; without even the implied warranty of#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU#  General Public License for more details.##  You should have received a copy of the GNU General Public License#  along with this program; if not, write to the Free Software#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA#  02111-1307, USA.## Description:#   #   Environment handling, identifier scoping, namingfrom omniidl import idlvisitor, idlutilimport id, config, utilimport string, re# CORBA2.3 P1-166 1.43 C++ Keywords#reservedWords = [    "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break",    "case", "catch", "char", "class", "compl", "const", "const_cast",    "continue", "default", "delete", "do", "double", "dynamic_cast",    "else", "enum", "explicit", "export", "extern", "false", "float",    "for", "friend", "goto", "if", "inline", "int", "long", "mutable",    "namespace", "new", "not", "not_eq", "operator", "or", "or_eq",    "private", "protected", "public", "register", "reinterpret_cast",    "return", "short", "signed", "sizeof", "static", "static_cast",    "struct", "switch", "template", "this", "throw", "true", "try",    "typedef", "typeid", "typename", "union", "unsigned", "using",    "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq" ]rwdict = {}for w in reservedWords:    rwdict[w] = Nonedef mapID(identifier):    """id.mapID(identifier string): string       Returns the identifier with an escape if it is a C++ keyword"""    if rwdict.has_key(identifier):        return config.state['Reserved Prefix'] + identifier    return identifierclass Name:    """Encapsulates an IDL identifier and facilitates its mapping into       C++"""    def __init__(self, scopedName):        """Create a Name object from a fully scoped IDL name"""        # stores the IDL name with prefix and suffix separately        self.__scopedName = scopedName        self.__prefix = ""        self.__suffix = ""    def __cmp__(self, other):        if not isinstance(other, Name): return 1        return self.fullyQualify() == other.fullyQualify()    def simple(self, cxx = 1):        """simple(id.Name, cxx boolean): string           Returns the 'simple' part of the name with the scope removed"""        sn = self.__scopedName        if cxx: sn = self.__map_cxx()        sn = self.__apply_presuffix(sn)        sname = sn[-1]                return sname    def scope(self):        """scope(id.Name): string list           Returns the scope of the name"""        return self.__scopedName[:-1]    def __apply_presuffix(self, scopedName):        # internal function to apply the prefix and suffix to the IDL name        scope = scopedName[:-1]        name = scopedName[-1]        return scope + [ self.__prefix + name + self.__suffix ]    def prefix(self, prefix):        """prefix(id.Name): id.Name           Add a prefix to the name               ie ::A::B::C -> ::A::B::_objref_C"""        new = Name(self.__scopedName)        new.__prefix = prefix + self.__prefix        new.__suffix = self.__suffix        return new    def suffix(self, suffix):        """suffix(id.Name): id.Name           Add a suffix to the name               ie ::A::B::C -> ::A::B::C_ptr"""        new = Name(self.__scopedName)        new.__prefix = self.__prefix        new.__suffix = self.__suffix + suffix        return new    def __map_cxx(self):        # __map_cxx(id.Name): string list        # Maps an IDL name into a cxx one with proper escaping        return map(mapID, self.__scopedName)        def fullyQualify(self, cxx = 1):        """fullyQualify(id.Name, cxx boolean, include_root boolean): string           Returns a fully qualified C++ name (initial root :: optional)"""        if cxx: sn = self.__map_cxx()        else:   sn = self.__scopedName        sn = self.__apply_presuffix(sn)        return string.join(sn, "::")    def fullName(self):        """fullName(id.Name): string list           Returns the fully scopedname (with prefixes and suffixes as           appropriate) as a string component list"""        return self.__apply_presuffix(self.__scopedName)    def relName(self, environment):        """relName(id.Name, id.Environment): string list           Returns a list of the name components essential to making           the name unambiguous"""        rscope = idlutil.relativeScope(environment._Environment__scope,                                       self.__scopedName)        if rscope and rscope[0] is None:            return None        else:            return rscope    def unambiguous(self, environment, cxx = 1):        """unambiguous(id.Name, id.Environment option, cxx boolean): string           Returns the unambiguous C++ name for a particular environment"""        if environment == None:            return self.fullyQualify(cxx)                relName = self.relName(environment)        if relName == None:            # must fully qualify from the root            return "::" + self.fullyQualify(cxx = cxx)        if cxx: relName = map(mapID, relName)        relName = self.__apply_presuffix(relName)        return string.join(relName, "::")    def guard(self):        """guard(id.Name): string           Produces a flattened guard string suitable for an #ifdef"""        def escapeChars(text):            # escape all escapes            text = re.sub(r"_", "__", text)            return re.sub(r"\W", "_", text)        scopedName = map(escapeChars, self.__scopedName[:])        return string.join(self.__apply_presuffix(scopedName), "_m")    # comment copied from src/tool/omniidl2/omniORB2_be/o2be_interface.cc:    # MSVC {4.2,5.0} cannot deal with a call to a virtual member    # of a base class using the member function's fully/partially    # scoped name. Have to use the alias for the base class in the    # global scope to refer to the virtual member function instead.    #    # We scan all the base interfaces to see if any of them has to    # be referred to by their fully/partially qualified names. If    # that is necessary, we generate a typedef to define an alias for    # this base interface. This alias is used in the stub generated below    #    # FIXME: is this a solution to the OMNI_BASE_CTOR stuff below?    #    def flatName(self):        return string.join(self.fullName(), "_")        def needFlatName(self, environment):        # does the name have scope :: qualifiers        relName = self.relName(environment)        #if not relName: return 0                    return len(relName) > 1    def hash(self):        """hash(id.Name): string           Returns a hashable unique key for this object"""        return string.join(self.__scopedName, "/")    def __str__(self):        return string.join(self.__scopedName, "/")class Environment:    """An environment encapsulates the naming environment at a point       in the AST. The environment consists of both a scope and a set       of already defined names."""    def __init__(self):        self.__scope = []        self.__names = {}    def copy(self):        """copy(id.Environment): id.Environment           Copy constructor"""        new = Environment()        new.__scope = self.__scope[:]        new.__names = self.__names.copy()        return new    def enter(self, scope_name, interface = None):        """enter(id.Environment, scope_name string, interface option)           Creates and returns a new environment for the new scope"""        new = Environment()        new.__scope = self.__scope + [ scope_name ]        new.__names = self.__names.copy()        # if the scope is an interface, special scoping rules apply        # (because of interface inheritance)        if interface:            assert isinstance(interface, idlast.Interface)            new.__interface = interface                    return new    def leave(self):        """leave(id.Environment): id.Environment           Returns an environment representing the outer scope. Defined           names are kept"""        new = Environment()        new.__scope = self.__scope[:-1]        new.__names = self.__names.copy()        return new    def addName(self, scopedName, allow_already_exists = 0):        """addName(id.Environment, scopedName, allow_already_exists boolean)           Adds a new scopedName to the current environment. Will throw           a fatal exception if it already exists (unless the           allow_already_exists flag is set to 1"""        name = Name(scopedName)        hash = name.hash()        if self.__names.has_key(hash) and not allow_already_exists:            util.fatalError("Attempt to redefine existing name: " + str(name))        self.__names[hash] = name    def lookup(self, relName):        """lookup(id.Environment, relName): id.Name option           Searches for a relative scoped name in the same manner as C++,           returning the Name object it refers to, or None if there is           nothing to find"""        scope = self.__scope[:]        while 1:            name = Name(scope + relName)            if self.__names.has_key(name.hash()):                return self.__names[name.hash()]            if scope == []:                return None            del scope[-1]    def scope(self):        """scope(id.Environment): scope string list           Returns the current scope"""        return self.__scope    def __str__(self):        text = "Environment {\n"        text = text + "\tscope = " + repr(self.__scope) + "\n"        text = text + "\tnames = "        names = []        for hashkey in self.__names.keys():            names.append(str(self.__names[hashkey]))        text = text + repr(names) + "\n"        text = text + "}"        return text# Hash of AST nodes -> environments# (facilitates multiple passes of the AST, by precaching naming info)id._environments = None# List of predefined namesid._predefined_names =  [ ["CORBA", "Object"] ]def predefine_decl(decl):    id._predefined_names.append(decl.scopedName())# Could annotate the tree instead?def lookup(node):    """lookup : AST node -> Environment"""    try:        return id._environments[node]    except KeyError:        util.fatalError("Failed to find environment corresponding to node" +\                        " (= " + repr(node.scopedName()) + ")")class WalkTree(idlvisitor.AstVisitor):    """Walks over the AST once building the hash of       AST nodes -> Environments"""    def __enter(self, name):        self.__env = self.__env.enter(name)    def __leave(self):        self.__env = self.__env.leave()    def __add(self, name, allow_already_exists = 0):        new = self.__env.copy()        scopedName = self.__env.scope() + [ name ]        new.addName(scopedName, allow_already_exists)        self.__env = new        return    def __cache(self, node):        if id._environments.has_key(node):            util.fatalError("Unexpected inconsistency: encountered node " +\                             "more than once while walking the tree")        id._environments[node] = self.__env                def __init__(self):        id._environments = {}        # Names which are predefined        self.__env = Environment()        for name in id._predefined_names:            self.__env.addName(name)            # Tree walking functions    def visitAST(self, node):        for n in node.declarations():            n.accept(self)        self.__cache(node)    def visitDeclRepoId(self, node):        name = node.identifier()        self.__add(name)        self.__cache(node)                def visitModule(self, node):        name = node.identifier()        # already exists => reopening module        self.__add(name, allow_already_exists = 1)                self.__enter(name)        for n in node.definitions():            n.accept(self)        self.__leave()        self.__cache(node)                    def visitInterface(self, node):        name = node.identifier()        self.__add(name, allow_already_exists = 1)                self.__enter(name)        for n in node.declarations():            n.accept(self)        self.__leave()        self.__cache(node)            def visitForward(self, node):        name = node.identifier()        self.__add(name, allow_already_exists = 1)        self.__cache(node)            def visitConst(self, node):        name = Name(node.scopedName()).simple()        self.__add(name)        self.__cache(node)            def visitDeclarator(self, node):        name = Name(node.scopedName()).simple()        self.__add(name)        self.__cache(node)            def visitTypedef(self, node):        if node.constrType():            node.aliasType().decl().accept(self)        for d in node.declarators():            d.accept(self)        self.__cache(node)                    def visitMember(self, node):        if node.constrType():            node.memberType().decl().accept(self)                    for d in node.declarators():            d.accept(self)        self.__cache(node)            def visitStruct(self, node):        name = node.identifier()        self.__add(name)        self.__enter(name)        for n in node.members():            n.accept(self)        self.__leave()        self.__cache(node)            def visitException(self, node):        name = node.identifier()        self.__add(name)        self.__enter(name)        for n in node.members():            n.accept(self)        self.__leave()        self.__cache(node)            def visitUnion(self, node):        name = node.identifier()        self.__add(name)        self.__enter(name)        # deal with constructed switch type        if node.constrType():            node.switchType().decl().accept(self)        # deal with constructed member types        for n in node.cases():            if n.constrType():                n.caseType().decl().accept(self)        self.__leave()        self.__cache(node)    def visitCaseLabel(self, node):        pass    def visitUnionCase(self, node):        pass    def visitEnumerator(self, node):        pass    def visitEnum(self, node):        name = node.identifier()        self.__add(name)        for value in node.enumerators():            self.__add(value.identifier())                self.__cache(node)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -