| 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 base functionality for systems to generate | 6 """This module provides base functionality for systems to generate |
| 7 Dart APIs from the IDL database.""" | 7 Dart APIs from the IDL database.""" |
| 8 | 8 |
| 9 import os | 9 import os |
| 10 from generator import * | 10 from generator import * |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 def Generate(self): | 109 def Generate(self): |
| 110 self.StartInterface() | 110 self.StartInterface() |
| 111 self.AddMembers(self._interface) | 111 self.AddMembers(self._interface) |
| 112 self.AddSecondaryMembers(self._interface) | 112 self.AddSecondaryMembers(self._interface) |
| 113 self.FinishInterface() | 113 self.FinishInterface() |
| 114 | 114 |
| 115 def AddMembers(self, interface): | 115 def AddMembers(self, interface): |
| 116 for const in sorted(interface.constants, ConstantOutputOrder): | 116 for const in sorted(interface.constants, ConstantOutputOrder): |
| 117 self.AddConstant(const) | 117 self.AddConstant(const) |
| 118 | 118 |
| 119 attributes = [attr for attr in interface.attributes | 119 for attr in interface.attributes: |
| 120 if attr.type.id != 'EventListener'] | 120 if attr.type.id != 'EventListener': |
| 121 for (getter, setter) in _PairUpAttributes(attributes): | 121 self.AddAttribute(attr) |
| 122 self.AddAttribute(getter, setter) | |
| 123 | 122 |
| 124 # The implementation should define an indexer if the interface directly | 123 # The implementation should define an indexer if the interface directly |
| 125 # extends List. | 124 # extends List. |
| 126 (element_type, requires_indexer) = ListImplementationInfo( | 125 (element_type, requires_indexer) = ListImplementationInfo( |
| 127 interface, self._database) | 126 interface, self._database) |
| 128 if element_type: | 127 if element_type: |
| 129 if requires_indexer: | 128 if requires_indexer: |
| 130 self.AddIndexer(element_type) | 129 self.AddIndexer(element_type) |
| 131 else: | 130 else: |
| 132 self.AmendIndexer(element_type) | 131 self.AmendIndexer(element_type) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 148 | 147 |
| 149 def AddSecondaryMembers(self, interface): | 148 def AddSecondaryMembers(self, interface): |
| 150 # With multiple inheritance, attributes and operations of non-first | 149 # With multiple inheritance, attributes and operations of non-first |
| 151 # interfaces need to be added. Sometimes the attribute or operation is | 150 # interfaces need to be added. Sometimes the attribute or operation is |
| 152 # defined in the current interface as well as a parent. In that case we | 151 # defined in the current interface as well as a parent. In that case we |
| 153 # avoid making a duplicate definition and pray that the signatures match. | 152 # avoid making a duplicate definition and pray that the signatures match. |
| 154 secondary_parents = self._TransitiveSecondaryParents(interface) | 153 secondary_parents = self._TransitiveSecondaryParents(interface) |
| 155 for parent_interface in secondary_parents: | 154 for parent_interface in secondary_parents: |
| 156 if isinstance(parent_interface, str): # IsDartCollectionType(parent_inter
face) | 155 if isinstance(parent_interface, str): # IsDartCollectionType(parent_inter
face) |
| 157 continue | 156 continue |
| 158 attributes = [attr for attr in parent_interface.attributes | 157 for attr in parent_interface.attributes: |
| 159 if not FindMatchingAttribute(interface, attr)] | 158 if not FindMatchingAttribute(interface, attr): |
| 160 for (getter, setter) in _PairUpAttributes(attributes): | 159 self.AddSecondaryAttribute(parent_interface, attr) |
| 161 self.AddSecondaryAttribute(parent_interface, getter, setter) | |
| 162 | 160 |
| 163 # Group overloaded operations by id | 161 # Group overloaded operations by id |
| 164 operationsById = {} | 162 operationsById = {} |
| 165 for operation in parent_interface.operations: | 163 for operation in parent_interface.operations: |
| 166 if operation.id not in operationsById: | 164 if operation.id not in operationsById: |
| 167 operationsById[operation.id] = [] | 165 operationsById[operation.id] = [] |
| 168 operationsById[operation.id].append(operation) | 166 operationsById[operation.id].append(operation) |
| 169 | 167 |
| 170 # Generate operations | 168 # Generate operations |
| 171 for id in sorted(operationsById.keys()): | 169 for id in sorted(operationsById.keys()): |
| 172 if not any(op.id == id for op in interface.operations): | 170 if not any(op.id == id for op in interface.operations): |
| 173 operations = operationsById[id] | 171 operations = operationsById[id] |
| 174 info = AnalyzeOperation(interface, operations) | 172 info = AnalyzeOperation(interface, operations) |
| 175 self.AddSecondaryOperation(parent_interface, info) | 173 self.AddSecondaryOperation(parent_interface, info) |
| 176 | 174 |
| 177 def AddConstant(self, constant): | 175 def AddConstant(self, constant): |
| 178 pass | 176 pass |
| 179 | 177 |
| 180 def AddAttribute(self, getter, setter): | 178 def AddAttribute(self, attribute): |
| 181 pass | 179 pass |
| 182 | 180 |
| 183 def AddIndexer(self, element_type): | 181 def AddIndexer(self, element_type): |
| 184 pass | 182 pass |
| 185 | 183 |
| 186 def AmendIndexer(self, element_type): | 184 def AmendIndexer(self, element_type): |
| 187 pass | 185 pass |
| 188 | 186 |
| 189 def AddOperation(self, info): | 187 def AddOperation(self, info): |
| 190 pass | 188 pass |
| 191 | 189 |
| 192 def AddStaticOperation(self, info): | 190 def AddStaticOperation(self, info): |
| 193 pass | 191 pass |
| 194 | 192 |
| 195 def AddSecondaryAttribute(self, interface, getter, setter): | 193 def AddSecondaryAttribute(self, interface, attribute): |
| 196 pass | 194 pass |
| 197 | 195 |
| 198 def AddSecondaryOperation(self, interface, attr): | 196 def AddSecondaryOperation(self, interface, info): |
| 199 pass | 197 pass |
| 200 | 198 |
| 201 def _TransitiveSecondaryParents(self, interface): | 199 def _TransitiveSecondaryParents(self, interface): |
| 202 """Returns a list of all non-primary parents. | 200 """Returns a list of all non-primary parents. |
| 203 | 201 |
| 204 The list contains the interface objects for interfaces defined in the | 202 The list contains the interface objects for interfaces defined in the |
| 205 database, and the name for undefined interfaces. | 203 database, and the name for undefined interfaces. |
| 206 """ | 204 """ |
| 207 def walk(parents): | 205 def walk(parents): |
| 208 for parent in parents: | 206 for parent in parents: |
| 209 if IsDartCollectionType(parent.type.id): | 207 if IsDartCollectionType(parent.type.id): |
| 210 result.append(parent.type.id) | 208 result.append(parent.type.id) |
| 211 continue | 209 continue |
| 212 if self._database.HasInterface(parent.type.id): | 210 if self._database.HasInterface(parent.type.id): |
| 213 parent_interface = self._database.GetInterface(parent.type.id) | 211 parent_interface = self._database.GetInterface(parent.type.id) |
| 214 result.append(parent_interface) | 212 result.append(parent_interface) |
| 215 walk(parent_interface.parents) | 213 walk(parent_interface.parents) |
| 216 | 214 |
| 217 result = [] | 215 result = [] |
| 218 if interface.parents: | 216 if interface.parents: |
| 219 parent = interface.parents[0] | 217 parent = interface.parents[0] |
| 220 if IsPureInterface(parent.type.id): | 218 if IsPureInterface(parent.type.id): |
| 221 walk(interface.parents) | 219 walk(interface.parents) |
| 222 else: | 220 else: |
| 223 walk(interface.parents[1:]) | 221 walk(interface.parents[1:]) |
| 224 return result | 222 return result |
| 225 | 223 |
| 226 | 224 |
| 227 def _PairUpAttributes(attributes): | 225 def IsReadOnly(attribute): |
| 228 """Returns a list of (getter, setter) pairs sorted by name. | 226 return attribute.is_read_only or 'Replaceable' in attribute.ext_attrs |
| 229 | |
| 230 One element of the pair may be None. | |
| 231 """ | |
| 232 names = sorted(set(attr.id for attr in attributes)) | |
| 233 getters = {} | |
| 234 setters = {} | |
| 235 for attr in attributes: | |
| 236 if attr.is_fc_getter: | |
| 237 getters[attr.id] = attr | |
| 238 elif attr.is_fc_setter and 'Replaceable' not in attr.ext_attrs: | |
| 239 setters[attr.id] = attr | |
| 240 return [(getters.get(id), setters.get(id)) for id in names] | |
| OLD | NEW |