| 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 | 8 import idlparser |
| 9 import logging | 9 import logging |
| 10 import multiprocessing | 10 import multiprocessing |
| 11 import os | 11 import os |
| 12 import os.path | 12 import os.path |
| 13 import re | 13 import re |
| 14 | 14 |
| 15 from idlnode import * | 15 from idlnode import * |
| 16 | 16 |
| 17 _logger = logging.getLogger('databasebuilder') | 17 _logger = logging.getLogger('databasebuilder') |
| 18 | 18 |
| 19 # Used in source annotations to specify the parent interface declaring | 19 # Used in source annotations to specify the parent interface declaring |
| 20 # a displaced declaration. The 'via' attribute specifies the parent interface | 20 # a displaced declaration. The 'via' attribute specifies the parent interface |
| 21 # which implements a displaced declaration. | 21 # which implements a displaced declaration. |
| 22 _VIA_ANNOTATION_ATTR_NAME = 'via' | 22 _VIA_ANNOTATION_ATTR_NAME = 'via' |
| 23 | 23 |
| 24 # Used in source annotations to specify the module that the interface was | |
| 25 # imported from. | |
| 26 _MODULE_ANNOTATION_ATTR_NAME = 'module' | |
| 27 | |
| 28 | 24 |
| 29 class DatabaseBuilderOptions(object): | 25 class DatabaseBuilderOptions(object): |
| 30 """Used in specifying options when importing new interfaces""" | 26 """Used in specifying options when importing new interfaces""" |
| 31 | 27 |
| 32 def __init__(self, | 28 def __init__(self, |
| 33 idl_syntax=idlparser.WEBIDL_SYNTAX, | 29 idl_syntax=idlparser.WEBIDL_SYNTAX, |
| 34 idl_defines=[], | 30 idl_defines=[], |
| 35 source=None, source_attributes={}, | 31 source=None, source_attributes={}, |
| 36 rename_operation_arguments_on_merge=False, | 32 rename_operation_arguments_on_merge=False, |
| 37 add_new_interfaces=True, | 33 add_new_interfaces=True, |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 for type_valued_attribute_name in ['Supplemental']: | 126 for type_valued_attribute_name in ['Supplemental']: |
| 131 if type_valued_attribute_name in ext_attrs_node: | 127 if type_valued_attribute_name in ext_attrs_node: |
| 132 value = ext_attrs_node[type_valued_attribute_name] | 128 value = ext_attrs_node[type_valued_attribute_name] |
| 133 if isinstance(value, str): | 129 if isinstance(value, str): |
| 134 ext_attrs_node[type_valued_attribute_name] = strip_modules(value) | 130 ext_attrs_node[type_valued_attribute_name] = strip_modules(value) |
| 135 | 131 |
| 136 map(rename_node, idl_file.all(IDLInterface)) | 132 map(rename_node, idl_file.all(IDLInterface)) |
| 137 map(rename_node, idl_file.all(IDLType)) | 133 map(rename_node, idl_file.all(IDLType)) |
| 138 map(rename_ext_attrs, idl_file.all(IDLExtAttrs)) | 134 map(rename_ext_attrs, idl_file.all(IDLExtAttrs)) |
| 139 | 135 |
| 140 def _annotate(self, interface, module_name, import_options): | 136 def _annotate(self, interface, import_options): |
| 141 """Adds @ annotations based on the source and source_attributes | 137 """Adds @ annotations based on the source and source_attributes |
| 142 members of import_options.""" | 138 members of import_options.""" |
| 143 | 139 |
| 144 source = import_options.source | 140 source = import_options.source |
| 145 if not source: | 141 if not source: |
| 146 return | 142 return |
| 147 | 143 |
| 148 def add_source_annotation(idl_node): | 144 def add_source_annotation(idl_node): |
| 149 annotation = IDLAnnotation( | 145 annotation = IDLAnnotation( |
| 150 copy.deepcopy(import_options.source_attributes)) | 146 copy.deepcopy(import_options.source_attributes)) |
| 151 idl_node.annotations[source] = annotation | 147 idl_node.annotations[source] = annotation |
| 152 if ((isinstance(idl_node, IDLInterface) or | 148 if ((isinstance(idl_node, IDLInterface) or |
| 153 isinstance(idl_node, IDLMember)) and | 149 isinstance(idl_node, IDLMember)) and |
| 154 idl_node.is_fc_suppressed): | 150 idl_node.is_fc_suppressed): |
| 155 annotation['suppressed'] = None | 151 annotation['suppressed'] = None |
| 156 | 152 |
| 157 add_source_annotation(interface) | 153 add_source_annotation(interface) |
| 158 interface.annotations[source][_MODULE_ANNOTATION_ATTR_NAME] = module_name | |
| 159 | 154 |
| 160 map(add_source_annotation, interface.parents) | 155 map(add_source_annotation, interface.parents) |
| 161 map(add_source_annotation, interface.constants) | 156 map(add_source_annotation, interface.constants) |
| 162 map(add_source_annotation, interface.attributes) | 157 map(add_source_annotation, interface.attributes) |
| 163 map(add_source_annotation, interface.operations) | 158 map(add_source_annotation, interface.operations) |
| 164 | 159 |
| 165 def _sign(self, node): | 160 def _sign(self, node): |
| 166 """Computes a unique signature for the node, for merging purposed, by | 161 """Computes a unique signature for the node, for merging purposed, by |
| 167 concatenating types and names in the declaration.""" | 162 concatenating types and names in the declaration.""" |
| 168 if isinstance(node, IDLType): | 163 if isinstance(node, IDLType): |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 parent.type = IDLType(implemented_name) | 383 parent.type = IDLType(implemented_name) |
| 389 if source: | 384 if source: |
| 390 parent.annotations[source] = IDLAnnotation( | 385 parent.annotations[source] = IDLAnnotation( |
| 391 import_options.source_attributes) | 386 import_options.source_attributes) |
| 392 interface.parents.append(parent) | 387 interface.parents.append(parent) |
| 393 | 388 |
| 394 def merge_imported_interfaces(self): | 389 def merge_imported_interfaces(self): |
| 395 """Merges all imported interfaces and loads them into the DB.""" | 390 """Merges all imported interfaces and loads them into the DB.""" |
| 396 | 391 |
| 397 # Step 1: Pre process imported interfaces | 392 # Step 1: Pre process imported interfaces |
| 398 for interface, module_name, import_options in self._imported_interfaces: | 393 for interface, import_options in self._imported_interfaces: |
| 399 self._annotate(interface, module_name, import_options) | 394 self._annotate(interface, import_options) |
| 400 | 395 |
| 401 # Step 2: Add all new interfaces and merge overlapping ones | 396 # Step 2: Add all new interfaces and merge overlapping ones |
| 402 for interface, module_name, import_options in self._imported_interfaces: | 397 for interface, import_options in self._imported_interfaces: |
| 403 if not interface.is_supplemental: | 398 if not interface.is_supplemental: |
| 404 if self._database.HasInterface(interface.id): | 399 if self._database.HasInterface(interface.id): |
| 405 old_interface = self._database.GetInterface(interface.id) | 400 old_interface = self._database.GetInterface(interface.id) |
| 406 self._merge_interfaces(old_interface, interface, import_options) | 401 self._merge_interfaces(old_interface, interface, import_options) |
| 407 else: | 402 else: |
| 408 if import_options.add_new_interfaces: | 403 if import_options.add_new_interfaces: |
| 409 self._database.AddInterface(interface) | 404 self._database.AddInterface(interface) |
| 410 | 405 |
| 411 # Step 3: Merge in supplemental interfaces | 406 # Step 3: Merge in supplemental interfaces |
| 412 for interface, module_name, import_options in self._imported_interfaces: | 407 for interface, import_options in self._imported_interfaces: |
| 413 if interface.is_supplemental: | 408 if interface.is_supplemental: |
| 414 target_name = interface.ext_attrs['Supplemental'] | 409 target_name = interface.ext_attrs['Supplemental'] |
| 415 if target_name: | 410 if target_name: |
| 416 # [Supplemental=DOMWindow] - merge into DOMWindow. | 411 # [Supplemental=DOMWindow] - merge into DOMWindow. |
| 417 target = target_name | 412 target = target_name |
| 418 else: | 413 else: |
| 419 # [Supplemental] - merge into existing inteface with same name. | 414 # [Supplemental] - merge into existing inteface with same name. |
| 420 target = interface.id | 415 target = interface.id |
| 421 if self._database.HasInterface(target): | 416 if self._database.HasInterface(target): |
| 422 old_interface = self._database.GetInterface(target) | 417 old_interface = self._database.GetInterface(target) |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 | 457 |
| 463 def _process_idl_file(self, idl_file, | 458 def _process_idl_file(self, idl_file, |
| 464 import_options): | 459 import_options): |
| 465 self._strip_ext_attributes(idl_file) | 460 self._strip_ext_attributes(idl_file) |
| 466 self._resolve_type_defs(idl_file) | 461 self._resolve_type_defs(idl_file) |
| 467 self._rename_types(idl_file, import_options) | 462 self._rename_types(idl_file, import_options) |
| 468 | 463 |
| 469 def enabled(idl_node): | 464 def enabled(idl_node): |
| 470 return self._is_node_enabled(idl_node, import_options.idl_defines) | 465 return self._is_node_enabled(idl_node, import_options.idl_defines) |
| 471 | 466 |
| 472 for module in idl_file.modules: | 467 for interface in idl_file.interfaces: |
| 473 for interface in module.interfaces: | 468 if not self._is_node_enabled(interface, import_options.idl_defines): |
| 474 if not self._is_node_enabled(interface, import_options.idl_defines): | 469 _logger.info('skipping interface %s (source=%s)' |
| 475 _logger.info('skipping interface %s/%s (source=%s)' | 470 % (interface.id, import_options.source)) |
| 476 % (module.id, interface.id, import_options.source)) | 471 continue |
| 477 continue | |
| 478 | 472 |
| 479 _logger.info('importing interface %s/%s (source=%s)' | 473 _logger.info('importing interface %s (source=%s)' |
| 480 % (module.id, interface.id, import_options.source)) | 474 % (interface.id, import_options.source)) |
| 481 interface.attributes = filter(enabled, interface.attributes) | 475 interface.attributes = filter(enabled, interface.attributes) |
| 482 interface.operations = filter(enabled, interface.operations) | 476 interface.operations = filter(enabled, interface.operations) |
| 483 self._imported_interfaces.append((interface, module.id, import_options)) | 477 self._imported_interfaces.append((interface, import_options)) |
| 484 | 478 |
| 485 for implStmt in module.implementsStatements: | 479 for implStmt in idl_file.implementsStatements: |
| 486 self._impl_stmts.append((implStmt, import_options)) | 480 self._impl_stmts.append((implStmt, import_options)) |
| 481 |
| 487 | 482 |
| 488 def _is_node_enabled(self, node, idl_defines): | 483 def _is_node_enabled(self, node, idl_defines): |
| 489 if not 'Conditional' in node.ext_attrs: | 484 if not 'Conditional' in node.ext_attrs: |
| 490 return True | 485 return True |
| 491 | 486 |
| 492 def enabled(condition): | 487 def enabled(condition): |
| 493 return 'ENABLE_%s' % condition in idl_defines | 488 return 'ENABLE_%s' % condition in idl_defines |
| 494 | 489 |
| 495 conditional = node.ext_attrs['Conditional'] | 490 conditional = node.ext_attrs['Conditional'] |
| 496 if conditional.find('&') != -1: | 491 if conditional.find('&') != -1: |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 # TODO(antonm): Ideally we'd like to have pristine copy of WebKit IDLs and
fetch | 579 # TODO(antonm): Ideally we'd like to have pristine copy of WebKit IDLs and
fetch |
| 585 # this information directly from it. Unfortunately right now database is
massaged | 580 # this information directly from it. Unfortunately right now database is
massaged |
| 586 # a lot so it's difficult to maintain necessary information on DOMWindow i
tself. | 581 # a lot so it's difficult to maintain necessary information on DOMWindow i
tself. |
| 587 interface = self._database.GetInterface(type) | 582 interface = self._database.GetInterface(type) |
| 588 if 'V8EnabledPerContext' in attr.ext_attrs: | 583 if 'V8EnabledPerContext' in attr.ext_attrs: |
| 589 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \ | 584 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \ |
| 590 attr.ext_attrs['V8EnabledPerContext'] | 585 attr.ext_attrs['V8EnabledPerContext'] |
| 591 if 'V8EnabledAtRuntime' in attr.ext_attrs: | 586 if 'V8EnabledAtRuntime' in attr.ext_attrs: |
| 592 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \ | 587 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \ |
| 593 attr.ext_attrs['V8EnabledAtRuntime'] or attr.id | 588 attr.ext_attrs['V8EnabledAtRuntime'] or attr.id |
| OLD | NEW |