OLD | NEW |
1 # Copyright (C) 2013 Google Inc. All rights reserved. | 1 # Copyright (C) 2013 Google Inc. All rights reserved. |
2 # | 2 # |
3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
5 # met: | 5 # met: |
6 # | 6 # |
7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 sys.path.extend([script_path]) | 77 sys.path.extend([script_path]) |
78 | 78 |
79 import jinja2 | 79 import jinja2 |
80 | 80 |
81 import idl_types | 81 import idl_types |
82 from idl_types import IdlType | 82 from idl_types import IdlType |
83 import dart_callback_interface | 83 import dart_callback_interface |
84 import dart_interface | 84 import dart_interface |
85 import dart_types | 85 import dart_types |
86 from dart_utilities import DartUtilities | 86 from dart_utilities import DartUtilities |
87 from utilities import write_pickle_file | 87 from utilities import write_pickle_file, idl_filename_to_interface_name |
| 88 import dart_dictionary |
88 from v8_globals import includes, interfaces | 89 from v8_globals import includes, interfaces |
89 | 90 |
90 # TODO(jacobr): remove this hacked together list. | 91 |
91 INTERFACES_WITHOUT_RESOLVERS = frozenset([ | 92 def render_template(interface_info, header_template, cpp_template, |
92 'TypeConversions', | 93 template_context): |
93 'GCObservation', | 94 template_context['code_generator'] = module_pyname |
94 'InternalProfilers', | 95 |
95 'InternalRuntimeFlags', | 96 # Add includes for any dependencies |
96 'InternalSettings', | 97 template_context['header_includes'] = sorted( |
97 'InternalSettingsGenerated', | 98 template_context['header_includes']) |
98 'Internals', | 99 includes.update(interface_info.get('dependencies_include_paths', [])) |
99 'LayerRect', | 100 template_context['cpp_includes'] = sorted(includes) |
100 'LayerRectList', | 101 |
101 'MallocStatistics', | 102 header_text = header_template.render(template_context) |
102 'TypeConversions']) | 103 cpp_text = cpp_template.render(template_context) |
| 104 return header_text, cpp_text |
103 | 105 |
104 class CodeGeneratorDart(object): | 106 class CodeGeneratorDart(object): |
105 def __init__(self, interfaces_info, cache_dir): | 107 def __init__(self, interfaces_info, cache_dir): |
106 interfaces_info = interfaces_info or {} | 108 interfaces_info = interfaces_info or {} |
107 self.interfaces_info = interfaces_info | 109 self.interfaces_info = interfaces_info |
108 self.jinja_env = initialize_jinja_env(cache_dir) | 110 self.jinja_env = initialize_jinja_env(cache_dir) |
109 | 111 |
110 # Set global type info | 112 # Set global type info |
111 idl_types.set_ancestors(dict( | 113 if 'ancestors' in interfaces_info: |
112 (interface_name, interface_info['ancestors']) | 114 idl_types.set_ancestors(interfaces_info['ancestors']) |
113 for interface_name, interface_info in interfaces_info.iteritems() | 115 if 'callback_interfaces' in interfaces_info: |
114 if interface_info['ancestors'])) | 116 IdlType.set_callback_interfaces(interfaces_info['callback_interfaces
']) |
115 IdlType.set_callback_interfaces(set( | 117 if 'dictionaries' in interfaces_info: |
116 interface_name | 118 IdlType.set_dictionaries(interfaces_info['dictionaries']) |
117 for interface_name, interface_info in interfaces_info.iteritems() | 119 if 'implemented_as_interfaces' in interfaces_info: |
118 if interface_info['is_callback_interface'])) | 120 IdlType.set_implemented_as_interfaces(interfaces_info['implemented_a
s_interfaces']) |
119 IdlType.set_implemented_as_interfaces(dict( | 121 if 'garbage_collected_interfaces' in interfaces_info: |
120 (interface_name, interface_info['implemented_as']) | 122 IdlType.set_garbage_collected_types(interfaces_info['garbage_collect
ed_interfaces']) |
121 for interface_name, interface_info in interfaces_info.iteritems() | 123 if 'will_be_garbage_collected_interfaces' in interfaces_info: |
122 if interface_info['implemented_as'])) | 124 IdlType.set_will_be_garbage_collected_types(interfaces_info['will_be
_garbage_collected_interfaces']) |
123 IdlType.set_garbage_collected_types(set( | 125 if 'component_dirs' in interfaces_info: |
124 interface_name | 126 dart_types.set_component_dirs(interfaces_info['component_dirs']) |
125 for interface_name, interface_info in interfaces_info.iteritems() | |
126 if 'GarbageCollected' in interface_info['inherited_extended_attribut
es'])) | |
127 IdlType.set_will_be_garbage_collected_types(set( | |
128 interface_name | |
129 for interface_name, interface_info in interfaces_info.iteritems() | |
130 if 'WillBeGarbageCollected' in interface_info['inherited_extended_at
tributes'])) | |
131 dart_types.set_component_dirs(dict( | |
132 (interface_name, interface_info['component_dir']) | |
133 for interface_name, interface_info in interfaces_info.iteritems())) | |
134 | 127 |
135 def generate_code(self, definitions, interface_name, idl_pickle_filename, | 128 def generate_code(self, definitions, interface_name, idl_pickle_filename, |
136 only_if_changed): | 129 only_if_changed): |
137 """Returns .h/.cpp code as (header_text, cpp_text).""" | 130 """Returns .h/.cpp code as (header_text, cpp_text).""" |
138 try: | 131 |
| 132 IdlType.set_enums((enum.name, enum.values) |
| 133 for enum in definitions.enumerations.values()) |
| 134 |
| 135 if interface_name in definitions.interfaces: |
139 interface = definitions.interfaces[interface_name] | 136 interface = definitions.interfaces[interface_name] |
140 except KeyError: | 137 elif interface_name in definitions.dictionaries: |
141 raise Exception('%s not in IDL definitions' % interface_name) | 138 output_code_list = self.generate_dictionary_code( |
| 139 definitions, interface_name, |
| 140 definitions.dictionaries[interface_name]) |
| 141 |
| 142 # Pickle the dictionary information... |
| 143 idl_world = self.load_idl_pickle_file(idl_pickle_filename) |
| 144 idl_world['dictionary'] = {'name': interface_name} |
| 145 write_pickle_file(idl_pickle_filename, idl_world, only_if_changed) |
| 146 |
| 147 return output_code_list |
| 148 else: |
| 149 raise ValueError('%s is not in IDL definitions' % interface_name) |
142 | 150 |
143 # Store other interfaces for introspection | 151 # Store other interfaces for introspection |
144 interfaces.update(definitions.interfaces) | 152 interfaces.update(definitions.interfaces) |
145 | 153 |
146 # Set local type info | 154 # Set local type info |
147 IdlType.set_callback_functions(definitions.callback_functions.keys()) | 155 IdlType.set_callback_functions(definitions.callback_functions.keys()) |
148 IdlType.set_enums((enum.name, enum.values) | |
149 for enum in definitions.enumerations.values()) | |
150 | 156 |
151 # Select appropriate Jinja template and contents function | 157 # Select appropriate Jinja template and contents function |
152 if interface.is_callback: | 158 if interface.is_callback: |
153 header_template_filename = 'callback_interface_h.template' | 159 header_template_filename = 'callback_interface_h.template' |
154 cpp_template_filename = 'callback_interface_cpp.template' | 160 cpp_template_filename = 'callback_interface_cpp.template' |
155 generate_contents = dart_callback_interface.generate_callback_interf
ace | 161 generate_contents = dart_callback_interface.generate_callback_interf
ace |
156 else: | 162 else: |
157 header_template_filename = 'interface_h.template' | 163 header_template_filename = 'interface_h.template' |
158 cpp_template_filename = 'interface_cpp.template' | 164 cpp_template_filename = 'interface_cpp.template' |
159 generate_contents = dart_interface.generate_interface | 165 generate_contents = dart_interface.interface_context |
160 header_template = self.jinja_env.get_template(header_template_filename) | 166 header_template = self.jinja_env.get_template(header_template_filename) |
161 cpp_template = self.jinja_env.get_template(cpp_template_filename) | 167 cpp_template = self.jinja_env.get_template(cpp_template_filename) |
162 | 168 |
163 # Generate contents (input parameters for Jinja) | 169 # Generate contents (input parameters for Jinja) |
164 template_contents = generate_contents(interface) | 170 template_contents = generate_contents(interface) |
165 template_contents['code_generator'] = module_pyname | 171 template_contents['code_generator'] = module_pyname |
166 | 172 |
167 # Add includes for interface itself and any dependencies | 173 # Add includes for interface itself and any dependencies |
168 interface_info = self.interfaces_info[interface_name] | 174 interface_info = self.interfaces_info[interface_name] |
169 template_contents['header_includes'].add(interface_info['include_path']) | 175 template_contents['header_includes'].add(interface_info['include_path']) |
170 template_contents['header_includes'] = sorted(template_contents['header_
includes']) | 176 template_contents['header_includes'] = sorted(template_contents['header_
includes']) |
171 includes.update(interface_info.get('dependencies_include_paths', [])) | 177 includes.update(interface_info.get('dependencies_include_paths', [])) |
172 | 178 |
173 # Remove includes that are not needed for Dart and trigger fatal | 179 # Remove includes that are not needed for Dart and trigger fatal |
174 # compile warnings if included. These IDL files need to be | 180 # compile warnings if included. These IDL files need to be |
175 # imported by Dart to generate the list of events but the | 181 # imported by Dart to generate the list of events but the |
176 # associated header files do not contain any code used by Dart. | 182 # associated header files do not contain any code used by Dart. |
177 includes.discard('core/dom/GlobalEventHandlers.h') | 183 includes.discard('core/dom/GlobalEventHandlers.h') |
178 includes.discard('core/frame/DOMWindowEventHandlers.h') | 184 includes.discard('core/frame/DOMWindowEventHandlers.h') |
179 | 185 |
| 186 # Remove v8 usages not needed. |
| 187 includes.discard('core/frame/UseCounter.h') |
| 188 includes.discard('bindings/core/v8/V8ScriptState.h') |
| 189 includes.discard('bindings/core/v8/V8DOMActivityLogger.h') |
| 190 includes.discard('bindings/core/v8/V8DOMConfiguration.h') |
| 191 includes.discard('bindings/core/v8/V8ExceptionState.h') |
| 192 includes.discard('bindings/core/v8/V8HiddenValue.h') |
| 193 includes.discard('bindings/core/v8/V8ObjectConstructor.h') |
| 194 includes.discard('core/dom/ContextFeatures.h') |
| 195 includes.discard('core/dom/Document.h') |
| 196 includes.discard('platform/RuntimeEnabledFeatures.h') |
| 197 includes.discard('platform/TraceEvent.h') |
| 198 |
180 template_contents['cpp_includes'] = sorted(includes) | 199 template_contents['cpp_includes'] = sorted(includes) |
181 | 200 |
182 idl_world = {'interface': None, 'callback': None} | 201 idl_world = self.load_idl_pickle_file(idl_pickle_filename) |
183 | |
184 # Load the pickle file for this IDL. | |
185 if os.path.isfile(idl_pickle_filename): | |
186 with open(idl_pickle_filename) as idl_pickle_file: | |
187 idl_global_data = pickle.load(idl_pickle_file) | |
188 idl_pickle_file.close() | |
189 idl_world['interface'] = idl_global_data['interface'] | |
190 idl_world['callback'] = idl_global_data['callback'] | |
191 | 202 |
192 if 'interface_name' in template_contents: | 203 if 'interface_name' in template_contents: |
193 interface_global = {'component_dir': interface_info['component_dir']
, | 204 # interfaces no longer remember there component_dir re-compute based |
194 'name': template_contents['interface_name'], | 205 # on relative_dir (first directory is the component). |
| 206 component_dir = split_path(interface_info['relative_dir'])[0] |
| 207 interface_global = {'name': template_contents['interface_name'], |
195 'parent_interface': template_contents['parent_in
terface'], | 208 'parent_interface': template_contents['parent_in
terface'], |
196 'is_active_dom_object': template_contents['is_ac
tive_dom_object'], | 209 'is_active_dom_object': template_contents['is_ac
tive_dom_object'], |
197 'is_event_target': template_contents['is_event_t
arget'], | 210 'is_event_target': template_contents['is_event_t
arget'], |
198 'has_resolver': template_contents['interface_nam
e'] not in INTERFACES_WITHOUT_RESOLVERS, | 211 'has_resolver': template_contents['interface_nam
e'], |
| 212 'native_entries': sorted(template_contents['nati
ve_entries'], key=lambda(x): x['blink_entry']), |
199 'is_node': template_contents['is_node'], | 213 'is_node': template_contents['is_node'], |
200 'conditional_string': template_contents['conditi
onal_string'], | 214 'conditional_string': template_contents['conditi
onal_string'], |
| 215 'component_dir': component_dir, |
201 } | 216 } |
202 idl_world['interface'] = interface_global | 217 idl_world['interface'] = interface_global |
203 else: | 218 else: |
204 callback_global = {'name': template_contents['cpp_class']} | 219 callback_global = {'name': template_contents['cpp_class']} |
205 idl_world['callback'] = callback_global | 220 idl_world['callback'] = callback_global |
206 | 221 |
207 write_pickle_file(idl_pickle_filename, idl_world, only_if_changed) | 222 write_pickle_file(idl_pickle_filename, idl_world, only_if_changed) |
208 | 223 |
209 # Render Jinja templates | 224 # Render Jinja templates |
210 header_text = header_template.render(template_contents) | 225 header_text = header_template.render(template_contents) |
211 cpp_text = cpp_template.render(template_contents) | 226 cpp_text = cpp_template.render(template_contents) |
212 return header_text, cpp_text | 227 return header_text, cpp_text |
213 | 228 |
214 # Generates global file for all interfaces. | 229 def load_idl_pickle_file(self, idl_pickle_filename): |
215 def generate_globals(self, global_pickle_directories, output_directory): | 230 # Pickle the dictionary information... |
216 header_template_filename = 'global_h.template' | 231 idl_world = {'interface': None, 'callback': None, 'dictionary': None} |
217 cpp_template_filename = 'global_cpp.template' | |
218 | 232 |
219 # Delete the global pickle file we'll rebuild from each pickle generated | 233 # Load the pickle file for this IDL. |
220 # for each IDL file '(%s_globals.pickle) % interface_name'. | 234 if os.path.isfile(idl_pickle_filename): |
221 global_pickle_filename = os.path.join(output_directory, 'global.pickle') | 235 with open(idl_pickle_filename) as idl_pickle_file: |
222 if os.path.isfile(global_pickle_filename): | 236 idl_global_data = pickle.load(idl_pickle_file) |
223 os.remove(global_pickle_filename) | 237 idl_pickle_file.close() |
| 238 idl_world['interface'] = idl_global_data['interface'] |
| 239 idl_world['callback'] = idl_global_data['callback'] |
| 240 idl_world['dictionary'] = idl_global_data['dictionary'] |
224 | 241 |
| 242 return idl_world |
| 243 |
| 244 def generate_dictionary_code(self, definitions, dictionary_name, |
| 245 dictionary): |
| 246 interface_info = self.interfaces_info[dictionary_name] |
| 247 bindings_results = self.generate_dictionary_bindings( |
| 248 dictionary_name, interface_info, dictionary) |
| 249 impl_results = self.generate_dictionary_impl( |
| 250 dictionary_name, interface_info, dictionary) |
| 251 return bindings_results + impl_results |
| 252 |
| 253 def generate_dictionary_bindings(self, dictionary_name, |
| 254 interface_info, dictionary): |
| 255 header_template = self.jinja_env.get_template('dictionary_dart_h.templat
e') |
| 256 cpp_template = self.jinja_env.get_template('dictionary_dart_cpp.template
') |
| 257 template_context = dart_dictionary.dictionary_context(dictionary) |
| 258 # Add the include for interface itself |
| 259 template_context['header_includes'].add(interface_info['include_path']) |
| 260 header_text, cpp_text = render_template( |
| 261 interface_info, header_template, cpp_template, template_context) |
| 262 return (header_text, cpp_text) |
| 263 |
| 264 def generate_dictionary_impl(self, dictionary_name, |
| 265 interface_info, dictionary): |
| 266 header_template = self.jinja_env.get_template('dictionary_impl_h.templat
e') |
| 267 cpp_template = self.jinja_env.get_template('dictionary_impl_cpp.template
') |
| 268 template_context = dart_dictionary.dictionary_impl_context( |
| 269 dictionary, self.interfaces_info) |
| 270 header_text, cpp_text = render_template( |
| 271 interface_info, header_template, cpp_template, template_context) |
| 272 return (header_text, cpp_text) |
| 273 |
| 274 def load_global_pickles(self, global_entries): |
225 # List of all interfaces and callbacks for global code generation. | 275 # List of all interfaces and callbacks for global code generation. |
226 world = {'interfaces': [], 'callbacks': []} | 276 world = {'interfaces': [], 'callbacks': [], 'dictionary': []} |
227 | 277 |
228 # Load all pickled data for each interface. | 278 # Load all pickled data for each interface. |
229 for pickle_directory in global_pickle_directories: | 279 for (directory, file_list) in global_entries: |
230 listing = os.listdir(pickle_directory) | 280 for idl_filename in file_list: |
231 for filename in listing: | 281 interface_name = idl_filename_to_interface_name(idl_filename) |
232 if filename.endswith('_globals.pickle'): | 282 idl_pickle_filename = interface_name + "_globals.pickle" |
233 idl_filename = os.path.join(pickle_directory, filename) | 283 idl_pickle_filename = os.path.join(directory, idl_pickle_filenam
e) |
234 with open(idl_filename) as idl_pickle_file: | 284 with open(idl_pickle_filename) as idl_pickle_file: |
235 idl_world = pickle.load(idl_pickle_file) | 285 idl_world = pickle.load(idl_pickle_file) |
236 if 'interface' in idl_world: | 286 if 'interface' in idl_world: |
237 # FIXME: Why are some of these None? | 287 # FIXME: Why are some of these None? |
238 if idl_world['interface']: | 288 if idl_world['interface']: |
239 world['interfaces'].append(idl_world['interface'
]) | 289 world['interfaces'].append(idl_world['interface']) |
240 if 'callbacks' in idl_world: | 290 if 'callbacks' in idl_world: |
241 # FIXME: Why are some of these None? | 291 # FIXME: Why are some of these None? |
242 if idl_world['callbacks']: | 292 if idl_world['callbacks']: |
243 world['callbacks'].append(idl_world['callback']) | 293 world['callbacks'].append(idl_world['callback']) |
244 idl_pickle_file.close() | 294 if 'dictionary' in idl_world: |
245 | 295 # It's an IDL dictionary |
| 296 if idl_world['dictionary']: |
| 297 world['dictionary'].append(idl_world['dictionary']) |
246 world['interfaces'] = sorted(world['interfaces'], key=lambda (x): x['nam
e']) | 298 world['interfaces'] = sorted(world['interfaces'], key=lambda (x): x['nam
e']) |
247 world['callbacks'] = sorted(world['callbacks'], key=lambda (x): x['name'
]) | 299 world['callbacks'] = sorted(world['callbacks'], key=lambda (x): x['name'
]) |
| 300 world['dictionary'] = sorted(world['dictionary'], key=lambda (x): x['nam
e']) |
| 301 return world |
248 | 302 |
249 template_contents = world | 303 # Generates global file for all interfaces. |
| 304 def generate_globals(self, global_entries): |
| 305 template_contents = self.load_global_pickles(global_entries) |
250 template_contents['code_generator'] = module_pyname | 306 template_contents['code_generator'] = module_pyname |
251 | 307 |
| 308 header_template_filename = 'global_h.template' |
252 header_template = self.jinja_env.get_template(header_template_filename) | 309 header_template = self.jinja_env.get_template(header_template_filename) |
253 header_text = header_template.render(template_contents) | 310 header_text = header_template.render(template_contents) |
254 | 311 |
| 312 cpp_template_filename = 'global_cpp.template' |
255 cpp_template = self.jinja_env.get_template(cpp_template_filename) | 313 cpp_template = self.jinja_env.get_template(cpp_template_filename) |
256 cpp_text = cpp_template.render(template_contents) | 314 cpp_text = cpp_template.render(template_contents) |
| 315 |
257 return header_text, cpp_text | 316 return header_text, cpp_text |
258 | 317 |
| 318 # Generates global dart blink file for all interfaces. |
| 319 def generate_dart_blink(self, global_entries): |
| 320 template_contents = self.load_global_pickles(global_entries) |
| 321 template_contents['code_generator'] = module_pyname |
| 322 |
| 323 template_filename = 'dart_blink.template' |
| 324 template = self.jinja_env.get_template(template_filename) |
| 325 |
| 326 text = template.render(template_contents) |
| 327 return text |
| 328 |
259 | 329 |
260 def initialize_jinja_env(cache_dir): | 330 def initialize_jinja_env(cache_dir): |
261 jinja_env = jinja2.Environment( | 331 jinja_env = jinja2.Environment( |
262 loader=jinja2.FileSystemLoader(templates_dir), | 332 loader=jinja2.FileSystemLoader(templates_dir), |
263 # Bytecode cache is not concurrency-safe unless pre-cached: | 333 # Bytecode cache is not concurrency-safe unless pre-cached: |
264 # if pre-cached this is read-only, but writing creates a race condition. | 334 # if pre-cached this is read-only, but writing creates a race condition. |
265 # bytecode_cache=jinja2.FileSystemBytecodeCache(cache_dir), | 335 # bytecode_cache=jinja2.FileSystemBytecodeCache(cache_dir), |
266 keep_trailing_newline=True, # newline-terminate generated files | 336 keep_trailing_newline=True, # newline-terminate generated files |
267 lstrip_blocks=True, # so can indent control flow tags | 337 lstrip_blocks=True, # so can indent control flow tags |
268 trim_blocks=True) | 338 trim_blocks=True) |
(...skipping 18 matching lines...) Expand all Loading... |
287 # [RuntimeEnabled] | 357 # [RuntimeEnabled] |
288 def runtime_enabled_if(code, runtime_enabled_function_name): | 358 def runtime_enabled_if(code, runtime_enabled_function_name): |
289 if not runtime_enabled_function_name: | 359 if not runtime_enabled_function_name: |
290 return code | 360 return code |
291 # Indent if statement to level of original code | 361 # Indent if statement to level of original code |
292 indent = re.match(' *', code).group(0) | 362 indent = re.match(' *', code).group(0) |
293 return ('%sif (%s())\n' % (indent, runtime_enabled_function_name) + | 363 return ('%sif (%s())\n' % (indent, runtime_enabled_function_name) + |
294 ' %s' % code) | 364 ' %s' % code) |
295 | 365 |
296 | 366 |
| 367 def split_path(path): |
| 368 path_list = [] |
| 369 while os.path.basename(path): |
| 370 path_list.append(os.path.basename(path)) |
| 371 path = os.path.dirname(path) |
| 372 path_list.reverse() |
| 373 return path_list |
| 374 |
| 375 |
297 ################################################################################ | 376 ################################################################################ |
298 | 377 |
299 def main(argv): | 378 def main(argv): |
300 # If file itself executed, cache templates | 379 # If file itself executed, cache templates |
301 try: | 380 try: |
302 cache_dir = argv[1] | 381 cache_dir = argv[1] |
303 dummy_filename = argv[2] | 382 dummy_filename = argv[2] |
304 except IndexError as err: | 383 except IndexError as err: |
305 print 'Usage: %s OUTPUT_DIR DUMMY_FILENAME' % argv[0] | 384 print 'Usage: %s OUTPUT_DIR DUMMY_FILENAME' % argv[0] |
306 return 1 | 385 return 1 |
307 | 386 |
308 # Cache templates | 387 # Cache templates |
309 jinja_env = initialize_jinja_env(cache_dir) | 388 jinja_env = initialize_jinja_env(cache_dir) |
310 template_filenames = [filename for filename in os.listdir(templates_dir) | 389 template_filenames = [filename for filename in os.listdir(templates_dir) |
311 # Skip .svn, directories, etc. | 390 # Skip .svn, directories, etc. |
312 if filename.endswith(('.cpp', '.h', '.template'))] | 391 if filename.endswith(('.cpp', '.h', '.template'))] |
313 for template_filename in template_filenames: | 392 for template_filename in template_filenames: |
314 jinja_env.get_template(template_filename) | 393 jinja_env.get_template(template_filename) |
315 | 394 |
316 # Create a dummy file as output for the build system, | 395 # Create a dummy file as output for the build system, |
317 # since filenames of individual cache files are unpredictable and opaque | 396 # since filenames of individual cache files are unpredictable and opaque |
318 # (they are hashes of the template path, which varies based on environment) | 397 # (they are hashes of the template path, which varies based on environment) |
319 with open(dummy_filename, 'w') as dummy_file: | 398 with open(dummy_filename, 'w') as dummy_file: |
320 pass # |open| creates or touches the file | 399 pass # |open| creates or touches the file |
321 | 400 |
322 | 401 |
323 if __name__ == '__main__': | 402 if __name__ == '__main__': |
324 sys.exit(main(sys.argv)) | 403 sys.exit(main(sys.argv)) |
OLD | NEW |