Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 # Copyright (c) 2012, 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 """This module provides shared functionality for the system to generate | 6 """This module provides shared functionality for the system to generate |
| 7 dart:html APIs from the IDL database.""" | 7 dart:html APIs from the IDL database.""" |
| 8 | 8 |
| 9 import emitter | 9 import emitter |
| 10 from generator import AnalyzeOperation, ConstantOutputOrder, \ | 10 from generator import AnalyzeOperation, ConstantOutputOrder, \ |
| 11 DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \ | 11 DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \ |
| 12 IsPureInterface, TypeOrNothing, ConvertToFuture, GetCallbackInfo | 12 IsPureInterface, TypeOrNothing, ConvertToFuture, GetCallbackInfo |
| 13 from htmlrenamer import convert_to_future_members | 13 from copy import deepcopy |
| 14 from htmlrenamer import convert_to_future_members, keep_overloaded_members, \ | |
| 15 private_html_members, renamed_html_members, renamed_overloads | |
| 16 import monitored | |
| 14 | 17 |
| 15 # Types that are accessible cross-frame in a limited fashion. | 18 # Types that are accessible cross-frame in a limited fashion. |
| 16 # In these cases, the base type (e.g., WindowBase) provides restricted access | 19 # In these cases, the base type (e.g., WindowBase) provides restricted access |
| 17 # while the subtype (e.g., Window) provides full access to the | 20 # while the subtype (e.g., Window) provides full access to the |
| 18 # corresponding objects if there are from the same frame. | 21 # corresponding objects if there are from the same frame. |
| 19 _secure_base_types = { | 22 _secure_base_types = { |
| 20 'Window': 'WindowBase', | 23 'Window': 'WindowBase', |
| 21 'Location': 'LocationBase', | 24 'Location': 'LocationBase', |
| 22 'History': 'HistoryBase', | 25 'History': 'HistoryBase', |
| 23 } | 26 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 76 else: | 79 else: |
| 77 for parent in self._database.Hierarchy(self._interface): | 80 for parent in self._database.Hierarchy(self._interface): |
| 78 if parent == self._interface: | 81 if parent == self._interface: |
| 79 continue | 82 continue |
| 80 parent_type_info = self._type_registry.TypeInfo(parent.id) | 83 parent_type_info = self._type_registry.TypeInfo(parent.id) |
| 81 if parent_type_info.list_item_type(): | 84 if parent_type_info.list_item_type(): |
| 82 self.AmendIndexer(parent_type_info.list_item_type()) | 85 self.AmendIndexer(parent_type_info.list_item_type()) |
| 83 break | 86 break |
| 84 | 87 |
| 85 # Group overloaded operations by name. | 88 # Group overloaded operations by name. |
| 89 self._AddRenamedOverloads(interface) | |
| 86 operationsByName = self._OperationsByName(interface) | 90 operationsByName = self._OperationsByName(interface) |
| 87 | 91 |
| 88 # Generate operations. | 92 # Generate operations. |
| 89 for id in sorted(operationsByName.keys()): | 93 for id in sorted(operationsByName.keys()): |
| 90 operations = operationsByName[id] | 94 operations = operationsByName[id] |
| 91 info = AnalyzeOperation(interface, operations) | 95 info = AnalyzeOperation(interface, operations) |
| 92 self.AddOperation(info, declare_only) | 96 self.AddOperation(info, declare_only) |
| 93 if ('%s.%s' % (interface.id, info.declared_name) in | 97 if ('%s.%s' % (interface.id, info.declared_name) in |
| 94 convert_to_future_members): | 98 convert_to_future_members): |
| 95 self.AddOperation(ConvertToFuture(info), declare_only) | 99 self.AddOperation(ConvertToFuture(info), declare_only) |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 112 operationsByName =self._OperationsByName(parent_interface) | 116 operationsByName =self._OperationsByName(parent_interface) |
| 113 | 117 |
| 114 # Generate operations. | 118 # Generate operations. |
| 115 for id in sorted(operationsByName.keys()): | 119 for id in sorted(operationsByName.keys()): |
| 116 if not any(op.id == id for op in interface.operations): | 120 if not any(op.id == id for op in interface.operations): |
| 117 operations = operationsByName[id] | 121 operations = operationsByName[id] |
| 118 info = AnalyzeOperation(interface, operations) | 122 info = AnalyzeOperation(interface, operations) |
| 119 self.SecondaryContext(parent_interface) | 123 self.SecondaryContext(parent_interface) |
| 120 self.AddOperation(info) | 124 self.AddOperation(info) |
| 121 | 125 |
| 126 def _AddRenamedOverloads(self, interface): | |
| 127 """The IDL has a number of functions with the same name but that accept | |
| 128 different types. This is fine for JavaScript, but results in vague type | |
| 129 signatures for Dart. We rename some of these (by adding a new identical | |
| 130 operation with a different DartName), but leave the original version as | |
| 131 well.""" | |
| 132 # This function gets called twice per interface if we generate both dart2js | |
| 133 # and dartium APIs, but we only want to rename the overloads once, so we | |
| 134 # keep track of this via already_renamed. | |
| 135 already_renamed = [operation.ext_attrs['DartName'] if 'DartName' in | |
| 136 operation.ext_attrs else '' for operation in interface.operations] | |
| 137 added_operations = [] | |
| 138 operations_by_name = self._OperationsByName(interface) | |
| 139 for operation in interface.operations: | |
| 140 full_operation_str = self._GetStringRepresentation(interface, operation) | |
| 141 if (full_operation_str in renamed_overloads and | |
| 142 renamed_overloads[full_operation_str] not in already_renamed): | |
| 143 cloned_operation = deepcopy(operation) | |
| 144 cloned_operation.ext_attrs['DartName'] = renamed_overloads[ | |
| 145 full_operation_str] | |
| 146 added_operations.append(cloned_operation) | |
| 147 operation_str = '%s.%s' % (interface.id, operation.id) | |
| 148 if (operation.id in operations_by_name and | |
| 149 len(operations_by_name[operation.id]) > 1 and | |
| 150 len(filter(lambda overload: overload.startswith(operation_str), | |
| 151 renamed_overloads.keys())) == 0 and | |
| 152 operation_str not in keep_overloaded_members and | |
| 153 operation_str not in renamed_html_members and | |
| 154 operation_str not in private_html_members): | |
| 155 print 'WARNING: Multiple type signatures for %s.%s' % ( | |
|
blois
2013/06/28 20:57:48
This should use the logging mechanism.
| |
| 156 interface.id, operation.id) | |
| 157 interface.operations += added_operations | |
| 158 | |
| 159 def _GetStringRepresentation(self, interface, operation): | |
| 160 """Given an IDLOperation, return a object-independent representation of the | |
| 161 operations's signature.""" | |
| 162 return '%s.%s(%s)' % (interface.id, operation.id, ', '.join( | |
| 163 ['%s %s' % (arg.type.id, arg.id) for arg in operation.arguments])) | |
| 164 | |
| 122 def _OperationsByName(self, interface): | 165 def _OperationsByName(self, interface): |
| 123 operationsByName = {} | 166 operationsByName = {} |
| 124 for operation in interface.operations: | 167 for operation in interface.operations: |
| 125 name = operation.ext_attrs.get('DartName', operation.id) | 168 name = operation.ext_attrs.get('DartName', operation.id) |
| 126 operationsByName.setdefault(name, []).append(operation) | 169 operationsByName.setdefault(name, []).append(operation) |
| 127 return operationsByName | 170 return operationsByName |
| 128 | 171 |
| 129 def AddConstant(self, constant): | 172 def AddConstant(self, constant): |
| 130 const_name = self._renamer.RenameMember( | 173 const_name = self._renamer.RenameMember( |
| 131 self._interface.id, constant, constant.id, 'get:', dartify_name=False) | 174 self._interface.id, constant, constant.id, 'get:', dartify_name=False) |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 585 if interface.parents: | 628 if interface.parents: |
| 586 parent = interface.parents[0] | 629 parent = interface.parents[0] |
| 587 if IsPureInterface(parent.type.id): | 630 if IsPureInterface(parent.type.id): |
| 588 walk(interface.parents) | 631 walk(interface.parents) |
| 589 else: | 632 else: |
| 590 walk(interface.parents[1:]) | 633 walk(interface.parents[1:]) |
| 591 return result | 634 return result |
| 592 | 635 |
| 593 def _DartType(self, type_name): | 636 def _DartType(self, type_name): |
| 594 return self._type_registry.DartType(type_name) | 637 return self._type_registry.DartType(type_name) |
| OLD | NEW |