dictbuilder.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: sjis -*-
00003 # -*- python -*-
00004 #
00005 #  @file omniidl_be/doil/dictbuilder
00006 #  @brief Dictionary Builder class for doil backend
00007 #  @date $Date$
00008 #  @author Noriaki Ando <n-ando@aist.go.jp>
00009 # 
00010 #  Copyright (C) 2008
00011 #      Task-intelligence Research Group,
00012 #      Intelligent Systems Research Institute,
00013 #      National Institute of
00014 #          Advanced Industrial Science and Technology (AIST), Japan
00015 #      All rights reserved.
00016 # 
00017 #  $Id$
00018 # 
00019 
00020 """Produce Dictionary from IDL AST"""
00021 
00022 import string
00023 
00024 # module from omniidl
00025 from omniidl import idlast, idlvisitor, idltype
00026 
00027 # module from omniidl_be/cxx
00028 from omniidl_be.cxx import ast, id, types, output
00029 import omniidl_be.cxx.id as corba_cxx_id
00030 
00031 # module from omniidl_be/doil
00032 from omniidl_be.doil import util
00033 
00034 import omniidl_be.doil.yat as yat
00035 
00036 #import dictbuilder
00037 
00038 #self = dictbuilder
00039 
00040 def impl_fullname(name):
00041     bits = name.suffix("Servant").fullName()
00042     return string.join(bits, "_")
00043 
00044 # Main code entrypoint
00045 def run(tree, config):
00046     # first thing is to build the interface implementations
00047     bsi = BuildDictionaryFromAST(tree, config)
00048     tree.accept(bsi)
00049     dict = bsi.get_dict()
00050 #    import yaml
00051 #    print yaml.dump(dict['tree'], default_flow_style=False)
00052     return dict
00053 
00054 
00055 
00056 
00057 # Build the interface implementations
00058 #
00059 class BuildDictionaryFromAST(idlvisitor.AstVisitor):
00060     def get_dict(self):
00061         return self.dict
00062 
00063     def __init__(self, tree, config):
00064         # configuration parameters from command options
00065         self.config = config
00066 
00067         # module's namespace stack
00068         self.module = []
00069 
00070         # main dictionary
00071         self.dict = {}
00072         self.dict['tree'] = []
00073 
00074         # idl file name
00075         idl_fname = ast.mainFile()
00076         self.dict['idl_fname'] = idl_fname
00077 
00078         # included idl files
00079         incs = []
00080         idl_incs = ast.includes()
00081         for inc in idl_incs:
00082             d = self.createHeaderInfo(inc)
00083             if inc == idl_fname:
00084                 self.dict.update(d)
00085             elif self.config['ImplicitInclude']:
00086                 # -Wbimplicit option makes process included IDLs
00087                 d = self.createHeaderInfo(inc)
00088                 incs.append(d)
00089         self.dict['idl_includes'] = incs
00090 
00091         # other includes
00092         self.dict['include_h'] = self.config["IncludeHeaders"]
00093 
00094         # type mapping
00095         self.typemap = self.config['TypeMapping']
00096         # now configurations can be accessed by self.config["key"]
00097 
00098         # keep track of all interfaces for later use
00099         self.__allInterfaces = []
00100         self.tk_map = {
00101             idltype.tk_null               : "tk_null",
00102             idltype.tk_void               : "tk_void",
00103             idltype.tk_short              : "tk_short",
00104             idltype.tk_long               : "tk_long",
00105             idltype.tk_ushort             : "tk_ushort",
00106             idltype.tk_ulong              : "tk_ulong",
00107             idltype.tk_float              : "tk_float",
00108             idltype.tk_double             : "tk_double",
00109             idltype.tk_boolean            : "tk_boolean",
00110             idltype.tk_char               : "tk_char",
00111             idltype.tk_octet              : "tk_octet",
00112             idltype.tk_any                : "tk_any",
00113             idltype.tk_TypeCode           : "tk_TypeCode",
00114             idltype.tk_Principal          : "tk_Principal",
00115             idltype.tk_objref             : "tk_objref",
00116             idltype.tk_struct             : "tk_struct",
00117             idltype.tk_union              : "tk_union",
00118             idltype.tk_enum               : "tk_enum",
00119             idltype.tk_string             : "tk_string",
00120             idltype.tk_sequence           : "tk_sequence",
00121             idltype.tk_array              : "tk_array",
00122             idltype.tk_alias              : "tk_alias",
00123             idltype.tk_except             : "tk_except",
00124             idltype.tk_longlong           : "tk_longlong",
00125             idltype.tk_ulonglong          : "tk_ulonglong",
00126             idltype.tk_longdouble         : "tk_longdouble",
00127             idltype.tk_wchar              : "tk_wchar",
00128             idltype.tk_wstring            : "tk_wstring",
00129             idltype.tk_fixed              : "tk_fixed",
00130             idltype.tk_value              : "tk_value",
00131             idltype.tk_value_box          : "tk_value_box",
00132             idltype.tk_native             : "tk_native",
00133             idltype.tk_abstract_interface : "tk_abstract_interface",
00134             idltype.tk_local_interface    : "tk_local_interface"
00135             }
00136 
00137         self.corba_primitive = {
00138             "CORBA::Short"                : "short int",
00139             "CORBA::UShort"               : "unsigned short int",
00140             "CORBA::Long"                 : "int",
00141             "CORBA::ULong"                : "unsigned int",
00142             "CORBA::Float"                : "float",
00143             "CORBA::Double"               : "double",
00144             "CORBA::Char"                 : "char",
00145             "CORBA::Boolean"              : "bool",
00146             "char*"                       : "::std::string",
00147             "CORBA::Any"                  : "::std::string",
00148             "CORBA::TypeCode_ptr"         : "::std::string"
00149             }
00150 
00151     def createHeaderInfo(self, idl_path):
00152         dict = {}
00153         idl_path_list = idl_path.split('/')
00154         idl_fname     = idl_path_list[-1]
00155 
00156         dict['idl_fname']     = idl_fname
00157         dict['idl_fname_path'] = idl_path
00158 
00159         # types.h
00160         base_name                   = idl_fname.split('.')[0]
00161         inc_guard                   = base_name.upper() + 'TYPES_H'
00162         dict['types_h']             = types_h = base_name + 'Types.h'
00163         dict['typeconv_h']          = base_name + 'TypeConversion.h'
00164         dict['typeconv_cpp']        = base_name + 'TypeConversion.cpp'
00165         dict['types_include_guard'] = inc_guard
00166         if self.config['IfaceDir'] != "":
00167             inc_types_h_path = self.config['IfaceDir'] \
00168                 + '/' + types_h
00169         else:
00170             inc_types_h_path = types_h
00171         dict['types_h_path'] = inc_types_h_path
00172 
00173         # typeconv.h
00174         dict['typeconv_h'] = typeconv_h = base_name + 'TypeConversion.h'
00175         dict['typeconv_cpp']            = base_name + 'TypeConversion.cpp'
00176         tc_inc_guard                    = base_name.upper() + 'TYPECONVERSION_H'
00177         dict['typeconv_include_guard']  = tc_inc_guard
00178         if self.config['ServantDir'] != "":
00179             inc_typeconv_h_path = self.config['ServantDir'] \
00180                 + '/' + typeconv_h
00181         else:
00182             inc_typeconv_h_path = typeconv_h
00183         dict['typeconv_h_path'] = inc_typeconv_h_path
00184         return dict
00185 
00186 
00187 
00188     def createDecl(self, decl_type):
00189         """
00190         宣言情報の基本ディクショナリの生成
00191 
00192         decl_type:     宣言のタイプ, struct, interface, union など
00193         corba:
00194           decl_type:     宣言のタイプ, struct, interface, union など
00195           corba_ns: []   ネームスペースのリスト
00196         local:
00197           decl_type:     宣言のタイプ, struct, interface, union など
00198           local_ns: []   ローカルインターフェースのネームスペース
00199           adapter_ns: [] アダプタのネームスペース
00200           servant_ns: [] サーバントのネームスペース
00201         """
00202         cdict = {'decl_type': decl_type}
00203         ldict = {'decl_type': decl_type}
00204         cdict['corba_ns'] = self.module
00205         ldict['iface_ns'] = self.module + self.config['IfaceNs']
00206         ldict['adapter_ns'] = self.module + self.config['AdapterNs']
00207         ldict['proxy_ns'] = self.module + self.config['ProxyNs']
00208         ldict['servant_ns'] = self.module + self.config['ServantNs']
00209         return {'decl_type': decl_type, 'corba': cdict, 'local': ldict}
00210 
00211 
00212     def getType(self, typeobj):
00213         """
00214         CORBA と Local の型名を取得する
00215         """
00216         corba_type = typeobj.base()
00217         # for omniidl4 4.1.1-2
00218         if corba_type[:2] == "::":
00219             corba_type = corba_type[2:]
00220         is_primitive = None
00221         # if CORBA to Local mapping is specified explicitly
00222         if self.typemap.has_key(corba_type):
00223             local_type = self.typemap[corba_type]
00224 
00225         # if CORBA type is primitive, string or Any
00226         elif self.corba_primitive.has_key(corba_type):
00227             local_type = self.corba_primitive[corba_type]
00228             if corba_type[:5] == 'CORBA':
00229                 corba_type = '::' + corba_type
00230             tk = self.tk_map[typeobj.kind()]
00231             primitive = ["tk_short", "tk_long", "tk_ushort", 
00232                          "tk_ulong", "tk_float", "tk_double",
00233                          "tk_boolean", "tk_char", "tk_octet"]
00234             if primitive.count(tk) > 0:
00235                 is_primitive = 'YES'
00236 
00237 
00238         # other case
00239         else:
00240             corba_scoped_type = corba_type.split('::')
00241             corba_ns = corba_scoped_type[:-1]
00242             corba_base = corba_scoped_type[-1]
00243             local_ns = corba_ns + self.config['IfaceNs']
00244             local_scope = string.join(local_ns, '::')
00245             if typeobj.objref():
00246                 corba_base = corba_base[:corba_base.rfind('_ptr')]
00247                 local_type = local_scope + '::' + \
00248                     self.config['IfacePrefix'] + \
00249                     corba_base + \
00250                     self.config['IfaceSuffix']
00251             elif typeobj.sequence():
00252                 seqType = types.Type(typeobj.type().seqType())
00253                 # get type of element of sequence
00254                 (corba_etype, local_etype, eis_primitive) = self.getType(seqType)
00255                 if seqType.objref():
00256                     local_etype = local_etype + '*'
00257                 local_type = "std::vector< " + local_etype + " >"
00258 
00259             else:
00260                 local_type = local_scope + '::' + corba_base
00261             corba_type = '::' + corba_type
00262             local_type = '::' + local_type
00263         return (corba_type, local_type, is_primitive)       
00264 
00265 
00266     def createIdent(self, dict, node):
00267         """
00268         宣言の識別子に関するディクショナリの生成
00269         主に、識別子のIDL、C++、Local名を生成する
00270         createDeclで生成したディクショナリとnodeを引数に取る
00271 
00272         corba:
00273           idl_name:       宣言のidl上の識別子
00274           name:           C++にマッピングされた識別子
00275           name_fq:        C++識別子の完全修飾名
00276           scoped_name: [] リスト形式の完全修飾名
00277         local:
00278           idl_name:       宣言のidl上の識別子
00279           name:           C++にマッピングされた識別子
00280           name_fq:        C++識別子の完全修飾名
00281           scoped_name: [] リスト形式の完全修飾名
00282 
00283         """
00284         cdict = dict['corba']
00285         ldict = dict['local']
00286 
00287         cdict['idl_name'] = idl_name = node.identifier()
00288         cdict['name'] = cxx_name = id.mapID(idl_name)
00289         ns = node.scopedName()[:-1]
00290         cdict['corba_ns'] = ns
00291         ldict['iface_ns'] = ns + self.config['IfaceNs']
00292         ldict['adapter_ns'] = ns + self.config['AdapterNs']
00293         ldict['proxy_ns'] = ns + self.config['ProxyNs']
00294         ldict['servant_ns'] = ns + self.config['ServantNs']
00295         cxx_fq_name = id.Name(node.scopedName()).fullyQualify()
00296         cdict['name_fq'] = '::' + cxx_fq_name
00297         cdict['scoped_name'] = node.scopedName()
00298 
00299         iface_ns = '::' + string.join(ldict['iface_ns'], '::')
00300 
00301         if self.typemap.has_key(cxx_fq_name):
00302             local_fq_name = self.typemap[cxx_fq_name]
00303             local_name = local_fq_name.split('::')[-1]
00304         elif self.corba_primitive.has_key(cxx_fq_name):
00305             local_fq_name = self.corba_primitive[cxx_fq_name]
00306             local_name    = local_fq_name
00307         else:
00308             local_name = cxx_name
00309             local_fq_name = iface_ns + '::' + local_name
00310 
00311         ldict['name'] = local_name
00312         ldict['name_fq'] = local_fq_name
00313         ldict['scoped_name'] = ldict['iface_ns'] + [local_name]
00314         return dict
00315 
00316 
00317     def createInterfaceIdent(self, dict, node):
00318         """
00319         インターフェース宣言の識別子に関するディクショナリの生成
00320         interface/servant/adapter 名を作成しディクショナリに追加する
00321 
00322         corba:
00323           name_poa:            CORBA POAクラス名
00324         local:
00325           iface_name:          Interfaceの識別子
00326           iface_name_fq:       Interfaceの完全修飾名
00327           iface_scoped_name:   Interfaceのリスト形式完全修飾名
00328           servant_name:        Servantの識別子
00329           servant_name_fq:     Servantの完全修飾名
00330           servant_scoped_name: Servantのリスト形式完全修飾名
00331           adapter_name:        Adapterの識別子
00332           adapter_name_fq:     Adapterの完全修飾名
00333           adapter_scoped_name: Adapterのリスト形式完全修飾名
00334 
00335         """
00336         self.createIdent(dict, node)
00337         cdict = dict['corba']
00338         ldict = dict['local']
00339         cdict['name_poa'] = '::POA_' + cdict['name_fq'].strip(':')
00340 
00341         # set iface_name, servant_name adapter_name
00342         name = ldict['name']
00343         p = "Prefix"
00344         s = "Suffix"
00345         n = "Ns"
00346         for t in ['Iface', 'Servant', 'Adapter', 'Proxy']:
00347         #for t in ['Iface', 'Servant', 'Adapter']:
00348             key = t.lower() + '_name'
00349             local_name = self.config[t + p] + name + self.config[t + s]
00350             scoped_name = cdict['corba_ns'] + self.config[t + n] + [local_name]
00351             local_fq_name = '::' + string.join(scoped_name, '::')
00352             ldict[key] = local_name
00353             ldict[key + '_fq'] = local_fq_name
00354             ldict[key + '_scoped_name'] = scoped_name
00355         return dict
00356 
00357 
00358     def createInterfaceFileInfo(self, dict, node):
00359         """
00360         インターフェース関連ファイル名のディクショナリの生成
00361 
00362         local:
00363           iface_h:               Interfaceヘッダファイル名
00364           iface_cpp:             Interface実装ファイル名
00365           iface_h_path:          Interfaceヘッダのインクルードパス
00366           iface_include_guard:   Interfaceヘッダののインクルードガード
00367           servant_h:             Servantヘッダファイル名
00368           servant_cpp:           Servant実装ファイル名
00369           servant_h_path:        Servantヘッダのインクルードパス
00370           servant_include_guard: Servantヘッダののインクルードガード
00371           adapter_h:             Adapterヘッダファイル名
00372           adapter_cpp:           Adapter実装ファイル名
00373           adapter_h_path:        Adapterヘッダのインクルードパス
00374           adapter_include_guard: Adapterヘッダののインクルードガード
00375 
00376         """
00377         cdict = dict['corba']
00378         ldict = dict['local']
00379         ldict['include_h'] = self.config["IncludeHeaders"]
00380 
00381         # set [iface|servant|adapter]_[h|cpp|h_path|include_guard]
00382         
00383         for t in ['Iface', 'Servant', 'Adapter', 'Proxy']:
00384         #for t in ['Iface', 'Servant', 'Adapter']:
00385             k = t.lower()
00386             ldict[k + '_h']   = ldict[k + '_name'] + ".h"
00387             ldict[k + '_cpp'] = ldict[k + '_name'] + ".cpp"
00388             if self.config[t + 'Dir'] == '':
00389                 ldict[k + '_h_path'] = ldict[k + '_h']
00390             else:
00391                 ldict[k + '_h_path'] = \
00392                     self.config[t + 'Dir'] + '/' + ldict[k + '_h']
00393             ns = string.join(map(lambda x: x + '_',
00394                                  ldict[k + '_ns']), '')
00395             ns = ns.upper()
00396             name = ldict[k + '_name'].upper()
00397             ldict[k + '_include_guard'] = ns + name + "_H"
00398         return dict
00399 
00400 
00401     def createUnionIdent(self, dict, node):
00402         """
00403         共用体宣言のの識別子に関するディクショナリの生成
00404         
00405         corba:
00406           idl_name:          宣言のidl上の識別子
00407           name:              C++にマッピングされた識別子
00408           name_fq:           C++識別子の完全修飾名
00409           scoped_name: []    リスト形式の完全修飾名
00410           switch_type:       switchの型
00411           switch_fq_type:    switchの完全修飾型
00412           deref_switch_type: switchの非参照型
00413         local:
00414           idl_name:          宣言のidl上の識別子
00415           name:              C++にマッピングされた識別子
00416           name_fq:           C++識別子の完全修飾名
00417           scoped_name: []    リスト形式の完全修飾名
00418 
00419         """
00420         self.createIdent(dict, node)
00421         cdict = dict['corba']
00422         ldict = dict['local']
00423 
00424         switchType = types.Type(node.switchType())
00425         ast.markDefaultCase(node)
00426         hasDefault = ast.defaultCase(node) != None
00427 
00428         (ctype, ltype, is_primitive) = self.getType(switchType)
00429         cdict['switch_fq_type'] = ctype
00430         cdict['switch_type']    = ctype.split('::')[-1]
00431         ldict['switch_fq_type'] = ltype
00432         ldict['switch_type']    = ltype.split('::')[-1]
00433         return 
00434 
00435 
00436     def createStructIdent(self, dict, node):
00437         return self.createIdent(dict, node)
00438 
00439 
00440     def createEnumIdent(self, dict, node):
00441         return self.createIdent(dict, node)
00442 
00443 
00444     def createExceptionIdent(self, dict, node):
00445         return self.createIdent(dict, node)
00446 
00447 
00448     def createMembers(self, dict, node):
00449         corba_name = dict['corba']['name']
00450         outer_environment = id.lookup(node)
00451         environment = outer_environment.enter(id.mapID(corba_name))
00452         scope = environment.scope()
00453 
00454         members = []
00455         for member in node.members():
00456             #------------------------------------------------------------
00457             # member
00458             # - type_d: type of a member
00459             # - decl_d: decralation list
00460             memberType = types.Type(member.memberType())
00461 
00462 #            self.createType(memberType, environment)
00463             memtype = memberType.member(environment)
00464             for decl in member.declarators():
00465                 m = self.createMember(decl, member, environment)
00466                 if m != None:
00467                     members.append(m)
00468         dict['members'] = members
00469         return dict
00470 
00471 
00472     def createMember(self, decl, member, env):
00473         dict = self.createDecl('member')
00474         cdict = dict['corba']
00475         ldict = dict['local']
00476 
00477         memberType = types.Type(member.memberType())
00478         memtype = memberType.member(env)
00479 
00480         (ctype, ltype, is_primitive) = self.getType(memberType)
00481         cdict['base_type'] = ctype
00482         cdict['tk'] = self.tk_map[memberType.kind()]
00483         ldict['base_type'] = ltype
00484         cdict['member_name'] = id.mapID(decl.identifier())
00485         cdict['member_dims'] = decl.sizes()
00486         ldict['member_name'] = cdict['member_name']
00487         ldict['member_dims'] = cdict['member_dims']
00488 
00489         if memberType.objref():
00490             corba_mtype = ctype
00491             local_mtype = ltype + '*'
00492         else:
00493             corba_mtype = ctype
00494             local_mtype = ltype
00495 
00496         cdict['member_type'] = corba_mtype
00497         ldict['member_type'] = local_mtype
00498         return dict
00499 
00500 
00501     def createUnionCases(self, dict, node):
00502         cases = []
00503         switchType = types.Type(node.switchType())
00504         ast.markDefaultCase(node) 
00505         outer_environment = id.lookup(node)
00506         environment = outer_environment.enter(node.identifier())
00507 
00508         for case in node.cases():
00509             c = self.createUnionCase(case, node, switchType, environment)
00510             if c != None:
00511                 cases.append(c)
00512         dict['cases'] = cases
00513         return dict
00514             
00515 
00516     def createUnionCase(self, case, node, switchtype, environment):
00517         dict = self.createDecl('union_case')
00518         cdict = dict['corba']
00519         ldict = dict['local']
00520 
00521         caseType = types.Type(case.caseType())
00522         d_caseType = caseType.deref()
00523         (corba_ctype, local_ctype, is_primitive) = self.getType(caseType)
00524         cdict['case_type'] = corba_ctype
00525         ldict['case_type'] = local_ctype
00526 
00527         decl = case.declarator()
00528         case_member = id.mapID(decl.identifier())
00529         cdict['case_member'] = case_member
00530         ldict['case_member'] = case_member
00531 
00532         decl_dims = decl.sizes()
00533         full_dims = decl_dims + caseType.dims()
00534         is_array = full_dims != []
00535         if is_array: raise "array union case type is not supported."
00536 
00537         # ------------------------------------------------------------
00538         # generate default discriminator
00539         def choose(switchType = switchtype,
00540                    values = ast.allCaseLabelValues(node),
00541                    environment = environment):
00542             switchType = switchType.deref()
00543             def min_unused(start, used = values):
00544                 x = start
00545                 while x in used:
00546                     x = x + 1
00547                 return x
00548             kind = switchType.type().kind()
00549             if switchType.integer():
00550                 (low, high) = ast.integer_type_ranges[kind]
00551                 s = switchType.literal(min_unused(low+1))
00552                 return s
00553             elif kind == idltype.tk_char:
00554                 all = map(chr, range(0, 255))
00555             elif kind == idltype.tk_boolean:
00556                 all = [0, 1]
00557             elif kind == idltype.tk_enum:
00558                 all = switchType.type().decl().enumerators()
00559             else:
00560                 util.fatalError("Failed to generate a default union " +\
00561                                     "discriminator value")
00562             possibles = util.minus(all, values)
00563             return switchType.literal(possibles[0], environment)
00564         # ------------------------------------------------------------
00565 
00566         labels = case.labels()
00567         if labels != []:
00568             non_default_labels = filter(lambda x:not x.default(), labels)
00569             if non_default_labels == []:
00570                 # only one label and it's the default
00571                 label = labels[0]
00572                 discrimvalue = choose()
00573             elif len(non_default_labels) > 1:
00574                 # oooh, we have a choice. Let's pick the second one.
00575                 # no-one will be expecting that
00576                 label = non_default_labels[1]
00577             else:
00578                 # just the one interesting label
00579                 label = non_default_labels[0]
00580 
00581             if label.default():
00582                 discrimvalue = choose()
00583             else:
00584                 discrimvalue = switchtype.literal(label.value(),
00585                                                       environment)
00586         cdict['discriminator'] = discrimvalue
00587         ldict['discriminator'] = discrimvalue
00588 
00589         if switchtype.enum():
00590             corba_ns = '::' + string.join(cdict['corba_ns'], '::')
00591             local_ns = '::' + string.join(ldict['iface_ns'], '::')
00592             cdict['discriminator_fq'] = corba_ns + '::' + discrimvalue
00593             ldict['discriminator_fq'] = local_ns + '::' + discrimvalue
00594         else:
00595             cdict['discriminator_fq'] = discrimvalue
00596             ldict['discriminator_fq'] = discrimvalue
00597         non_default_labels = filter(lambda x:not x.default(), labels)
00598         return dict
00599 
00600 
00601     def createTypedef(self, aliasType, decl, env):
00602         """
00603         typedef宣言に関するディクショナリの生成
00604 
00605         corba:
00606           derived_type:    導出型名
00607           derived_fq_type: 完全修飾導出型名
00608           deref_type:      非参照型名
00609           deref_fq_type:   完全修飾非参型名
00610           tk: TypeCode
00611         local:
00612           derived_type:    導出型名
00613           derived_fq_type: 完全修飾導出型名
00614           deref_type:      非参照型名
00615           deref_fq_type:   完全修飾非参型名
00616         """
00617 
00618         dict = self.createDecl('typedef')
00619         cdict = dict['corba']
00620         ldict = dict['local']
00621 
00622         (cdict['base_type'], ldict['base_type'], is_primitive) = self.getType(aliasType)
00623         derivedName = id.mapID(decl.identifier())
00624         alias_dims = aliasType.dims()
00625         cdict['derived_type'] = derivedName
00626         ldict['derived_type'] = derivedName
00627 
00628         corba_ns = '::' + string.join(cdict['corba_ns'], '::')
00629         local_ns = '::' + string.join(ldict['iface_ns'], '::')
00630         cdict['derived_type_fq'] = corba_ns + '::' + derivedName
00631         ldict['derived_type_fq'] = local_ns + '::' + derivedName
00632         cdict['tk'] = tk = self.tk_map[aliasType.kind()]
00633         primitive = ["tk_short", "tk_long", "tk_ushort", 
00634                      "tk_ulong", "tk_float", "tk_double",
00635                      "tk_boolean", "tk_char", "tk_octet"]
00636         if primitive.count(tk) > 0:
00637             cdict['is_primitive'] = 'YES'
00638 
00639         if aliasType.sequence():
00640             seqType = types.Type(aliasType.type().seqType())
00641             # get type of element of sequence
00642             (corba_etype, local_etype, is_primitive) = self.getType(seqType)
00643             cdict['element_tk'] = self.tk_map[seqType.kind()]
00644             if seqType.objref():
00645                 cdict['element_type_fq'] = corba_etype
00646                 ldict['element_type_fq'] = local_etype + '*'
00647             else:
00648                 cdict['element_type_fq'] = corba_etype
00649                 ldict['element_type_fq'] = local_etype
00650         return dict
00651 
00652 
00653     # ------------------------------------------------------------
00654     # オペレーションに関する辞書を作成する
00655     #
00656     # name: オペレーションの名称
00657     #
00658     def createOperation(self, operation):
00659         dict = {}
00660         dict['name'] = id.mapID(operation.identifier())
00661         dict['raises'] = []
00662         for r in operation.raises():
00663             edict = self.createDecl('exception')
00664             self.createExceptionIdent(edict, r)
00665             dict['raises'].append(edict)
00666         return dict
00667 
00668     def createAttribute(self, ident):
00669         dict = {}
00670         dict['name'] = id.mapID(ident)
00671         return dict
00672 
00673     # ------------------------------------------------------------
00674     # オペレーションの戻り値に関する辞書を作成する
00675     #
00676     # type_r: remote戻り値の型名
00677     # type_l: local戻り値の型名
00678     # var_r: remote戻り値の変数名
00679     # var_l: local戻り値の変数名
00680     # to_doil: to_remote変換関数
00681     # to_local: to_local変換関数
00682     #
00683     def createReturn(self, operation):
00684         """
00685         corba:
00686           base_type:
00687           ret_type:
00688           decl_type:
00689           tk:
00690         local:
00691           base_type:
00692           ret_type:
00693           decl_type:
00694           tk:
00695         """
00696         dict = self.createDecl('return')
00697         cdict = dict['corba']
00698         ldict = dict['local']
00699 
00700         retType = types.Type(operation.returnType())
00701         (corba_type, local_type, is_primitive) = self.getType(retType)
00702         cdict['base_type'] = corba_type
00703         ldict['base_type'] = local_type 
00704         if is_primitive != None:
00705             cdict['is_primitive'] = is_primitive
00706         retn_type = types.Type(operation.returnType()).op(types.RET)
00707         retn_type = retn_type.replace('CORBA', '::CORBA')
00708         retn_type = retn_type.replace('RTC', '::RTC')
00709         retn_type = retn_type.replace('SDOPackage', '::SDOPackage')
00710         retn_type = retn_type.replace('::::', '::')
00711         cdict['retn_type'] = retn_type
00712 
00713         if retType.objref(): local_rtype = local_type + '*'
00714         else:                local_rtype = local_type
00715 
00716         ldict['retn_type'] = local_rtype
00717         cdict['tk'] = ldict['tk'] = self.tk_map[retType.kind()]
00718 
00719         if retType.deref().sequence():
00720             retType = retType.deref()
00721 
00722         if retType.sequence():
00723             seqType = types.Type(retType.type().seqType())
00724             # get type of element of sequence
00725             (corba_etype, local_etype, is_primitive) = self.getType(seqType)
00726             cdict['deref_tk'] = self.tk_map[seqType.kind()]
00727         else:
00728             derefType = retType.deref()
00729             (corba_dtype, local_dtype, is_primitive) = self.getType(derefType)
00730             cdict['deref_tk'] = self.tk_map[derefType.kind()]
00731         return dict
00732 
00733 
00734     # ------------------------------------------------------------
00735     # オペレーションの引数に関する辞書を作成する
00736     #
00737     # type_r: remoteの引数の型
00738     # type_l: localの引数の型
00739     # var_r: remoteの変数名
00740     # var_l: localの変数名
00741     # to_doil: to_remote変換関数
00742     # to_local: to_local変換関数
00743     #
00744     def createArgs(self, operation, env):
00745         """
00746 
00747         corba:
00748           base_type:
00749           arg_type:
00750           arg_name:
00751           var_name:
00752           decl_type:
00753           direction:
00754           tk:
00755         local:
00756           base_type:
00757           arg_type:
00758           arg_name:
00759           var_name:
00760           decl_type:
00761           direction:
00762           tk:
00763 
00764 
00765         """
00766         args = []
00767         direction = ['in', 'out', 'inout','return']
00768         for arg in operation.parameters():
00769             # corba args information
00770             dict = self.createDecl('arg')
00771             cdict = dict['corba']
00772             ldict = dict['local']
00773 
00774             paramType = types.Type(arg.paramType())
00775             (corba_type, local_type, is_primitive) = self.getType(paramType)
00776 
00777             cdict['base_type'] = corba_type
00778             ldict['base_type'] = local_type
00779             if is_primitive != None:
00780                 cdict['is_primitive'] = is_primitive
00781 
00782             arg_name = id.mapID(arg.identifier())
00783             cdict['arg_name'] = arg_name
00784             ldict['arg_name'] = arg_name
00785             cdict['var_name'] = '_' + arg_name
00786             ldict['var_name'] = '_' + arg_name
00787 
00788             direction_val = direction[arg.direction()]
00789             cdict['direction'] = direction_val
00790             ldict['direction'] = direction_val
00791 
00792             cdict['tk'] = ldict['tk'] = self.tk_map[paramType.kind()]
00793             arg_type = paramType.op(types.direction(arg), use_out = 0)
00794             arg_type = arg_type.replace('CORBA', '::CORBA')
00795             arg_type = arg_type.replace('RTC', '::RTC')
00796             arg_type = arg_type.replace('SDOPackage', '::SDOPackage')
00797             arg_type = arg_type.replace('::::', '::')
00798             cdict['arg_type']  = arg_type
00799             out = arg.is_out()
00800             self.createArg(dict, paramType, out)
00801             args.append(dict)
00802         return args
00803 
00804     def createArg(self, dict, typeobj, out):
00805         (corba_type, local_type, is_primitive) = self.getType(typeobj)
00806         cdict = dict['corba']
00807         ldict = dict['local']
00808         if is_primitive != None:
00809             cdict['is_primitive'] = is_primitive
00810 
00811         paramType = typeobj
00812         if paramType.typedef():
00813             paramType = paramType.deref()
00814         # primitive type
00815         if paramType.is_basic_data_types():
00816             if out: ldict['arg_type'] = local_type + '&'
00817             else:   ldict['arg_type'] = local_type
00818             ldict['var_type'] = local_type
00819             cdict['var_type'] = corba_type
00820         # Enum type
00821         elif paramType.enum():
00822             if out: ldict['arg_type'] = local_type + '&'
00823             else:   ldict['arg_type'] = local_type
00824             ldict['var_type'] = local_type
00825             cdict['var_type'] = corba_type
00826         # Struct type
00827         # Sequence type
00828         # Union type           
00829         elif paramType.struct() or paramType.sequence() or \
00830                 paramType.union():
00831             if out: ldict['arg_type'] = local_type + '&'
00832             else:   ldict['arg_type'] = 'const '+local_type+'&'
00833             ldict['var_type'] = local_type
00834             cdict['var_type'] = corba_type + '*'
00835         # Object type
00836         elif paramType.objref():
00837             if out: ldict['arg_type'] = local_type + '*'
00838             else:   ldict['arg_type'] = 'const '+local_type+'*'
00839             ldict['var_type'] = local_type + '*'
00840             cdict['var_type'] = corba_type
00841         # String type
00842         # Any type
00843         elif paramType.any() or paramType.string():
00844             if out: ldict['arg_type'] = local_type + '&'
00845             else:   ldict['arg_type'] = 'const ' + local_type + '&'
00846             ldict['var_type'] = local_type
00847             cdict['var_type'] = corba_type
00848         else:
00849             raise "UNKNOWN TYPE", (
00850                 self.tk_map[paramType.kind()],
00851                 paramType.typedef())
00852 
00853 
00854     #------------------------------------------------------------
00855     # AST visitor functions
00856     #
00857     # Tree walking code
00858     def visitAST(self, node):
00859         for n in node.declarations():
00860             if ast.shouldGenerateCodeForDecl(n):
00861                 n.accept(self)
00862 
00863     # modules can contain interfaces
00864     def visitModule(self, node):
00865         module = id.mapID(node.identifier())
00866         self.module.append(module)
00867         for n in node.definitions():
00868             # enter tree inside this module
00869             n.accept(self)
00870         self.module.pop()
00871 
00872 
00873     def visitDeclarator(self, node):
00874         print "Declarator", id.mapID(node.identifier())
00875 
00876 
00877     def visitStructForward(self, node):
00878         dict = self.createDecl('struct_forward')
00879         # set corba/local struct identifier
00880         self.createStructIdent(dict, node)
00881         # append dicts to tree
00882         self.dict['tree'].append(dict)
00883         return
00884 
00885 
00886     def visitUnionForward(self, node):
00887         dict = self.createDecl('union_forward')
00888         # set corba/local union identifier
00889         self.getUnionIdent(dict, node)
00890         # append dicts to tree
00891         self.dict['tree'].append(dict)
00892         return
00893 
00894 
00895     def visitForward(self, node):
00896         dict = self.createDecl('interface_forward')
00897         # set corba/local interface identifier
00898         self.createInterfaceIdent(dict, node)
00899         # append dicts to tree
00900         self.dict['tree'].append(dict)
00901         return
00902 
00903     def visitException(self, node):
00904         dict = self.createDecl('exception')
00905         # set corba/local exception identifier
00906         self.createExceptionIdent(dict, node)
00907         # create members
00908         self.createMembers(dict, node)
00909         # add to dict
00910         self.dict['tree'].append(dict)
00911         return
00912 
00913 
00914     def visitUnion(self, node):
00915         dict = self.createDecl('union')
00916         # set corba/local union identifier
00917         self.createUnionIdent(dict, node)
00918         # create union cases
00919         self.createUnionCases(dict, node)
00920         # add to dict
00921         self.dict['tree'].append(dict)
00922         return
00923 
00924 
00925     def visitEnum(self, node):
00926         dict = self.createDecl('enum')
00927         cdict = dict['corba']
00928         ldict = dict['local']
00929         self.createEnumIdent(dict, node)
00930 
00931         enumerators = node.enumerators()
00932         memberlist = map(lambda x: id.Name(x.scopedName()).simple(),
00933                          enumerators)
00934         cdict['members'] = memberlist
00935         ldict['members'] = memberlist
00936         self.dict['tree'].append(dict)
00937         return
00938 
00939 
00940     def visitTypedef(self, node):
00941         environment = id.lookup(node)
00942         scope = environment.scope()
00943         aliasType = types.Type(node.aliasType())
00944         aliasTypeID = aliasType.member(environment)
00945 
00946         if node.constrType():
00947             node.aliasType().decl().accept(self)
00948 
00949 
00950         for decl in node.declarators():
00951             dict = self.createTypedef(aliasType, decl, environment)
00952             self.dict['tree'].append(dict)
00953         return
00954 
00955 
00956     def visitStruct(self, node):
00957         dict = self.createDecl('struct')
00958         self.createStructIdent(dict, node)
00959         self.createMembers(dict, node)
00960         self.dict['tree'].append(dict)
00961         return       
00962 
00963 
00964     # interfaces cannot be further nested
00965     def visitInterface(self, node):
00966         self.__allInterfaces.append(node)
00967         # listed scope and interface name
00968         dict = self.createDecl('interface')
00969         self.createInterfaceIdent(dict, node)
00970         self.createInterfaceFileInfo(dict, node)
00971 
00972         dict['inherits'] = []
00973         for ihnode in ast.allInherits(node):
00974             idict = self.createDecl('inherit')
00975             self.createInterfaceIdent(idict, ihnode)
00976             self.createInterfaceFileInfo(idict, ihnode)
00977             dict['inherits'].append(idict)
00978 
00979         env = id.lookup(node)
00980 
00981         allInterfaces = [node]# + ast.allInherits(node)
00982         allCallables = util.fold( map(lambda x:x.callables(), allInterfaces),
00983                                   [], lambda x, y: x + y )
00984 
00985         dict['operations'] = []
00986         dict['attributes'] = []
00987         for c in allCallables:
00988             if isinstance(c, idlast.Attribute):
00989                 attrType = types.Type(c.attrType())
00990                 d_attrType = attrType.deref()
00991                 (corba_atype, local_atype, is_primitive) = self.getType(attrType)
00992 
00993                 for i in c.identifiers():
00994                     ident = id.mapID(i)
00995                     returnType = attrType.op(types.RET)
00996                     inType = attrType.op(types.IN)
00997 
00998                     adict = createDecl('attribute')
00999                     cdict = adict['corba']
01000                     ldict = adict['local']
01001                     cdict['base_type'] = corba_atype;
01002                     ldict['base_type'] = local_atype
01003                     cdict['name'] = ident
01004                     adict['return'] = self.createReturn(c)
01005                     adict['arg'] = {}
01006                     self.createArg(adict['arg'], attrType, False)
01007 
01008                     dict['attributes'].append(adict)
01009                     if c.readonly():
01010                         dict['readonly'] = 'yes'
01011                     dict['attributes'].append(gdict)
01012 
01013             elif isinstance(c, idlast.Operation):
01014                 # operations
01015                 op_dict           = self.createOperation(c)
01016                 op_dict['return'] = self.createReturn(c)
01017                 op_dict['args']   = self.createArgs(c, env)
01018                 dict['operations'].append(op_dict)
01019             else:
01020                 util.fatalError("Internal error generating interface member")
01021                 raise "No code for interface member: " + repr(c)
01022 
01023 #        self.dict['interfaces'].append(dict)
01024         self.dict['tree'].append(dict)
01025         return
01026 
01027 


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Sun Mar 26 2017 03:37:15