Package pyplusplus :: Package module_creator :: Module creator

# Source Code for Module pyplusplus.module_creator.creator

      1  # Copyright 2004-2008 Roman Yakovenko.
      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  import types_database
      7  import creators_wizard
      8  import sort_algorithms
      9  import dependencies_manager
     10  import opaque_types_manager
     11  import call_policies_resolver
     12  import fake_constructors_manager
     13
     14  from pygccxml import declarations
     15  from pyplusplus import decl_wrappers
     16  from pyplusplus import code_creators
     17  from pyplusplus import code_repository
     18  from pyplusplus import _logging_
     19
     20  ACCESS_TYPES = declarations.ACCESS_TYPES
     21  VIRTUALITY_TYPES = declarations.VIRTUALITY_TYPES
     22
     23 -class creator_t( declarations.decl_visitor_t ):
     24      """Creating code creators.
     25
     26      This class takes a set of declarations as input and creates a code
     27      creator tree that contains the Boost.Python C++ source code for the
     28      final extension module. Each node in the code creators tree represents
     29      a block of text (C++ source code).
     30
     31      Usage of this class: Create an instance and pass all relevant input
     32      data to the constructor. Then call L{create()} to obtain the code
     33      creator tree whose root node is a L{module_t<code_creators.module_t>}
     34      object representing the source code for the entire extension module.
     35      """
     36
     37 -    def __init__( self
     38                    , decls
     39                    , module_name
     40                    , boost_python_ns_name='bp'
     41                    , call_policies_resolver_=None
     42                    , types_db=None
     43                    , target_configuration=None
     44                    , enable_indexing_suite=True
     45                    , doc_extractor=None ):
     46          """Constructor.
     47
     48          @param decls: Declarations that should be exposed in the final module.
     49          @param module_name: The name of the final module.
     50          @param boost_python_ns_name: The alias for the boost::python namespace.
     51          @param call_policies_resolver_: Callable that takes one declaration (calldef_t) as input and returns a call policy object which should be used for this declaration.
     52          @param types_db: ...todo...
     53          @param target_configuration: A target configuration object can be used to customize the generated source code to a particular compiler or a particular version of Boost.Python.
     54          @param doc_extractor: callable, that takes as argument declaration reference and returns documentation string
     55          @param already_exposed_dbs: list of files/directories other modules, this module depends on, generated their code too
     56          @type decls: list of declaration_t
     57          @type module_name: str
     58          @type boost_python_ns_name: str
     59          @type call_policies_resolver_: callable
     60          @type types_db: L{types_database_t<types_database.types_database_t>}
     61          @type target_configuration: L{target_configuration_t<code_creators.target_configuration_t>}
     62          @type doc_extractor: callable
     63          @type already_exposed_dbs: list of strings
     64          """
     65          declarations.decl_visitor_t.__init__(self)
     66          self.logger = _logging_.loggers.module_builder
     67          self.decl_logger = _logging_.loggers.declarations
     68
     69          self.__enable_indexing_suite = enable_indexing_suite
     70          self.__target_configuration = target_configuration
     71          if not self.__target_configuration:
     72              self.__target_configuration = code_creators.target_configuration_t()
     73
     74          self.__call_policies_resolver = call_policies_resolver_
     75          if not self.__call_policies_resolver:
     76              self.__call_policies_resolver \
     77                  = call_policies_resolver.built_in_resolver_t(self.__target_configuration)
     78
     79          self.__types_db = types_db
     80          if not self.__types_db:
     81              self.__types_db = types_database.types_database_t()
     82
     83          global_ns = declarations.get_global_namespace(decls)
     84          self.__extmodule = code_creators.module_t( global_ns )
     85          if boost_python_ns_name:
     86              bp_ns_alias = code_creators.namespace_alias_t( alias=boost_python_ns_name
     87                                                             , full_namespace_name='::boost::python' )
     88              self.__extmodule.adopt_creator( bp_ns_alias )
     89
     90          self.__module_body = code_creators.module_body_t( name=module_name )
     91
     92          self.__extmodule.adopt_creator( self.__module_body )
     93
     94          self.__opaque_types_manager = opaque_types_manager.manager_t( self.__extmodule )
     95          self.__dependencies_manager = dependencies_manager.manager_t(self.decl_logger)
     96
     97          prepared_decls = self._prepare_decls( decls, doc_extractor )
     98          self.__decls = sort_algorithms.sort( prepared_decls )
     99
    100          self.curr_code_creator = self.__module_body
    101          self.curr_decl = None
    102          self.__array_1_registered = set() #(type.decl_string,size)
    103          self.__free_operators = []
    104          self.__exposed_free_fun_overloads = set()
    105          self.__fc_manager = fake_constructors_manager.manager_t( global_ns )
    106
    107 -    def __print_readme( self, decl ):
    108          readme = decl.readme()
    109          if not readme:
    110              return
    111
    112          if not decl.exportable:
    113              reason = readme[0]
    114              readme = readme[1:]
    115              self.decl_logger.warn( "%s;%s" % ( decl, reason ) )
    116
    117          for msg in readme:
    118              self.decl_logger.warn( "%s;%s" % ( decl, msg ) )
    119
    120 -    def _prepare_decls( self, decls, doc_extractor ):
    121          to_be_exposed = []
    122          for decl in declarations.make_flatten( decls ):
    123              if decl.ignore:
    124                  continue
    125
    126              if isinstance( decl, declarations.namespace_t ):
    127                  continue
    128
    129              if not decl.exportable:
    130                  #leave only decls that user wants to export and that could be exported
    131                  self.__print_readme( decl )
    132                  continue
    133
    134              if decl.already_exposed:
    135                  #check wether this is already exposed in other module
    136                  continue
    137
    138              if isinstance( decl.parent, declarations.namespace_t ):
    139                  #leave only declarations defined under namespace, but remove namespaces
    140                  to_be_exposed.append( decl )
    141
    142              #Right now this functionality introduce a bug: declarations that should
    143              #not be exported for some reason are not marked as such. I will need to
    144              #find out.
    145              #if isinstance( decl, declarations.calldef_t ) and not isinstance( decl, declarations.destructor_t ):
    146                  #self.__types_db.update( decl )
    147                  #if None is decl.call_policies:
    148                      #decl.call_policies = self.__call_policies_resolver( decl )
    149
    150              #if isinstance( decl, declarations.variable_t ):
    151                  #self.__types_db.update( decl )
    152
    153              if doc_extractor:
    154                  decl.documentation = doc_extractor( decl )
    155
    156              self.__print_readme( decl )
    157
    158          return to_be_exposed
    159
    160 -    def _adopt_free_operator( self, operator ):
    161          def adopt_operator_impl( operator, found_creators ):
    162              creator = filter( lambda creator: isinstance( creator, code_creators.class_t )
    163                                , found_creators )
    164              if len(creator) == 1:
    165                  creator = creator[0]
    166                  #I think I don't need this condition any more
    167                  if not find( lambda creator: isinstance( creator, code_creators.declaration_based_t )
    168                                               and operator is creator.declaration
    169                               , creator.creators ):
    170                      #expose operator only once
    171                      self.__dependencies_manager.add_exported( operator )
    172                      creator.adopt_creator( code_creators.operator_t( operator=operator ) )
    173              elif not creator:
    174                  pass
    175              else:
    176                  assert not "Found %d class code creators" % len(creator)
    177          find = code_creators.creator_finder.find_by_declaration
    178          if isinstance( operator.parent, declarations.class_t ):
    179              found = find( lambda decl: operator.parent is decl
    180                            , self.__extmodule.body.creators )
    181              adopt_operator_impl( operator, found )
    182          else:
    183              #select all to be exposed declarations
    184              included = filter( lambda decl: decl.ignore == False, operator.class_types )
    185              if not included:
    186                  msg = 'Py++ bug found!' \
    187                        ' For some reason Py++ decided to expose free operator "%s", when all class types related to the operator definition are excluded.' \
    188                        ' Please report this bug. Thanks! '
    189                  raise RuntimeError( msg % str( operator ) )
    190
    191              found = find( lambda decl: included[0] is decl, self.__extmodule.body.creators )
    192              adopt_operator_impl( operator, found )
    193
    194 -    def _is_registered_smart_pointer_creator( self, creator, db ):
    195          for registered in db:
    196              if not isinstance( creator, registered.__class__ ):
    197                  continue
    198              elif registered.smart_ptr != creator.smart_ptr:
    199                  continue
    200              elif isinstance( creator, code_creators.smart_pointer_registrator_t ):
    201                  if creator.declaration is registered.declaration:
    202                      return True
    203              elif isinstance( creator, code_creators.smart_pointers_converter_t ):
    204                  if ( creator.source is registered.source ) \
    205                     and ( creator.target is registered.target ):
    206                      return True
    207              else:
    208                  assert not "unknown instace of registrator: " % str( registered )
    209
    210 -    def _treat_smart_pointers( self ):
    211          """ Go to all class creators and apply held_type and creator registrators
    212              as needed.
    213          """
    214          find_classes = code_creators.creator_finder.find_by_class_instance
    215          class_creators = find_classes( what=code_creators.class_t
    216                                         , where=self.__extmodule.body.creators
    217                                         , recursive=True )
    218          registrators_db = []
    219          for creator in class_creators:
    220              if None is creator.held_type:
    221                  if not creator.declaration.is_abstract:
    222                      creator.held_type = self.__types_db.create_holder( creator.declaration )
    223              registrators = self.__types_db.create_registrators( creator )
    224              for r in registrators:
    225                  if not self._is_registered_smart_pointer_creator( r, registrators_db ):
    226                      creator.adopt_creator(r)
    227                      registrators_db.append(r)
    228
    229 -    def _append_user_code( self ):
    230          find_classes = code_creators.creator_finder.find_by_class_instance
    231          class_creators = find_classes( what=code_creators.class_t
    232                                         , where=self.__extmodule.body.creators
    233                                         , recursive=True )
    234
    235          ctext_t = code_creators.custom_text_t
    236          for cls_creator in class_creators:
    237              cls_decl = cls_creator.declaration
    238
    239              uc_creators_head = map( lambda uc: ctext_t( uc.text, uc.works_on_instance )
    240                                      , cls_decl.registration_code_head )
    241              cls_creator.adopt_creators( uc_creators_head, 0 )
    242
    243              uc_creators_tail = map( lambda uc: ctext_t( uc.text, uc.works_on_instance )
    244                                      , cls_decl.registration_code_tail )
    245              cls_creator.adopt_creators( uc_creators_tail )
    246
    247              uc_creators = map( lambda uc: ctext_t( uc.text ), cls_decl.wrapper_code )
    248              if uc_creators:
    249                  cls_creator.wrapper.adopt_creators( uc_creators )
    250
    251              uc_creators = map( lambda uc: ctext_t( uc.text ), cls_decl.declaration_code )
    252              insert_pos = self.__extmodule.creators.index( self.__module_body )
    253              self.__extmodule.adopt_creators( uc_creators, insert_pos )
    254              cls_creator.associated_decl_creators.extend( uc_creators )
    255
    256 -    def __get_exposed_containers(self):
    257          """list of exposed declarations, which were not ``included``, but still
    258          were exposed. For example, std containers
    259
    260          std containers exposed by Py++, even if the user didn't ``include`` them.
    261          """
    262          cmp_by_name = lambda cls1, cls2: cmp( cls1.decl_string, cls2.decl_string )
    263          used_containers = list( self.__types_db.used_containers )
    264          used_containers = filter( lambda cls: cls.indexing_suite.include_files
    265                                    , used_containers )
    266          used_containers.sort( cmp_by_name )
    267          used_containers = filter( lambda cnt: cnt.already_exposed == False
    268                                    , used_containers )
    269          return used_containers
    270
    271 -    def _treat_indexing_suite( self ):
    272          def create_explanation(cls):
    273              msg = '//WARNING: the next line of code will not compile, because "%s" does not have operator== !'
    274              msg = msg % cls.indexing_suite.element_type.decl_string
    275              return code_creators.custom_text_t( msg, False )
    276
    277          def create_cls_cc( cls ):
    278              if isinstance( cls, declarations.class_t ):
    279                  return code_creators.class_t( class_inst=cls )
    280              else:
    281                  return code_creators.class_declaration_t( class_inst=cls )
    282
    283          if not self.__types_db.used_containers:
    284              return
    285
    286          creators = []
    287          created_value_traits = set()
    288
    289          for cls in self.__get_exposed_containers():
    290              self.__print_readme( cls )
    291
    292              cls_creator = create_cls_cc( cls )
    293              self.__dependencies_manager.add_exported( cls )
    294              creators.append( cls_creator )
    295              try:
    296                  element_type = cls.indexing_suite.element_type
    297              except:
    298                  element_type = None
    299
    300              if isinstance( cls.indexing_suite, decl_wrappers.indexing_suite1_t ):
    301                  if not ( None is element_type ) \
    302                     and declarations.is_class( element_type ) \
    303                     and not declarations.has_public_equal( element_type ):
    304                      cls_creator.adopt_creator( create_explanation( cls ) )
    305                  cls_creator.adopt_creator( code_creators.indexing_suite1_t(cls) )
    306              else:
    307                  class_traits = declarations.class_traits
    308                  if not ( None is element_type ) and class_traits.is_my_case( element_type ):
    309                      value_cls = class_traits.get_declaration( element_type )
    310                      has_prerequisits = value_cls.less_than_comparable \
    311                                         and value_cls.equality_comparable
    312                      if ( not has_prerequisits ) and ( value_cls not in created_value_traits ):
    313                          created_value_traits.add( value_cls )
    314                          element_type_cc = code_creators.value_traits_t( value_cls )
    315                          self.__extmodule.adopt_declaration_creator( element_type_cc )
    316                  cls_creator.adopt_creator( code_creators.indexing_suite2_t(cls) )
    317
    318          creators.reverse()
    319          self.__module_body.adopt_creators( creators, 0 )
    320
    321 -    def create(self, decl_headers=None):
    322          """Create and return the module for the extension.
    323
    324          @param decl_headers: If None the headers for the wrapped decls are automatically found.
    325          But you can pass a list of headers here to override that search.
    326          @returns: Returns the root of the code creators tree
    327          @rtype: L{module_t<code_creators.module_t>}
    328          """
    329          # Invoke the appropriate visit_*() method on all decls
    330          for decl in self.__decls:
    331              self.curr_decl = decl
    332              declarations.apply_visitor( self, decl )
    333          for operator in self.__free_operators:
    334              self._adopt_free_operator( operator )
    335          self._treat_smart_pointers()
    336          if self.__enable_indexing_suite:
    337              self._treat_indexing_suite()
    338          for creator in code_creators.make_flatten_generator( self.__extmodule ):
    339              creator.target_configuration = self.__target_configuration
    340          #last action.
    341          self._append_user_code()
    342
    343          add_include = self.__extmodule.add_include
    344          #add system headers
    345          system_headers = self.__extmodule.get_system_headers( recursive=True, unique=True )
    346          map( lambda header: add_include( header, user_defined=False, system=True )
    347               , system_headers )
    348          #add user defined header files
    349          if decl_headers is None:
    350              decl_headers = declarations.declaration_files( self.__decls )
    351          map( lambda header: add_include( header, user_defined=False, system=False )
    352               , decl_headers )
    353
    354          self.__dependencies_manager.inform_user()
    355
    356          return self.__extmodule
    357
    358 -    def visit_member_function( self ):
    359          self.__types_db.update( self.curr_decl )
    360          self.__dependencies_manager.add_exported( self.curr_decl )
    361
    362          if self.__fc_manager.is_fake_constructor( self.curr_decl ):
    363              return
    364
    365          fwrapper = None
    366          if None is self.curr_decl.call_policies:
    367              self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl )
    368
    369          maker_cls, fwrapper_cls = creators_wizard.find_out_mem_fun_creator_classes( self.curr_decl )
    370
    371          maker = None
    372          fwrapper = None
    373          if fwrapper_cls:
    374              fwrapper = fwrapper_cls( function=self.curr_decl )
    375              if fwrapper_cls is code_creators.mem_fun_transformed_wrapper_t:
    376                  if self.curr_code_creator.wrapper:
    377                      class_wrapper = self.curr_code_creator.wrapper
    378                      class_wrapper.adopt_creator( fwrapper )
    379                  else:
    380                      self.__extmodule.adopt_declaration_creator( fwrapper )
    381                      self.curr_code_creator.associated_decl_creators.append(fwrapper)
    382              else:
    383                  class_wrapper = self.curr_code_creator.wrapper
    384                  class_wrapper.adopt_creator( fwrapper )
    385
    386          if maker_cls:
    387              if fwrapper:
    388                  maker = maker_cls( function=self.curr_decl, wrapper=fwrapper )
    389              else:
    390                  maker = maker_cls( function=self.curr_decl )
    391              self.curr_code_creator.adopt_creator( maker )
    392              self.__opaque_types_manager.register_opaque( maker, self.curr_decl )
    393
    394          if self.curr_decl.has_static:
    395              #static_method should be created only once.
    396              found = filter( lambda creator: isinstance( creator, code_creators.static_method_t )
    397                                              and creator.declaration.name == self.curr_decl.name
    398                                       , self.curr_code_creator.creators )
    399              if not found:
    400                  static_method = code_creators.static_method_t( function=self.curr_decl
    401                                                                 , function_code_creator=maker )
    402                  self.curr_code_creator.adopt_creator( static_method )
    403
    404 -    def visit_constructor( self ):
    405          self.__types_db.update( self.curr_decl )
    406          self.__dependencies_manager.add_exported( self.curr_decl )
    407
    408          cwrapper = None
    409          if self.curr_decl.parent.is_wrapper_needed():
    410              class_wrapper = self.curr_code_creator.wrapper
    411              cwrapper = code_creators.constructor_wrapper_t( constructor=self.curr_decl )
    412              class_wrapper.adopt_creator( cwrapper )
    413          #TODO: FT for constructor
    414              #~ if self.curr_decl.transformations:
    415                  #~ cwrapper = code_creators.constructor_transformed_wrapper_t( constructor=self.curr_decl )
    416                  #~ class_wrapper.adopt_creator( cwrapper )
    417          #~ else:
    418              #~ if self.curr_decl.transformations:
    419                  #~ cwrapper = code_creators.constructor_transformed_wrapper_t( constructor=self.curr_decl )
    420                  #~ class_wrapper.adopt_creator( cwrapper )
    421                  #~ self.__module_body.adopt_creator( cwrapper )
    422                  #~ self.curr_code_creator.associated_decl_creators.append( cwrapper )
    423          #~ maker = None
    424          #~ if self.curr_decl.transformations:
    425              #~ maker = code_creators.constructor_transformed_t( constructor=self.curr_decl )
    426          #~ else:
    427          maker = code_creators.constructor_t( constructor=self.curr_decl, wrapper=cwrapper )
    428          if None is self.curr_decl.call_policies:
    429              self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl )
    430          self.curr_code_creator.adopt_creator( maker )
    431
    432          if self.curr_decl.allow_implicit_conversion:
    433              maker = code_creators.casting_constructor_t( constructor=self.curr_decl )
    434              #casting constructor will be generated in the same file as class
    435              self.curr_code_creator.adopt_creator( maker )
    436
    437
    438 -    def visit_destructor( self ):
    439          pass
    440
    441 -    def visit_member_operator( self ):
    442          if self.curr_decl.symbol in ( '()', '[]', '=' ):
    443              self.visit_member_function()
    444          else:
    445              self.__types_db.update( self.curr_decl )
    446              maker = code_creators.operator_t( operator=self.curr_decl )
    447              self.curr_code_creator.adopt_creator( maker )
    448              self.__dependencies_manager.add_exported( self.curr_decl )
    449
    450 -    def visit_casting_operator( self ):
    451          self.__dependencies_manager.add_exported( self.curr_decl )
    452          if None is self.curr_decl.call_policies:
    453              self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl )
    454
    455          self.__types_db.update( self.curr_decl )
    456          if not self.curr_decl.parent.is_abstract and not declarations.is_reference( self.curr_decl.return_type ):
    457              maker = code_creators.casting_operator_t( operator=self.curr_decl )
    458              self.__module_body.adopt_creator( maker )
    459              self.__opaque_types_manager.register_opaque( maker, self.curr_decl )
    460
    461          #what to do if class is abstract
    462          maker = code_creators.casting_member_operator_t( operator=self.curr_decl )
    463          self.curr_code_creator.adopt_creator( maker )
    464          self.__opaque_types_manager.register_opaque( maker, self.curr_decl )
    465
    466 -    def visit_free_function( self ):
    467          if self.curr_decl in self.__exposed_free_fun_overloads:
    468              return
    469
    470          if self.__fc_manager.is_fake_constructor( self.curr_decl ):
    471              self.__types_db.update( self.curr_decl )
    472              self.__dependencies_manager.add_exported( self.curr_decl )
    473              return
    474
    475          elif self.curr_decl.use_overload_macro:
    476              parent_decl = self.curr_decl.parent
    477              names = set( map( lambda decl: decl.name
    478                                , parent_decl.free_functions( allow_empty=True, recursive=False ) ) )
    479              for name in names:
    480                  overloads = parent_decl.free_functions( name, allow_empty=True, recursive=False )
    481                  overloads = filter( lambda decl: decl.ignore == False and decl.use_overload_macro, overloads )
    482                  if not overloads:
    483                      continue
    484                  else:
    485                      self.__exposed_free_fun_overloads.update( overloads )
    486                      for f in overloads:
    487                          self.__types_db.update( f )
    488                          self.__dependencies_manager.add_exported( f )
    489                          if None is f.call_policies:
    490                              f.call_policies = self.__call_policies_resolver( f )
    491
    492                      overloads_cls_creator = code_creators.free_fun_overloads_class_t( overloads )
    493                      self.__extmodule.adopt_declaration_creator( overloads_cls_creator )
    494
    495                      overloads_reg = code_creators.free_fun_overloads_t( overloads_cls_creator )
    496                      self.curr_code_creator.adopt_creator( overloads_reg )
    497                      overloads_reg.associated_decl_creators.append( overloads_cls_creator )
    498                      self.__opaque_types_manager.register_opaque( overloads_reg, overloads )
    499
    500                      ctext_t = code_creators.custom_text_t
    501                      for f in overloads:
    502                          uc_creators = map( lambda uc: ctext_t( uc.text ), f.declaration_code )
    503                          insert_pos = self.__extmodule.creators.index( self.__module_body )
    504                          self.__extmodule.adopt_creators( uc_creators, insert_pos )
    505                          overloads_reg.associated_decl_creators.extend( uc_creators )
    506          else:
    507              self.__types_db.update( self.curr_decl )
    508              self.__dependencies_manager.add_exported( self.curr_decl )
    509              if None is self.curr_decl.call_policies:
    510                  self.curr_decl.call_policies = self.__call_policies_resolver( self.curr_decl )
    511
    512              maker = None
    513              if self.curr_decl.transformations:
    514                  wrapper = code_creators.free_fun_transformed_wrapper_t( self.curr_decl )
    515                  self.__extmodule.adopt_declaration_creator( wrapper )
    516                  maker = code_creators.free_fun_transformed_t( self.curr_decl, wrapper )
    517                  maker.associated_decl_creators.append( wrapper )
    518              else:
    519                  maker = code_creators.free_function_t( function=self.curr_decl )
    520              self.curr_code_creator.adopt_creator( maker )
    521              self.__opaque_types_manager.register_opaque( maker, self.curr_decl )
    522
    523              ctext_t = code_creators.custom_text_t
    524              uc_creators = map( lambda uc: ctext_t( uc.text ), self.curr_decl.declaration_code )
    525              insert_pos = self.__extmodule.creators.index( self.__module_body )
    526              self.__extmodule.adopt_creators( uc_creators, insert_pos )
    527              maker.associated_decl_creators.extend( uc_creators )
    528
    529 -    def visit_free_operator( self ):
    530          self.__types_db.update( self.curr_decl )
    531          self.__free_operators.append( self.curr_decl )
    532
    533 -    def visit_class_declaration(self ):
    534          pass
    535
    536 -    def expose_overloaded_mem_fun_using_macro( self, cls, cls_creator ):
    537          #returns set of exported member functions
    538          exposed = set()
    539          names = set( map( lambda decl: decl.name
    540                            , cls.member_functions( allow_empty=True, recursive=False ) ) )
    541          for name in names:
    542              overloads = cls.member_functions( name, allow_empty=True, recursive=False )
    543              overloads = filter( lambda decl: decl.ignore == False and decl.use_overload_macro
    544                                  , overloads )
    545              if not overloads:
    546                  continue
    547              else:
    548                  exposed.update( overloads )
    549
    550                  for f in overloads:
    551                      self.__types_db.update( f )
    552                      self.__dependencies_manager.add_exported( f )
    553                      if None is f.call_policies:
    554                          f.call_policies = self.__call_policies_resolver( f )
    555
    556                  overloads_cls_creator = code_creators.mem_fun_overloads_class_t( overloads )
    557                  self.__extmodule.adopt_declaration_creator( overloads_cls_creator )
    558
    559                  overloads_reg = code_creators.mem_fun_overloads_t( overloads_cls_creator )
    560                  cls_creator.adopt_creator( overloads_reg )
    561                  overloads_reg.associated_decl_creators.append( overloads_cls_creator )
    562
    563                  self.__opaque_types_manager.register_opaque( overloads_reg, overloads )
    564          return exposed
    565
    566 -    def visit_class(self ):
    567          self.__dependencies_manager.add_exported( self.curr_decl )
    568          cls_decl = self.curr_decl
    569          cls_parent_cc = self.curr_code_creator
    570          exportable_members = self.curr_decl.get_exportable_members(sort_algorithms.sort)
    571
    572          wrapper = None
    573          cls_cc = None
    574          if cls_decl.introduces_new_scope:
    575              cls_cc = code_creators.class_t( class_inst=self.curr_decl )
    576          else:
    577              cls_cc = self.curr_code_creator
    578
    579          if self.curr_decl.is_wrapper_needed():
    580              wrapper = code_creators.class_wrapper_t( declaration=self.curr_decl
    581                                                       , class_creator=cls_cc )
    582              cls_cc.wrapper = wrapper
    583              cls_cc.associated_decl_creators.append( wrapper )
    584              #insert wrapper before module body
    585              if isinstance( self.curr_decl.parent, declarations.class_t ):
    586                  #we deal with internal class
    587                  self.curr_code_creator.wrapper.adopt_creator( wrapper )
    588              else:
    589                  self.__extmodule.adopt_declaration_creator( wrapper )
    590
    591              #next constructors are not present in code, but compiler generated
    592              #Boost.Python requiers them to be declared in the wrapper class
    593              noncopyable_vars = self.curr_decl.find_noncopyable_vars()
    594
    595              copy_constr = self.curr_decl.find_copy_constructor()
    596              if not self.curr_decl.noncopyable and copy_constr and copy_constr.is_artificial:
    597                  cccc = code_creators.copy_constructor_wrapper_t( constructor=copy_constr)
    598                  wrapper.adopt_creator( cccc )
    599
    600              trivial_constr = self.curr_decl.find_trivial_constructor()
    601              if trivial_constr and trivial_constr.is_artificial and not noncopyable_vars:
    602                  tcons = code_creators.null_constructor_wrapper_t( constructor=trivial_constr )
    603                  wrapper.adopt_creator( tcons )
    604
    605          exposed = self.expose_overloaded_mem_fun_using_macro( cls_decl, cls_cc )
    606
    607          if cls_decl.introduces_new_scope:
    608              cls_parent_cc.adopt_creator( cls_cc )
    609          self.curr_code_creator = cls_cc
    610
    611          if cls_decl.expose_this:
    612              cls_cc.adopt_creator( code_creators.expose_this_t( cls_decl ) )
    613
    614          if cls_decl.expose_sizeof:
    615              cls_cc.adopt_creator( code_creators.expose_sizeof_t( cls_decl ) )
    616
    617          for decl in exportable_members:
    618              if decl in exposed:
    619                  continue
    620              self.curr_decl = decl
    621              declarations.apply_visitor( self, decl )
    622
    623          for redefined_func in cls_decl.redefined_funcs():
    624              if isinstance( redefined_func, declarations.operator_t ):
    625                  continue
    626              self.curr_decl = redefined_func
    627              declarations.apply_visitor( self, redefined_func )
    628
    629          #all static_methods_t should be moved to the end
    630          #better approach is to move them after last def of relevant function
    631          static_methods = filter( lambda creator: isinstance( creator, code_creators.static_method_t )
    632                                   , cls_cc.creators )
    633          for static_method in static_methods:
    634              cls_cc.remove_creator( static_method )
    635              cls_cc.adopt_creator( static_method )
    636
    637          if cls_decl.exception_translation_code:
    638              translator = code_creators.exception_translator_t( cls_decl )
    639              self.__extmodule.adopt_declaration_creator( translator )
    640              cls_cc.associated_decl_creators.append( translator )
    641              translator_register \
    642                  = code_creators.exception_translator_register_t( cls_decl, translator )
    643              cls_cc.adopt_creator( translator_register )
    644
    645          for property_def in cls_decl.properties:
    646              cls_cc.adopt_creator( code_creators.property_t(property_def) )
    647
    648          if wrapper and cls_decl.destructor_code:
    649              destructor = code_creators.destructor_wrapper_t( class_=cls_decl )
    650              wrapper.adopt_creator( destructor )
    651
    652          for fc in cls_decl.fake_constructors:
    653              if self.__fc_manager.should_generate_code( fc ):
    654                  self.__dependencies_manager.add_exported( fc )
    655                  cls_cc.adopt_creator( code_creators.make_constructor_t( fc ) )
    656
    657          self.curr_decl = cls_decl
    658          self.curr_code_creator = cls_parent_cc
    659
    660
    661 -    def visit_enumeration(self):
    662          self.__dependencies_manager.add_exported( self.curr_decl )
    663          maker = None
    664          if self.curr_decl.name:
    665              maker = code_creators.enum_t( enum=self.curr_decl )
    666          else:
    667              maker = code_creators.unnamed_enum_t( unnamed_enum=self.curr_decl )
    668          self.curr_code_creator.adopt_creator( maker )
    669
    670 -    def visit_namespace(self):
    671          pass
    672
    673 -    def visit_typedef(self):
    674          pass
    675
    676 -    def _register_array_1( self, array_type ):
    677          data = ( array_type.decl_string, declarations.array_size( array_type ) )
    678          if data in self.__array_1_registered:
    679              return False
    680          else:
    681              self.__array_1_registered.add( data )
    682              return True
    683
    684 -    def visit_variable(self):
    685          self.__types_db.update( self.curr_decl )
    686          self.__dependencies_manager.add_exported( self.curr_decl )
    687
    688          if self.curr_decl.expose_address:
    689              creator_type = None
    690              if isinstance( self.curr_decl.parent, declarations.namespace_t ):
    691                  creator_type = code_creators.global_variable_addressof_t
    692              else:
    693                  creator_type = code_creators.member_variable_addressof_t
    694              self.curr_code_creator.adopt_creator( creator_type(self.curr_decl) )
    695              return
    696
    697          if not self.curr_decl.expose_value:
    698              return
    699
    700          if declarations.is_array( self.curr_decl.type ):
    701              if self._register_array_1( self.curr_decl.type ):
    702                  array_1_registrator = code_creators.array_1_registrator_t( array_type=self.curr_decl.type )
    703                  self.curr_code_creator.adopt_creator( array_1_registrator )
    704
    705          if isinstance( self.curr_decl.parent, declarations.namespace_t ):
    706              maker = None
    707              wrapper = None
    708              if declarations.is_array( self.curr_decl.type ):
    709                  wrapper = code_creators.array_gv_wrapper_t( variable=self.curr_decl )
    710                  maker = code_creators.array_gv_t( variable=self.curr_decl, wrapper=wrapper )
    711              else:
    712                  maker = code_creators.global_variable_t( variable=self.curr_decl )
    713              if wrapper:
    714                  self.__extmodule.adopt_declaration_creator( wrapper )
    715          else:
    716              maker = None
    717              wrapper = None
    718              if self.curr_decl.bits != None:
    719                  wrapper = code_creators.bit_field_wrapper_t( variable=self.curr_decl )
    720                  maker = code_creators.bit_field_t( variable=self.curr_decl, wrapper=wrapper )
    721              elif declarations.is_array( self.curr_decl.type ):
    722                  wrapper = code_creators.array_mv_wrapper_t( variable=self.curr_decl )
    723                  maker = code_creators.array_mv_t( variable=self.curr_decl, wrapper=wrapper )
    724              elif declarations.is_pointer( self.curr_decl.type ):
    725                  wrapper = code_creators.member_variable_wrapper_t( variable=self.curr_decl )
    726                  maker = code_creators.member_variable_t( variable=self.curr_decl, wrapper=wrapper )
    727              elif declarations.is_reference( self.curr_decl.type ):
    728                  if None is self.curr_decl.getter_call_policies:
    729                      self.curr_decl.getter_call_policies = self.__call_policies_resolver( self.curr_decl, 'get' )
    730                  if None is self.curr_decl.setter_call_policies:
    731                      self.curr_decl.setter_call_policies = self.__call_policies_resolver( self.curr_decl, 'set' )
    732                  wrapper = code_creators.mem_var_ref_wrapper_t( variable=self.curr_decl )
    733                  maker = code_creators.mem_var_ref_t( variable=self.curr_decl, wrapper=wrapper )
    734                  self.__opaque_types_manager.register_opaque( maker, self.curr_decl )
    735              else:
    736                  maker = code_creators.member_variable_t( variable=self.curr_decl )
    737              if wrapper:
    738                  self.curr_code_creator.wrapper.adopt_creator( wrapper )
    739          self.curr_code_creator.adopt_creator( maker )
    740