Trees | Indices | Help |
|
---|
|
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 os 7 import types 8 import scoped 9 import calldef 10 import algorithm 11 import smart_pointers 12 import declaration_based 13 import registration_based 14 from pygccxml import declarations8719 scoped.scoped_t.__init__( self, declaration=class_inst ) 20 registration_based.registration_based_t.__init__( self ) 21 self.works_on_instance = False2224 class_identifier = algorithm.create_identifier( self, '::boost::python::class_' ) 25 return declarations.templates.join( class_identifier, [self.decl_identifier] )2628 result = [] 29 result.append( self._generate_class_definition() + '("%s")' % self.declaration.alias ) 30 for x in self.creators: 31 code = x.create() 32 tmpl = '%s.%s' 33 if self.is_comment( code ): 34 tmpl = '%s%s' 35 result.append( self.indent( tmpl % ( os.linesep, code ) ) ) 36 result.append( ';' ) 37 return ''.join( result )38 39 @property 4244 if self.declaration.always_expose_using_scope: 45 return True 46 return bool( filter( lambda cc: not cc.works_on_instance, self.creators ) )47 48 @property50 return self.class_var_name + '_t'5153 result = [] 54 scope_var_name = self.alias + '_scope' 55 result.append( 'typedef ' + self._generate_class_definition() + ' ' + self.typedef_name + ';') 56 result.append( self.typedef_name + ' ' + self.class_var_name ) 57 result[-1] = result[-1] + ' = '+ self.typedef_name + '("%s");' % self.declaration.alias 58 59 result.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) 60 result[-1] = result[-1] + ' ' + scope_var_name 61 result[-1] = result[-1] + '( %s );' % self.class_var_name 62 63 for x in self.creators: 64 if not x.works_on_instance: 65 result.append( x.create() ) 66 else: 67 result.append( '%s.%s;' % ( self.class_var_name, x.create() ) ) 68 69 code = os.linesep.join( result ) 70 71 result = [ '{ //scope begin' ] 72 result.append( self.indent( code ) ) 73 result.append( '} //scope end' ) 74 75 return os.linesep.join( result )7678 if self.declaration.already_exposed: 79 return '' 80 if self.is_exposed_using_scope(): 81 return self._generate_code_with_scope() 82 else: 83 return self._generate_code_no_scope()8489 """ 90 Creates boost.python code that needed to export a class 91 """32593 scoped.scoped_t.__init__( self, declaration=class_inst ) 94 registration_based.registration_based_t.__init__( self ) 95 self._wrapper = wrapper 96 self.works_on_instance = False97 102 wrapper = property( _get_wrapper, _set_wrapper ) 103107 assert isinstance( held_type, types.NoneType ) \ 108 or isinstance( held_type, smart_pointers.held_type_t ) \ 109 or isinstance( held_type, types.StringTypes ) 110 if isinstance( held_type, types.StringTypes ): 111 assert held_type # should be non emptry string 112 self.declaration.held_type = held_type113 held_type = property( _get_held_type, _set_held_type ) 114116 if not self.declaration.bases: 117 return {}, {} 118 base_classes = {} 119 for hierarchy_info in self.declaration.recursive_bases: 120 if hierarchy_info.access_type == declarations.ACCESS_TYPES.PRIVATE: 121 continue 122 base_classes[ id( hierarchy_info.related_class ) ] = hierarchy_info 123 base_classes_size = len( base_classes ) 124 creators = {} 125 creators_len = 0 126 for creator in algorithm.make_flatten_generator( self.top_parent.body.creators ): 127 if isinstance( creator, class_t ) and id(creator.declaration) in base_classes: 128 creators[ id(creator.declaration) ] = creator 129 if len( creators ) == base_classes_size: 130 break #all classes has been found 131 return base_classes, creators132134 #May be in future I will redefine operators on wrapper class 135 #thus I will support [protected|private] [ [not|pure|] virtual] operators. 136 operator_creators = [] 137 for base_creator in base_creators.values(): 138 hierarchy_info = base_classes[ id( base_creator.declaration )] 139 if hierarchy_info.access_type != declarations.ACCESS_TYPES.PUBLIC: 140 continue 141 base_operator_creators = filter( lambda creator: 142 isinstance( creator, calldef.operator_t ) 143 and isinstance( creator.declaration, declarations.member_operator_t ) 144 and creator.declaration.access_type 145 == declarations.ACCESS_TYPES.PUBLIC 146 , base_creator.creators ) 147 operator_creators.extend( base_operator_creators ) 148 return operator_creators149151 noncopyable_vars = self.declaration.find_noncopyable_vars() 152 copy_constr = self.declaration.find_copy_constructor() 153 154 if self.declaration.noncopyable \ 155 or copy_constr and copy_constr.is_artificial and noncopyable_vars: 156 return algorithm.create_identifier( self, '::boost::noncopyable' )157159 bases = [] 160 assert isinstance( self.declaration, declarations.class_t ) 161 for base_desc in self.declaration.bases: 162 assert isinstance( base_desc, declarations.hierarchy_info_t ) 163 if base_desc.access != declarations.ACCESS_TYPES.PUBLIC: 164 continue 165 if base_creators.has_key( id(base_desc.related_class) ): 166 bases.append( algorithm.create_identifier( self, base_desc.related_class.partial_decl_string ) ) 167 elif base_desc.related_class.already_exposed: 168 bases.append( base_desc.related_class.partial_decl_string ) 169 if not bases: 170 return None 171 bases_identifier = algorithm.create_identifier( self, '::boost::python::bases' ) 172 return declarations.templates.join( bases_identifier, bases )173175 if isinstance( self.held_type, smart_pointers.held_type_t ): 176 return self.held_type.create( self ) 177 elif isinstance( self.held_type, types.StringTypes): 178 return self.held_type 179 else: 180 return None181183 class_identifier = algorithm.create_identifier( self, '::boost::python::class_' ) 184 args = [] 185 186 held_type = self._generated_held_type() 187 if self.wrapper: 188 if self.declaration.exposed_class_type == self.declaration.EXPOSED_CLASS_TYPE.WRAPPER: 189 args.append( self.wrapper.full_name ) 190 else: 191 if not self.target_configuration.boost_python_has_wrapper_held_type \ 192 or self.declaration.require_self_reference: 193 args.append( self.decl_identifier ) 194 if self.declaration.require_self_reference: 195 if not held_type: 196 args.append( self.wrapper.full_name ) 197 else: 198 args.append( self.wrapper.full_name ) 199 else: 200 args.append( self.decl_identifier ) 201 202 bases = self._generate_bases(base_creators) 203 if bases: 204 args.append( bases ) 205 206 if held_type: 207 args.append( held_type ) 208 notcopyable = self._generate_noncopyable() 209 if notcopyable: 210 args.append( notcopyable ) 211 return declarations.templates.join( class_identifier, args)212214 result = [] 215 result.append( '(' ) 216 result.append( ' "%s"' % self.alias ) 217 if self.documentation: 218 result.append( ', %s' % self.documentation ) 219 used_init = None 220 inits = filter( lambda x: isinstance( x, calldef.constructor_t ), self.creators ) 221 222 trivial_constructor = self.declaration.find_trivial_constructor() 223 224 if self.declaration.no_init: 225 result.append( ", " ) 226 result.append( algorithm.create_identifier( self, '::boost::python::no_init' ) ) 227 else: 228 if inits: 229 used_init = inits[0] 230 result.append( ", " ) 231 result.append( used_init.create_init_code() ) 232 result.append( ' )' ) 233 return ( ''.join( result ), used_init )234236 result = [] 237 base_classes, base_creators = self._exported_base_classes() 238 result.append( self._generate_class_definition(base_creators) ) 239 class_constructor, used_init = self._generate_constructor() 240 result.append( class_constructor ) 241 creators = self.creators 242 if self.declaration.redefine_operators: 243 creators = self.creators + self._get_base_operators(base_classes, base_creators) 244 for x in creators: 245 if not ( x is used_init ): 246 code = x.create() 247 tmpl = '%s.%s' 248 if self.is_comment( code ): 249 tmpl = '%s%s' 250 result.append( self.indent( tmpl % ( os.linesep, code ) ) ) 251 result.append( ';' ) 252 return ''.join( result )253 254 @property 257 258 @property260 return self.class_var_name + '_t'261263 base_classes, base_creators = self._exported_base_classes() 264 return 'typedef ' + self._generate_class_definition(base_creators) + ' ' + self.typedef_name + ';'265 266268 result = [] 269 scope_var_name = self.alias + '_scope' 270 base_classes, base_creators = self._exported_base_classes() 271 result.append( 'typedef ' + self._generate_class_definition(base_creators) + ' ' + self.typedef_name + ';') 272 result.append( self.typedef_name + ' ' + self.class_var_name ) 273 result[-1] = result[-1] + ' = ' 274 class_constructor, used_init = self._generate_constructor() 275 result[-1] = result[-1] + self.typedef_name + class_constructor 276 result[-1] = result[-1] + ';' 277 278 result.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) 279 result[-1] = result[-1] + ' ' + scope_var_name 280 result[-1] = result[-1] + '( %s );' % self.class_var_name 281 282 creators = self.creators 283 if self.declaration.redefine_operators: 284 creators = self.creators + self._get_base_operators(base_classes, base_creators) 285 286 for x in creators: 287 if x is used_init: 288 continue 289 if isinstance( x, ( calldef.calldef_t, calldef.calldef_overloads_t ) ): 290 x.works_on_instance = False 291 code = x.create() 292 if code: 293 result.append( code ) 294 continue 295 if not x.works_on_instance: 296 code = x.create() 297 if code: 298 result.append( code ) 299 else: 300 result.append( '%s.%s;' % ( self.class_var_name, x.create() ) ) 301 302 code = os.linesep.join( result ) 303 304 result = [ '{ //%s' % declarations.full_name( self.declaration, with_defaults=False ) ] 305 result.append( self.indent( code ) ) 306 result.append( '}' ) 307 308 return os.linesep.join( result )309311 if self.declaration.always_expose_using_scope: 312 return True 313 return bool( filter( lambda cc: not cc.works_on_instance, self.creators ) )314316 if self.declaration.already_exposed: 317 return '' 318 if self.is_exposed_using_scope(): 319 return self._generate_code_with_scope() 320 else: 321 return self._generate_code_no_scope()322326 #open question: should I put class wrapper under some specifiec namespace? 327 -class class_wrapper_t( scoped.scoped_t ):328 """ 329 Creates C++ code that creates wrapper arround some class 330 """ 331400333 scoped.scoped_t.__init__( self, declaration=declaration ) 334 self._class_creator = class_creator 335 self._base_wrappers = []336 341 wrapper_alias = property( _get_wrapper_alias, _set_wrapper_alias ) 342 343 @property345 if self.declaration.is_abstract and not self._base_wrappers: 346 bases = [ hi.related_class for hi in self.declaration.bases ] 347 creators_before_me = algorithm.creators_affect_on_me( self ) 348 self._base_wrappers \ 349 = filter( lambda creator: isinstance( creator, class_wrapper_t ) 350 and creator.declaration in bases 351 , creators_before_me ) 352 return self._base_wrappers353 354 @property 357 358 @property 361 362 @property364 if not isinstance( self.parent, class_wrapper_t ): 365 return self.declaration.wrapper_alias 366 else: 367 full_name = [self.wrapper_alias] 368 #may be we deal with enum 369 parent = self.parent 370 while isinstance( parent, class_wrapper_t ): 371 full_name.append( parent.wrapper_alias ) 372 parent = parent.parent 373 full_name.reverse() 374 return '::'.join( full_name )375 376 @property378 return self._class_creator.held_type379 380 @property382 boost_wrapper = algorithm.create_identifier( self, '::boost::python::wrapper' ) 383 return declarations.templates.join( boost_wrapper, [self.exposed_identifier] )384 387389 if self.declaration.already_exposed: 390 return '' 391 answer = ['struct %s : %s {' % ( self.wrapper_alias, self._create_bases() )] 392 answer.append( '' ) 393 answer.append( self.create_internal_code( self.creators ) ) 394 answer.append( '' ) 395 answer.append( '};' ) 396 return os.linesep.join( answer )397
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Mon Oct 20 08:51:47 2008 | http://epydoc.sourceforge.net |