Synopsis - Synopsis/Parsers/IDL/idltype.py

File: Synopsis/Parsers/IDL/idltype.py

      1# -*- python -*-
      2#                           Package   : omniidl
      3# idltype.py                Created on: 1999/10/27
      4#			    Author    : Duncan Grisby (dpg1)
      5#
      6#    Copyright (C) 1999 AT&T Laboratories Cambridge
      7#
      8#  This file is part of omniidl.
      9#
     10#  omniidl is free software; you can redistribute it and/or modify it
     11#  under the terms of the GNU General Public License as published by
     12#  the Free Software Foundation; either version 2 of the License, or
     13#  (at your option) any later version.
     14#
     15#  This program is distributed in the hope that it will be useful,
     16#  but WITHOUT ANY WARRANTY; without even the implied warranty of
     17#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     18#  General Public License for more details.
     19#
     20#  You should have received a copy of the GNU General Public License
     21#  along with this program; if not, write to the Free Software
     22#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
     23#  02111-1307, USA.
     24#
     25# Description:
     26#
     27#   IDL type representation
     28
     29"""Definitions for IDL type representation
     30
     31Classes:
     32
     33  Type     -- abstract base class.
     34  Base     -- class for CORBA base types.
     35  String   -- class for string types.
     36  WString  -- class for wide string types.
     37  Sequence -- class for sequence types.
     38  Fixed    -- class for fixed-point types.
     39  Declared -- class for declared types.
     40
     41TypeCode kind constants:
     42
     43  tk_null, tk_void, tk_short, tk_long, tk_ushort, tk_ulong, tk_float,
     44  tk_double, tk_boolean, tk_char, tk_octet, tk_any, tk_TypeCode,
     45  tk_Principal, tk_objref, tk_struct, tk_union, tk_enum, tk_string,
     46  tk_sequence, tk_array, tk_alias, tk_except, tk_longlong,
     47  tk_ulonglong, tk_longdouble, tk_wchar, tk_wstring, tk_fixed,
     48  tk_value, tk_value_box, tk_native, tk_abstract_interface"""
     49
     50import idlutil
     51
     52tk_null               = 0
     53tk_void               = 1
     54tk_short              = 2
     55tk_long               = 3
     56tk_ushort             = 4
     57tk_ulong              = 5
     58tk_float              = 6
     59tk_double             = 7
     60tk_boolean            = 8
     61tk_char               = 9
     62tk_octet              = 10
     63tk_any               = 11
     64tk_TypeCode           = 12
     65tk_Principal          = 13
     66tk_objref             = 14
     67tk_struct             = 15
     68tk_union              = 16
     69tk_enum               = 17
     70tk_string             = 18
     71tk_sequence           = 19
     72tk_array              = 20
     73tk_alias              = 21
     74tk_except             = 22
     75tk_longlong           = 23
     76tk_ulonglong          = 24
     77tk_longdouble         = 25
     78tk_wchar              = 26
     79tk_wstring            = 27
     80tk_fixed              = 28
     81tk_value              = 29
     82tk_value_box          = 30
     83tk_native             = 31
     84tk_abstract_interface = 32
     85tk_local_interface    = 33
     86
     87# Non-standard kinds for forward-declared structs and unions
     88ot_structforward      = 100
     89ot_unionforward       = 101
     90
     91
     92class Error:
     93    """Exception class used by IdlType internals."""
     94
     95    def __init__(self, err):
     96        self.err = err
     97
     98    def __repr__(self):
     99        return self.err
    100
    101
    102class Type:
    103    """Type abstract class.
    104
    105Function:
    106
    107  kind()          -- TypeCode kind of type.
    108  unalias()       -- Return an equivalent Type object with aliases stripped
    109  accept(visitor) -- visitor pattern accept. See idlvisitor.py."""
    110
    111    def __init__(self, kind, local):
    112        self.__kind  = kind
    113        self.__local = local
    114
    115    def kind(self):            return self.__kind
    116    def local(self):           return self.__local
    117
    118    def unalias(self):
    119        type = self
    120        while type.kind() == tk_alias:
    121            if len(type.decl().sizes()) > 0:
    122                return type
    123            type = type.decl().alias().aliasType()
    124        return type
    125
    126    def accept(self, visitor): pass
    127
    128
    129# Base types
    130class Base (Type):
    131    """Class for CORBA base types. (Type)
    132
    133No non-inherited functions."""
    134
    135    def __init__(self, kind):
    136        if kind not in [tk_null, tk_void, tk_short, tk_long, tk_ushort,
    137                        tk_ulong, tk_float, tk_double, tk_boolean,
    138                        tk_char, tk_octet, tk_any, tk_TypeCode,
    139                        tk_Principal, tk_longlong, tk_ulonglong,
    140                        tk_longdouble, tk_wchar]:
    141
    142            raise Error("Attempt to create Base type with invalid kind.")
    143
    144        Type.__init__(self, kind, 0)
    145
    146    def accept(self, visitor): visitor.visitBaseType(self)
    147
    148
    149# Strings can be used like base types without a declaration. eg:
    150#
    151#   void op(in string<10> s);
    152#
    153# therefore, the String type must include its bound here, rather than
    154# relying on looking at the corresponding declaration
    155
    156class String (Type):
    157    """Class for string types (Type)
    158
    159Function:
    160
    161  bound() -- bound of bounded string. 0 for unbounded."""
    162
    163    def __init__(self, bound):
    164        Type.__init__(self, tk_string, 0)
    165        self.__bound = bound
    166
    167    def accept(self, visitor): visitor.visitStringType(self)
    168    def bound(self): return self.__bound
    169
    170class WString (Type):
    171    """Class for wide string types (Type)
    172
    173Function:
    174
    175  bound() -- bound of bounded wstring. 0 for unbounded."""
    176
    177    def __init__(self, bound):
    178        Type.__init__(self, tk_wstring, 0)
    179        self.__bound = bound
    180
    181    def accept(self, visitor): visitor.visitWStringType(self)
    182    def bound(self): return self.__bound
    183
    184
    185# Sequences are never declared. They either appear as
    186#
    187#   typedef sequence <...> ...
    188#
    189# or inside a struct, union, or valuetype
    190
    191class Sequence (Type):
    192    """Class for sequence types (Type)
    193
    194Functions:
    195
    196  seqType() -- Type this is a sequence of.
    197  bound()   -- bound of bounded sequence. 0 for unbounded."""
    198
    199    def __init__(self, seqType, bound, local):
    200        Type.__init__(self, tk_sequence, local)
    201        self.__seqType = seqType
    202        self.__bound   = bound
    203
    204    def accept(self, visitor): visitor.visitSequenceType(self)
    205    def seqType(self): return self.__seqType
    206    def bound(self):   return self.__bound
    207
    208
    209# Same goes for fixed
    210
    211class Fixed (Type):
    212    """Class for fixed point types (Type)
    213
    214Functions:
    215
    216  digits() -- digits.
    217  scale()  -- scale."""
    218
    219    def __init__(self, digits, scale):
    220        Type.__init__(self, tk_fixed, 0)
    221        self.__digits = digits
    222        self.__scale  = scale
    223
    224    def accept(self, visitor): visitor.visitFixedType(self)
    225    def digits(self): return self.__digits
    226    def scale(self):  return self.__scale
    227
    228
    229# All other types must be declared, at least implicitly, so they have
    230# an associated declaration object
    231
    232class Declared (Type):
    233    """Class for declared types (Type)
    234
    235Functions:
    236
    237  decl()       -- Decl object which corresponds to this type.
    238  scopedName() -- Fully scoped name of the type as a list of strings.
    239  name()       -- Simple name of the type."""
    240
    241    def __init__(self, decl, scopedName, kind, local):
    242        if kind not in [tk_objref, tk_struct, tk_union, tk_enum,
    243                        tk_array, tk_alias, tk_except, tk_value,
    244                        tk_value_box, tk_native, tk_abstract_interface,
    245                        tk_local_interface, ot_structforward,
    246                        ot_unionforward]:
    247
    248            raise Error("Attempt to create Declared type with invalid kind.")
    249
    250        Type.__init__(self, kind, local)
    251        self.__decl       = decl
    252        self.__scopedName = scopedName
    253
    254    def accept(self, visitor): visitor.visitDeclaredType(self)
    255
    256    # Decl object where the type was declared.
    257    def decl(self):       return self.__decl
    258
    259    # List containing scoped name:
    260    def scopedName(self): return self.__scopedName
    261
    262    # Simple name
    263    def name(self):       return self.__scopedName[-1]
    264
    265
    266def containsValueType(t, track=None):
    267    """Returns true if the type contains valuetypes"""
    268
    269    import idlast
    270
    271    if track is None:
    272        track = {}
    273
    274    if track.has_key(id(t)):
    275        return 0
    276    track[id(t)] = None
    277
    278    if isinstance(t, Sequence):
    279        return containsValueType(t.seqType(), track)
    280
    281    if isinstance(t, Declared):
    282        d = t.decl()
    283
    284        if isinstance(d, idlast.Declarator):
    285            alias = d.alias()
    286            if alias:
    287                return containsValueType(alias.aliasType(), track)
    288
    289        if isinstance(d, idlast.Struct):
    290            for m in d.members():
    291                if containsValueType(m.memberType(), track):
    292                    return 1
    293
    294        if isinstance(d, idlast.Union):
    295            for c in d.cases():
    296                if containsValueType(c.caseType(), track):
    297                    return 1
    298
    299        if isinstance(d, idlast.ValueAbs):
    300            return 1
    301
    302        if isinstance(d, idlast.Value):
    303            return 1
    304
    305        if isinstance(d, idlast.ValueBox):
    306            return 1
    307
    308        if isinstance(d, idlast.Interface) and d.abstract():
    309            return 1
    310
    311    return 0
    312
    313
    314# Map of singleton Base Type objects
    315baseTypeMap = {
    316    tk_null:       Base(tk_null),
    317    tk_void:       Base(tk_void),
    318    tk_short:      Base(tk_short),
    319    tk_long:       Base(tk_long),
    320    tk_ushort:     Base(tk_ushort),
    321    tk_ulong:      Base(tk_ulong),
    322    tk_float:      Base(tk_float),
    323    tk_double:     Base(tk_double),
    324    tk_boolean:    Base(tk_boolean),
    325    tk_char:       Base(tk_char),
    326    tk_octet:      Base(tk_octet),
    327    tk_any:        Base(tk_any),
    328    tk_TypeCode:   Base(tk_TypeCode),
    329    tk_Principal:  Base(tk_Principal),
    330    tk_longlong:   Base(tk_longlong),
    331    tk_ulonglong:  Base(tk_ulonglong),
    332    tk_longdouble: Base(tk_longdouble),
    333    tk_wchar:      Base(tk_wchar)
    334    }
    335
    336# Maps of String and WString Type objects, indexed by bound
    337stringTypeMap =  { 0: String(0) }
    338wstringTypeMap = { 0: WString(0) }
    339
    340# Map of Sequence Type objects, indexed by (type object,bound)
    341sequenceTypeMap = {}
    342
    343# Map of Fixed Type objects, indexed by (digits,scale)
    344fixedTypeMap = {}
    345
    346# Map of declared type objects, indexed by stringified scoped name
    347declaredTypeMap = {}
    348
    349
    350# Private functions to create or return existing Type objects
    351def baseType(kind):
    352    return baseTypeMap[kind]
    353
    354def stringType(bound):
    355    try:
    356        return stringTypeMap[bound]
    357    except KeyError:
    358        st = String(bound)
    359        stringTypeMap[bound] = st
    360        return st
    361
    362def wstringType(bound):
    363    try:
    364        return wstringTypeMap[bound]
    365    except KeyError:
    366        wst = WString(bound)
    367        wstringTypeMap[bound] = wst
    368        return wst
    369
    370def sequenceType(type_spec, bound, local):
    371    try:
    372        return sequenceTypeMap[(type_spec,bound)]
    373    except KeyError:
    374        st = Sequence(type_spec, bound, local)
    375        sequenceTypeMap[(type_spec,bound)] = st
    376        return st
    377
    378def fixedType(digits, scale):
    379    try:
    380        return fixedTypeMap[(digits,scale)]
    381    except KeyError:
    382        ft = Fixed(digits, scale)
    383        fixedTypeMap[(digits,scale)] = ft
    384        return ft
    385
    386def declaredType(decl, scopedName, kind, local):
    387    sname = idlutil.slashName(scopedName)
    388    if declaredTypeMap.has_key(sname):
    389        dt = declaredTypeMap[sname]
    390        if dt.kind() == kind:
    391            return dt
    392    dt = Declared(decl, scopedName, kind, local)
    393    declaredTypeMap[sname] = dt
    394    return dt
    395
    396def clear():
    397    """Clear back-end structures ready for another run"""
    398    stringTypeMap.clear()
    399    wstringTypeMap.clear()
    400    sequenceTypeMap.clear()
    401    fixedTypeMap.clear()
    402    declaredTypeMap.clear()
    403

Generated on Thu Apr 16 16:27:14 2009 by
synopsis (version devel)