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