Package pygccxml :: Package declarations :: Module decl_printer |

# Source Code for Module pygccxml.declarations.decl_printer

      1  # Copyright 2004-2008 Roman Yakovenko, 2006 Allen Bierbaum, Matthias Baas
      2  # Distributed under the Boost Software License, Version 1.0. (See
      3  # accompanying file LICENSE_1_0.txt or copy at
      4  # http://www.boost.org/LICENSE_1_0.txt)
      5
      6  """
      7  defines class, decl_printer_t that prints declarations tree in a user friendly format
      8  """
      9
     10  import os
     11  import sys
     12  import calldef
     13  import algorithm
     14  import decl_visitor
     15
     16
     17 -class decl_printer_t( decl_visitor.decl_visitor_t ):
     18      """Helper class for printing decl tree.
     19
     20      This class provides more information than the __str__() methods do.
     21      The class is not just meant to provide a unique "id" for a declaration
     22      but to inspect an entire declaration tree. This is particularly useful
     23      for new users who want to find out how Py++ works and how it
     24      stores its data.
     25      """
     26      JUSTIFY = 20
     27      INDENT_SIZE = 4
     28
     29 -    def __init__( self, level=0, print_details=True, recursive=True, writer=None ):
     30          decl_visitor.decl_visitor_t.__init__(self)
     31          self.__inst = None
     32          self.__level = level
     33          self.__print_details = print_details
     34          self.__recursive = recursive
     35          self.__writer = writer
     36          if not self.__writer:
     37              self.__writer = lambda x: sys.stdout.write( x + os.linesep )
     38
     39 -    def clone(self, increment_level=True):
     40          level = self.__level
     41          if increment_level:
     42              level += 1
     43          return decl_printer_t( level
     44                                 , self.print_details
     45                                 , recursive=self.recursive
     46                                 , writer=self.writer )
     47
     48 -    def _get_recursive(self):
     49          return self.__recursive
     50 -    def _set_recursive(self, recursive):
     51          self.__recursive = recursive
     52      recursive = property( _get_recursive, _set_recursive)
     53
     54 -    def _get_level(self):
     55          return self.__level
     56 -    def _set_level(self, lvl):
     57          self.__level = lvl
     58      level = property( _get_level, _set_level )
     59
     60 -    def _get_print_details(self):
     61          return self.__print_details
     62 -    def _set_print_details(self, details):
     63          self.__print_details = details
     64      print_details = property( _get_print_details, _set_print_details)
     65
     66 -    def _get_writer(self):
     67          return self.__writer
     68 -    def _set_writer(self, writer):
     69          self.__writer = writer
     70      writer = property( _get_writer, _set_writer)
     71
     72 -    def _get_inst(self):
     73          return self.__inst
     74 -    def _set_inst(self, inst):
     75          self.__inst = inst
     76      instance = property( _get_inst, _set_inst )
     77
     78 -    def __nice_decl_name( self, inst ):
     79          name = inst.__class__.__name__
     80          return name
     81          #if name.endswith( '_t' ):
     82          #    name = name[:-len('_t')]
     83          #return name.replace( '_', ' ' )
     84
     85 -    def print_decl_header(self):
     86          header = self.__nice_decl_name( self.__inst ) + ": '%s'" % self.__inst.name
     87          self.writer( ' ' * self.level * self.INDENT_SIZE + header.ljust( self.JUSTIFY ))
     88          if self.__print_details:
     89              curr_level = self.level + 1
     90              if self.__inst.location:
     91                  location = 'location: [%s]:%s'%(self.__inst.location.file_name, self.__inst.location.line)
     92                  self.writer( ' ' * curr_level * self.INDENT_SIZE + location)
     93              artificial = 'artificial: ' + "'%s'" % str(self.__inst.is_artificial)
     94              self.writer( ' ' * curr_level * self.INDENT_SIZE + artificial.ljust( self.JUSTIFY ))
     95              if self.__inst.attributes:
     96                  attributes = 'attributes: %s'%(self.__inst.attributes)
     97                  self.writer( ' ' * curr_level * self.INDENT_SIZE + attributes)
     98              if self.__inst.demangled:
     99                  demangled = 'demangled: %s'%(self.__inst.demangled)
    100                  self.writer( ' ' * curr_level * self.INDENT_SIZE + demangled)
    101              if self.__inst.mangled:
    102                  mangled = 'mangled: %s'%(self.__inst.mangled)
    103                  self.writer( ' ' * curr_level * self.INDENT_SIZE + mangled)
    104
    105
    106
    107 -    def print_calldef_info(self, decl=None):
    108          """ Returns function signature: [retval, [arg1, ..., argN]]. """
    109          if None is decl:
    110              decl = self.__inst
    111
    112          retval = None
    113          if decl.return_type:
    114              retval = decl.return_type.decl_string
    115          args = []
    116          for arg in decl.arguments:
    117              args.append(arg.type.decl_string + ' ' + arg.name)
    118          indent = ' ' * (self.level+1) * self.INDENT_SIZE
    119          self.writer( indent + "return type: " + str(retval) )
    120          self.writer( indent + "arguments type: " + ', '.join(args))
    121          if isinstance( decl, calldef.member_calldef_t ):
    122              self.writer( indent + "virtual: " + str(decl.virtuality))
    123              self.writer( indent + "is const: " + str(decl.has_const))
    124              self.writer( indent + "is static: " + str(decl.has_static))
    125
    126 -    def visit_member_function( self ):
    127          self.print_decl_header()
    128          self.print_calldef_info()
    129
    130 -    def visit_constructor( self ):
    131          self.print_decl_header()
    132          self.print_calldef_info()
    133
    134          if self.__print_details:
    135              self.writer( ' ' * ( self.level + 1 ) * self.INDENT_SIZE
    136                           + 'copy constructor: ' + str(self.__inst.is_copy_constructor) )
    137
    138 -    def visit_destructor( self ):
    139          self.print_decl_header()
    140
    141 -    def visit_member_operator( self ):
    142          self.print_decl_header()
    143          self.print_calldef_info()
    144
    145 -    def visit_casting_operator( self ):
    146          self.print_decl_header()
    147          self.print_calldef_info()
    148
    149 -    def visit_free_function( self ):
    150          self.print_decl_header()
    151          self.print_calldef_info()
    152
    153 -    def visit_free_operator( self ):
    154          self.print_decl_header()
    155          self.print_calldef_info()
    156
    157 -    def visit_class_declaration(self ):
    158          self.print_decl_header()
    159
    160 -    def visit_class(self ):
    161          self.print_decl_header()
    162          curr_level = self.level + 1
    163          class_type = 'class type: ' + "'%s'" % str(self.__inst.class_type)
    164          self.writer( ' ' * curr_level * self.INDENT_SIZE + class_type.ljust( self.JUSTIFY ))
    165          if self.__print_details:
    166              byte_size = 'size: %d'%(self.__inst.byte_size)
    167              self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_size.ljust( self.JUSTIFY ))
    168              try:
    169                  byte_align = 'align: %d'%(self.__inst.byte_align)
    170                  self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_align.ljust( self.JUSTIFY ))
    171              except NotImplementedError:
    172                  self.writer( ' ' * curr_level * self.INDENT_SIZE + "align: not implemented".ljust( self.JUSTIFY ))
    173
    174          if self.__inst.aliases:
    175              aliases = map( lambda typedef: typedef.name, self.__inst.aliases )
    176              aliases.sort()
    177              msg = 'aliases: ' + `aliases`
    178              self.writer( ' ' * curr_level * self.INDENT_SIZE + msg.ljust( self.JUSTIFY ))
    179
    180          def print_hierarchy(hierarchy_type, classes, curr_level):
    181              self.writer( ' ' * curr_level * self.INDENT_SIZE + hierarchy_type.ljust( self.JUSTIFY ))
    182              curr_level += 1
    183              for class_ in classes:
    184                  class_str = 'class: ' + "'%s'" % str(class_.related_class.decl_string)
    185                  self.writer( ' ' * curr_level * self.INDENT_SIZE + class_str.ljust( self.JUSTIFY ))
    186                  access = 'access type: ' + "'%s'" % str(class_.access)
    187                  self.writer( ' ' * (curr_level + 1)* self.INDENT_SIZE + access.ljust( self.JUSTIFY ))
    188                  if not ( None is class_.is_virtual ):
    189                      is_virtual = 'virtual inheritance: ' + "'%s'" % str(class_.is_virtual)
    190                      self.writer( ' ' * (curr_level + 1)* self.INDENT_SIZE + is_virtual.ljust( self.JUSTIFY ))
    191
    192          def print_members(members_type, members, curr_level):
    193              self.writer( ' ' * curr_level * self.INDENT_SIZE + members_type.ljust( self.JUSTIFY ))
    194              if self.__recursive:
    195                 curr_level += 1
    196                 for member in members:
    197                    prn = self.clone()
    198                    prn.instance = member
    199                    algorithm.apply_visitor( prn, member )
    200
    201          if self.__inst.bases:
    202              print_hierarchy( 'base classes: ', self.__inst.bases, curr_level )
    203
    204          if self.__inst.derived:
    205              print_hierarchy( 'derived classes: ', self.__inst.derived, curr_level )
    206
    207          print_members( 'public: ', self.__inst.public_members, curr_level )
    208          print_members( 'protected: ', self.__inst.protected_members, curr_level )
    209          print_members( 'private: ', self.__inst.private_members, curr_level )
    210
    211 -    def visit_enumeration(self):
    212          self.print_decl_header()
    213          curr_level = self.level + 1
    214          self.writer( ' ' * curr_level * self.INDENT_SIZE + 'values:'.ljust( self.JUSTIFY ) )
    215          value_level = ' ' * ( curr_level + 1 )* self.INDENT_SIZE
    216          self.writer( os.linesep )
    217          for name, value in self.__inst.values:
    218              self.writer( value_level + "%s : %s"% (name, value))
    219
    220 -    def visit_namespace(self ):
    221          self.print_decl_header()
    222          if self.__recursive:
    223             for decl in self.__inst.declarations:
    224                prn = self.clone()
    225                prn.instance = decl
    226                algorithm.apply_visitor( prn, decl )
    227
    228 -    def visit_typedef(self ):
    229          self.print_decl_header()
    230          curr_level = self.level + 1
    231          self.writer( ' ' * curr_level * self.INDENT_SIZE + 'alias to: ' + self.__inst.type.decl_string)
    232
    233 -    def visit_variable(self ):
    234          self.print_decl_header()
    235          curr_level = self.level + 1
    236          self.writer( ' ' * curr_level * self.INDENT_SIZE + 'type: %s  value: %s'%(self.__inst.type.decl_string, self.__inst.value)  + os.linesep)
    237          if self.__print_details:
    238              byte_size = 'size: %d'%(self.__inst.type.byte_size)
    239              self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_size.ljust( self.JUSTIFY ))
    240              try:
    241                  byte_align = 'align: %d'%(self.__inst.type.byte_align)
    242                  self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_align.ljust( self.JUSTIFY ))
    243              except NotImplementedError:
    244                  self.writer( ' ' * curr_level * self.INDENT_SIZE + "align: not implemented".ljust( self.JUSTIFY ))
    245              byte_offset = 'offset: %d'%(self.__inst.byte_offset)
    246              self.writer( ' ' * curr_level * self.INDENT_SIZE + byte_offset + os.linesep)
    247
    248 -def print_declarations( decls, detailed=True, recursive=True, writer=lambda x: sys.stdout.write( x + os.linesep ) ):
    249      """ Print decl tree rooted at each of the included nodes.
    250          decls - either a single decl or a list of decls.
    251      """
    252      prn = decl_printer_t(0, detailed, recursive, writer)
    253      if type(decls) is not list:
    254         decls = [decls]
    255      for d in decls:
    256         prn.level = 0
    257         prn.instance = d
    258         algorithm.apply_visitor(prn, d)
    259