File: Synopsis/Parsers/IDL/idlast.py
   1# -*- python -*-
   2#                           Package   : omniidl
   3# idlast.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#   Python definitions for abstract syntax tree classes
  28
  29# $Id: idlast.py,v 1.20.2.7 2006/01/18 19:23:17 dgrisby Exp $
  30# $Log: idlast.py,v $
  31# Revision 1.20.2.7  2006/01/18 19:23:17  dgrisby
  32# Code generation problems with valuetype inheritance / typedefs.
  33#
  34# Revision 1.20.2.6  2004/10/13 17:58:26  dgrisby
  35# Abstract interfaces support; values support interfaces; value bug fixes.
  36#
  37# Revision 1.20.2.5  2003/11/06 11:56:57  dgrisby
  38# Yet more valuetype. Plain valuetype and abstract valuetype are now working.
  39#
  40# Revision 1.20.2.4  2003/09/04 14:00:35  dgrisby
  41# ValueType IDL updates.
  42#
  43# Revision 1.20.2.3  2003/07/10 21:54:47  dgrisby
  44# Missed methods in ValueAbs.
  45#
  46# Revision 1.20.2.2  2003/05/20 16:53:17  dgrisby
  47# Valuetype marshalling support.
  48#
  49# Revision 1.20.2.1  2003/03/23 21:01:39  dgrisby
  50# Start of omniORB 4.1.x development branch.
  51#
  52# Revision 1.15.2.7  2002/09/21 21:07:51  dgrisby
  53# Support ValueBase in omniidl. (No use to omniORB yet...)
  54#
  55# Revision 1.15.2.6  2001/08/29 11:55:23  dpg1
  56# Enumerator nodes record their value.
  57#
  58# Revision 1.15.2.5  2001/06/08 17:12:25  dpg1
  59# Merge all the bug fixes from omni3_develop.
  60#
  61# Revision 1.15.2.4  2000/11/01 15:57:03  dpg1
  62# More updates for 2.4.
  63#
  64# Revision 1.15.2.3  2000/11/01 12:45:59  dpg1
  65# Update to CORBA 2.4 specification.
  66#
  67# Revision 1.15.2.2  2000/10/10 10:18:54  dpg1
  68# Update omniidl front-end from omni3_develop.
  69#
  70# Revision 1.13.2.4  2000/08/29 10:20:29  dpg1
  71# Operations and attributes now have repository ids.
  72#
  73# Revision 1.13.2.3  2000/06/29 14:08:11  dpg1
  74# Incorrect visitor method called for Value nodes.
  75#
  76# Revision 1.13.2.2  2000/06/08 14:36:21  dpg1
  77# Comments and pragmas are now objects rather than plain strings, so
  78# they can have file,line associated with them.
  79#
  80# Revision 1.13.2.1  2000/03/06 15:03:45  dpg1
  81# Minor bug fixes to omniidl. New -nf and -k flags.
  82#
  83# Revision 1.13  1999/11/29 16:43:51  dpg1
  84# Forgot a case in registerDecl().
  85#
  86# Revision 1.12  1999/11/29 15:04:47  dpg1
  87# Fixed bug in clear().
  88#
  89# Revision 1.11  1999/11/25 11:20:33  dpg1
  90# Tidy documentation changes.
  91#
  92# Revision 1.10  1999/11/23 09:52:11  dpg1
  93# Dumb bug where maps weren't cleared between runs.
  94#
  95# Revision 1.9  1999/11/15 15:49:23  dpg1
  96# Documentation strings.
  97#
  98# Revision 1.8  1999/11/11 15:55:30  dpg1
  99# Python back-end interface now supports valuetype declarations.
 100# Back-ends still don't support them, though.
 101#
 102# Revision 1.7  1999/11/02 17:07:24  dpg1
 103# Changes to compile on Solaris.
 104#
 105# Revision 1.6  1999/11/02 10:01:46  dpg1
 106# Minor fixes.
 107#
 108# Revision 1.5  1999/11/01 20:19:55  dpg1
 109# Support for union switch types declared inside the switch statement.
 110#
 111# Revision 1.4  1999/11/01 16:39:01  dpg1
 112# Small fixes and cosmetic changes.
 113#
 114# Revision 1.3  1999/11/01 10:05:01  dpg1
 115# New file attribute to AST.
 116#
 117# Revision 1.2  1999/10/29 18:19:39  dpg1
 118# Clean up
 119#
 120# Revision 1.1  1999/10/29 15:47:08  dpg1
 121# First revision.
 122#
 123
 124"""Classes and functions for handling the IDL Abstract Syntax Tree
 125
 126Function:
 127
 128  findDecl(scopedName) -- find a Decl object given a fully-scoped
 129                          name, represented as a list of strings.
 130                          eg. ::foo::bar::baz is represented as
 131                          ['foo', 'bar', 'baz'].
 132Classes:
 133
 134  AST          -- top level of Abstract Syntax Tree.
 135  Decl         -- base of all declarations.
 136  DeclRepoId   -- mixin class for Decls with repository ids.
 137  Pragma       -- record of an unknown pragma
 138  Comment      -- record of a comment
 139  Module       -- module declaration.
 140  Interface    -- interface declaration.
 141  Forward      -- forward-declared interface.
 142  Const        -- constant declaration.
 143  Declarator   -- declarator used in typedef, struct members, etc.
 144  Typedef      -- typedef.
 145  Member       -- member of a struct or exception.
 146  Struct       -- struct declaration.
 147  Exception    -- exception declaration.
 148  CaseLabel    -- case label within a union.
 149  UnionCase    -- one case within a union.
 150  Union        -- union declaration.
 151  Enumerator   -- enumerator of an enum.
 152  Enum         -- enum declaration.
 153  Attribute    -- attribute declaration.
 154  Parameter    -- parameter of an operation of factory.
 155  Operation    -- operation declaration.
 156  Native       -- native declaration.
 157  StateMember  -- state member of a valuetype.
 158  Factory      -- factory method of a valuetype.
 159  ValueForward -- forward-declared valuetype.
 160  ValueBox     -- boxed value declaration.
 161  ValueAbs     -- abstract valuetype declaration.
 162  Value        -- valuetype declaration."""
 163
 164import idlutil
 165import idlvisitor
 166
 167class AST:
 168    """Class for top-level Abstract Syntax Tree.
 169
 170Functions:
 171
 172  file()          -- the file name of the main IDL file.
 173  declarations()  -- list of Decl objects corresponding to declarations
 174                     at file scope.
 175  pragmas()       -- list of Pragma objects containing #pragmas which
 176                     occurred before any declarations. Later #pragmas
 177                     are attached to Decl objects.
 178  comments()      -- list of Comment objects containing comments which
 179                     occurred before any declarations.
 180  accept(visitor) -- visitor pattern accept. See idlvisitor.py."""
 181
 182    def __init__(self, file, declarations, pragmas, comments):
 183        self.__file         = file
 184        self.__declarations = declarations
 185        self.__pragmas      = pragmas
 186        self.__comments     = comments
 187
 188    def file(self):            return self.__file
 189    def declarations(self):    return self.__declarations
 190    def pragmas(self):         return self.__pragmas
 191    def comments(self):        return self.__comments
 192    def accept(self, visitor): visitor.visitAST(self)
 193
 194
 195class Decl:
 196    """Base class for all declarations.
 197
 198Functions:
 199
 200  file()          -- the IDL file this declaration came from.
 201  line()          -- the line number within the file.
 202  mainFile()      -- boolean: true if the file was the main IDL file;
 203                     false if it was an included file.
 204  pragmas()       -- list of Pragma objects containing #pragmas which
 205                     immediately followed this declaration.
 206  comments()      -- list of Comment objects containing comments which
 207                     immediately followed this declaration.
 208  fullDecl()      -- the 'full' Decl for typedefs, forwards, etc.
 209
 210  accept(visitor) -- visitor pattern accept. See idlvisitor.py."""
 211
 212    def __init__(self, file, line, mainFile, pragmas, comments):
 213        self.__file     = file
 214        self.__line     = line
 215        self.__mainFile = mainFile
 216        self.__builtIn  = 0
 217        self.__pragmas  = pragmas
 218        self.__comments = comments
 219
 220    def accept(self, visitor): pass
 221
 222    def file(self):     return self.__file
 223    def line(self):     return self.__line
 224    def mainFile(self): return self.__mainFile
 225    def builtIn(self):  return self.__builtIn
 226    def pragmas(self):  return self.__pragmas
 227    def comments(self): return self.__comments
 228    def fullDecl(self): return self
 229
 230
 231class DeclRepoId :
 232    """Mixin class for Decls which have a Repository Id
 233
 234Functions:
 235
 236  identifier() -- name of the declaration as a string
 237  scopedName() -- list of strings forming the fully-scoped name of the
 238                  declaration. e.g. ::foo::bar::baz is represented as
 239                  ['foo', 'bar', 'baz'].
 240  repoId()     -- repository identifier for this declaration."""
 241
 242    def __init__(self, identifier, scopedName, repoId):
 243        self.__identifier = identifier
 244        self.__scopedName = scopedName
 245        self.__repoId     = repoId
 246
 247    def identifier(self): return self.__identifier
 248    def scopedName(self): return self.__scopedName
 249    def repoId(self):     return self.__repoId
 250
 251
 252# Pragmas and comments
 253
 254class Pragma :
 255    """Class containing information about an unknown pragma
 256
 257Functions:
 258
 259  text()    -- text of the pragma
 260  __str__() -- same as text()
 261  file()    -- file containing the pragma
 262  line()    -- line number in file"""
 263
 264    def __init__(self, text, file, line):
 265        self.__text = text
 266        self.__file = file
 267        self.__line = line
 268
 269    def text(self)    : return self.__text
 270    def __str__(self) : return self.__text
 271    def file(self)    : return self.__file
 272    def line(self)    : return self.__line
 273
 274class Comment :
 275    """Class containing information about a comment
 276
 277Functions:
 278
 279  text()    -- text of the comment
 280  __str__() -- same as text()
 281  file()    -- file containing the comment
 282  line()    -- line number in file"""
 283
 284    def __init__(self, text, file, line):
 285        self.__text = text
 286        self.__file = file
 287        self.__line = line
 288
 289    def text(self)    : return self.__text
 290    def __str__(self) : return self.__text
 291    def file(self)    : return self.__file
 292    def line(self)    : return self.__line
 293
 294
 295
 296
 297# Concrete declaration objects
 298
 299class Module (Decl, DeclRepoId):
 300    """Module declaration (Decl, DeclRepoId)
 301
 302Functions:
 303
 304  definitions()   -- list of Decl objects declared within this module.
 305  continuations() -- list containing continuations of this module.
 306                     When modules are re-opened, multiple Module
 307                     objects with the same name appear in the
 308                     enclosing Module or AST object. In case it's
 309                     useful, the first Module object for a particular
 310                     module has a list containing continuations of
 311                     that module. You will probably not have any use
 312                     for this."""
 313
 314    def __init__(self, file, line, mainFile, pragmas, comments,
 315                 identifier, scopedName, repoId,
 316                 definitions):
 317
 318        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 319        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 320
 321        self.__definitions  = definitions
 322        self._continuations = []
 323
 324    def accept(self, visitor): visitor.visitModule(self)
 325
 326    def definitions(self):   return self.__definitions
 327    def continuations(self): return self._continuations
 328
 329
 330class Interface (Decl, DeclRepoId):
 331    """Interface declaration (Decl, DeclRepoId)
 332
 333Functions:
 334
 335  abstract()     -- boolean: true if the interface is declared abstract.
 336  local()        -- boolean: true if the interface is declared local.
 337  inherits()     -- list of Interface objects from which this one
 338                    inherits.
 339  contents()     -- list of Decl objects for all items declared within
 340                    this interface.
 341  declarations() -- subset of contents() containing types, constants
 342                    and exceptions.
 343  callables()    -- subset of contents() containing Operations and
 344                    Attributes.
 345  all_callables()-- callables of this and inherited interfaces."""
 346
 347    def __init__(self, file, line, mainFile, pragmas, comments,
 348                 identifier, scopedName, repoId,
 349                 abstract, local, inherits):
 350
 351        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 352        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 353
 354        self.__abstract     = abstract
 355        self.__local        = local
 356        self.__inherits     = inherits
 357        self.__contents     = []
 358        self.__declarations = []
 359        self.__callables    = []
 360
 361    def _setContents(self, contents):
 362        self.__contents     = contents
 363        self.__declarations = filter(lambda c: not (isinstance(c, Attribute) or
 364                                                    isinstance(c, Operation)),
 365                                     contents)
 366        self.__callables    = filter(lambda c: (isinstance(c, Attribute) or
 367                                                isinstance(c, Operation)),
 368                                     contents)
 369
 370    def accept(self, visitor): visitor.visitInterface(self)
 371
 372    def abstract(self):     return self.__abstract
 373    def local(self):        return self.__local
 374    def inherits(self):     return self.__inherits
 375    def contents(self):     return self.__contents
 376    def declarations(self): return self.__declarations
 377    def callables(self):    return self.__callables
 378    def all_callables(self):
 379        r = []
 380        # This loop is very inefficient, but the lists should be quite
 381        # short.
 382        for b in self.__inherits:
 383            for c in b.all_callables():
 384                if c not in r:
 385                    r.append(c)
 386        r.extend(self.__callables)
 387        return r
 388
 389
 390class Forward (Decl, DeclRepoId):
 391    """Forward-declared interface (Decl, DeclRepoId)
 392
 393Functions:
 394
 395  abstract() -- boolean: true if the interface is declared abstract.
 396  local()    -- boolean: true if the interface is declared local.
 397  fullDecl() -- Interface object corresponding to full interface
 398                declaration or None if there is no full declaration."""
 399
 400    def __init__(self, file, line, mainFile, pragmas, comments,
 401                 identifier, scopedName, repoId,
 402                 abstract, local):
 403
 404        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 405        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 406
 407        self.__abstract = abstract
 408        self.__local    = local
 409        self._fullDecl  = None
 410        self._more      = []
 411
 412    def accept(self, visitor): visitor.visitForward(self)
 413
 414    def abstract(self): return self.__abstract
 415    def local(self):    return self.__abstract
 416    def fullDecl(self): return self._fullDecl
 417
 418
 419class Const (Decl, DeclRepoId):
 420    """Constant declaration (Decl, DeclRepoId)
 421
 422Functions:
 423
 424  constType() -- IdlType.Type object of this constant. Aliases not
 425                 stripped.
 426  constKind() -- TypeCode kind of constant with aliases stripped.
 427  value()     -- value of the constant. Either an integer or an
 428                 Enumerator object."""
 429
 430    def __init__(self, file, line, mainFile, pragmas, comments,
 431                 identifier, scopedName, repoId,
 432                 constType, constKind, value):
 433
 434        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 435        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 436
 437        self.__constType = constType
 438        self.__constKind = constKind
 439        self.__value     = value
 440        #print line, "Const init:", constType, identifier, value
 441
 442    def accept(self, visitor): visitor.visitConst(self)
 443
 444    def constType(self):  return self.__constType
 445    def constKind(self):  return self.__constKind
 446    def value(self):      return self.__value
 447
 448
 449class Declarator (Decl, DeclRepoId):
 450    """Declarator used in typedefs, struct members, etc. (Decl, DeclRepoId)
 451
 452Functions:
 453
 454  sizes() -- list of array sizes, or None if this is a simple
 455             declarator.
 456  alias() -- Typedef object for this declarator if this is a typedef
 457             declarator. None otherwise."""
 458
 459    def __init__(self, file, line, mainFile, pragmas, comments,
 460                 identifier, scopedName, repoId,
 461                 sizes):
 462
 463        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 464        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 465
 466        self.__sizes = sizes
 467        self.__alias = None
 468
 469    def _setAlias(self, alias): self.__alias = alias
 470
 471    def accept(self, visitor): visitor.visitDeclarator(self)
 472
 473    def sizes(self): return self.__sizes
 474    def alias(self): return self.__alias
 475
 476    def fullDecl(self):
 477        if self.__alias is not None:
 478            try:
 479                return self.__alias.aliasType().decl()
 480            except AttributeError:
 481                pass
 482        return self
 483
 484
 485class Typedef (Decl):
 486    """Typedef (Decl)
 487
 488Functions:
 489
 490  aliasType()   -- IdlType.Type object that this is an alias to.
 491  constrType()  -- boolean: true if the alias type was constructed
 492                   within this typedef declaration.
 493  declarators() -- list of Declarator objects."""
 494
 495    def __init__(self, file, line, mainFile, pragmas, comments,
 496                 aliasType, constrType, declarators):
 497
 498        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 499
 500        self.__aliasType   = aliasType
 501        self.__constrType  = constrType
 502        self.__declarators = declarators
 503
 504    def accept(self, visitor): visitor.visitTypedef(self)
 505
 506    def aliasType(self):   return self.__aliasType
 507    def constrType(self):  return self.__constrType
 508    def declarators(self): return self.__declarators
 509
 510
 511class Member (Decl):
 512    """Member of a struct or exception (Decl)
 513
 514Functions:
 515
 516  memberType()  -- IdlType.Type object for the type of this member.
 517  constrType()  -- boolean: true if the member type was constructed
 518                   within the member declaration.
 519  declarators() -- list of Declarator objects."""
 520
 521    def __init__(self, file, line, mainFile, pragmas, comments,
 522                 memberType, constrType, declarators):
 523
 524        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 525
 526        self.__memberType  = memberType
 527        self.__constrType  = constrType
 528        self.__declarators = declarators
 529
 530    def accept(self, visitor): visitor.visitMember(self)
 531
 532    def memberType(self):  return self.__memberType
 533    def constrType(self):  return self.__constrType
 534    def declarators(self): return self.__declarators
 535
 536
 537class Struct (Decl, DeclRepoId):
 538    """Struct declaration (Decl, DeclRepoId)
 539
 540Functions:
 541
 542  members()   -- list of Member objects for the struct contents.
 543  recursive() -- boolean: true if the struct is recursive."""
 544
 545    def __init__(self, file, line, mainFile, pragmas, comments,
 546                 identifier, scopedName, repoId,
 547                 recursive):
 548
 549        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 550        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 551
 552        self.__recursive = recursive
 553
 554    def _setMembers(self, members):
 555        self.__members = members
 556
 557    def accept(self, visitor): visitor.visitStruct(self)
 558
 559    def members(self):    return self.__members
 560    def recursive(self):  return self.__recursive
 561
 562
 563class StructForward (Decl, DeclRepoId):
 564    """Struct forward declaration (Decl, DeclRepoId)
 565
 566Functions:
 567
 568  fullDecl() -- full definition of the struct."""
 569
 570    def __init__(self, file, line, mainFile, pragmas, comments,
 571                 identifier, scopedName, repoId):
 572
 573        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 574        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 575
 576        self._fullDecl = None
 577        self._more     = []
 578
 579    def accept(self, visitor): visitor.visitStructForward(self)
 580
 581    def fullDecl(self): return self._fullDecl
 582
 583
 584class Exception (Decl, DeclRepoId):
 585    """Exception declaration (Decl, DeclRepoId)
 586
 587Function:
 588
 589  members() -- list of Member objects for the exception contents."""
 590
 591    def __init__(self, file, line, mainFile, pragmas, comments,
 592                 identifier, scopedName, repoId,
 593                 members):
 594
 595        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 596        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 597
 598        self.__members    = members
 599        #print line, "Exception init:", identifier, members
 600
 601    def accept(self, visitor): visitor.visitException(self)
 602
 603    def members(self):    return self.__members
 604
 605
 606class CaseLabel (Decl):
 607    """Case label within a union (Decl)
 608
 609Functions:
 610
 611  default()   -- boolean: true if this is the default label.
 612  value()     -- label value. Either an integer or an Enumerator
 613                 object. If default() is true, returns a value used by
 614                 none of the other union labels.
 615  labelKind() -- TypeCode kind of label."""
 616
 617    def __init__(self, file, line, mainFile, pragmas, comments,
 618                 default, value, labelKind):
 619
 620        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 621
 622        self.__default   = default
 623        self.__value     = value
 624        self.__labelKind = labelKind
 625
 626    def accept(self, visitor): visitor.visitCaseLabel(self)
 627
 628    def default(self): return self.__default
 629    def value(self): return self.__value
 630    def labelKind(self): return self.__labelKind
 631
 632
 633class UnionCase (Decl):
 634    """One case within a union (Decl)
 635
 636Functions:
 637
 638  labels()     -- list of CaseLabel objects.
 639  caseType()   -- IdlType.Type object for the case type.
 640  constrType() -- boolean: true if the case type was constructed
 641                  within the case.
 642  declarator() -- Declarator object"""
 643
 644    def __init__(self, file, line, mainFile, pragmas, comments,
 645                 labels, caseType, constrType, declarator):
 646
 647        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 648
 649        self.__labels     = labels
 650        self.__caseType   = caseType
 651        self.__constrType = constrType
 652        self.__declarator = declarator
 653
 654    def accept(self, visitor): visitor.visitUnionCase(self)
 655
 656    def labels(self):     return self.__labels
 657    def caseType(self):   return self.__caseType
 658    def constrType(self): return self.__constrType
 659    def declarator(self): return self.__declarator
 660
 661
 662class Union (Decl, DeclRepoId):
 663    """Union declaration (Decl, DeclRepoId)
 664
 665Functions:
 666
 667  switchType() -- IdlType.Type object corresponding to the switch type.
 668  constrType() -- boolean: true if the switch type was declared within
 669                  the switch statement. Only possible for Enums.
 670  cases()      -- list of UnionCase objects.
 671  recursive()  -- boolean: true if the union is recursive."""
 672
 673
 674    def __init__(self, file, line, mainFile, pragmas, comments,
 675                 identifier, scopedName, repoId,
 676                 switchType, constrType, recursive):
 677
 678        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 679        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 680
 681        self.__switchType = switchType
 682        self.__constrType = constrType
 683        self.__recursive  = recursive
 684
 685    def _setCases(self, cases):
 686        self.__cases = cases
 687
 688    def accept(self, visitor): visitor.visitUnion(self)
 689
 690    def switchType(self): return self.__switchType
 691    def constrType(self): return self.__constrType
 692    def cases(self):      return self.__cases
 693    def recursive(self):  return self.__recursive
 694
 695
 696class UnionForward (Decl, DeclRepoId):
 697    """Union forward declaration (Decl, DeclRepoId)
 698
 699Functions:
 700
 701  fullDecl() -- full definition of the union."""
 702
 703    def __init__(self, file, line, mainFile, pragmas, comments,
 704                 identifier, scopedName, repoId):
 705
 706        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 707        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 708
 709        self._fullDecl = None
 710        self._more     = []
 711
 712    def accept(self, visitor): visitor.visitUnionForward(self)
 713
 714    def fullDecl(self): return self._fullDecl
 715
 716
 717class Enumerator (Decl, DeclRepoId):
 718    """Enumerator of an Enum (Decl, DeclRepoId)
 719
 720Function:
 721
 722  value() -- integer value of enumerator, as marshalled."""
 723
 724    def __init__(self, file, line, mainFile, pragmas, comments,
 725                 identifier, scopedName, repoId, value):
 726
 727        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 728        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 729
 730        self.__value = value
 731
 732    def accept(self, visitor): visitor.visitEnumerator(self)
 733
 734    def value(self): return self.__value
 735
 736
 737class Enum (Decl, DeclRepoId):
 738    """Enum declaration (Decl, DeclRepoId)
 739
 740Function:
 741
 742  enumerators() -- list of Enumerator objects."""
 743
 744    def __init__(self, file, line, mainFile, pragmas, comments,
 745                 identifier, scopedName, repoId,
 746                 enumerators):
 747
 748        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 749        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 750
 751        self.__enumerators = enumerators
 752
 753    def accept(self, visitor): visitor.visitEnum(self)
 754
 755    def enumerators(self): return self.__enumerators
 756
 757
 758class Attribute (Decl):
 759    """Attribute declaration (Decl)
 760
 761Functions:
 762
 763  readonly()    -- boolean: true if the attribute is read only.
 764  attrType()    -- IdlType.Type object for the attribute's type.
 765  declarators() -- list of the attribute's declarators.
 766  identifiers() -- list of strings containing the attribute identifiers
 767                     (equivalent to the identifiers inside the declarators)."""
 768
 769    def __init__(self, file, line, mainFile, pragmas, comments,
 770                 readonly, attrType, declarators):
 771
 772        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 773
 774        self.__readonly    = readonly
 775        self.__attrType    = attrType
 776        self.__declarators = declarators
 777        self.__identifiers = map(lambda d: d.identifier(), declarators)
 778        #print line, "Attribute init:", readonly, identifiers
 779
 780    def accept(self, visitor): visitor.visitAttribute(self)
 781
 782    def readonly(self):    return self.__readonly
 783    def attrType(self):    return self.__attrType
 784    def declarators(self): return self.__declarators
 785    def identifiers(self): return self.__identifiers
 786
 787
 788class Parameter (Decl):
 789    """A Parameter of an operation or factory specifier (Decl)
 790
 791Functions:
 792
 793  direction()  -- integer: 0 == in, 1 == out, 2 == inout.
 794  is_in()      -- boolean: true if in or inout.
 795  is_out()     -- boolean: true if out or inout.
 796  paramType()  -- IdlType.Type object for the parameter type.
 797  identifier() -- string of parameter identifier."""
 798
 799    def __init__(self, file, line, mainFile, pragmas, comments,
 800                 direction, paramType, identifier):
 801
 802        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 803
 804        self.__direction  = direction
 805        self.__is_in      = (direction == 0 or direction == 2)
 806        self.__is_out     = (direction == 1 or direction == 2)
 807        self.__paramType  = paramType
 808        self.__identifier = identifier
 809        #print line, "Parameter init:", identifier
 810
 811    def accept(self, visitor): visitor.visitParameter(self)
 812
 813    def direction(self):  return self.__direction
 814    def is_in(self):      return self.__is_in
 815    def is_out(self):     return self.__is_out
 816    def paramType(self):  return self.__paramType
 817    def identifier(self): return self.__identifier
 818
 819
 820class Operation (Decl, DeclRepoId):
 821    """Operation declaration (Decl, DeclRepoId)
 822
 823Functions:
 824
 825  oneway()     -- boolean: true if operation is one way.
 826  returnType() -- IdlType.Type object for return type.
 827  parameters() -- list of Parameter objects.
 828  raises()     -- list of Exception objects.
 829  contexts()   -- list of strings for context expressions."""
 830
 831    def __init__(self, file, line, mainFile, pragmas, comments,
 832                 oneway, returnType, identifier, scopedName, repoId,
 833                 parameters, raises, contexts):
 834
 835        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 836        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 837
 838        self.__oneway     = oneway
 839        self.__returnType = returnType
 840        self.__parameters = parameters
 841        self.__raises     = raises
 842        self.__contexts   = contexts
 843        #print line, "Operation init:", identifier, raises, contexts
 844
 845    def accept(self, visitor): visitor.visitOperation(self)
 846
 847    def oneway(self):     return self.__oneway
 848    def returnType(self): return self.__returnType
 849    def parameters(self): return self.__parameters
 850    def raises(self):     return self.__raises
 851    def contexts(self):   return self.__contexts
 852
 853
 854class Native (Decl, DeclRepoId):
 855    """Native declaration (Decl, DeclRepoId)
 856
 857Native should not be used in normal IDL.
 858
 859No non-inherited functions."""
 860
 861    def __init__(self, file, line, mainFile, pragmas, comments,
 862                 identifier, scopedName, repoId):
 863
 864        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 865        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 866
 867    def accept(self, visitor): visitor.visitNative(self)
 868
 869
 870class StateMember (Decl):
 871    """State member of a valuetype (Decl)
 872
 873Functions:
 874
 875  memberAccess() -- integer: 0 == public, 1 == private.
 876  memberType()   -- IdlType.Type object for member type.
 877  constrType()   -- boolean: true if member type is declared within
 878                    the StateMember.
 879  declarators()  -- list of Declarator objects."""
 880
 881    def __init__(self, file, line, mainFile, pragmas, comments,
 882                 memberAccess, memberType, constrType, declarators):
 883
 884        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 885
 886        self.__memberAccess = memberAccess
 887        self.__memberType   = memberType
 888        self.__constrType   = constrType
 889        self.__declarators  = declarators
 890
 891    def accept(self, visitor): visitor.visitStateMember(self)
 892
 893    # Access specifier: 0 for public, 1 for private
 894    def memberAccess(self): return self.__memberAccess
 895    def memberType(self):   return self.__memberType
 896    def constrType(self):   return self.__constrType
 897    def declarators(self):  return self.__declarators
 898
 899
 900class Factory (Decl):
 901    """Factory method of valuetype (Decl)
 902
 903Functions:
 904
 905  identifier() -- string.
 906  parameters() -- list of Parameter objects.
 907  raises()     -- list of Exception objects."""
 908
 909    def __init__(self, file, line, mainFile, pragmas, comments,
 910                 identifier, parameters, raises):
 911
 912        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 913
 914        self.__identifier = identifier
 915        self.__parameters = parameters
 916        self.__raises     = raises
 917
 918    def accept(self, visitor): visitor.visitFactory(self)
 919
 920    def identifier(self): return self.__identifier
 921    def parameters(self): return self.__parameters
 922    def raises(self):     return self.__raises
 923
 924
 925class ValueForward (Decl, DeclRepoId):
 926    """Forward declared valuetype (Decl, DeclRepoId)
 927
 928Function:
 929
 930  abstract() -- boolean: true if declared abstract.
 931  fullDecl() -- Value or ValueAbs object corresponding to the full
 932                valuetype declaration or None if there is no full
 933                declaration."""
 934
 935    def __init__(self, file, line, mainFile, pragmas, comments,
 936                 identifier, scopedName, repoId,
 937                 abstract):
 938
 939        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 940        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 941
 942        self.__abstract = abstract
 943        self._fullDecl  = None
 944        self._more      = []
 945
 946    def accept(self, visitor): visitor.visitValueForward(self)
 947
 948    def abstract(self): return self.__abstract
 949    def fullDecl(self): return self._fullDecl
 950
 951
 952class ValueBox (Decl, DeclRepoId):
 953    """ValueBox declaration (Decl, DeclRepoId)
 954
 955Functions:
 956
 957  boxedType()  -- IdlType.Type object for boxed type.
 958  constrType() -- boolean: true if boxed type is declared inside the
 959                  ValueBox declaration."""
 960
 961    def __init__(self, file, line, mainFile, pragmas, comments,
 962                 identifier, scopedName, repoId,
 963                 boxedType, constrType):
 964
 965        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 966        DeclRepoId.__init__(self, identifier, scopedName, repoId)
 967
 968        self.__boxedType  = boxedType
 969        self.__constrType = constrType
 970
 971    def accept(self, visitor): visitor.visitValueBox(self)
 972
 973    def boxedType(self):  return self.__boxedType
 974    def constrType(self): return self.__constrType
 975
 976
 977class ValueAbs (Decl, DeclRepoId):
 978    """Abstract valuetype declaration (Decl, DeclRepoId)
 979
 980Functions:
 981
 982  inherits()     -- list of ValueAbs objects from which this inherits.
 983  supports()     -- list of Interface objects which this supports.
 984  contents()     -- list of Decl objects for declarations within this
 985                    valuetype.
 986  declarations() -- subset of contents() containing types, constants
 987                    and exceptions.
 988  callables()    -- subset of contents() containing Operations and
 989                    Attributes.
 990  statemembers() -- subset of contents() containing StateMembers.
 991  factories()    -- subset of contents() containing Factory instances.
 992  """
 993
 994    def __init__(self, file, line, mainFile, pragmas, comments,
 995                 identifier, scopedName, repoId,
 996                 inherits, supports):
 997
 998        Decl.__init__(self, file, line, mainFile, pragmas, comments)
 999        DeclRepoId.__init__(self, identifier, scopedName, repoId)
