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 6import os 7from . import algorithm 8from . import registration_based 9from pygccxml import declarations 10 11class property_t( registration_based.registration_based_t ): 12 def __init__(self, property_def, wrapper=None ): 13 registration_based.registration_based_t.__init__( self ) 14 self._property_def = property_def 15 self.works_on_instance = False 16 self._make_function = None 17 18 @property 19 def property_def( self ): 20 return self._property_def 21 22 @property 23 def make_function_identifier( self ): 24 if not self._make_function: 25 self._make_function = algorithm.create_identifier( self, '::boost::python::make_function' ) 26 return self._make_function 27 28 def create_function_type_alias_code( self, f, ftype_alias, exported_class_alias=None ): 29 return 'typedef ' + f.function_type().create_typedef( ftype_alias, exported_class_alias ) + ';' 30 31 def create_accessor_code( self, f, ftype_alias ): 32 f_ref_code = '%s( &%s )' % ( ftype_alias, declarations.full_name( f ) ) 33 if f.call_policies and f.call_policies.is_default(): 34 return f_ref_code 35 result = [ self.make_function_identifier ] 36 result.append( '( ' ) 37 result.append( os.linesep ) 38 result.append( self.indent( ' ', 2 ) ) 39 result.append( f_ref_code ) 40 if f.call_policies: 41 result.append( os.linesep ) 42 result.append( self.indent( ', ', 2 ) ) 43 result.append( f.call_policies.create( self ) ) 44 else: 45 result.append( os.linesep ) 46 result.append( self.indent( ' ', 2 ) ) 47 result.append( '/* undefined call policies */' ) 48 result.append( ' ) ' ) 49 return ''.join( result ) 50 51 def has_long_line( self ): 52 pd = self.property_def 53 if pd.fget.call_policies and not pd.fget.call_policies.is_default(): 54 return True 55 elif pd.fset or ( pd.fset and ( pd.fset.call_policies or not pd.fset.call_policies.is_default() ) ): 56 return True 57 elif pd.doc: 58 return True 59 else: 60 return True 61 62 def is_same_parent( self ): 63 pd = self.property_def 64 if not pd.fset: 65 return False 66 return pd.fget.parent is pd.fset.parent 67 68 def create_class_typedef_on_demand( self, f, prefix='' ): 69 if None is f: 70 return ( None, None ) 71 if not isinstance( f.parent, declarations.class_t ): 72 return ( None, None ) 73 if not declarations.templates.is_instantiation( f.parent.decl_string ): 74 return ( None, None ) 75 cls_name = None 76 cls_identifier = algorithm.create_identifier( self, f.parent.decl_string ) 77 if prefix: 78 cls_name = prefix + 'class_t' 79 else: 80 cls_name = 'exported_class_t' 81 return ( 'typedef %s %s;' % ( cls_identifier, cls_name ), cls_name ) 82 83 def create_property_code( self ): 84 result = [] 85 param_sep = ', ' 86 if self.has_long_line(): 87 param_sep = os.linesep + self.indent( param_sep ) 88 89 fget_class_typedef_code, fget_class_alias = None, None 90 fset_class_typedef_code, fset_class_alias = None, None 91 if self.is_same_parent(): 92 fget_class_typedef_code, fget_class_alias \ 93 = self.create_class_typedef_on_demand( self.property_def.fget ) 94 fset_class_alias = fget_class_alias 95 fset_class_typedef_code = fget_class_typedef_code 96 else: 97 fget_class_typedef_code, fget_class_alias \ 98 = self.create_class_typedef_on_demand( self.property_def.fget, 'fget_' ) 99 fset_class_typedef_code, fset_class_alias \ 100 = self.create_class_typedef_on_demand( self.property_def.fset, 'fset_' ) 101 102 if fget_class_typedef_code: 103 result.append( fget_class_typedef_code ) 104 105 if fset_class_typedef_code and fset_class_typedef_code != fget_class_typedef_code: 106 result.append( os.linesep ) 107 result.append( fset_class_typedef_code ) 108 109 if result: 110 result.append( 2 * os.linesep ) 111 112 result.append( self.create_function_type_alias_code( self.property_def.fget, 'fget', fget_class_alias ) ) 113 if self.property_def.fset: 114 result.append( os.linesep ) 115 result.append( self.create_function_type_alias_code( self.property_def.fset, 'fset', fset_class_alias ) ) 116 117 result.append( 2 * os.linesep ) 118 119 add_property = None 120 if self.property_def.is_static: 121 add_property = 'add_static_property' 122 else: 123 add_property = 'add_property' 124 125 class_var_name = self.parent.class_var_name 126 if self.has_long_line(): 127 result.append( '%s.%s( ' % ( class_var_name, add_property ) ) 128 result.append( os.linesep + self.indent( '"%s"' % self.property_def.name ) ) 129 else: 130 result.append( '%s.%s( "%s"' % ( class_var_name, add_property, self.property_def.name ) ) 131 result.append( param_sep + self.create_accessor_code( self.property_def.fget, 'fget' ) ) 132 if self.property_def.fset: 133 result.append( param_sep + self.create_accessor_code( self.property_def.fset, 'fset' )) 134 if self.property_def.doc: 135 result.append( param_sep + self.property_def.doc) 136 result.append( ' );') 137 return ''.join( result ) 138 139 def _create_impl( self ): 140 result = [] 141 result.append( '{ //%s' % self.property_def ) 142 result.append( '' ) 143 result.append( self.indent( self.create_property_code() ) ) 144 result.append( '' ) 145 result.append( '}' ) 146 return os.linesep.join( result ) 147 148 def _get_system_files_impl( self ): 149 return [] 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171