Package pyplusplus :: Package function_transformers :: Module controllers

Source Code for Module pyplusplus.function_transformers.controllers

  1  # Copyright 2006 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  """defines controller classes which help to define the function transformation 
  7   
  8  The idea behind implementation of "Function Transformation" functionality is simple: 
  9  Py++ defines few templates. Transformers are just editors for the templates. 
 10  In most cases, transformers don't directly edit the template, but use controller 
 11  classes for this purpose. Controller classes provide an abstraction of the templates. 
 12  """ 
 13   
 14  import string 
 15  import templates 
 16  from pygccxml import declarations 
17 18 -class variable_t( object ):
19 """defines C++ variable"""
20 - def __init__( self, type, name, initialize_expr='' ):
21 """ 22 @param type: type of the variable 23 @type type: instance of L{pygccxml.declarations.type_t} 24 25 @param name: name( str ) of the variable 26 27 @param initialize_expr: an expression that initialize the variable 28 """ 29 self.__name = name 30 self.__type = type 31 self.__initialize_expr = initialize_expr
32 33 @property
34 - def name( self ):
35 "variable name" 36 return self.__name
37 38 @property
39 - def type( self ):
40 "variable type" 41 return self.__type
42 43 @property
44 - def initialize_expr( self ):
45 "inirialize expression" 46 return self.__initialize_expr
47
48 - def declare_var_string( self ):
49 return templates.substitute( "$type $name$initialize_expr;" 50 , name=self.name 51 , type=self.type 52 , initialize_expr=self.initialize_expr )
53
54 -class variables_manager_t( object ):
55 """function wrapper variables manager 56 57 Almost every time we define new transformer, we need to define variables. 58 It is important to keep the variable names unique. This class will ensure this. 59 Every time you declare new variable, it will return the unique variable name. 60 The name will be built from the original variable name and some index, which 61 will make the variable to be unique. 62 """
63 - def __init__( self ):
64 object.__init__( self ) 65 self.__variables = [] #variables 66 self.__names_in_use = set()
67 68 @property
69 - def variables( self ):
70 "list of all declared variables" 71 return self.__variables
72
73 - def declare_variable( self, type, name, initialize_expr='' ):
74 """declare variable 75 76 @param type: type of the variable 77 @type type: instance of L{pygccxml.declarations.type_t} 78 79 @param name: name( str ) of the variable 80 81 @param initialize_expr: an expression that initialize the variable 82 83 @return: the unique variable name 84 """ 85 unique_name = self.__create_unique_var_name( name ) 86 self.__variables.append( variable_t( type, unique_name, initialize_expr ) ) 87 return unique_name
88
89 - def register_name( self, name ):
90 """register predefined variable name 91 92 There are use cases, where it is convenience to define variables within 93 a template. In such cases, the only thing that should be done is registering 94 a unique name of the variable. 95 """ 96 return self.__create_unique_var_name( name )
97
98 - def __create_unique_var_name( self, name ):
99 n = 2 100 unique_name = name 101 while 1: 102 if unique_name in self.__names_in_use: 103 unique_name = "%s%d" % ( name, n ) 104 n += 1 105 else: 106 self.__names_in_use.add( unique_name ) 107 return unique_name
108
109 -def create_variables_manager( function ):
110 vm = variables_manager_t() 111 map( lambda arg: vm.register_name( arg.name ) , function.arguments ) 112 return vm
113
114 -class controller_base_t( object ):
115 """base class for all controller classes""" 116
117 - def __init__( self, function ):
118 self.__function = function
119 120 @property
121 - def function( self ):
122 return self.__function
123
124 - def apply( self, transformations ):
125 """asks all transformations to configure the controller""" 126 raise NotImplementedError()
127
128 -class sealed_fun_controller_t( controller_base_t ):
129 """base class for free and member function controllers"""
130 - def __init__( self, function ):
131 controller_base_t.__init__( self, function ) 132 self.__vars_manager = create_variables_manager( function ) 133 self.__wrapper_args = [ arg.clone() for arg in function.arguments ] 134 self.__result_var = variable_t( self.function.return_type 135 , self.register_variable_name( 'result' ) ) 136 self.__return_variables = [] 137 self.__pre_call = [] 138 self.__post_call = [] 139 self.__arg_expressions = [ arg.name for arg in function.arguments ]
140 141 @property
142 - def variables( self ):
143 return self.__vars_manager.variables
144
145 - def declare_variable( self, type, name, initialize_expr='' ):
146 return self.__vars_manager.declare_variable( type, name, initialize_expr)
147
148 - def register_variable_name( self, name ):
149 return self.__vars_manager.register_name( name )
150 151 @property
152 - def result_variable( self ):
153 return self.__result_var
154 155 @property
156 - def template( self ):
157 return templates.sealed_fun.body
158 159 @property
160 - def wrapper_args( self ):
161 return filter( None, self.__wrapper_args )
162
163 - def find_wrapper_arg( self, name ):
164 for arg in self.wrapper_args: 165 if arg.name == name: 166 return arg 167 return None
168
169 - def remove_wrapper_arg( self, name ):
170 arg = self.find_wrapper_arg( name ) 171 if not arg: 172 raise LookupError( "Unable to remove '%s' argument - not found!" % name ) 173 self.__wrapper_args[ self.__wrapper_args.index(arg) ] = None
174 175 @property
176 - def arg_expressions( self ):
177 return self.__arg_expressions
178
179 - def modify_arg_expression( self, index, expression ):
180 self.arg_expressions[ index ] = expression
181 182 @property
183 - def wrapper_return_type( self ):
184 return_vars_count = len( self.return_variables ) 185 if not declarations.is_void( self.function.return_type ): 186 return_vars_count += 1 187 if 0 == return_vars_count: 188 return self.function.return_type #return type is void 189 elif 1 == return_vars_count: 190 return declarations.dummy_type_t( 'boost::python::object' ) 191 else: 192 return declarations.dummy_type_t( 'boost::python::tuple' )
193 194 @property
195 - def return_variables( self ):
196 return self.__return_variables
197
198 - def return_variable( self, variable_name ):
199 self.__return_variables.append( variable_name )
200 201 @property
202 - def pre_call( self ):
203 return self.__pre_call
204
205 - def add_pre_call_code( self, code ):
206 self.__pre_call.append( code )
207 208 @property
209 - def post_call( self ):
210 return self.__post_call
211
212 - def add_post_call_code( self, code ):
213 self.__post_call.append( code )
214
215 -class mem_fun_controller_t( sealed_fun_controller_t ):
216 - def __init__( self, function ):
228
229 - def apply( self, transformations ):
230 map( lambda t: t.configure_mem_fun( self ), transformations )
231 232 @property
233 - def inst_arg( self ):
234 return self.__inst_arg
235
236 -class free_fun_controller_t( sealed_fun_controller_t ):
237 - def __init__( self, function ):
239
240 - def apply( self, transformations ):
241 map( lambda t: t.configure_free_fun( self ), transformations )
242
243 244 -class virtual_mem_fun_controller_t( controller_base_t ):
245 - class override_fun_controller_t( controller_base_t ):
246 - def __init__( self, function ):
247 controller_base_t.__init__( self, function ) 248 self.__py_vars_manager = create_variables_manager( function ) 249 self.__py_function_var \ 250 = self.__py_vars_manager.register_name( 'func_' + function.alias ) 251 self.__py_pre_call = [] 252 self.__py_post_call = [] 253 self.__py_result_var = variable_t( declarations.dummy_type_t( 'boost::python::object' ) 254 , self.register_py_variable_name( 'py_result' ) ) 255 256 self.__py_arg_expressions = [ arg.name for arg in function.arguments ]
257 258 @property
259 - def template( self ):
261 262 @property
263 - def py_variables( self ):
264 return self.__py_vars_manager.variables
265
266 - def declare_py_variable( self, type, name, initialize_expr='' ):
267 return self.__py_vars_manager.declare_variable( type, name, initialize_expr)
268
269 - def register_py_variable_name( self, name ):
270 return self.__py_vars_manager.register_name( name )
271 272 @property
273 - def py_function_var( self ):
274 return self.__py_function_var
275 276 @property
277 - def py_pre_call( self ):
278 return self.__py_pre_call
279
280 - def add_py_pre_call_code( self, code ):
281 self.__py_pre_call.append( code )
282 283 @property
284 - def py_post_call( self ):
285 return self.__py_post_call
286
287 - def add_py_post_call_code( self, code ):
288 self.__py_post_call.append( code )
289 290 @property
291 - def py_result_variable( self ):
292 return self.__py_result_var
293 294 @property
295 - def py_arg_expressions( self ):
296 return filter( None, self.__py_arg_expressions )
297
298 - def remove_py_arg( self, index ):
299 self.__py_arg_expressions[ index ] = None
300
301 - def modify_py_arg_expression( self, index, expression ):
302 self.arg_expressions[ index ] = expression
303
304 - class default_fun_controller_t( sealed_fun_controller_t ):
305 - def __init__( self, function ):
315 316 @property
317 - def inst_arg( self ):
318 return self.__inst_arg
319 320 @property
321 - def template( self ):
323
324 - def __init__( self, function ):
325 controller_base_t.__init__( self, function ) 326 self.__override_cntrl = self.override_fun_controller_t( function ) 327 self.__default_cntrl = self.default_fun_controller_t( function )
328
329 - def apply( self, transformations ):
330 map( lambda t: t.configure_virtual_mem_fun( self ), transformations )
331 332 @property
333 - def override_controller( self ):
334 return self.__override_cntrl
335 336 @property
337 - def default_controller( self ):
338 return self.__default_cntrl
339 340 341 #TODO: FT for constructor 342 343 #~ class constructor_controller_t( controller_base_t ): 344 #~ def __init__( self, function ): 345 #~ controller_base_t.__init__( self, function ) 346 #~ self.__vars_manager = create_variables_manager( function ) 347 #~ self.__wrapper_args = [ arg.clone() for arg in function.arguments ] 348 #~ self.__result_var = variable_t( self.wrapper_return_type 349 #~ , self.register_variable_name( 'result' ) ) 350 #~ self.__pre_call = [] 351 #~ self.__post_call = [] 352 #~ self.__arg_expressions = [ arg.name for arg in function.arguments ] 353 354 #~ @property 355 #~ def variables( self ): 356 #~ return self.__vars_manager.variables 357 358 #~ def declare_variable( self, type, name, initialize_expr='' ): 359 #~ return self.__vars_manager.declare_variable( type, name, initialize_expr) 360 361 #~ def register_variable_name( self, name ): 362 #~ return self.__vars_manager.register_name( name ) 363 364 #~ @property 365 #~ def result_variable( self ): 366 #~ return self.__result_var 367 368 #~ @property 369 #~ def template( self ): 370 #~ return templates.constructor.body 371 372 #~ @property 373 #~ def wrapper_args( self ): 374 #~ return filter( None, self.__wrapper_args ) 375 376 #~ def find_wrapper_arg( self, name ): 377 #~ for arg in self.wrapper_args: 378 #~ if arg.name == name: 379 #~ return arg 380 #~ return None 381 382 #~ def remove_wrapper_arg( self, name ): 383 #~ arg = self.find_wrapper_arg( name ) 384 #~ if not arg: 385 #~ raise LookupError( "Unable to remove '%s' argument - not found!" % name ) 386 #~ self.__wrapper_args[ self.__wrapper_args.index(arg) ] = None 387 388 #~ @property 389 #~ def arg_expressions( self ): 390 #~ return self.__arg_expressions 391 392 #~ def modify_arg_expression( self, index, expression ): 393 #~ self.arg_expressions[ index ] = expression 394 395 #~ @property 396 #~ def wrapper_return_type( self ): 397 #~ return declarations.dummy_type_t( 'std::auto_ptr< %s >' % self.function.parent.decl_string ) 398 399 #~ @property 400 #~ def pre_call( self ): 401 #~ return self.__pre_call 402 403 #~ def add_pre_call_code( self, code ): 404 #~ self.__pre_call.append( code ) 405 406 #~ @property 407 #~ def post_call( self ): 408 #~ return self.__post_call 409 410 #~ def add_post_call_code( self, code ): 411 #~ self.__post_call.append( code ) 412 413 #~ def apply( self, transformations ): 414 #~ map( lambda t: t.configure_mem_fun( self ), transformations ) 415