| 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 generates Dart APIs from the IDL database.""" | 6 """This module generates Dart APIs from the IDL database.""" |
| 7 | 7 |
| 8 import emitter | 8 import emitter |
| 9 import idlnode | 9 import idlnode |
| 10 import logging | 10 import logging |
| 11 import os | 11 import os |
| 12 import re | 12 import re |
| 13 import shutil | 13 import shutil |
| 14 import systembase |
| 14 from generator import * | 15 from generator import * |
| 15 from systembase import * | |
| 16 | 16 |
| 17 _logger = logging.getLogger('dartgenerator') | 17 _logger = logging.getLogger('dartgenerator') |
| 18 | 18 |
| 19 def MergeNodes(node, other): | 19 def MergeNodes(node, other): |
| 20 node.operations.extend(other.operations) | 20 node.operations.extend(other.operations) |
| 21 for attribute in other.attributes: | 21 for attribute in other.attributes: |
| 22 if not node.has_attribute(attribute): | 22 if not node.has_attribute(attribute): |
| 23 node.attributes.append(attribute) | 23 node.attributes.append(attribute) |
| 24 | 24 |
| 25 node.constants.extend(other.constants) | 25 node.constants.extend(other.constants) |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 _logger.info('Generating %s' % interface.id) | 265 _logger.info('Generating %s' % interface.id) |
| 266 | 266 |
| 267 generator = system.InterfaceGenerator(interface, | 267 generator = system.InterfaceGenerator(interface, |
| 268 common_prefix, | 268 common_prefix, |
| 269 super_interface_name, | 269 super_interface_name, |
| 270 source_filter) | 270 source_filter) |
| 271 if not generator: | 271 if not generator: |
| 272 return | 272 return |
| 273 | 273 |
| 274 generator.StartInterface() | 274 generator.StartInterface() |
| 275 | 275 generator.AddMembers(interface) |
| 276 for const in sorted(interface.constants, ConstantOutputOrder): | 276 secondary_parents = self._TransitiveSecondaryParents(interface) |
| 277 generator.AddConstant(const) | 277 generator.AddSecondaryMembers(interface, secondary_parents) |
| 278 | |
| 279 attributes = [attr for attr in interface.attributes | |
| 280 if attr.type.id != 'EventListener'] | |
| 281 for (getter, setter) in _PairUpAttributes(attributes): | |
| 282 generator.AddAttribute(getter, setter) | |
| 283 | |
| 284 # The implementation should define an indexer if the interface directly | |
| 285 # extends List. | |
| 286 (element_type, requires_indexer) = ListImplementationInfo( | |
| 287 interface, self._database) | |
| 288 if element_type: | |
| 289 if requires_indexer: | |
| 290 generator.AddIndexer(element_type) | |
| 291 else: | |
| 292 generator.AmendIndexer(element_type) | |
| 293 # Group overloaded operations by id | |
| 294 operationsById = {} | |
| 295 for operation in interface.operations: | |
| 296 if operation.id not in operationsById: | |
| 297 operationsById[operation.id] = [] | |
| 298 operationsById[operation.id].append(operation) | |
| 299 | |
| 300 # Generate operations | |
| 301 for id in sorted(operationsById.keys()): | |
| 302 operations = operationsById[id] | |
| 303 info = AnalyzeOperation(interface, operations) | |
| 304 if info.IsStatic(): | |
| 305 generator.AddStaticOperation(info) | |
| 306 else: | |
| 307 generator.AddOperation(info) | |
| 308 | |
| 309 # With multiple inheritance, attributes and operations of non-first | |
| 310 # interfaces need to be added. Sometimes the attribute or operation is | |
| 311 # defined in the current interface as well as a parent. In that case we | |
| 312 # avoid making a duplicate definition and pray that the signatures match. | |
| 313 | |
| 314 for parent_interface in self._TransitiveSecondaryParents(interface): | |
| 315 if isinstance(parent_interface, str): # IsDartCollectionType(parent_inter
face) | |
| 316 continue | |
| 317 attributes = [attr for attr in parent_interface.attributes | |
| 318 if not FindMatchingAttribute(interface, attr)] | |
| 319 for (getter, setter) in _PairUpAttributes(attributes): | |
| 320 generator.AddSecondaryAttribute(parent_interface, getter, setter) | |
| 321 | |
| 322 # Group overloaded operations by id | |
| 323 operationsById = {} | |
| 324 for operation in parent_interface.operations: | |
| 325 if operation.id not in operationsById: | |
| 326 operationsById[operation.id] = [] | |
| 327 operationsById[operation.id].append(operation) | |
| 328 | |
| 329 # Generate operations | |
| 330 for id in sorted(operationsById.keys()): | |
| 331 if not any(op.id == id for op in interface.operations): | |
| 332 operations = operationsById[id] | |
| 333 info = AnalyzeOperation(interface, operations) | |
| 334 generator.AddSecondaryOperation(parent_interface, info) | |
| 335 | |
| 336 generator.FinishInterface() | 278 generator.FinishInterface() |
| 337 | 279 |
| 338 def _TransitiveSecondaryParents(self, interface): | 280 def _TransitiveSecondaryParents(self, interface): |
| 339 """Returns a list of all non-primary parents. | 281 """Returns a list of all non-primary parents. |
| 340 | 282 |
| 341 The list contains the interface objects for interfaces defined in the | 283 The list contains the interface objects for interfaces defined in the |
| 342 database, and the name for undefined interfaces. | 284 database, and the name for undefined interfaces. |
| 343 """ | 285 """ |
| 344 def walk(parents): | 286 def walk(parents): |
| 345 for parent in parents: | 287 for parent in parents: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 | 320 |
| 379 def FixEventTargets(self, database): | 321 def FixEventTargets(self, database): |
| 380 for interface in database.GetInterfaces(): | 322 for interface in database.GetInterfaces(): |
| 381 # Create fake EventTarget parent interface for interfaces that have | 323 # Create fake EventTarget parent interface for interfaces that have |
| 382 # 'EventTarget' extended attribute. | 324 # 'EventTarget' extended attribute. |
| 383 if 'EventTarget' in interface.ext_attrs: | 325 if 'EventTarget' in interface.ext_attrs: |
| 384 ast = [('Annotation', [('Id', 'WebKit')]), | 326 ast = [('Annotation', [('Id', 'WebKit')]), |
| 385 ('InterfaceType', ('ScopedName', 'EventTarget'))] | 327 ('InterfaceType', ('ScopedName', 'EventTarget'))] |
| 386 interface.parents.append(idlnode.IDLParentInterface(ast)) | 328 interface.parents.append(idlnode.IDLParentInterface(ast)) |
| 387 | 329 |
| 388 def _PairUpAttributes(attributes): | |
| 389 """Returns a list of (getter, setter) pairs sorted by name. | |
| 390 | |
| 391 One element of the pair may be None. | |
| 392 """ | |
| 393 names = sorted(set(attr.id for attr in attributes)) | |
| 394 getters = {} | |
| 395 setters = {} | |
| 396 for attr in attributes: | |
| 397 if attr.is_fc_getter: | |
| 398 getters[attr.id] = attr | |
| 399 elif attr.is_fc_setter and 'Replaceable' not in attr.ext_attrs: | |
| 400 setters[attr.id] = attr | |
| 401 return [(getters.get(id), setters.get(id)) for id in names] | |
| 402 | |
| 403 # ------------------------------------------------------------------------------ | 330 # ------------------------------------------------------------------------------ |
| 404 | 331 |
| 405 class DummyImplementationSystem(System): | 332 class DummyImplementationSystem(systembase.System): |
| 406 """Generates a dummy implementation for use by the editor analysis. | 333 """Generates a dummy implementation for use by the editor analysis. |
| 407 | 334 |
| 408 All the code comes from hand-written library files. | 335 All the code comes from hand-written library files. |
| 409 """ | 336 """ |
| 410 | 337 |
| 411 def __init__(self, templates, database, emitters, output_dir): | 338 def __init__(self, templates, database, emitters, output_dir): |
| 412 super(DummyImplementationSystem, self).__init__( | 339 super(DummyImplementationSystem, self).__init__( |
| 413 templates, database, emitters, output_dir) | 340 templates, database, emitters, output_dir) |
| 414 factory_providers_file = os.path.join(self._output_dir, 'src', 'dummy', | 341 factory_providers_file = os.path.join(self._output_dir, 'src', 'dummy', |
| 415 'RegularFactoryProviders.dart') | 342 'RegularFactoryProviders.dart') |
| (...skipping 16 matching lines...) Expand all Loading... |
| 432 self._GenerateLibFile( | 359 self._GenerateLibFile( |
| 433 'dom_dummy.darttemplate', | 360 'dom_dummy.darttemplate', |
| 434 os.path.join(self._output_dir, 'dom_dummy.dart'), | 361 os.path.join(self._output_dir, 'dom_dummy.dart'), |
| 435 (self._interface_system._dart_interface_file_paths + | 362 (self._interface_system._dart_interface_file_paths + |
| 436 self._interface_system._dart_callback_file_paths + | 363 self._interface_system._dart_callback_file_paths + |
| 437 self._impl_file_paths)) | 364 self._impl_file_paths)) |
| 438 | 365 |
| 439 | 366 |
| 440 # ------------------------------------------------------------------------------ | 367 # ------------------------------------------------------------------------------ |
| 441 | 368 |
| 442 class DummyInterfaceGenerator(object): | 369 class DummyInterfaceGenerator(systembase.BaseGenerator): |
| 443 """Generates dummy implementation.""" | 370 """Generates dummy implementation.""" |
| 444 | 371 |
| 445 def __init__(self, system, interface): | 372 def __init__(self, system, interface): |
| 373 super(DummyInterfaceGenerator, self).__init__(system._database) |
| 446 self._system = system | 374 self._system = system |
| 447 self._interface = interface | 375 self._interface = interface |
| 448 | 376 |
| 449 def StartInterface(self): | 377 def StartInterface(self): |
| 450 # There is no implementation to match the interface, but there might be a | 378 # There is no implementation to match the interface, but there might be a |
| 451 # factory constructor for the Dart interface. | 379 # factory constructor for the Dart interface. |
| 452 constructor_info = AnalyzeConstructor(self._interface) | 380 constructor_info = AnalyzeConstructor(self._interface) |
| 453 if constructor_info: | 381 if constructor_info: |
| 454 dart_interface_name = self._interface.id | 382 dart_interface_name = self._interface.id |
| 455 self._EmitFactoryProvider(dart_interface_name, constructor_info) | 383 self._EmitFactoryProvider(dart_interface_name, constructor_info) |
| 456 | 384 |
| 457 def _EmitFactoryProvider(self, interface_name, constructor_info): | 385 def _EmitFactoryProvider(self, interface_name, constructor_info): |
| 458 factory_provider = '_' + interface_name + 'FactoryProvider' | 386 factory_provider = '_' + interface_name + 'FactoryProvider' |
| 459 self._system._factory_providers_emitter.Emit( | 387 self._system._factory_providers_emitter.Emit( |
| 460 self._system._templates.Load('factoryprovider.darttemplate'), | 388 self._system._templates.Load('factoryprovider.darttemplate'), |
| 461 FACTORYPROVIDER=factory_provider, | 389 FACTORYPROVIDER=factory_provider, |
| 462 CONSTRUCTOR=interface_name, | 390 CONSTRUCTOR=interface_name, |
| 463 PARAMETERS=constructor_info.ParametersImplementationDeclaration()) | 391 PARAMETERS=constructor_info.ParametersImplementationDeclaration()) |
| 464 | 392 |
| 465 def FinishInterface(self): | 393 def FinishInterface(self): |
| 466 pass | 394 pass |
| 467 | 395 |
| 468 def AddConstant(self, constant): | |
| 469 pass | |
| 470 | |
| 471 def AddAttribute(self, getter, setter): | |
| 472 pass | |
| 473 | |
| 474 def AddSecondaryAttribute(self, interface, getter, setter): | |
| 475 pass | |
| 476 | |
| 477 def AddSecondaryOperation(self, interface, info): | |
| 478 pass | |
| 479 | |
| 480 def AddIndexer(self, element_type): | |
| 481 pass | |
| 482 | |
| 483 def AmendIndexer(sefl, element_type): | |
| 484 pass | |
| 485 | |
| 486 def AddTypedArrayConstructors(self, element_type): | 396 def AddTypedArrayConstructors(self, element_type): |
| 487 pass | 397 pass |
| 488 | 398 |
| 489 def AddOperation(self, info): | |
| 490 pass | |
| 491 | |
| 492 def AddStaticOperation(self, info): | |
| 493 pass | |
| 494 | |
| 495 def AddEventAttributes(self, event_attrs): | 399 def AddEventAttributes(self, event_attrs): |
| 496 pass | 400 pass |
| OLD | NEW |