OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright (C) 2013 Google Inc. All rights reserved. | 3 # Copyright (C) 2013 Google Inc. All rights reserved. |
4 # | 4 # |
5 # Redistribution and use in source and binary forms, with or without | 5 # Redistribution and use in source and binary forms, with or without |
6 # modification, are permitted provided that the following conditions are | 6 # modification, are permitted provided that the following conditions are |
7 # met: | 7 # met: |
8 # | 8 # |
9 # * Redistributions of source code must retain the above copyright | 9 # * Redistributions of source code must retain the above copyright |
10 # notice, this list of conditions and the following disclaimer. | 10 # notice, this list of conditions and the following disclaimer. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
68 """Raised if the IDL file implementing an interface cannot be found.""" | 68 """Raised if the IDL file implementing an interface cannot be found.""" |
69 pass | 69 pass |
70 | 70 |
71 | 71 |
72 def parse_options(): | 72 def parse_options(): |
73 usage = 'Usage: %prog [options] [generated1.idl]...' | 73 usage = 'Usage: %prog [options] [generated1.idl]...' |
74 parser = optparse.OptionParser(usage=usage) | 74 parser = optparse.OptionParser(usage=usage) |
75 parser.add_option('--event-names-file', help='output file') | 75 parser.add_option('--event-names-file', help='output file') |
76 parser.add_option('--idl-files-list', help='file listing IDL files') | 76 parser.add_option('--idl-files-list', help='file listing IDL files') |
77 parser.add_option('--interface-dependencies-file', help='output file') | 77 parser.add_option('--interface-dependencies-file', help='output file') |
78 parser.add_option('--interfaces-info-file', help='output pickle file') | |
Nils Barth (inactive)
2014/02/24 08:38:56
We need this separate file for the build, so could
terry
2014/02/27 23:40:26
Done.
Nils Barth (inactive)
2014/03/03 06:45:48
Just to clarify:
it's fine to not write Interfaces
| |
79 parser.add_option('--window-constructors-file', help='output file') | 78 parser.add_option('--window-constructors-file', help='output file') |
80 parser.add_option('--workerglobalscope-constructors-file', help='output file ') | 79 parser.add_option('--workerglobalscope-constructors-file', help='output file ') |
81 parser.add_option('--sharedworkerglobalscope-constructors-file', help='outpu t file') | 80 parser.add_option('--sharedworkerglobalscope-constructors-file', help='outpu t file') |
82 parser.add_option('--dedicatedworkerglobalscope-constructors-file', help='ou tput file') | 81 parser.add_option('--dedicatedworkerglobalscope-constructors-file', help='ou tput file') |
83 parser.add_option('--serviceworkerglobalscope-constructors-file', help='outp ut file') | 82 parser.add_option('--serviceworkerglobalscope-constructors-file', help='outp ut file') |
84 parser.add_option('--write-file-only-if-changed', type='int', help='if true, do not write an output file if it would be identical to the existing one, which avoids unnecessary rebuilds in ninja') | 83 parser.add_option('--write-file-only-if-changed', type='int', help='if true, do not write an output file if it would be identical to the existing one, which avoids unnecessary rebuilds in ninja') |
85 options, args = parser.parse_args() | 84 options, args = parser.parse_args() |
86 if options.event_names_file is None: | 85 if options.event_names_file is None: |
87 parser.error('Must specify an output file using --event-names-file.') | 86 parser.error('Must specify an output file using --event-names-file.') |
88 if options.interface_dependencies_file is None: | 87 if options.interface_dependencies_file is None: |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
318 | 317 |
319 def add_paths_to_partials_dict(partial_interface_name, full_path, this_include_p ath=None): | 318 def add_paths_to_partials_dict(partial_interface_name, full_path, this_include_p ath=None): |
320 paths_dict = partial_interface_files.setdefault(partial_interface_name, | 319 paths_dict = partial_interface_files.setdefault(partial_interface_name, |
321 {'full_paths': [], | 320 {'full_paths': [], |
322 'include_paths': []}) | 321 'include_paths': []}) |
323 paths_dict['full_paths'].append(full_path) | 322 paths_dict['full_paths'].append(full_path) |
324 if this_include_path: | 323 if this_include_path: |
325 paths_dict['include_paths'].append(this_include_path) | 324 paths_dict['include_paths'].append(this_include_path) |
326 | 325 |
327 | 326 |
328 def generate_dependencies(idl_filename): | 327 def generate_dependencies(idl_filename, idl_full_path, idl_file_contents): |
329 """Compute dependencies for IDL file, returning True if main (non-partial) i nterface""" | 328 """Compute dependencies for IDL file, returning True if main (non-partial) i nterface""" |
330 full_path = os.path.realpath(idl_filename) | |
331 idl_file_contents = get_file_contents(full_path) | |
332 | 329 |
333 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents) | 330 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents) |
334 implemented_as = extended_attributes.get('ImplementedAs') | 331 implemented_as = extended_attributes.get('ImplementedAs') |
335 # FIXME: remove [NoHeader] once switch to Python | 332 # FIXME: remove [NoHeader] once switch to Python |
336 this_include_path = (include_path(idl_filename, implemented_as) | 333 this_include_path = (include_path(idl_filename, implemented_as) |
337 if 'NoHeader' not in extended_attributes else None) | 334 if 'NoHeader' not in extended_attributes else None) |
338 | 335 |
339 # Handle partial interfaces | 336 # Handle partial interfaces |
340 partial_interface_name = get_partial_interface_name_from_idl(idl_file_conten ts) | 337 partial_interface_name = get_partial_interface_name_from_idl(idl_file_conten ts) |
341 if partial_interface_name: | 338 if partial_interface_name: |
342 add_paths_to_partials_dict(partial_interface_name, full_path, this_inclu de_path) | 339 add_paths_to_partials_dict(partial_interface_name, idl_full_path, this_i nclude_path) |
343 return False | 340 return False |
344 | 341 |
345 # If not a partial interface, the basename is the interface name | 342 # If not a partial interface, the basename is the interface name |
346 interface_name, _ = os.path.splitext(os.path.basename(idl_filename)) | 343 interface_name, _ = os.path.splitext(os.path.basename(idl_filename)) |
347 | 344 |
348 interfaces_info[interface_name] = { | 345 interfaces_info[interface_name] = { |
349 'full_path': full_path, | 346 'full_path': idl_full_path, |
350 'implements_interfaces': get_implemented_interfaces_from_idl(idl_file_co ntents, interface_name), | 347 'implements_interfaces': get_implemented_interfaces_from_idl(idl_file_co ntents, interface_name), |
351 'is_callback_interface': is_callback_interface_from_idl(idl_file_content s), | 348 'is_callback_interface': is_callback_interface_from_idl(idl_file_content s), |
352 # Interfaces that are referenced (used as types) and that we introspect | 349 # Interfaces that are referenced (used as types) and that we introspect |
353 # during code generation (beyond interface-level data ([ImplementedAs], | 350 # during code generation (beyond interface-level data ([ImplementedAs], |
354 # is_callback_interface, ancestors, and inherited extended attributes): | 351 # is_callback_interface, ancestors, and inherited extended attributes): |
355 # deep dependencies. | 352 # deep dependencies. |
356 # These cause rebuilds of referrers, due to the dependency, so these | 353 # These cause rebuilds of referrers, due to the dependency, so these |
357 # should be minimized; currently only targets of [PutForwards]. | 354 # should be minimized; currently only targets of [PutForwards]. |
358 'referenced_interfaces': get_put_forward_interfaces_from_idl(idl_file_co ntents), | 355 'referenced_interfaces': get_put_forward_interfaces_from_idl(idl_file_co ntents), |
359 } | 356 } |
(...skipping 25 matching lines...) Expand all Loading... | |
385 named_constructor = extended_attributes['NamedConstructor'] | 382 named_constructor = extended_attributes['NamedConstructor'] |
386 # Extract function name, namely everything before opening '(' | 383 # Extract function name, namely everything before opening '(' |
387 constructor_name = re.sub(r'\(.*', '', named_constructor) | 384 constructor_name = re.sub(r'\(.*', '', named_constructor) |
388 # Note the reduplicated 'ConstructorConstructor' | 385 # Note the reduplicated 'ConstructorConstructor' |
389 attribute_string = 'attribute %sConstructorConstructor %s' % (interface_ name, constructor_name) | 386 attribute_string = 'attribute %sConstructorConstructor %s' % (interface_ name, constructor_name) |
390 attributes_list.append(extended_string + attribute_string) | 387 attributes_list.append(extended_string + attribute_string) |
391 | 388 |
392 return attributes_list | 389 return attributes_list |
393 | 390 |
394 | 391 |
395 def record_global_constructors_and_extended_attributes(idl_filename, global_cons tructors): | 392 def record_global_constructors_and_extended_attributes(idl_filename, idl_file_co ntents, global_constructors): |
396 interface_name, _ = os.path.splitext(os.path.basename(idl_filename)) | 393 interface_name, _ = os.path.splitext(os.path.basename(idl_filename)) |
397 full_path = os.path.realpath(idl_filename) | |
398 idl_file_contents = get_file_contents(full_path) | |
399 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents) | 394 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents) |
400 | 395 |
401 # Record extended attributes | 396 # Record extended attributes |
402 extended_attributes_by_interface[interface_name] = extended_attributes | 397 extended_attributes_by_interface[interface_name] = extended_attributes |
403 | 398 |
404 # Record global constructors | 399 # Record global constructors |
405 if (not is_callback_interface_from_idl(idl_file_contents) and | 400 if (not is_callback_interface_from_idl(idl_file_contents) and |
406 'NoInterfaceObject' not in extended_attributes): | 401 'NoInterfaceObject' not in extended_attributes): |
407 global_contexts = extended_attributes.get('GlobalContext', 'Window').spl it('&') | 402 global_contexts = extended_attributes.get('GlobalContext', 'Window').spl it('&') |
408 new_constructor_list = generate_constructor_attribute_list(interface_nam e, extended_attributes) | 403 new_constructor_list = generate_constructor_attribute_list(interface_nam e, extended_attributes) |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
468 global_constructors: | 463 global_constructors: |
469 dict of global objects -> list of constructors on that object | 464 dict of global objects -> list of constructors on that object |
470 """ | 465 """ |
471 global_constructors = dict([ | 466 global_constructors = dict([ |
472 (global_object, []) | 467 (global_object, []) |
473 for global_object in global_constructors_filenames]) | 468 for global_object in global_constructors_filenames]) |
474 | 469 |
475 # Generate dependencies, and (for main IDL files), record | 470 # Generate dependencies, and (for main IDL files), record |
476 # global_constructors and extended_attributes_by_interface. | 471 # global_constructors and extended_attributes_by_interface. |
477 for idl_filename in idl_files: | 472 for idl_filename in idl_files: |
473 interface_name, _ = os.path.splitext(os.path.basename(idl_filename)) | |
474 full_path = os.path.realpath(idl_filename) | |
475 idl_file_contents = get_file_contents(full_path) | |
476 | |
478 # Test skips partial interfaces | 477 # Test skips partial interfaces |
479 if generate_dependencies(idl_filename): | 478 if generate_dependencies(idl_filename, full_path, idl_file_contents): |
480 record_global_constructors_and_extended_attributes(idl_filename, glo bal_constructors) | 479 record_global_constructors_and_extended_attributes(idl_filename, |
480 idl_file_contents , | |
481 global_constructo rs) | |
481 | 482 |
482 for interface_name in interfaces_info: | 483 for interface_name in interfaces_info: |
483 generate_ancestors_and_inherited_extended_attributes(interface_name) | 484 generate_ancestors_and_inherited_extended_attributes(interface_name) |
484 | 485 |
485 # Add constructors on global objects to partial interfaces | 486 # Add constructors on global objects to partial interfaces |
486 # These are all partial interfaces, but the files are dynamically generated, | 487 # These are all partial interfaces, but the files are dynamically generated, |
487 # so they need to be handled separately from static partial interfaces. | 488 # so they need to be handled separately from static partial interfaces. |
488 for global_object, constructor_filename in global_constructors_filenames.ite ritems(): | 489 for global_object, constructor_filename in global_constructors_filenames.ite ritems(): |
489 if global_object in interfaces_info: | 490 if global_object in interfaces_info: |
490 # No include path needed, as already included in the header file | 491 # No include path needed, as already included in the header file |
(...skipping 22 matching lines...) Expand all Loading... | |
513 interface_info['dependencies_full_paths'] = ( | 514 interface_info['dependencies_full_paths'] = ( |
514 partial_interfaces_full_paths + | 515 partial_interfaces_full_paths + |
515 implemented_interfaces_full_paths) | 516 implemented_interfaces_full_paths) |
516 interface_info['dependencies_include_paths'] = ( | 517 interface_info['dependencies_include_paths'] = ( |
517 partial_interfaces_include_paths + | 518 partial_interfaces_include_paths + |
518 implemented_interfaces_include_paths) | 519 implemented_interfaces_include_paths) |
519 | 520 |
520 return global_constructors | 521 return global_constructors |
521 | 522 |
522 | 523 |
524 def clear_globals(): | |
525 interfaces_info.clear() | |
526 partial_interface_files.clear() | |
527 parent_interfaces.clear() | |
528 extended_attributes_by_interface.clear() # interface name -> extended attri butes | |
529 | |
530 | |
531 def compute(idl_files_list, interface_dependencies_file, | |
532 window_constructors_file, workerglobalscope_constructors_file, | |
533 sharedworkerglobalscope_constructors_file, | |
534 dedicatedworkerglobalscope_constructors_file, | |
535 serviceworkerglobalscope_constructors_file, | |
536 event_names_file, only_if_changed): | |
537 | |
538 clear_globals() | |
539 | |
540 global_constructors_filenames = { | |
541 'Window': window_constructors_file, | |
542 'WorkerGlobalScope': workerglobalscope_constructors_file, | |
543 'SharedWorkerGlobalScope': sharedworkerglobalscope_constructors_file , | |
544 'DedicatedWorkerGlobalScope': dedicatedworkerglobalscope_constructor s_file, | |
545 'ServiceWorkerGlobalScope': serviceworkerglobalscope_constructors_fi le, | |
546 } | |
547 | |
548 global_constructors = parse_idl_files(idl_files_list, global_constructors_fi lenames) | |
549 | |
550 write_dependencies_file(interface_dependencies_file, only_if_changed) | |
551 for interface_name, filename in global_constructors_filenames.iteritems(): | |
552 if interface_name in interfaces_info: | |
553 write_global_constructors_partial_interface(interface_name, filename , global_constructors[interface_name], only_if_changed) | |
554 write_event_names_file(event_names_file, only_if_changed) | |
555 return interfaces_info | |
556 | |
557 | |
523 ################################################################################ | 558 ################################################################################ |
524 | 559 |
525 def main(): | 560 def main(): |
526 options, args = parse_options() | 561 options, args = parse_options() |
527 | 562 |
528 # Static IDL files are passed in a file (generated at GYP time), due to OS | 563 # Static IDL files are passed in a file (generated at GYP time), due to OS |
529 # command line length limits | 564 # command line length limits |
530 with open(options.idl_files_list) as idl_files_list: | 565 with open(options.idl_files_list) as idl_files_list: |
531 idl_files = [line.rstrip('\n') for line in idl_files_list] | 566 idl_files = [line.rstrip('\n') for line in idl_files_list] |
532 # Generated IDL files are passed at the command line, since these are in the | 567 # Generated IDL files are passed at the command line, since these are in the |
533 # build directory, which is determined at build time, not GYP time, so these | 568 # build directory, which is determined at build time, not GYP time, so these |
534 # cannot be included in the file listing static files | 569 # cannot be included in the file listing static files |
535 idl_files.extend(args) | 570 idl_files.extend(args) |
536 | 571 |
537 only_if_changed = options.write_file_only_if_changed | 572 compute(idl_files, |
538 global_constructors_filenames = { | 573 options.interface_dependencies_file, |
539 'Window': options.window_constructors_file, | 574 options.window_constructors_file, |
540 'WorkerGlobalScope': options.workerglobalscope_constructors_file, | 575 options.workerglobalscope_constructors_file, |
541 'SharedWorkerGlobalScope': options.sharedworkerglobalscope_constructors_ file, | 576 options.sharedworkerglobalscope_constructors_file, |
542 'DedicatedWorkerGlobalScope': options.dedicatedworkerglobalscope_constru ctors_file, | 577 options.dedicatedworkerglobalscope_constructors_file, |
543 'ServiceWorkerGlobalScope': options.serviceworkerglobalscope_constructor s_file, | 578 options.serviceworkerglobalscope_constructors_file, |
544 } | 579 options.event_names_file, |
545 | 580 options.write_file_only_if_changed) |
546 global_constructors = parse_idl_files(idl_files, global_constructors_filenam es) | |
547 | |
548 write_dependencies_file(options.interface_dependencies_file, only_if_changed ) | |
549 write_pickle_file(options.interfaces_info_file, interfaces_info, only_if_cha nged) | |
550 for interface_name, filename in global_constructors_filenames.iteritems(): | |
551 if interface_name in interfaces_info: | |
552 write_global_constructors_partial_interface(interface_name, filename , global_constructors[interface_name], only_if_changed) | |
553 write_event_names_file(options.event_names_file, only_if_changed) | |
554 | |
555 | 581 |
556 if __name__ == '__main__': | 582 if __name__ == '__main__': |
557 main() | 583 main() |
OLD | NEW |