Chromium Code Reviews| 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 |