1
2
3
4
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
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
55
56 ]
57
60
63
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
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
110 source_code = []
111 if self.extmodule.license:
112 source_code.append( self.extmodule.license.create() )
113
114
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
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
149
155
173
177
181
185
193
199
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
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
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
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
259
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