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 ):
    217          sealed_fun_controller_t.__init__( self, function )
    218
    219          inst_arg_type = declarations.declarated_t( self.function.parent )
    220          if self.function.has_const:
    221              inst_arg_type = declarations.const_t( inst_arg_type )
    222          inst_arg_type = declarations.reference_t( inst_arg_type )
    223
    224          self.__inst_arg = None
    225          if not self.function.has_static:
    226              self.__inst_arg = declarations.argument_t( name=self.register_variable_name( 'inst' )
    227                                                         , type=inst_arg_type )
    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 ):
    238          sealed_fun_controller_t.__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 ):
    260              return templates.virtual_mem_fun.override
    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 ):
    306              sealed_fun_controller_t.__init__( self, function )
    307
    308              inst_arg_type = declarations.declarated_t( self.function.parent )
    309              if self.function.has_const:
    310                  inst_arg_type = declarations.const_t( inst_arg_type )
    311              inst_arg_type = declarations.reference_t( inst_arg_type )
    312
    313              self.__inst_arg = declarations.argument_t( name=self.register_variable_name( 'inst' )
    314                                                         , type=inst_arg_type )
    315
    316          @property
    317 -        def inst_arg( self ):
    318              return self.__inst_arg
    319
    320          @property
    321 -        def template( self ):
    322              return templates.virtual_mem_fun.default
    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