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 |