Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: Source/bindings/scripts/compute_dependencies.py

Issue 169743005: Faster run-bindings-tests (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Removed timings and fast is the only mode. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698