1000
1001        self.__inherits     = inherits
1002        self.__supports     = supports
1003        self.__contents     = []
1004        self.__declarations = []
1005        self.__callables    = []
1006        self.__statemembers = []
1007        self.__factories    = []
1008
1009    def _setContents(self, contents):
1010        self.__contents     = contents
1011        self.__declarations = filter(lambda c: not(isinstance(c, Attribute) or
1012                                      isinstance(c, Operation) or
1013                                      isinstance(c, StateMember) or
1014                                      isinstance(c, Factory)),
1015                                     contents)
1016        self.__callables    = filter(lambda c:(isinstance(c, Attribute) or
1017                                      isinstance(c, Operation)),
1018                                     contents)
1019
1020        self.__statemembers = filter(lambda c:(isinstance(c, StateMember)),
1021                                     contents)
1022
1023        self.__factories    = filter(lambda c:(isinstance(c, Factory)),
1024                                     contents)
1025
1026    def accept(self, visitor): visitor.visitValueAbs(self)
1027
1028    def inherits(self):     return self.__inherits
1029    def supports(self):     return self.__supports
1030    def contents(self):     return self.__contents
1031    def declarations(self): return self.__declarations
1032    def callables(self):    return self.__callables
1033    def statemembers(self): return self.__statemembers
1034    def factories(self):    return self.__factories
1035
1036
1037class Value (Decl, DeclRepoId):
1038    """valuetype declaration (Decl, DeclRepoId)
1039
1040Functions:
1041
1042  custom()       -- boolean: true if declared custom.
1043  inherits()     -- list of valuetypes from which this inherits. The
1044                    first may be a Value object or a ValueAbs object;
1045                    any others will be ValueAbs objects.
1046  truncatable()  -- boolean: true if the inherited Value is declared
1047                    truncatable.
1048  supports()     -- list of Interface objects which this supports.
1049  contents()     -- list of Decl objects for all items declared within
1050                    this valuetype.
1051  declarations() -- subset of contents() containing types, constants
1052                    and exceptions.
1053  callables()    -- subset of contents() containing Operations and
1054                    Attributes.
1055  statemembers() -- subset of contents() containing StateMembers.
1056  factories()    -- subset of contents() containing Factory instances.
1057  """
1058
1059    def __init__(self, file, line, mainFile, pragmas, comments,
1060                 identifier, scopedName, repoId,
1061                 custom, inherits, truncatable, supports):
1062
1063        Decl.__init__(self, file, line, mainFile, pragmas, comments)
1064        DeclRepoId.__init__(self, identifier, scopedName, repoId)
1065
1066        self.__custom       = custom
1067        self.__inherits     = inherits
1068        self.__truncatable  = truncatable
1069        self.__supports     = supports
1070        self.__contents     = []
1071        self.__declarations = []
1072        self.__callables    = []
1073        self.__statemembers = []
1074        self.__factories    = []
1075
1076    def _setContents(self, contents):
1077        self.__contents     = contents
1078        self.__declarations = filter(lambda c: not(isinstance(c, Attribute) or
1079                                      isinstance(c, Operation) or
1080                                      isinstance(c, StateMember) or
1081                                      isinstance(c, Factory)),
1082                                     contents)
1083        self.__callables    = filter(lambda c:(isinstance(c, Attribute) or
1084                                      isinstance(c, Operation)),
1085                                     contents)
1086
1087        self.__statemembers = filter(lambda c:(isinstance(c, StateMember)),
1088                                     contents)
1089
1090        self.__factories    = filter(lambda c:(isinstance(c, Factory)),
1091                                     contents)
1092
1093    def accept(self, visitor): visitor.visitValue(self)
1094
1095    def custom(self):       return self.__custom
1096    def inherits(self):     return self.__inherits
1097    def truncatable(self):  return self.__truncatable
1098    def supports(self):     return self.__supports
1099    def contents(self):     return self.__contents
1100    def declarations(self): return self.__declarations
1101    def callables(self):    return self.__callables
1102    def statemembers(self): return self.__statemembers
1103    def factories(self):    return self.__factories
1104
1105
1106# Map of Decl objects, indexed by stringified scoped name, and
1107# functions to access it
1108
1109declMap = {}
1110
1111def registerDecl(scopedName, decl):
1112    """Private function"""
1113    sname = idlutil.slashName(scopedName)
1114    if declMap.has_key(sname):
1115
1116        rdecl = declMap[sname]
1117
1118        isi = isinstance
1119
1120        if (isi(decl, Interface) and isi(rdecl, Forward))       or(isi(decl, ValueAbs)  and isi(rdecl, ValueForward))  or(isi(decl, Value)     and isi(rdecl, ValueForward))  or(isi(decl, Struct)    and isi(rdecl, StructForward)) or(isi(decl, Union)     and isi(rdecl, UnionForward)):
1121
1122            # resolving a forward declaration
1123            rdecl._fullDecl = decl
1124            for f in rdecl._more: f._fullDecl = decl
1125            declMap[sname] = decl
1126
1127        elif (isi(decl, Forward)       and isi(rdecl, Forward))       or(isi(decl, ValueForward)  and isi(rdecl, ValueForward))  or(isi(decl, StructForward) and isi(rdecl, StructForward)) or(isi(decl, UnionForward)  and isi(rdecl, UnionForward)):
1128
1129            # repeat forward declaration
1130            rdecl._more.append(decl)
1131
1132        elif (isi(decl, Forward)       and isi(rdecl, Interface)) or(isi(decl, ValueForward)  and isi(rdecl, ValueAbs))  or(isi(decl, ValueForward)  and isi(rdecl, Value))     or(isi(decl, StructForward) and isi(rdecl, Struct))    or(isi(decl, UnionForward)  and isi(rdecl, Union)):
1133
1134            # forward declaration of full declaration
1135            decl._fullDecl = rdecl
1136
1137        elif (isi(decl, Module) and isi(rdecl, Module)):
1138            # continued module
1139            rdecl._continuations.append(decl)
1140
1141        else:
1142            print "***Warning: attempt to re-register", sname
1143
1144        return
1145
1146    declMap[sname] = decl
1147
1148
1149class DeclNotFound:
1150
1151    """Exception to indicate that findDecl() could not find the
1152    requested Decl object."""
1153
1154    def __init__(self, scopedName):
1155        self.__scopedName = scopedName
1156
1157    def scopedName(self): return self.__scopedName
1158
1159
1160def findDecl(scopedName):
1161    """findDecl(scopedName) -> Decl
1162
1163Find a Decl object given a fully scoped name represented as a list of
1164strings. Raises DeclNotFound if the name is not recognised."""
1165
1166    sname = idlutil.slashName(scopedName)
1167    if not declMap.has_key(sname):
1168        raise DeclNotFound(scopedName)
1169
1170    return declMap[sname]
1171
1172
1173# Declarations of non-basic `built-in' types
1174
1175CORBAObject = Interface("<built in>", 0, 0, [], [],
1176                        "Object", ["CORBA", "Object"],
1177                        "IDL:omg.org/CORBA/Object:1.0",
1178                        0, 0, [])
1179CORBAObject._Decl__builtIn = 1
1180registerDecl(["CORBA", "Object"], CORBAObject)
1181
1182CORBAValueBase = Value("<built in>", 0, 0, [], [],
1183                       "ValueBase", ["CORBA", "ValueBase"],
1184                       "IDL:omg.org/CORBA/ValueBase:1.0",
1185                       0, [], 0, [])
1186CORBAValueBase._Decl__builtIn = 1
1187registerDecl(["CORBA", "ValueBase"], CORBAValueBase)
1188
1189CORBAModule = Module("<built in>", 0, 0, [], [], "CORBA", ["CORBA"],
1190                     "IDL:omg.org/CORBA:1.0", [CORBAObject, CORBAValueBase])
1191registerDecl(["CORBA"], CORBAModule)
1192
1193
1194def clear():
1195    """Clear back-end structures ready for another run"""
1196    declMap.clear()
1197    registerDecl(["CORBA", "Object"], CORBAObject)
1198    registerDecl(["CORBA", "ValueBase"], CORBAValueBase)
1199    registerDecl(["CORBA"], CORBAModule)
1200