| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 3 # for details. All rights reserved. Use of this source code is governed by a | 3 # for details. All rights reserved. Use of this source code is governed by a |
| 4 # BSD-style license that can be found in the LICENSE file. | 4 # BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 import copy | 6 import copy |
| 7 import database | 7 import database |
| 8 import idlparser | |
| 9 import logging | 8 import logging |
| 10 import monitored | 9 import monitored |
| 11 import multiprocessing | 10 import multiprocessing |
| 12 import os | 11 import os |
| 13 import os.path | 12 import os.path |
| 14 import re | 13 import re |
| 15 import sys | 14 import sys |
| 16 import tempfile | 15 import tempfile |
| 17 import time | 16 import time |
| 18 import traceback | 17 import traceback |
| (...skipping 14 matching lines...) Expand all Loading... |
| 33 # Used in source annotations to specify the parent interface declaring | 32 # Used in source annotations to specify the parent interface declaring |
| 34 # a displaced declaration. The 'via' attribute specifies the parent interface | 33 # a displaced declaration. The 'via' attribute specifies the parent interface |
| 35 # which implements a displaced declaration. | 34 # which implements a displaced declaration. |
| 36 _VIA_ANNOTATION_ATTR_NAME = 'via' | 35 _VIA_ANNOTATION_ATTR_NAME = 'via' |
| 37 | 36 |
| 38 | 37 |
| 39 class DatabaseBuilderOptions(object): | 38 class DatabaseBuilderOptions(object): |
| 40 """Used in specifying options when importing new interfaces""" | 39 """Used in specifying options when importing new interfaces""" |
| 41 | 40 |
| 42 def __init__(self, | 41 def __init__(self, |
| 43 idl_syntax=idlparser.WEBIDL_SYNTAX, | |
| 44 idl_defines=[], | 42 idl_defines=[], |
| 45 source=None, source_attributes={}, | 43 source=None, source_attributes={}, |
| 46 rename_operation_arguments_on_merge=False, | 44 rename_operation_arguments_on_merge=False, |
| 47 add_new_interfaces=True, | 45 add_new_interfaces=True, |
| 48 obsolete_old_declarations=False, | 46 obsolete_old_declarations=False, |
| 49 logging_level=logging.WARNING): | 47 logging_level=logging.WARNING): |
| 50 """Constructor. | 48 """Constructor. |
| 51 Args: | 49 Args: |
| 52 idl_syntax -- the syntax of the IDL file that is imported. | |
| 53 idl_defines -- list of definitions for the idl gcc pre-processor | 50 idl_defines -- list of definitions for the idl gcc pre-processor |
| 54 source -- the origin of the IDL file, used for annotating the | 51 source -- the origin of the IDL file, used for annotating the |
| 55 database. | 52 database. |
| 56 source_attributes -- this map of attributes is used as | 53 source_attributes -- this map of attributes is used as |
| 57 annotation attributes. | 54 annotation attributes. |
| 58 rename_operation_arguments_on_merge -- if True, will rename | 55 rename_operation_arguments_on_merge -- if True, will rename |
| 59 operation arguments when merging using the new name rather | 56 operation arguments when merging using the new name rather |
| 60 than the old. | 57 than the old. |
| 61 add_new_interfaces -- when False, if an interface is a new | 58 add_new_interfaces -- when False, if an interface is a new |
| 62 addition, it will be ignored. | 59 addition, it will be ignored. |
| 63 obsolete_old_declarations -- when True, if a declaration | 60 obsolete_old_declarations -- when True, if a declaration |
| 64 from a certain source is not re-declared, it will be removed. | 61 from a certain source is not re-declared, it will be removed. |
| 65 """ | 62 """ |
| 66 self.source = source | 63 self.source = source |
| 67 self.source_attributes = source_attributes | 64 self.source_attributes = source_attributes |
| 68 self.idl_syntax = idl_syntax | |
| 69 self.idl_defines = idl_defines | 65 self.idl_defines = idl_defines |
| 70 self.rename_operation_arguments_on_merge = \ | 66 self.rename_operation_arguments_on_merge = \ |
| 71 rename_operation_arguments_on_merge | 67 rename_operation_arguments_on_merge |
| 72 self.add_new_interfaces = add_new_interfaces | 68 self.add_new_interfaces = add_new_interfaces |
| 73 self.obsolete_old_declarations = obsolete_old_declarations | 69 self.obsolete_old_declarations = obsolete_old_declarations |
| 74 _logger.setLevel(logging_level) | 70 _logger.setLevel(logging_level) |
| 75 | 71 |
| 76 | 72 |
| 77 def _load_idl_file(build, file_name, import_options): | |
| 78 """Loads an IDL file into memory""" | |
| 79 idl_parser = idlparser.IDLParser(import_options.idl_syntax) | |
| 80 | |
| 81 try: | |
| 82 f = open(file_name, 'r') | |
| 83 content = f.read() | |
| 84 f.close() | |
| 85 | |
| 86 idl_ast = idl_parser.parse(content) | |
| 87 | |
| 88 return IDLFile(idl_ast, file_name) | |
| 89 except SyntaxError, e: | |
| 90 raise RuntimeError('Failed to load file %s: %s: Content: %s[end]' | |
| 91 % (file_name, e, content)) | |
| 92 | |
| 93 | |
| 94 def format_exception(e): | 73 def format_exception(e): |
| 95 exception_list = traceback.format_stack() | 74 exception_list = traceback.format_stack() |
| 96 exception_list = exception_list[:-2] | 75 exception_list = exception_list[:-2] |
| 97 exception_list.extend(traceback.format_tb(sys.exc_info()[2])) | 76 exception_list.extend(traceback.format_tb(sys.exc_info()[2])) |
| 98 exception_list.extend(traceback.format_exception_only(sys.exc_info()[0], sys
.exc_info()[1])) | 77 exception_list.extend(traceback.format_exception_only(sys.exc_info()[0], sys
.exc_info()[1])) |
| 99 | 78 |
| 100 exception_str = "Traceback (most recent call last):\n" | 79 exception_str = "Traceback (most recent call last):\n" |
| 101 exception_str += "".join(exception_list) | 80 exception_str += "".join(exception_list) |
| 102 # Removing the last \n | 81 # Removing the last \n |
| 103 exception_str = exception_str[:-1] | 82 exception_str = exception_str[:-1] |
| 104 | 83 |
| 105 return exception_str | 84 return exception_str |
| 106 | 85 |
| 107 | 86 |
| 108 # Compile IDL using Blink's IDL compiler. | 87 # Compile IDL using Blink's IDL compiler. |
| 109 def _new_compile_idl_file(build, file_name, import_options): | 88 def _compile_idl_file(build, file_name, import_options): |
| 110 try: | 89 try: |
| 111 idl_file_fullpath = os.path.realpath(file_name) | 90 idl_file_fullpath = os.path.realpath(file_name) |
| 112 idl_definition = build.idl_compiler.compile_file(idl_file_fullpath) | 91 idl_definition = build.idl_compiler.compile_file(idl_file_fullpath) |
| 113 return idl_definition | 92 return idl_definition |
| 114 except Exception as err: | 93 except Exception as err: |
| 115 print 'ERROR: idl_compiler.py: ' + os.path.basename(file_name) | 94 print 'ERROR: idl_compiler.py: ' + os.path.basename(file_name) |
| 116 print err | 95 print err |
| 117 print | 96 print |
| 118 print 'Stack Dump:' | 97 print 'Stack Dump:' |
| 119 print format_exception(err) | 98 print format_exception(err) |
| 120 | 99 |
| 121 return 1 | 100 return 1 |
| 122 | 101 |
| 123 | 102 |
| 124 # Create the Model (IDLFile) from the new AST of the compiled IDL file. | 103 # Create the Model (IDLFile) from the new AST of the compiled IDL file. |
| 125 def _new_load_idl_file(build, file_name, import_options): | 104 def _load_idl_file(build, file_name, import_options): |
| 126 try: | 105 try: |
| 127 # Compute interface name from IDL filename (it's one for one in WebKit). | 106 # Compute interface name from IDL filename (it's one for one in WebKit). |
| 128 name = os.path.splitext(os.path.basename(file_name))[0] | 107 name = os.path.splitext(os.path.basename(file_name))[0] |
| 129 | 108 |
| 130 idl_definition = new_asts[name] | 109 idl_definition = new_asts[name] |
| 131 return IDLFile(idl_definition, file_name) | 110 return IDLFile(idl_definition, file_name) |
| 132 except Exception as err: | 111 except Exception as err: |
| 133 print 'ERROR: loading AST from cache: ' + os.path.basename(file_name) | 112 print 'ERROR: loading AST from cache: ' + os.path.basename(file_name) |
| 134 print err | 113 print err |
| 135 print | 114 print |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 import_options.source_attributes) | 495 import_options.source_attributes) |
| 517 return | 496 return |
| 518 # not found, so add new one | 497 # not found, so add new one |
| 519 parent = IDLParentInterface(None) | 498 parent = IDLParentInterface(None) |
| 520 parent.type = IDLType(implemented_name) | 499 parent.type = IDLType(implemented_name) |
| 521 if source: | 500 if source: |
| 522 parent.annotations[source] = IDLAnnotation( | 501 parent.annotations[source] = IDLAnnotation( |
| 523 import_options.source_attributes) | 502 import_options.source_attributes) |
| 524 interface.parents.append(parent) | 503 interface.parents.append(parent) |
| 525 | 504 |
| 526 def merge_imported_interfaces(self, blink_parser): | 505 def merge_imported_interfaces(self): |
| 527 """Merges all imported interfaces and loads them into the DB.""" | 506 """Merges all imported interfaces and loads them into the DB.""" |
| 528 imported_interfaces = self._imported_interfaces | 507 imported_interfaces = self._imported_interfaces |
| 529 | 508 |
| 530 # Step 1: Pre process imported interfaces | 509 # Step 1: Pre process imported interfaces |
| 531 # for interface, import_options in imported_interfaces.iteritems(): | 510 # for interface, import_options in imported_interfaces.iteritems(): |
| 532 for interface, import_options in imported_interfaces: | 511 for interface, import_options in imported_interfaces: |
| 533 self._annotate(interface, import_options) | 512 self._annotate(interface, import_options) |
| 534 | 513 |
| 535 # Step 2: Add all new interfaces and merge overlapping ones | 514 # Step 2: Add all new interfaces and merge overlapping ones |
| 536 for interface, import_options in imported_interfaces: | 515 for interface, import_options in imported_interfaces: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 r'(\w+)\s+' | 548 r'(\w+)\s+' |
| 570 r'implements\s+' | 549 r'implements\s+' |
| 571 r'(\w+)\s*' | 550 r'(\w+)\s*' |
| 572 r';') | 551 r';') |
| 573 | 552 |
| 574 implements_matches = re.finditer(implements_re, idl_file_contents, re.MULTIL
INE) | 553 implements_matches = re.finditer(implements_re, idl_file_contents, re.MULTIL
INE) |
| 575 return [match.groups() for match in implements_matches] | 554 return [match.groups() for match in implements_matches] |
| 576 | 555 |
| 577 # Compile the IDL file with the Blink compiler and remember each AST for the | 556 # Compile the IDL file with the Blink compiler and remember each AST for the |
| 578 # IDL. | 557 # IDL. |
| 579 def _blink_compile_idl_files(self, file_paths, import_options, parallel, is_da
rt_idl): | 558 def _blink_compile_idl_files(self, file_paths, import_options, is_dart_idl): |
| 580 if not(is_dart_idl): | 559 if not(is_dart_idl): |
| 581 start_time = time.time() | 560 start_time = time.time() |
| 582 | 561 |
| 583 # 2-stage computation: individual, then overall | 562 # 2-stage computation: individual, then overall |
| 584 for file_path in file_paths: | 563 for file_path in file_paths: |
| 585 compute_info_individual(file_path, 'dart') | 564 compute_info_individual(file_path, 'dart') |
| 586 info_individuals = [info_individual()] | 565 info_individuals = [info_individual()] |
| 587 compute_interfaces_info_overall(info_individuals) | 566 compute_interfaces_info_overall(info_individuals) |
| 588 | 567 |
| 589 end_time = time.time() | 568 end_time = time.time() |
| 590 print 'Compute dependencies %s seconds' % round((end_time - start_time), 2
) | 569 print 'Compute dependencies %s seconds' % round((end_time - start_time), 2
) |
| 591 else: | 570 else: |
| 592 # Compute the interface_info for dart.idl for implements defined. This | 571 # Compute the interface_info for dart.idl for implements defined. This |
| 593 # file is special in that more than one interface can exist in this file. | 572 # file is special in that more than one interface can exist in this file. |
| 594 implement_pairs = self._compute_dart_idl_implements(file_paths[0]) | 573 implement_pairs = self._compute_dart_idl_implements(file_paths[0]) |
| 595 | 574 |
| 596 interfaces_info['__dart_idl___'] = { | 575 interfaces_info['__dart_idl___'] = { |
| 597 'implement_pairs': implement_pairs, | 576 'implement_pairs': implement_pairs, |
| 598 } | 577 } |
| 599 | 578 |
| 600 # use --parallel for async on a pool. Look at doing it like Blink | 579 # Parse the IDL files serially. |
| 601 blink_compiler = _new_compile_idl_file | 580 start_time = time.time() |
| 602 process_ast = self._process_ast | |
| 603 | 581 |
| 604 if parallel: | 582 for file_path in file_paths: |
| 605 # Parse the IDL files in parallel. | 583 file_path = os.path.normpath(file_path) |
| 606 pool = multiprocessing.Pool() | 584 ast = _compile_idl_file(self.build, file_path, import_options) |
| 607 try: | 585 self._process_ast(os.path.splitext(os.path.basename(file_path))[0], ast) |
| 608 for file_path in file_paths: | |
| 609 pool.apply_async(blink_compiler, | |
| 610 [ self.build, file_path, import_options], | |
| 611 callback = lambda new_ast: process_ast(new_ast, True)
) | |
| 612 pool.close() | |
| 613 pool.join() | |
| 614 except: | |
| 615 pool.terminate() | |
| 616 raise | |
| 617 else: | |
| 618 # Parse the IDL files serially. | |
| 619 start_time = time.time() | |
| 620 | 586 |
| 621 for file_path in file_paths: | 587 end_time = time.time() |
| 622 file_path = os.path.normpath(file_path) | 588 print 'Compiled %s IDL files in %s seconds' % (len(file_paths), |
| 623 ast = blink_compiler(self.build, file_path, import_options) | 589 round((end_time - start_time),
2)) |
| 624 process_ast(os.path.splitext(os.path.basename(file_path))[0], ast, True) | |
| 625 | 590 |
| 626 end_time = time.time() | 591 def _process_ast(self, filename, ast): |
| 627 print 'Compiled %s IDL files in %s seconds' % (len(file_paths), | 592 new_asts[filename] = ast |
| 628 round((end_time - start_time
), 2)) | |
| 629 | 593 |
| 630 def _process_ast(self, filename, ast, blink_parser = False): | 594 def import_idl_files(self, file_paths, import_options, is_dart_idl): |
| 631 if blink_parser: | 595 self._blink_compile_idl_files(file_paths, import_options, is_dart_idl) |
| 632 new_asts[filename] = ast | |
| 633 else: | |
| 634 for name in ast.interfaces: | |
| 635 # Index by filename some files are partial on another interface (e.g., | |
| 636 # DocumentFontFaceSet.idl). | |
| 637 new_asts[filename] = ast.interfaces | |
| 638 | 596 |
| 639 def import_idl_files(self, file_paths, import_options, parallel, blink_parser,
is_dart_idl): | 597 start_time = time.time() |
| 640 if blink_parser: | |
| 641 self._blink_compile_idl_files(file_paths, import_options, parallel, is_dar
t_idl) | |
| 642 | 598 |
| 643 # use --parallel for async on a pool. Look at doing it like Blink | 599 # Parse the IDL files in serial. |
| 644 idl_loader = _new_load_idl_file if blink_parser else _load_idl_file | 600 for file_path in file_paths: |
| 601 file_path = os.path.normpath(file_path) |
| 602 idl_file = _load_idl_file(self.build, file_path, import_options) |
| 603 _logger.info('Processing %s' % os.path.splitext(os.path.basename(file_path
))[0]) |
| 604 self._process_idl_file(idl_file, import_options, is_dart_idl) |
| 645 | 605 |
| 646 if parallel: | 606 end_time = time.time() |
| 647 # Parse the IDL files in parallel. | |
| 648 pool = multiprocessing.Pool() | |
| 649 try: | |
| 650 for file_path in file_paths: | |
| 651 pool.apply_async(idl_loader, | |
| 652 [ self.build, file_path, import_options], | |
| 653 callback = lambda idl_file: | |
| 654 self._process_idl_file(idl_file, import_options)) | |
| 655 pool.close() | |
| 656 pool.join() | |
| 657 except: | |
| 658 pool.terminate() | |
| 659 raise | |
| 660 else: | |
| 661 start_time = time.time() | |
| 662 | 607 |
| 663 # Parse the IDL files in serial. | 608 print 'Total %s files %sprocessed in databasebuilder in %s seconds' % \ |
| 664 for file_path in file_paths: | 609 (len(file_paths), '', round((end_time - start_time), 2)) |
| 665 file_path = os.path.normpath(file_path) | |
| 666 idl_file = idl_loader(self.build, file_path, import_options) | |
| 667 _logger.info('Processing %s' % os.path.splitext(os.path.basename(file_pa
th))[0]) | |
| 668 self._process_idl_file(idl_file, import_options, is_dart_idl) | |
| 669 | |
| 670 end_time = time.time() | |
| 671 | |
| 672 print 'Total %s files %sprocessed in databasebuilder in %s seconds' % \ | |
| 673 (len(file_paths), '' if blink_parser else 'compiled/', \ | |
| 674 round((end_time - start_time), 2)) | |
| 675 | 610 |
| 676 def _process_idl_file(self, idl_file, import_options, dart_idl = False): | 611 def _process_idl_file(self, idl_file, import_options, dart_idl = False): |
| 677 # TODO(terry): strip_ext_attributes on an idl_file does nothing. | 612 # TODO(terry): strip_ext_attributes on an idl_file does nothing. |
| 678 #self._strip_ext_attributes(idl_file) | 613 #self._strip_ext_attributes(idl_file) |
| 679 self._resolve_type_defs(idl_file) | 614 self._resolve_type_defs(idl_file) |
| 680 self._rename_types(idl_file, import_options) | 615 self._rename_types(idl_file, import_options) |
| 681 | 616 |
| 682 def enabled(idl_node): | 617 def enabled(idl_node): |
| 683 return self._is_node_enabled(idl_node, import_options.idl_defines) | 618 return self._is_node_enabled(idl_node, import_options.idl_defines) |
| 684 | 619 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 # TODO(antonm): Ideally we'd like to have pristine copy of WebKit IDLs and
fetch | 740 # TODO(antonm): Ideally we'd like to have pristine copy of WebKit IDLs and
fetch |
| 806 # this information directly from it. Unfortunately right now database is
massaged | 741 # this information directly from it. Unfortunately right now database is
massaged |
| 807 # a lot so it's difficult to maintain necessary information on Window itse
lf. | 742 # a lot so it's difficult to maintain necessary information on Window itse
lf. |
| 808 interface = self._database.GetInterface(type) | 743 interface = self._database.GetInterface(type) |
| 809 if 'V8EnabledPerContext' in attr.ext_attrs: | 744 if 'V8EnabledPerContext' in attr.ext_attrs: |
| 810 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \ | 745 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \ |
| 811 attr.ext_attrs['V8EnabledPerContext'] | 746 attr.ext_attrs['V8EnabledPerContext'] |
| 812 if 'V8EnabledAtRuntime' in attr.ext_attrs: | 747 if 'V8EnabledAtRuntime' in attr.ext_attrs: |
| 813 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \ | 748 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \ |
| 814 attr.ext_attrs['V8EnabledAtRuntime'] or attr.id | 749 attr.ext_attrs['V8EnabledAtRuntime'] or attr.id |
| OLD | NEW |