| 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 """defines a class that writes L{code_creators.module_t} to multiple files, the class
7 also splits huge C++ classes to few source files
8 """
9
10 import os
11 import writer
12 import multiple_files
13 from pygccxml import declarations
14 from pyplusplus import decl_wrappers
15 from pyplusplus import code_creators
16 from pyplusplus import utils as pypp_utils
17
18 #TODO: to add namespace_alias_t classes
20 """
21 This class will split code, generated for huge classes, to few files.
22 Next strategy will be used:
23 1. New directory with class alias name will be created.
24 2. pyplusplus will generate
25 wrapper header - header that will contain code generated for class wrappers
26 classes h/cpp - will contain registration code for internal classes
27 memfun h/cpp - will contain registration code for member functions
28
29 alias + _main h/cpp this class will contain main registration function.
30 """
31
32 - def __init__( self
33 , extmodule
34 , directory_path
35 , huge_classes
36 , num_of_functions_per_file=20
37 , files_sum_repository=None
38 , encoding='ascii'):
39 multiple_files.multiple_files_t.__init__(self
40 , extmodule
41 , directory_path
42 , files_sum_repository=files_sum_repository
43 , encoding=encoding)
44 self.huge_classes = huge_classes
45 self.num_of_functions_per_file = num_of_functions_per_file
46 self.internal_splitters = [
47 self.split_internal_enums
48 , self.split_internal_unnamed_enums
49 , self.split_internal_classes
50 , self.split_internal_memfuns
51 , self.split_internal_v_memfuns
52 , self.split_internal_pv_memfuns
53 , self.split_internal_protected_memfuns
54 #not supported yet
55 #, self.split_internal_member_variables
56 ]
57
60
63
65 answer = []
66 if self.extmodule.license:
67 answer.append( self.extmodule.license.create() )
68
69 creators = [class_creator]
70 if class_creator.wrapper:
71 creators.append( class_creator.wrapper )
72
73 answer.append( self.create_include_code( creators ) )
74 answer.append( '' )
75 answer.append( self.create_namespaces_code( creators ) )
76
77 if class_creator.wrapper:
78 answer.append( class_creator.wrapper.create() )
79 class_creator.wrapper.create = lambda: ''
80
81 answer.append( '' )
82 answer.append( class_creator.create_typedef_code() )
83
84 code = os.linesep.join( answer )
85 wrapper_code = self.create_header( self.create_base_fname(class_creator, 'wrapper'), code )
86 header_file = os.path.join( self.directory_path, self.wrapper_header(class_creator) )
87 self.write_file( header_file, wrapper_code )
88
90 file_path = os.path.join( self.directory_path
91 , self.create_base_fname( class_creator, pattern ) )
92
93 function_name = 'register_%(cls_alias)s_%(pattern)s' \
94 % { 'cls_alias' : class_creator.alias, 'pattern' : pattern }
95
96 function_decl = 'void %(fname)s( %(exposer_type)s& %(var_name)s )' \
97 % { 'fname' : function_name
98 , 'exposer_type' : class_creator.typedef_name
99 , 'var_name' : class_creator.class_var_name }
100
101 #writting header file
102 header_code = [ '#include "%s"' % self.wrapper_header( class_creator ) ]
103 header_code.append( '' )
104 header_code.append( function_decl + ';' )
105 self.write_file( file_path + self.HEADER_EXT
106 , self.create_header( class_creator.alias + '_' + pattern
107 , os.linesep.join(header_code) ) )
108
109 #writting source file
110 source_code = []
111 if self.extmodule.license:
112 source_code.append( self.extmodule.license.create() )
113
114 #relevant header file
115 head_headers = [ self.create_base_fname( class_creator, pattern + self.HEADER_EXT ) ]
116 source_code.append( self.create_include_code( creators, tail_headers=head_headers ) )
117
118 source_code.append( '' )
119 source_code.append( self.create_namespaces_code( creators ) )
120
121 for creator in creators:
122 for decl_creator in self.associated_decl_creators( creator ):
123 source_code.append( '' )
124 source_code.append( decl_creator.create() )
125 if not isinstance( decl_creator, self.ref_count_creators ):
126 decl_creator.create = lambda: ''
127
128 # Write the register() function...
129 source_code.append( '' )
130 source_code.append( '%s{' % function_decl )
131 source_code.append( '' )
132 for index, creator in enumerate( creators ):
133 source_code.append( code_creators.code_creator_t.indent( creator.create() ) )
134 source_code.append( '' )
135 if 0 == index:
136 creator.create = lambda: function_name + '(%s);' % class_creator.class_var_name
137 else:
138 creator.create = lambda: ''
139 source_code.append( '}' )
140 self.write_file( file_path + self.SOURCE_EXT, os.linesep.join( source_code ) )
141
143 """Write all enumerations into a separate .h/.cpp file.
144 """
145 enums_creators = filter( lambda x: isinstance(x, code_creators.enum_t )
146 , class_creator.creators )
147 self.split_internal_creators( class_creator, enums_creators, 'enums' )
148 return 'enums'
149
151 creators = filter( lambda x: isinstance(x, code_creators.unnamed_enum_t )
152 , class_creator.creators )
153 self.split_internal_creators( class_creator, creators, 'unnamed_enums' )
154 return 'unnamed_enums'
155
157 creators = filter( lambda x: isinstance(x, calldef_types ), class_creator.creators )
158 grouped_creators = pypp_utils.split_sequence( creators, self.num_of_functions_per_file )
159 if len( grouped_creators ) == 1:
160 for creator in creators:
161 creator.works_on_instance = False
162 self.split_internal_creators( class_creator, creators, pattern )
163 return pattern
164 else:
165 patterns = []
166 for index, group in enumerate( grouped_creators ):
167 pattern_tmp = pattern + str( index )
168 patterns.append( pattern_tmp )
169 for creator in group:
170 creator.works_on_instance = False
171 self.split_internal_creators( class_creator, group, pattern_tmp )
172 return patterns
173
175 calldef_types = ( code_creators.mem_fun_t, code_creators.mem_fun_overloads_t )
176 return self.split_internal_calldefs( class_creator, calldef_types, 'memfuns' )
177
179 calldef_types = ( code_creators.mem_fun_v_t )
180 return self.split_internal_calldefs( class_creator, calldef_types, 'memfuns_virtual' )
181
183 calldef_types = ( code_creators.mem_fun_pv_t )
184 return self.split_internal_calldefs( class_creator, calldef_types, 'memfuns_pvirtual' )
185
187 calldef_types = (
188 code_creators.mem_fun_protected_t
189 , code_creators.mem_fun_protected_s_t
190 , code_creators.mem_fun_protected_v_t
191 , code_creators.mem_fun_protected_pv_t )
192 return self.split_internal_calldefs( class_creator, calldef_types, 'protected_memfuns' )
193
195 class_types = ( code_creators.class_t, code_creators.class_declaration_t )
196 creators = filter( lambda x: isinstance(x, class_types ), class_creator.creators )
197 self.split_internal_creators( class_creator, creators, 'classes' )
198 return 'classes'
199
201 creators = filter( lambda x: isinstance(x, code_creators.member_variable_base_t)
202 , class_creator.creators )
203 self.split_internal_creators( class_creator, creators, 'memvars' )
204 return 'memvars'
205
207 if not class_creator.declaration in self.huge_classes:
208 return super( class_multiple_files_t, self ).split_class_impl( class_creator )
209
210 class_creator.declaration.always_expose_using_scope = True
211
212 function_name = 'register_%s_class' % class_creator.alias
213 file_path = os.path.join( self.directory_path, class_creator.alias )
214 # Write the .h file...
215 header_name = file_path + self.HEADER_EXT
216 self.write_file( header_name
217 , self.create_header( class_creator.alias
218 , self.create_function_code( function_name ) ) )
219
220 self.write_wrapper( class_creator )
221
222 tail_headers = []
223 for splitter in self.internal_splitters:
224 pattern = splitter( class_creator )
225 if not pattern:
226 continue
227 if isinstance( pattern, str ):
228 tail_headers.append( self.create_base_fname( class_creator, pattern + self.HEADER_EXT ) )
229 else:
230 assert( isinstance( pattern, list ) )
231 for p in pattern:
232 tail_headers.append( self.create_base_fname( class_creator, p + self.HEADER_EXT ) )
233 #writting source file
234 source_code = []
235 if self.extmodule.license:
236 source_code.append( self.extmodule.license.create() )
237
238 source_code.append( self.create_include_code( [class_creator], tail_headers=tail_headers ) )
239
240 source_code.append( '' )
241 source_code.append( self.create_namespaces_code( [class_creator] ) )
242
243 for creator in class_creator.associated_decl_creators:
244 source_code.append( '' )
245 source_code.append( creator.create() )
246 if not isinstance( creator, self.ref_count_creators ):
247 creator.create = lambda: ''
248
249 # Write the register() function...
250 source_code.append( '' )
251 source_code.append( 'void %s(){' % function_name )
252 source_code.append( '' )
253 source_code.append( class_creator.create() )
254 source_code.append( '' )
255 source_code.append( '}' )
256 self.write_file( file_path + self.SOURCE_EXT, os.linesep.join( source_code ) )
257
258 # Replace the create() method so that only the register() method is called
259 # (this is called later for the main source file).
260 class_creator.create = lambda: function_name +'();'
261 self.include_creators.append( code_creators.include_t( header_name ) )
262 self.split_header_names.append(header_name)
263 self.split_method_names.append(function_name)
264
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Oct 20 08:51:34 2008 | http://epydoc.sourceforge.net |