| OLD | NEW |
| 1 # Copyright (C) 2013 Google Inc. All rights reserved. | 1 # Copyright (C) 2013 Google Inc. All rights reserved. |
| 2 # coding=utf-8 |
| 2 # | 3 # |
| 3 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
| 5 # met: | 6 # met: |
| 6 # | 7 # |
| 7 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 11 # copyright notice, this list of conditions and the following disclaimer |
| 11 # in the documentation and/or other materials provided with the | 12 # in the documentation and/or other materials provided with the |
| (...skipping 13 matching lines...) Expand all Loading... |
| 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | 29 |
| 29 """Generate template values for an interface. | 30 """Generate template values for an interface. |
| 30 | 31 |
| 31 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler | 32 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler |
| 32 """ | 33 """ |
| 33 | 34 |
| 34 from collections import defaultdict | 35 from collections import defaultdict |
| 36 import itertools |
| 37 from operator import itemgetter |
| 35 | 38 |
| 36 import idl_types | 39 import idl_types |
| 37 from idl_types import IdlType, inherits_interface, IdlArrayOrSequenceType, IdlAr
rayType | 40 from idl_types import IdlType, inherits_interface, IdlArrayOrSequenceType, IdlAr
rayType |
| 38 import dart_attributes | 41 import dart_attributes |
| 39 import dart_methods | 42 import dart_methods |
| 40 import dart_types | 43 import dart_types |
| 41 from dart_utilities import DartUtilities | 44 from dart_utilities import DartUtilities |
| 42 from v8_globals import includes | 45 from v8_globals import includes |
| 46 import v8_attributes |
| 47 import v8_interface |
| 43 | 48 |
| 44 | 49 |
| 45 INTERFACE_H_INCLUDES = frozenset([ | 50 INTERFACE_H_INCLUDES = frozenset([ |
| 46 'bindings/core/dart/DartDOMWrapper.h', | 51 'bindings/core/dart/DartDOMWrapper.h', |
| 47 'platform/heap/Handle.h', | 52 'platform/heap/Handle.h', |
| 48 ]) | 53 ]) |
| 49 | 54 |
| 50 INTERFACE_CPP_INCLUDES = frozenset([ | 55 INTERFACE_CPP_INCLUDES = frozenset([ |
| 51 | 56 |
| 52 'bindings/core/dart/DartUtilities.h', | 57 'bindings/core/dart/DartUtilities.h', |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 for extended_attribute_name in extended_attributes: | 394 for extended_attribute_name in extended_attributes: |
| 390 ignore_extended_values = IGNORE_EXTENDED_ATTRIBUTES.get(extended_attribu
te_name) | 395 ignore_extended_values = IGNORE_EXTENDED_ATTRIBUTES.get(extended_attribu
te_name) |
| 391 if ignore_extended_values != None: | 396 if ignore_extended_values != None: |
| 392 extended_attribute_value = extended_attributes.get(extended_attribut
e_name) | 397 extended_attribute_value = extended_attributes.get(extended_attribut
e_name) |
| 393 if ((not ignore_extended_values and extended_attribute_value == None
) or | 398 if ((not ignore_extended_values and extended_attribute_value == None
) or |
| 394 extended_attribute_value in ignore_extended_values): | 399 extended_attribute_value in ignore_extended_values): |
| 395 return True | 400 return True |
| 396 return False | 401 return False |
| 397 | 402 |
| 398 | 403 |
| 399 def add_native_entries(interface, constructors, is_custom): | 404 # TODO(terry): Rename genenerate_interface to interface_context. |
| 400 for constructor in constructors: | 405 def interface_context(interface): |
| 401 types = None | 406 context = v8_interface.interface_context(interface) |
| 402 if not is_custom: | |
| 403 types = [arg['preprocessed_type'] | |
| 404 for arg in constructor['arguments']] | |
| 405 argument_names = [arg['name'] for arg in constructor['arguments']] | |
| 406 native_entry = \ | |
| 407 DartUtilities.generate_native_entry(interface.name, constructor, | |
| 408 None, 'Constructor', None, | |
| 409 argument_names, types) | |
| 410 constructor.update({'native_entry': native_entry}) | |
| 411 | 407 |
| 408 includes.clear() |
| 412 | 409 |
| 413 def generate_interface(interface): | |
| 414 includes.clear() | |
| 415 includes.update(INTERFACE_CPP_INCLUDES) | 410 includes.update(INTERFACE_CPP_INCLUDES) |
| 416 header_includes = set(INTERFACE_H_INCLUDES) | 411 header_includes = set(INTERFACE_H_INCLUDES) |
| 417 | 412 |
| 418 parent_interface = interface.parent | 413 parent_interface = interface.parent |
| 419 if parent_interface: | 414 if parent_interface: |
| 420 header_includes.update(dart_types.includes_for_interface(parent_interfac
e)) | 415 header_includes.update(dart_types.includes_for_interface(parent_interfac
e)) |
| 421 extended_attributes = interface.extended_attributes | 416 extended_attributes = interface.extended_attributes |
| 422 | 417 |
| 423 is_audio_buffer = inherits_interface(interface.name, 'AudioBuffer') | |
| 424 if is_audio_buffer: | |
| 425 includes.add('modules/webaudio/AudioBuffer.h') | |
| 426 | |
| 427 is_document = inherits_interface(interface.name, 'Document') | 418 is_document = inherits_interface(interface.name, 'Document') |
| 428 if is_document: | 419 if is_document: |
| 429 # FIXME(vsm): We probably need bindings/dart/DartController and | 420 # FIXME(vsm): We probably need bindings/dart/DartController and |
| 430 # core/frame/LocalFrame.h here. | 421 # core/frame/LocalFrame.h here. |
| 431 includes.update(['DartDocument.h']) | 422 includes.update(['DartDocument.h']) |
| 432 | 423 |
| 433 if inherits_interface(interface.name, 'DataTransferItemList'): | 424 if inherits_interface(interface.name, 'DataTransferItemList'): |
| 434 # FIXME(jacobr): this is a hack. | 425 # FIXME(jacobr): this is a hack. |
| 435 includes.update(['core/html/HTMLCollection.h']) | 426 includes.update(['core/html/HTMLCollection.h']) |
| 436 | 427 |
| 437 | 428 |
| 438 if inherits_interface(interface.name, 'EventTarget'): | 429 if inherits_interface(interface.name, 'EventTarget'): |
| 439 includes.update(['bindings/core/dart/DartEventListener.h']) | 430 includes.update(['bindings/core/dart/DartEventListener.h']) |
| 440 | 431 |
| 441 # [ActiveDOMObject] | |
| 442 is_active_dom_object = 'ActiveDOMObject' in extended_attributes | |
| 443 | |
| 444 # [CheckSecurity] | |
| 445 is_check_security = 'CheckSecurity' in extended_attributes | |
| 446 if is_check_security: | |
| 447 includes.add('bindings/common/BindingSecurity.h') | |
| 448 | |
| 449 # [DependentLifetime] | |
| 450 is_dependent_lifetime = 'DependentLifetime' in extended_attributes | |
| 451 | |
| 452 # [MeasureAs] | |
| 453 # TODO(terry): Remove Me? | |
| 454 # is_measure_as = 'MeasureAs' in extended_attributes | |
| 455 # if is_measure_as: | |
| 456 # includes.add('core/frame/UseCounter.h') | |
| 457 | |
| 458 # [SetWrapperReferenceFrom] | |
| 459 reachable_node_function = extended_attributes.get('SetWrapperReferenceFrom') | |
| 460 if reachable_node_function: | |
| 461 # FIXME(vsm): We may need bindings/dart/DartGCController.h instead. | |
| 462 includes.update(['bindings/core/v8/V8GCController.h', | |
| 463 'core/dom/Element.h']) | |
| 464 | |
| 465 # [SetWrapperReferenceTo] | 432 # [SetWrapperReferenceTo] |
| 466 set_wrapper_reference_to_list = [{ | 433 set_wrapper_reference_to_list = [{ |
| 467 'name': argument.name, | 434 'name': argument.name, |
| 468 # FIXME: properly should be: | 435 # FIXME: properly should be: |
| 469 # 'cpp_type': argument.idl_type.cpp_type_args(used_as_rvalue_type=True), | 436 # 'cpp_type': argument.idl_type.cpp_type_args(used_as_rvalue_type=True), |
| 470 # (if type is non-wrapper type like NodeFilter, normally RefPtr) | 437 # (if type is non-wrapper type like NodeFilter, normally RefPtr) |
| 471 # Raw pointers faster though, and NodeFilter hacky anyway. | 438 # Raw pointers faster though, and NodeFilter hacky anyway. |
| 472 'cpp_type': argument.idl_type.implemented_as + '*', | 439 'cpp_type': argument.idl_type.implemented_as + '*', |
| 473 'idl_type': argument.idl_type, | 440 'idl_type': argument.idl_type, |
| 474 'v8_type': dart_types.v8_type(argument.idl_type.name), | 441 'v8_type': dart_types.v8_type(argument.idl_type.name), |
| 475 } for argument in extended_attributes.get('SetWrapperReferenceTo', [])] | 442 } for argument in extended_attributes.get('SetWrapperReferenceTo', [])] |
| 476 for set_wrapper_reference_to in set_wrapper_reference_to_list: | 443 for set_wrapper_reference_to in set_wrapper_reference_to_list: |
| 477 set_wrapper_reference_to['idl_type'].add_includes_for_type() | 444 set_wrapper_reference_to['idl_type'].add_includes_for_type() |
| 478 | 445 |
| 479 # [SpecialWrapFor] | 446 context.update({ |
| 480 if 'SpecialWrapFor' in extended_attributes: | |
| 481 special_wrap_for = extended_attributes['SpecialWrapFor'].split('|') | |
| 482 else: | |
| 483 special_wrap_for = [] | |
| 484 for special_wrap_interface in special_wrap_for: | |
| 485 dart_types.add_includes_for_interface(special_wrap_interface) | |
| 486 | |
| 487 # [Custom=Wrap], [SetWrapperReferenceFrom] | |
| 488 has_visit_dom_wrapper = ( | |
| 489 DartUtilities.has_extended_attribute_value(interface, 'Custom', 'VisitDO
MWrapper') or | |
| 490 reachable_node_function or | |
| 491 set_wrapper_reference_to_list) | |
| 492 | |
| 493 this_gc_type = DartUtilities.gc_type(interface) | |
| 494 | |
| 495 template_contents = { | |
| 496 'conditional_string': DartUtilities.conditional_string(interface), # [C
onditional] | 447 'conditional_string': DartUtilities.conditional_string(interface), # [C
onditional] |
| 497 'cpp_class': DartUtilities.cpp_name(interface), | 448 'cpp_class': DartUtilities.cpp_name(interface), |
| 498 'gc_type': this_gc_type, | |
| 499 'has_custom_legacy_call_as_function': DartUtilities.has_extended_attribu
te_value(interface, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFu
nction] | |
| 500 'has_custom_to_v8': DartUtilities.has_extended_attribute_value(interface
, 'Custom', 'ToV8'), # [Custom=ToV8] | |
| 501 'has_custom_wrap': DartUtilities.has_extended_attribute_value(interface,
'Custom', 'Wrap'), # [Custom=Wrap] | |
| 502 'has_visit_dom_wrapper': has_visit_dom_wrapper, | |
| 503 'header_includes': header_includes, | 449 'header_includes': header_includes, |
| 504 'interface_name': interface.name, | 450 'is_garbage_collected': context['gc_type'] == 'GarbageCollectedObject', |
| 505 'is_active_dom_object': is_active_dom_object, | 451 'is_will_be_garbage_collected': context['gc_type'] == 'WillBeGarbageColl
ectedObject', |
| 506 'is_audio_buffer': is_audio_buffer, | |
| 507 'is_check_security': is_check_security, | |
| 508 'is_dependent_lifetime': is_dependent_lifetime, | |
| 509 'is_document': is_document, | |
| 510 'is_event_target': inherits_interface(interface.name, 'EventTarget'), | |
| 511 'is_exception': interface.is_exception, | |
| 512 'is_garbage_collected': this_gc_type == 'GarbageCollectedObject', | |
| 513 'is_will_be_garbage_collected': this_gc_type == 'WillBeGarbageCollectedO
bject', | |
| 514 'is_node': inherits_interface(interface.name, 'Node'), | |
| 515 'measure_as': DartUtilities.measure_as(interface), # [MeasureAs] | 452 'measure_as': DartUtilities.measure_as(interface), # [MeasureAs] |
| 516 'parent_interface': parent_interface, | |
| 517 'pass_cpp_type': dart_types.cpp_template_type( | 453 'pass_cpp_type': dart_types.cpp_template_type( |
| 518 dart_types.cpp_ptr_type('PassRefPtr', 'RawPtr', this_gc_type), | 454 dart_types.cpp_ptr_type('PassRefPtr', 'RawPtr', context['gc_type']), |
| 519 DartUtilities.cpp_name(interface)), | 455 DartUtilities.cpp_name(interface)), |
| 520 'reachable_node_function': reachable_node_function, | |
| 521 'runtime_enabled_function': DartUtilities.runtime_enabled_function_name(
interface), # [RuntimeEnabled] | 456 'runtime_enabled_function': DartUtilities.runtime_enabled_function_name(
interface), # [RuntimeEnabled] |
| 522 'set_wrapper_reference_to_list': set_wrapper_reference_to_list, | 457 'set_wrapper_reference_to_list': set_wrapper_reference_to_list, |
| 523 'special_wrap_for': special_wrap_for, | |
| 524 'dart_class': dart_types.dart_type(interface.name), | 458 'dart_class': dart_types.dart_type(interface.name), |
| 525 'v8_class': DartUtilities.v8_class_name(interface), | 459 'v8_class': DartUtilities.v8_class_name(interface), |
| 526 'wrapper_configuration': 'WrapperConfiguration::Dependent' | 460 }) |
| 527 if (has_visit_dom_wrapper or | |
| 528 is_active_dom_object or | |
| 529 is_dependent_lifetime) | |
| 530 else 'WrapperConfiguration::Independent', | |
| 531 } | |
| 532 | 461 |
| 533 # Constructors | 462 # Constructors |
| 534 constructors = [generate_constructor(interface, constructor) | 463 constructors = [constructor_context(interface, constructor) |
| 535 for constructor in interface.constructors | 464 for constructor in interface.constructors |
| 536 # FIXME: shouldn't put named constructors with constructors | 465 # FIXME: shouldn't put named constructors with constructors |
| 537 # (currently needed for Perl compatibility) | 466 # (currently needed for Perl compatibility) |
| 538 # Handle named constructors separately | 467 # Handle named constructors separately |
| 539 if constructor.name == 'Constructor'] | 468 if constructor.name == 'Constructor'] |
| 540 generate_constructor_overloads(constructors) | 469 if len(constructors) > 1: |
| 470 context.update({'constructor_overloads': overloads_context(constructors)
}) |
| 541 | 471 |
| 542 # [CustomConstructor] | 472 # [CustomConstructor] |
| 543 custom_constructors = [generate_custom_constructor(interface, constructor) | 473 custom_constructors = [custom_constructor_context(interface, constructor) |
| 544 for constructor in interface.custom_constructors] | 474 for constructor in interface.custom_constructors] |
| 545 | 475 |
| 546 # [EventConstructor] | |
| 547 has_event_constructor = 'EventConstructor' in extended_attributes | |
| 548 any_type_attributes = [attribute for attribute in interface.attributes | |
| 549 if attribute.idl_type.name == 'Any'] | |
| 550 if has_event_constructor: | |
| 551 includes.add('bindings/core/v8/Dictionary.h') | |
| 552 if any_type_attributes: | |
| 553 includes.add('bindings/core/v8/SerializedScriptValue.h') | |
| 554 | |
| 555 # [NamedConstructor] | 476 # [NamedConstructor] |
| 556 named_constructor = generate_named_constructor(interface) | 477 named_constructor = generate_named_constructor(interface) |
| 557 | 478 |
| 558 add_native_entries(interface, constructors, bool(custom_constructors)) | 479 generate_method_native_entries(interface, constructors, 'Constructor') |
| 559 add_native_entries(interface, custom_constructors, bool(custom_constructors)
) | 480 generate_method_native_entries(interface, custom_constructors, 'Constructor'
) |
| 560 if named_constructor: | 481 if named_constructor: |
| 561 add_native_entries(interface, [named_constructor], bool(custom_construct
ors)) | 482 generate_method_native_entries(interface, [named_constructor], |
| 483 'Constructor') |
| 484 event_constructor = None |
| 485 if context['has_event_constructor']: |
| 486 event_constructor = { |
| 487 'native_entries': [ |
| 488 DartUtilities.generate_native_entry( |
| 489 interface.name, None, 'Constructor', False, 2)], |
| 490 } |
| 562 | 491 |
| 563 if (constructors or custom_constructors or has_event_constructor or | 492 if (context['constructors'] or custom_constructors or context['has_event_con
structor'] or |
| 564 named_constructor): | 493 named_constructor): |
| 565 includes.add('core/frame/LocalDOMWindow.h') | 494 includes.add('core/frame/LocalDOMWindow.h') |
| 566 | 495 |
| 567 template_contents.update({ | 496 context.update({ |
| 568 'any_type_attributes': any_type_attributes, | |
| 569 'constructors': constructors, | 497 'constructors': constructors, |
| 570 'custom_constructors': custom_constructors, | 498 'custom_constructors': custom_constructors, |
| 499 'event_constructor': event_constructor, |
| 571 'has_custom_constructor': bool(custom_constructors), | 500 'has_custom_constructor': bool(custom_constructors), |
| 572 'has_event_constructor': has_event_constructor, | |
| 573 'interface_length': | 501 'interface_length': |
| 574 interface_length(interface, constructors + custom_constructors), | 502 v8_interface.interface_length(interface, constructors + custom_const
ructors), |
| 575 'is_constructor_call_with_document': DartUtilities.has_extended_attribut
e_value( | 503 'is_constructor_call_with_document': DartUtilities.has_extended_attribut
e_value( |
| 576 interface, 'ConstructorCallWith', 'Document'), # [ConstructorCallWi
th=Document] | 504 interface, 'ConstructorCallWith', 'Document'), # [ConstructorCallWi
th=Document] |
| 577 'is_constructor_call_with_execution_context': DartUtilities.has_extended
_attribute_value( | 505 'is_constructor_call_with_execution_context': DartUtilities.has_extended
_attribute_value( |
| 578 interface, 'ConstructorCallWith', 'ExecutionContext'), # [Construct
orCallWith=ExeuctionContext] | 506 interface, 'ConstructorCallWith', 'ExecutionContext'), # [Construct
orCallWith=ExeuctionContext] |
| 579 'is_constructor_raises_exception': extended_attributes.get('RaisesExcept
ion') == 'Constructor', # [RaisesException=Constructor] | |
| 580 'named_constructor': named_constructor, | 507 'named_constructor': named_constructor, |
| 581 }) | 508 }) |
| 582 | 509 |
| 583 # Constants | |
| 584 template_contents.update({ | |
| 585 'constants': [generate_constant(constant) for constant in interface.cons
tants], | |
| 586 'do_not_check_constants': 'DoNotCheckConstants' in extended_attributes, | |
| 587 }) | |
| 588 | |
| 589 # Attributes | 510 # Attributes |
| 590 attributes = [dart_attributes.generate_attribute(interface, attribute) | 511 attributes = [dart_attributes.attribute_context(interface, attribute) |
| 591 for attribute in interface.attributes | 512 for attribute in interface.attributes |
| 592 # Skip attributes in the IGNORE_MEMBERS list or if an | 513 # Skip attributes in the IGNORE_MEMBERS list or if an |
| 593 # extended attribute is in the IGNORE_EXTENDED_ATTRIBUTES. | 514 # extended attribute is in the IGNORE_EXTENDED_ATTRIBUTES. |
| 594 if (not _suppress_attribute(interface.name, attribute.name
) and | 515 if (not _suppress_attribute(interface.name, attribute.name
) and |
| 595 not dart_attributes.is_constructor_attribute(attribute
) and | 516 not v8_attributes.is_constructor_attribute(attribute)
and |
| 596 not _suppress_extended_attributes(attribute.extended_a
ttributes) and | 517 not _suppress_extended_attributes(attribute.extended_a
ttributes) and |
| 597 not ('DartSuppress' in attribute.extended_attributes a
nd | 518 not ('DartSuppress' in attribute.extended_attributes a
nd |
| 598 attribute.extended_attributes.get('DartSuppress') ==
None))] | 519 attribute.extended_attributes.get('DartSuppress') ==
None))] |
| 599 template_contents.update({ | 520 context.update({ |
| 600 'attributes': attributes, | 521 'attributes': attributes, |
| 601 'has_accessors': any(attribute['is_expose_js_accessors'] for attribute i
n attributes), | 522 'has_accessors': any(attribute['is_expose_js_accessors'] for attribute i
n attributes), |
| 602 'has_attribute_configuration': any( | 523 'has_attribute_configuration': any( |
| 603 not (attribute['is_expose_js_accessors'] or | 524 not (attribute['is_expose_js_accessors'] or |
| 604 attribute['is_static'] or | 525 attribute['is_static'] or |
| 605 attribute['runtime_enabled_function'] or | 526 attribute['runtime_enabled_function'] or |
| 606 attribute['per_context_enabled_function']) | 527 attribute['per_context_enabled_function']) |
| 607 for attribute in attributes), | 528 for attribute in attributes), |
| 608 'has_constructor_attributes': any(attribute['constructor_type'] for attr
ibute in attributes), | 529 'has_constructor_attributes': any(attribute['constructor_type'] for attr
ibute in attributes), |
| 609 'has_per_context_enabled_attributes': any(attribute['per_context_enabled
_function'] for attribute in attributes), | 530 'has_per_context_enabled_attributes': any(attribute['per_context_enabled
_function'] for attribute in attributes), |
| 610 'has_replaceable_attributes': any(attribute['is_replaceable'] for attrib
ute in attributes), | 531 'has_replaceable_attributes': any(attribute['is_replaceable'] for attrib
ute in attributes), |
| 611 }) | 532 }) |
| 612 | 533 |
| 613 # Methods | 534 # Methods |
| 614 methods = [dart_methods.generate_method(interface, method) | 535 methods = [dart_methods.method_context(interface, method) |
| 615 for method in interface.operations | 536 for method in interface.operations |
| 616 # Skip anonymous special operations (methods name empty). | 537 # Skip anonymous special operations (methods name empty). |
| 617 # Skip methods in our IGNORE_MEMBERS list. | 538 # Skip methods in our IGNORE_MEMBERS list. |
| 618 # Skip methods w/ extended attributes in IGNORE_EXTENDED_ATTRIBUT
ES list. | 539 # Skip methods w/ extended attributes in IGNORE_EXTENDED_ATTRIBUT
ES list. |
| 619 if (method.name and | 540 if (method.name and |
| 541 # detect unnamed getters from v8_interface. |
| 542 method.name != 'anonymousNamedGetter' and |
| 620 # TODO(terry): Eventual eliminate the IGNORE_MEMBERS in favor
of DartSupress. | 543 # TODO(terry): Eventual eliminate the IGNORE_MEMBERS in favor
of DartSupress. |
| 621 not _suppress_method(interface.name, method.name) and | 544 not _suppress_method(interface.name, method.name) and |
| 622 not _suppress_extended_attributes(method.extended_attributes)
and | 545 not _suppress_extended_attributes(method.extended_attributes)
and |
| 623 not 'DartSuppress' in method.extended_attributes)] | 546 not 'DartSuppress' in method.extended_attributes)] |
| 624 generate_overloads(methods) | 547 compute_method_overloads_context(methods) |
| 625 for method in methods: | 548 for method in methods: |
| 626 method['do_generate_method_configuration'] = ( | 549 method['do_generate_method_configuration'] = ( |
| 627 method['do_not_check_signature'] and | 550 method['do_not_check_signature'] and |
| 628 not method['per_context_enabled_function'] and | 551 not method['per_context_enabled_function'] and |
| 629 # For overloaded methods, only generate one accessor | 552 # For overloaded methods, only generate one accessor |
| 630 ('overload_index' not in method or method['overload_index'] == 1)) | 553 ('overload_index' not in method or method['overload_index'] == 1)) |
| 631 | 554 |
| 632 generate_method_native_entries(interface, methods) | 555 generate_method_native_entries(interface, methods, 'Method') |
| 633 | 556 |
| 634 template_contents.update({ | 557 context.update({ |
| 635 'has_origin_safe_method_setter': any( | 558 'has_origin_safe_method_setter': any( |
| 636 method['is_check_security_for_frame'] and not method['is_read_only'] | 559 method['is_check_security_for_frame'] and not method['is_read_only'] |
| 637 for method in methods), | 560 for method in methods), |
| 638 'has_method_configuration': any(method['do_generate_method_configuration
'] for method in methods), | 561 'has_method_configuration': any(method['do_generate_method_configuration
'] for method in methods), |
| 639 'has_per_context_enabled_methods': any(method['per_context_enabled_funct
ion'] for method in methods), | 562 'has_per_context_enabled_methods': any(method['per_context_enabled_funct
ion'] for method in methods), |
| 640 'methods': methods, | 563 'methods': methods, |
| 641 }) | 564 }) |
| 642 | 565 |
| 643 native_entries = generate_native_entries(interface, constructors, | 566 context.update({ |
| 644 custom_constructors, attributes, | |
| 645 methods, named_constructor) | |
| 646 | |
| 647 template_contents.update({ | |
| 648 'indexed_property_getter': indexed_property_getter(interface), | 567 'indexed_property_getter': indexed_property_getter(interface), |
| 649 'indexed_property_setter': indexed_property_setter(interface), | 568 'indexed_property_setter': indexed_property_setter(interface), |
| 650 'indexed_property_deleter': indexed_property_deleter(interface), | 569 'indexed_property_deleter': v8_interface.indexed_property_deleter(interf
ace), |
| 651 'is_override_builtins': 'OverrideBuiltins' in extended_attributes, | 570 'is_override_builtins': 'OverrideBuiltins' in extended_attributes, |
| 652 'named_property_getter': named_property_getter(interface), | 571 'named_property_getter': named_property_getter(interface), |
| 653 'named_property_setter': named_property_setter(interface), | 572 'named_property_setter': named_property_setter(interface), |
| 654 'named_property_deleter': named_property_deleter(interface), | 573 'named_property_deleter': v8_interface.named_property_deleter(interface)
, |
| 574 }) |
| 575 |
| 576 generate_native_entries_for_specials(interface, context) |
| 577 |
| 578 native_entries = generate_interface_native_entries(context) |
| 579 |
| 580 context.update({ |
| 655 'native_entries': native_entries, | 581 'native_entries': native_entries, |
| 656 }) | 582 }) |
| 657 | 583 |
| 658 return template_contents | 584 return context |
| 659 | 585 |
| 660 | 586 |
| 661 def generate_native_entries(interface, constructors, custom_constructors, | 587 def generate_interface_native_entries(context): |
| 662 attributes, methods, named_constructor): | 588 entries = {} |
| 663 entries = [] | 589 |
| 664 for constructor in constructors: | 590 def add(ne): |
| 665 entries.append(constructor['native_entry']) | 591 entries[ne['blink_entry']] = ne |
| 666 for constructor in custom_constructors: | 592 |
| 667 entries.append(constructor['native_entry']) | 593 def addAll(nes): |
| 668 if named_constructor: | 594 for ne in nes: |
| 669 entries.append(named_constructor['native_entry']) | 595 add(ne) |
| 596 |
| 597 for constructor in context['constructors']: |
| 598 addAll(constructor['native_entries']) |
| 599 for constructor in context['custom_constructors']: |
| 600 addAll(constructor['native_entries']) |
| 601 if context['named_constructor']: |
| 602 addAll(context['named_constructor']['native_entries']) |
| 603 if context['event_constructor']: |
| 604 addAll(context['event_constructor']['native_entries']) |
| 605 for method in context['methods']: |
| 606 addAll(method['native_entries']) |
| 607 for attribute in context['attributes']: |
| 608 add(attribute['native_entry_getter']) |
| 609 if not attribute['is_read_only'] or attribute['put_forwards']: |
| 610 add(attribute['native_entry_setter']) |
| 611 if context['indexed_property_getter']: |
| 612 addAll(context['indexed_property_getter']['native_entries']) |
| 613 if context['indexed_property_setter']: |
| 614 addAll(context['indexed_property_setter']['native_entries']) |
| 615 if context['indexed_property_deleter']: |
| 616 addAll(context['indexed_property_deleter']['native_entries']) |
| 617 if context['named_property_getter']: |
| 618 addAll(context['named_property_getter']['native_entries']) |
| 619 if context['named_property_setter']: |
| 620 addAll(context['named_property_setter']['native_entries']) |
| 621 if context['named_property_deleter']: |
| 622 addAll(context['named_property_deleter']['native_entries']) |
| 623 return list(entries.values()) |
| 624 |
| 625 |
| 626 def generate_method_native_entry(interface, method, count, kind): |
| 627 name = method.get('name') |
| 628 is_static = bool(method.get('is_static')) |
| 629 native_entry = \ |
| 630 DartUtilities.generate_native_entry(interface.name, name, |
| 631 kind, is_static, count) |
| 632 return native_entry |
| 633 |
| 634 |
| 635 def generate_method_native_entries(interface, methods, kind): |
| 670 for method in methods: | 636 for method in methods: |
| 671 entries.extend(method['native_entries']) | 637 native_entries = [] |
| 672 for attribute in attributes: | 638 arg_count = method['number_of_arguments'] |
| 673 entries.append(attribute['native_entry_getter']) | 639 min_arg_count = method['number_of_required_arguments'] |
| 674 entries.append(attribute['native_entry_setter']) | 640 lb = min_arg_count - 2 if min_arg_count > 2 else 0 |
| 675 return entries | 641 for x in range(lb, arg_count + 3): |
| 676 | 642 native_entry = \ |
| 677 | 643 generate_method_native_entry(interface, method, x, kind) |
| 678 # [DeprecateAs], [Reflect], [RuntimeEnabled] | 644 native_entries.append(native_entry) |
| 679 def generate_constant(constant): | 645 |
| 680 # (Blink-only) string literals are unquoted in tokenizer, must be re-quoted | 646 method.update({'native_entries': native_entries}) |
| 681 # in C++. | |
| 682 if constant.idl_type.name == 'String': | |
| 683 value = '"%s"' % constant.value | |
| 684 else: | |
| 685 value = constant.value | |
| 686 | |
| 687 extended_attributes = constant.extended_attributes | |
| 688 return { | |
| 689 'cpp_class': extended_attributes.get('PartialInterfaceImplementedAs'), | |
| 690 'name': constant.name, | |
| 691 # FIXME: use 'reflected_name' as correct 'name' | |
| 692 'reflected_name': extended_attributes.get('Reflect', constant.name), | |
| 693 'runtime_enabled_function': DartUtilities.runtime_enabled_function_name(
constant), | |
| 694 'value': value, | |
| 695 } | |
| 696 | 647 |
| 697 | 648 |
| 698 ################################################################################ | 649 ################################################################################ |
| 699 # Overloads | 650 # Overloads |
| 700 ################################################################################ | 651 ################################################################################ |
| 701 | 652 |
| 702 def generate_method_native_entry(interface, method, count, optional_index): | 653 def compute_method_overloads_context(methods): |
| 703 types = None | 654 # Regular methods |
| 704 if not method['is_custom']: | 655 compute_method_overloads_context_by_type([method for method in methods |
| 705 types = [arg['preprocessed_type'] for arg in method['arguments'][0:count
]] | 656 if not method['is_static']]) |
| 706 if method['is_call_with_script_arguments']: | 657 # Static methods |
| 707 types.append("object") | 658 compute_method_overloads_context_by_type([method for method in methods |
| 708 argument_names = [arg['name'] for arg in method['arguments'][0:count]] | 659 if method['is_static']]) |
| 709 name = method['name'] | 660 |
| 710 native_entry = \ | 661 |
| 711 DartUtilities.generate_native_entry(interface.name, method, | 662 def compute_method_overloads_context_by_type(methods): |
| 712 name, 'Method', | 663 """Computes |method.overload*| template values. |
| 713 optional_index, | 664 |
| 714 argument_names, types) | 665 Called separately for static and non-static (regular) methods, |
| 715 return native_entry | 666 as these are overloaded separately. |
| 716 | 667 Modifies |method| in place for |method| in |methods|. |
| 717 | 668 Doesn't change the |methods| list itself (only the values, i.e. individual |
| 718 def generate_method_native_entries(interface, methods): | 669 methods), so ok to treat these separately. |
| 719 for method in methods: | 670 """ |
| 720 native_entries = [] | |
| 721 required_arg_count = method['number_of_required_arguments'] | |
| 722 arg_count = method['number_of_arguments'] | |
| 723 if required_arg_count != arg_count: | |
| 724 for x in range(required_arg_count, arg_count + 1): | |
| 725 # This is really silly, but is here for now just to match up | |
| 726 # the existing name generation in the old dart:html scripts | |
| 727 index = arg_count - x + 1 | |
| 728 native_entry = \ | |
| 729 generate_method_native_entry(interface, method, x, index) | |
| 730 native_entries.append(native_entry) | |
| 731 else: | |
| 732 # Eventually, we should probably always generate an unindexed | |
| 733 # native entry, to handle cases like | |
| 734 # addEventListener in which we suppress the optionality, | |
| 735 # and in general to make us more robust against optional changes | |
| 736 native_entry = \ | |
| 737 generate_method_native_entry(interface, method, arg_count, None) | |
| 738 native_entries.append(native_entry) | |
| 739 | |
| 740 method.update({'native_entries': native_entries}) | |
| 741 | |
| 742 def generate_overloads(methods): | |
| 743 generate_overloads_by_type(methods, is_static=False) # Regular methods | |
| 744 generate_overloads_by_type(methods, is_static=True) | |
| 745 | |
| 746 | |
| 747 def generate_overloads_by_type(methods, is_static): | |
| 748 # Generates |overloads| template values and modifies |methods| in place; | |
| 749 # |is_static| flag used (instead of partitioning list in 2) because need to | |
| 750 # iterate over original list of methods to modify in place | |
| 751 method_counts = defaultdict(lambda: 0) | |
| 752 for method in methods: | |
| 753 if method['is_static'] != is_static: | |
| 754 continue | |
| 755 name = method['name'] | |
| 756 # FIXME(vsm): We don't seem to capture optional param | |
| 757 # overloads here. | |
| 758 method_counts[name] += 1 | |
| 759 | |
| 760 # Filter to only methods that are actually overloaded | |
| 761 overloaded_method_counts = dict((name, count) | |
| 762 for name, count in method_counts.iteritems() | |
| 763 if count > 1) | |
| 764 | |
| 765 # Add overload information only to overloaded methods, so template code can | 671 # Add overload information only to overloaded methods, so template code can |
| 766 # easily verify if a function is overloaded | 672 # easily verify if a function is overloaded |
| 767 method_overloads = defaultdict(list) | 673 for name, overloads in v8_interface.method_overloads_by_name(methods): |
| 768 for method in methods: | 674 # Resolution function is generated after last overloaded function; |
| 769 name = method['name'] | 675 # package necessary information into |method.overloads| for that method. |
| 770 if (method['is_static'] != is_static or | 676 overloads[-1]['overloads'] = overloads_context(overloads) |
| 771 name not in overloaded_method_counts): | 677 overloads[-1]['overloads']['name'] = name |
| 772 continue | 678 |
| 773 # Overload index includes self, so first append, then compute index | 679 |
| 774 method_overloads[name].append(method) | 680 def overloads_context(overloads): |
| 775 method.update({ | 681 """Returns |overloads| template values for a single name. |
| 776 'overload_index': len(method_overloads[name]), | 682 |
| 777 'overload_resolution_expression': overload_resolution_expression(met
hod), | 683 Sets |method.overload_index| in place for |method| in |overloads| |
| 778 }) | 684 and returns dict of overall overload template values. |
| 779 # FIXME(vsm): Looks like we only handle optional parameters if | 685 """ |
| 780 # the method is already overloaded. For a non-overloaded method | 686 assert len(overloads) > 1 # only apply to overloaded names |
| 781 # with optional parameters, we never get here. | 687 for index, method in enumerate(overloads, 1): |
| 782 | 688 method['overload_index'] = index |
| 783 # Resolution function is generated after last overloaded function; | 689 |
| 784 # package necessary information into |method.overloads| for that method. | 690 effective_overloads_by_length = v8_interface.effective_overload_set_by_lengt
h(overloads) |
| 785 for method in methods: | 691 lengths = [length for length, _ in effective_overloads_by_length] |
| 786 if (method['is_static'] != is_static or | 692 name = overloads[0].get('name', '<constructor>') |
| 787 'overload_index' not in method): | 693 |
| 788 continue | 694 # Check and fail if all overloads with the shortest acceptable arguments |
| 789 name = method['name'] | 695 # list are runtime enabled, since we would otherwise set 'length' on the |
| 790 if method['overload_index'] != overloaded_method_counts[name]: | 696 # function object to an incorrect value when none of those overloads were |
| 791 continue | 697 # actually enabled at runtime. The exception is if all overloads are |
| 792 overloads = method_overloads[name] | 698 # controlled by the same runtime enabled feature, in which case there would |
| 793 minimum_number_of_required_arguments = min( | 699 # be no function object at all if it is not enabled. |
| 794 overload['number_of_required_arguments'] | 700 shortest_overloads = effective_overloads_by_length[0][1] |
| 795 for overload in overloads) | 701 if (all(method.get('runtime_enabled_function') |
| 796 method['overloads'] = { | 702 for method, _, _ in shortest_overloads) and |
| 797 'has_exception_state': bool(minimum_number_of_required_arguments), | 703 not v8_interface.common_value(overloads, 'runtime_enabled_function')): |
| 798 'methods': overloads, | 704 raise ValueError('Function.length of %s depends on runtime enabled featu
res' % name) |
| 799 'minimum_number_of_required_arguments': minimum_number_of_required_a
rguments, | 705 |
| 800 'name': name, | 706 return { |
| 801 } | 707 'deprecate_all_as': v8_interface.common_value(overloads, 'deprecate_as')
, # [DeprecateAs] |
| 802 | 708 'exposed_test_all': v8_interface.common_value(overloads, 'exposed_test')
, # [Exposed] |
| 803 | 709 'length_tests_methods': length_tests_methods(effective_overloads_by_leng
th), |
| 804 def overload_resolution_expression(method): | 710 # 1. Let maxarg be the length of the longest type list of the |
| 805 # Expression is an OR of ANDs: each term in the OR corresponds to a | 711 # entries in S. |
| 806 # possible argument count for a given method, with type checks. | 712 'maxarg': lengths[-1], |
| 807 # FIXME: Blink's overload resolution algorithm is incorrect, per: | 713 'measure_all_as': v8_interface.common_value(overloads, 'measure_as'), #
[MeasureAs] |
| 808 # Implement WebIDL overload resolution algorithm. | 714 'minarg': lengths[0], |
| 809 # https://code.google.com/p/chromium/issues/detail?id=293561 | 715 'per_context_enabled_function_all': v8_interface.common_value(overloads,
'per_context_enabled_function'), # [PerContextEnabled] |
| 716 'runtime_enabled_function_all': v8_interface.common_value(overloads, 'ru
ntime_enabled_function'), # [RuntimeEnabled] |
| 717 'valid_arities': lengths |
| 718 # Only need to report valid arities if there is a gap in the |
| 719 # sequence of possible lengths, otherwise invalid length means |
| 720 # "not enough arguments". |
| 721 if lengths[-1] - lengths[0] != len(lengths) - 1 else None, |
| 722 } |
| 723 |
| 724 |
| 725 def length_tests_methods(effective_overloads_by_length): |
| 726 """Returns sorted list of resolution tests and associated methods, by length
. |
| 727 |
| 728 This builds the main data structure for the overload resolution loop. |
| 729 For a given argument length, bindings test argument at distinguishing |
| 730 argument index, in order given by spec: if it is compatible with |
| 731 (optionality or) type required by an overloaded method, resolve to that |
| 732 method. |
| 733 |
| 734 Returns: |
| 735 [(length, [(test, method)])] |
| 736 """ |
| 737 return [(length, list(resolution_tests_methods(effective_overloads))) |
| 738 for length, effective_overloads in effective_overloads_by_length] |
| 739 |
| 740 |
| 741 DART_CHECK_TYPE = { |
| 742 'ArrayBufferView': 'Dart_IsTypedData({cpp_value})', |
| 743 'ArrayBuffer': 'Dart_IsByteBuffer({cpp_value})', |
| 744 'Uint8Array': 'DartUtilities::isUint8Array({cpp_value})', |
| 745 'Uint8ClampedArray': 'DartUtilities::isUint8ClampedArray({cpp_value})', |
| 746 } |
| 747 |
| 748 |
| 749 def resolution_tests_methods(effective_overloads): |
| 750 """Yields resolution test and associated method, in resolution order, for ef
fective overloads of a given length. |
| 751 |
| 752 This is the heart of the resolution algorithm. |
| 753 http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm |
| 754 |
| 755 Note that a given method can be listed multiple times, with different tests! |
| 756 This is to handle implicit type conversion. |
| 757 |
| 758 Returns: |
| 759 [(test, method)] |
| 760 """ |
| 761 methods = [effective_overload[0] |
| 762 for effective_overload in effective_overloads] |
| 763 if len(methods) == 1: |
| 764 # If only one method with a given length, no test needed |
| 765 yield 'true', methods[0] |
| 766 return |
| 767 |
| 768 # 6. If there is more than one entry in S, then set d to be the |
| 769 # distinguishing argument index for the entries of S. |
| 770 index = v8_interface.distinguishing_argument_index(effective_overloads) |
| 771 # (7-9 are for handling |undefined| values for optional arguments before |
| 772 # the distinguishing argument (as "missing"), so you can specify only some |
| 773 # optional arguments. We don't support this, so we skip these steps.) |
| 774 # 10. If i = d, then: |
| 775 # (d is the distinguishing argument index) |
| 776 # 1. Let V be argi. |
| 777 # Note: This is the argument that will be used to resolve which |
| 778 # overload is selected. |
| 779 cpp_value = 'Dart_GetNativeArgument(args, %s + argOffset)' % index |
| 780 |
| 781 # Extract argument and IDL type to simplify accessing these in each loop. |
| 782 arguments = [method['arguments'][index] for method in methods] |
| 783 arguments_methods = zip(arguments, methods) |
| 784 idl_types = [argument['idl_type_object'] for argument in arguments] |
| 785 idl_types_methods = zip(idl_types, methods) |
| 786 |
| 787 # We can't do a single loop through all methods or simply sort them, because |
| 788 # a method may be listed in multiple steps of the resolution algorithm, and |
| 789 # which test to apply differs depending on the step. |
| 810 # | 790 # |
| 811 # Currently if distinguishing non-primitive type from primitive type, | 791 # Instead, we need to go through all methods at each step, either finding |
| 812 # (e.g., sequence<DOMString> from DOMString or Dictionary from double) | 792 # first match (if only one test is allowed) or filtering to matches (if |
| 813 # the method with a non-primitive type argument must appear *first* in the | 793 # multiple tests are allowed), and generating an appropriate tests. |
| 814 # IDL file, since we're not adding a check to primitive types. | 794 |
| 815 # FIXME: Once fixed, check IDLs, as usually want methods with primitive | 795 # 2. If V is undefined, and there is an entry in S whose list of |
| 816 # types to appear first (style-wise). | 796 # optionality values has "optional" at index i, then remove from S all |
| 817 # | 797 # other entries. |
| 818 # Properly: | 798 try: |
| 819 # 1. Compute effective overload set. | 799 method = next(method for argument, method in arguments_methods |
| 820 # 2. First check type list length. | 800 if argument['is_optional']) |
| 821 # 3. If multiple entries for given length, compute distinguishing argument | 801 test = 'Dart_IsNull(%s)' % cpp_value |
| 822 # index and have check for that type. | 802 yield test, method |
| 823 arguments = method['arguments'] | 803 except StopIteration: |
| 824 overload_checks = [overload_check_expression(method, index) | 804 pass |
| 825 # check *omitting* optional arguments at |index| and up: | 805 |
| 826 # index 0 => argument_count 0 (no arguments) | 806 # 3. Otherwise: if V is null or undefined, and there is an entry in S that |
| 827 # index 1 => argument_count 1 (index 0 argument only) | 807 # has one of the following types at position i of its type list, |
| 828 for index, argument in enumerate(arguments) | 808 # - a nullable type |
| 829 if argument['is_optional']] | 809 try: |
| 830 # FIXME: this is wrong if a method has optional arguments and a variadic | 810 method = next(method for idl_type, method in idl_types_methods |
| 831 # one, though there are not yet any examples of this | 811 if idl_type.is_nullable) |
| 832 if not method['is_variadic']: | 812 test = 'Dart_IsNull(%s)' % cpp_value |
| 833 # Includes all optional arguments (len = last index + 1) | 813 yield test, method |
| 834 overload_checks.append(overload_check_expression(method, len(arguments))
) | 814 except StopIteration: |
| 835 return ' || '.join('(%s)' % check for check in overload_checks) | 815 pass |
| 836 | 816 |
| 837 | 817 # 4. Otherwise: if V is a platform object - but not a platform array |
| 838 def overload_check_expression(method, argument_count): | 818 # object - and there is an entry in S that has one of the following |
| 839 overload_checks = ['info.Length() == %s' % argument_count] | 819 # types at position i of its type list, |
| 840 arguments = method['arguments'][:argument_count] | 820 # - an interface type that V implements |
| 841 overload_checks.extend(overload_check_argument(index, argument) | 821 # (Unlike most of these tests, this can return multiple methods, since we |
| 842 for index, argument in | 822 # test if it implements an interface. Thus we need a for loop, not a next.) |
| 843 enumerate(arguments)) | 823 # (We distinguish wrapper types from built-in interface types.) |
| 844 return ' && '.join('(%s)' % check for check in overload_checks if check) | 824 for idl_type, method in ((idl_type, method) |
| 845 | 825 for idl_type, method in idl_types_methods |
| 846 | 826 if idl_type.is_wrapper_type): |
| 847 def overload_check_argument(index, argument): | 827 fmtstr = 'Dart{idl_type}::hasInstance({cpp_value})' |
| 848 def null_or_optional_check(): | 828 if idl_type.base_type in DART_CHECK_TYPE: |
| 849 # If undefined is passed for an optional argument, the argument should | 829 fmtstr = DART_CHECK_TYPE[idl_type.base_type] |
| 850 # be treated as missing; otherwise undefined is not allowed. | 830 test = fmtstr.format(idl_type=idl_type.base_type, cpp_value=cpp_value) |
| 851 | 831 yield test, method |
| 852 # FIXME(vsm): We need Dart specific checks here. | 832 |
| 853 if idl_type.is_nullable: | 833 # 8. Otherwise: if V is any kind of object except for a native Date object, |
| 854 if argument['is_optional']: | 834 # a native RegExp object, and there is an entry in S that has one of the |
| 855 return 'isUndefinedOrNull(%s)' | 835 # following types at position i of its type list, |
| 856 return '%s->IsNull()' | 836 # - an array type |
| 857 if argument['is_optional']: | 837 # - a sequence type |
| 858 return '%s->IsUndefined()' | 838 # ... |
| 859 return None | 839 # - a dictionary |
| 860 | 840 try: |
| 861 cpp_value = 'info[%s]' % index | 841 # FIXME: IDL dictionary not implemented, so use Blink Dictionary |
| 862 idl_type = argument['idl_type_object'] | 842 # http://crbug.com/321462 |
| 863 # FIXME(vsm): We need Dart specific checks for the rest of this method. | 843 idl_type, method = next((idl_type, method) |
| 864 # FIXME: proper type checking, sharing code with attributes and methods | 844 for idl_type, method in idl_types_methods |
| 865 # FIXME(terry): DartStrictTypeChecking no longer supported; TypeChecking is | 845 if (idl_type.native_array_element_type or |
| 866 # new extended attribute. | 846 idl_type.name == 'Dictionary')) |
| 867 if idl_type.name == 'String' and argument['is_strict_type_checking']: | 847 if idl_type.native_array_element_type: |
| 868 return ' || '.join(['isUndefinedOrNull(%s)' % cpp_value, | 848 # (We test for Array instead of generic Object to type-check.) |
| 869 '%s->IsString()' % cpp_value, | 849 # FIXME: test for Object during resolution, then have type check for |
| 870 '%s->IsObject()' % cpp_value]) | 850 # Array in overloaded method: http://crbug.com/262383 |
| 871 if idl_type.native_array_element_type: | 851 test = 'Dart_IsList(%s)' % cpp_value |
| 872 return '%s->IsArray()' % cpp_value | 852 else: |
| 873 if idl_type.is_callback_interface: | 853 # FIXME: should be '{1}->IsObject() && !{1}->IsDate() && !{1}->IsReg
Exp()'.format(cpp_value) |
| 874 return ' || '.join(['%s->IsNull()' % cpp_value, | 854 # FIXME: the IsDate and IsRegExp checks can be skipped if we've |
| 875 '%s->IsFunction()' % cpp_value]) | 855 # already generated tests for them. |
| 876 if idl_type.is_wrapper_type: | 856 test = 'Dart_IsInstance(%s)' % cpp_value |
| 877 type_check = 'V8{idl_type}::hasInstance({cpp_value}, info.GetIsolate())'
.format(idl_type=idl_type.base_type, cpp_value=cpp_value) | 857 yield test, method |
| 878 if idl_type.is_nullable: | 858 except StopIteration: |
| 879 type_check = ' || '.join(['%s->IsNull()' % cpp_value, type_check]) | 859 pass |
| 880 return type_check | 860 |
| 881 if idl_type.is_interface_type: | 861 # (Check for exact type matches before performing automatic type conversion; |
| 882 # Non-wrapper types are just objects: we don't distinguish type | 862 # only needed if distinguishing between primitive types.) |
| 883 # We only allow undefined for non-wrapper types (notably Dictionary), | 863 if len([idl_type.is_primitive_type for idl_type in idl_types]) > 1: |
| 884 # as we need it for optional Dictionary arguments, but we don't want to | 864 # (Only needed if match in step 11, otherwise redundant.) |
| 885 # change behavior of existing bindings for other types. | 865 if any(idl_type.is_string_type or idl_type.is_enum |
| 886 type_check = '%s->IsObject()' % cpp_value | 866 for idl_type in idl_types): |
| 887 added_check_template = null_or_optional_check() | 867 # 10. Otherwise: if V is a Number value, and there is an entry in S |
| 888 if added_check_template: | 868 # that has one of the following types at position i of its type |
| 889 type_check = ' || '.join([added_check_template % cpp_value, | 869 # list, |
| 890 type_check]) | 870 # - a numeric type |
| 891 return type_check | 871 try: |
| 892 return None | 872 method = next(method for idl_type, method in idl_types_methods |
| 873 if idl_type.is_numeric_type) |
| 874 test = 'Dart_IsNumber(%s)' % cpp_value |
| 875 yield test, method |
| 876 except StopIteration: |
| 877 pass |
| 878 |
| 879 # (Perform automatic type conversion, in order. If any of these match, |
| 880 # that's the end, and no other tests are needed.) To keep this code simple, |
| 881 # we rely on the C++ compiler's dead code elimination to deal with the |
| 882 # redundancy if both cases below trigger. |
| 883 |
| 884 # 11. Otherwise: if there is an entry in S that has one of the following |
| 885 # types at position i of its type list, |
| 886 # - DOMString |
| 887 # - ByteString |
| 888 # - ScalarValueString [a DOMString typedef, per definition.] |
| 889 # - an enumeration type |
| 890 try: |
| 891 method = next(method for idl_type, method in idl_types_methods |
| 892 if idl_type.is_string_type or idl_type.is_enum) |
| 893 yield 'true', method |
| 894 except StopIteration: |
| 895 pass |
| 896 |
| 897 # 12. Otherwise: if there is an entry in S that has one of the following |
| 898 # types at position i of its type list, |
| 899 # - a numeric type |
| 900 try: |
| 901 method = next(method for idl_type, method in idl_types_methods |
| 902 if idl_type.is_numeric_type) |
| 903 yield 'true', method |
| 904 except StopIteration: |
| 905 pass |
| 893 | 906 |
| 894 | 907 |
| 895 ################################################################################ | 908 ################################################################################ |
| 896 # Constructors | 909 # Constructors |
| 897 ################################################################################ | 910 ################################################################################ |
| 898 | 911 |
| 899 # [Constructor] | 912 # [Constructor] |
| 900 def generate_custom_constructor(interface, constructor): | 913 def custom_constructor_context(interface, constructor): |
| 901 return { | 914 return { |
| 902 'arguments': [custom_constructor_argument(argument, index) | 915 'arguments': [custom_constructor_argument(argument, index) |
| 903 for index, argument in enumerate(constructor.arguments)], | 916 for index, argument in enumerate(constructor.arguments)], |
| 904 'auto_scope': 'true', | 917 'auto_scope': 'true', |
| 905 'is_auto_scope': True, | 918 'is_auto_scope': True, |
| 919 'is_call_with_script_arguments': False, |
| 920 'is_custom': True, |
| 906 'number_of_arguments': len(constructor.arguments), | 921 'number_of_arguments': len(constructor.arguments), |
| 907 'number_of_required_arguments': | 922 'number_of_required_arguments': |
| 908 number_of_required_arguments(constructor), | 923 v8_interface.number_of_required_arguments(constructor), |
| 909 } | 924 } |
| 910 | 925 |
| 911 | 926 |
| 912 # We don't need much from this - just the idl_type_objects and preproceed_type | 927 # We don't need much from this - just the idl_type_objects and preproceed_type |
| 913 # to use in generating the resolver strings. | 928 # to use in generating the resolver strings. |
| 914 def custom_constructor_argument(argument, index): | 929 def custom_constructor_argument(argument, index): |
| 915 return { | 930 return { |
| 916 'idl_type_object': argument.idl_type, | 931 'idl_type_object': argument.idl_type, |
| 917 'name': argument.name, | 932 'name': argument.name, |
| 918 'preprocessed_type': str(argument.idl_type.preprocessed_type), | 933 'preprocessed_type': str(argument.idl_type.preprocessed_type), |
| 919 } | 934 } |
| 920 | 935 |
| 921 | 936 |
| 922 # [Constructor] | 937 # [Constructor] |
| 923 def generate_constructor(interface, constructor): | 938 def constructor_context(interface, constructor): |
| 924 return { | 939 return { |
| 925 'argument_list': constructor_argument_list(interface, constructor), | 940 'arguments': [dart_methods.argument_context(interface, constructor, argu
ment, index) |
| 926 # TODO(terry): Use dart_methods.generate_argument instead constructor_ar
gument. | |
| 927 'arguments': [constructor_argument(interface, argument, index) | |
| 928 for index, argument in enumerate(constructor.arguments)], | 941 for index, argument in enumerate(constructor.arguments)], |
| 942 'auto_scope': 'true', |
| 943 'cpp_value': dart_methods.cpp_value( |
| 944 interface, constructor, len(constructor.arguments)), |
| 929 'has_exception_state': | 945 'has_exception_state': |
| 930 # [RaisesException=Constructor] | 946 # [RaisesException=Constructor] |
| 931 interface.extended_attributes.get('RaisesException') == 'Constructor
' or | 947 interface.extended_attributes.get('RaisesException') == 'Constructor
' or |
| 932 any(argument for argument in constructor.arguments | 948 any(argument for argument in constructor.arguments |
| 933 if argument.idl_type.name == 'SerializedScriptValue' or | 949 if argument.idl_type.name == 'SerializedScriptValue' or |
| 934 argument.idl_type.is_integer_type), | 950 argument.idl_type.is_integer_type), |
| 951 'is_auto_scope': True, |
| 952 'is_call_with_script_arguments': False, |
| 935 'is_constructor': True, | 953 'is_constructor': True, |
| 936 'auto_scope': 'true', | 954 'is_custom': False, |
| 937 'is_auto_scope': True, | |
| 938 'is_variadic': False, # Required for overload resolution | 955 'is_variadic': False, # Required for overload resolution |
| 939 'number_of_required_arguments': | 956 'number_of_required_arguments': |
| 940 number_of_required_arguments(constructor), | 957 v8_interface.number_of_required_arguments(constructor), |
| 941 'number_of_arguments': len(constructor.arguments), | 958 'number_of_arguments': len(constructor.arguments), |
| 942 } | 959 } |
| 943 | 960 |
| 944 | 961 |
| 945 def constructor_argument_list(interface, constructor): | |
| 946 # FIXME: unify with dart_methods.cpp_argument. | |
| 947 | |
| 948 def cpp_argument(argument): | |
| 949 argument_name = dart_types.check_reserved_name(argument.name) | |
| 950 idl_type = argument.idl_type | |
| 951 # FIXMEDART: there has to be a cleaner way to check for arraylike | |
| 952 # types such as Uint8ClampedArray. | |
| 953 if isinstance(idl_type, IdlArrayType) or idl_type.preprocessed_type.is_t
yped_array_type: | |
| 954 return '%s.get()' % argument_name | |
| 955 | |
| 956 return argument_name | |
| 957 | |
| 958 arguments = [] | |
| 959 # [ConstructorCallWith=ExecutionContext] | |
| 960 if DartUtilities.has_extended_attribute_value(interface, 'ConstructorCallWit
h', 'ExecutionContext'): | |
| 961 arguments.append('context') | |
| 962 # [ConstructorCallWith=Document] | |
| 963 if DartUtilities.has_extended_attribute_value(interface, 'ConstructorCallWit
h', 'Document'): | |
| 964 arguments.append('document') | |
| 965 | |
| 966 arguments.extend([cpp_argument(argument) for argument in constructor.argumen
ts]) | |
| 967 | |
| 968 # [RaisesException=Constructor] | |
| 969 if interface.extended_attributes.get('RaisesException') == 'Constructor': | |
| 970 arguments.append('es') | |
| 971 | |
| 972 return arguments | |
| 973 | |
| 974 | |
| 975 # TODO(terry): Eliminate this function use dart_methods.generate_argument instea
d | |
| 976 # for all constructor arguments. | |
| 977 def constructor_argument(interface, argument, index): | |
| 978 idl_type = argument.idl_type | |
| 979 default_value = str(argument.default_value) if argument.default_value else N
one | |
| 980 | |
| 981 argument_content = { | |
| 982 'cpp_type': idl_type.cpp_type_args(), | |
| 983 'local_cpp_type': idl_type.cpp_type_args(argument.extended_attributes, r
aw_type=True), | |
| 984 # FIXME: check that the default value's type is compatible with the argu
ment's | |
| 985 'default_value': default_value, | |
| 986 # FIXME: remove once [Default] removed and just use argument.default_val
ue | |
| 987 'has_default': 'Default' in argument.extended_attributes or default_valu
e, | |
| 988 'idl_type_object': idl_type, | |
| 989 'preprocessed_type': str(idl_type.preprocessed_type), | |
| 990 # Dictionary is special-cased, but arrays and sequences shouldn't be | |
| 991 'idl_type': idl_type.native_array_element_type, | |
| 992 'index': index, | |
| 993 'is_array_or_sequence_type': not not idl_type.native_array_element_type, | |
| 994 'is_optional': argument.is_optional, | |
| 995 'is_strict_type_checking': False, # Required for overload resolution | |
| 996 'name': argument.name, | |
| 997 'dart_value_to_local_cpp_value': dart_methods.dart_value_to_local_cpp_va
lue(interface, argument, index), | |
| 998 } | |
| 999 return argument_content | |
| 1000 | |
| 1001 | |
| 1002 def generate_constructor_overloads(constructors): | |
| 1003 if len(constructors) <= 1: | |
| 1004 return | |
| 1005 for overload_index, constructor in enumerate(constructors): | |
| 1006 constructor.update({ | |
| 1007 'overload_index': overload_index + 1, | |
| 1008 'overload_resolution_expression': | |
| 1009 overload_resolution_expression(constructor), | |
| 1010 }) | |
| 1011 | |
| 1012 | |
| 1013 # [NamedConstructor] | 962 # [NamedConstructor] |
| 1014 def generate_named_constructor(interface): | 963 def generate_named_constructor(interface): |
| 1015 extended_attributes = interface.extended_attributes | 964 extended_attributes = interface.extended_attributes |
| 1016 if 'NamedConstructor' not in extended_attributes: | 965 if 'NamedConstructor' not in extended_attributes: |
| 1017 return None | 966 return None |
| 1018 # FIXME: parser should return named constructor separately; | 967 # FIXME: parser should return named constructor separately; |
| 1019 # included in constructors (and only name stored in extended attribute) | 968 # included in constructors (and only name stored in extended attribute) |
| 1020 # for Perl compatibility | 969 # for Perl compatibility |
| 1021 idl_constructor = interface.constructors[0] | 970 idl_constructor = interface.constructors[0] |
| 1022 constructor = generate_constructor(interface, idl_constructor) | 971 constructor = constructor_context(interface, idl_constructor) |
| 1023 # FIXME(vsm): We drop the name. We don't use this in Dart APIs right now. | 972 # FIXME(vsm): We drop the name. We don't use this in Dart APIs right now. |
| 1024 # We probably need to encode this somehow to deal with conflicts. | 973 # We probably need to encode this somehow to deal with conflicts. |
| 1025 # constructor['name'] = extended_attributes['NamedConstructor'] | 974 # constructor['name'] = extended_attributes['NamedConstructor'] |
| 1026 return constructor | 975 return constructor |
| 1027 | 976 |
| 1028 | 977 |
| 1029 def number_of_required_arguments(constructor): | |
| 1030 return len([argument for argument in constructor.arguments | |
| 1031 if not (argument.is_optional and not (('Default' in argument.extended_at
tributes) or argument.default_value))]) | |
| 1032 | |
| 1033 | |
| 1034 def interface_length(interface, constructors): | |
| 1035 # Docs: http://heycam.github.io/webidl/#es-interface-call | |
| 1036 if 'EventConstructor' in interface.extended_attributes: | |
| 1037 return 1 | |
| 1038 if not constructors: | |
| 1039 return 0 | |
| 1040 return min(constructor['number_of_required_arguments'] | |
| 1041 for constructor in constructors) | |
| 1042 | |
| 1043 | |
| 1044 ################################################################################ | 978 ################################################################################ |
| 1045 # Special operations (methods) | 979 # Special operations (methods) |
| 1046 # http://heycam.github.io/webidl/#idl-special-operations | 980 # http://heycam.github.io/webidl/#idl-special-operations |
| 1047 ################################################################################ | 981 ################################################################################ |
| 1048 | 982 |
| 1049 def property_getter(getter, cpp_arguments): | 983 def property_getter(getter, cpp_arguments): |
| 1050 def is_null_expression(idl_type): | 984 def is_null_expression(idl_type): |
| 1051 if idl_type.is_union_type: | 985 if idl_type.is_union_type: |
| 1052 return ' && '.join('!result%sEnabled' % i | 986 return ' && '.join('!result%sEnabled' % i |
| 1053 for i, _ in enumerate(idl_type.member_types)) | 987 for i, _ in enumerate(idl_type.member_types)) |
| 1054 if idl_type.name == 'String': | 988 if idl_type.name == 'String': |
| 1055 # FIXME(vsm): This looks V8 specific. | 989 # FIXME(vsm): This looks V8 specific. |
| 1056 return 'result.isNull()' | 990 return 'result.isNull()' |
| 1057 if idl_type.is_interface_type: | 991 if idl_type.is_interface_type: |
| 1058 return '!result' | 992 return '!result' |
| 1059 return '' | 993 return '' |
| 1060 | 994 |
| 995 context = v8_interface.property_getter(getter, []) |
| 996 |
| 1061 idl_type = getter.idl_type | 997 idl_type = getter.idl_type |
| 1062 extended_attributes = getter.extended_attributes | 998 extended_attributes = getter.extended_attributes |
| 1063 is_raises_exception = 'RaisesException' in extended_attributes | 999 is_raises_exception = 'RaisesException' in extended_attributes |
| 1064 | 1000 |
| 1065 # FIXME: make more generic, so can use dart_methods.cpp_value | 1001 # FIXME: make more generic, so can use dart_methods.cpp_value |
| 1066 cpp_method_name = 'receiver->%s' % DartUtilities.cpp_name(getter) | 1002 cpp_method_name = 'receiver->%s' % DartUtilities.cpp_name(getter) |
| 1067 | 1003 |
| 1068 if is_raises_exception: | 1004 if is_raises_exception: |
| 1069 cpp_arguments.append('es') | 1005 cpp_arguments.append('es') |
| 1070 union_arguments = idl_type.union_arguments | 1006 union_arguments = idl_type.union_arguments |
| 1071 if union_arguments: | 1007 if union_arguments: |
| 1072 cpp_arguments.extend(union_arguments) | 1008 cpp_arguments.extend([member_argument['cpp_value'] |
| 1009 for member_argument in union_arguments]) |
| 1073 | 1010 |
| 1074 cpp_value = '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments)) | 1011 cpp_value = '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments)) |
| 1075 | 1012 |
| 1076 return { | 1013 context.update({ |
| 1077 'cpp_type': idl_type.cpp_type, | 1014 'cpp_type': idl_type.cpp_type, |
| 1078 'cpp_value': cpp_value, | 1015 'cpp_value': cpp_value, |
| 1079 'is_custom': | |
| 1080 'Custom' in extended_attributes and | |
| 1081 (not extended_attributes['Custom'] or | |
| 1082 DartUtilities.has_extended_attribute_value(getter, 'Custom', 'Prope
rtyGetter')), | |
| 1083 'is_custom_property_enumerator': DartUtilities.has_extended_attribute_va
lue( | |
| 1084 getter, 'Custom', 'PropertyEnumerator'), | |
| 1085 'is_custom_property_query': DartUtilities.has_extended_attribute_value( | |
| 1086 getter, 'Custom', 'PropertyQuery'), | |
| 1087 'is_enumerable': 'NotEnumerable' not in extended_attributes, | |
| 1088 'is_null_expression': is_null_expression(idl_type), | 1016 'is_null_expression': is_null_expression(idl_type), |
| 1089 'is_raises_exception': is_raises_exception, | 1017 'is_raises_exception': is_raises_exception, |
| 1090 'name': DartUtilities.cpp_name(getter), | 1018 'name': DartUtilities.cpp_name(getter), |
| 1091 'union_arguments': union_arguments, | 1019 'union_arguments': union_arguments, |
| 1092 'dart_set_return_value': idl_type.dart_set_return_value('result', | 1020 'dart_set_return_value': idl_type.dart_set_return_value('result', |
| 1093 extended_attribu
tes=extended_attributes, | 1021 extended_attribu
tes=extended_attributes, |
| 1094 script_wrappable
='receiver', | 1022 script_wrappable
='receiver', |
| 1095 release=idl_type
.release)} | 1023 release=idl_type
.release)}) |
| 1024 return context |
| 1096 | 1025 |
| 1097 | 1026 |
| 1098 def property_setter(interface, setter): | 1027 def property_setter(setter): |
| 1028 context = v8_interface.property_setter(setter) |
| 1029 |
| 1099 idl_type = setter.arguments[1].idl_type | 1030 idl_type = setter.arguments[1].idl_type |
| 1100 extended_attributes = setter.extended_attributes | 1031 extended_attributes = setter.extended_attributes |
| 1101 interface_extended_attributes = interface.extended_attributes | 1032 |
| 1102 is_raises_exception = 'RaisesException' in extended_attributes | 1033 context.update({ |
| 1103 return { | |
| 1104 'has_strict_type_checking': | |
| 1105 'DartStrictTypeChecking' in extended_attributes and | |
| 1106 idl_type.is_wrapper_type, | |
| 1107 'idl_type': idl_type.base_type, | |
| 1108 'is_custom': 'Custom' in extended_attributes, | |
| 1109 'has_exception_state': is_raises_exception or | |
| 1110 idl_type.is_integer_type, | |
| 1111 'is_raises_exception': is_raises_exception, | |
| 1112 'name': DartUtilities.cpp_name(setter), | |
| 1113 'dart_value_to_local_cpp_value': idl_type.dart_value_to_local_cpp_value( | 1034 'dart_value_to_local_cpp_value': idl_type.dart_value_to_local_cpp_value( |
| 1114 interface_extended_attributes, extended_attributes, 'propertyValue',
False), | 1035 extended_attributes, 'propertyValue', False, |
| 1115 } | 1036 context['has_type_checking_interface']), |
| 1037 }) |
| 1116 | 1038 |
| 1117 | 1039 return context |
| 1118 def property_deleter(deleter): | |
| 1119 idl_type = deleter.idl_type | |
| 1120 if str(idl_type) != 'boolean': | |
| 1121 raise Exception( | |
| 1122 'Only deleters with boolean type are allowed, but type is "%s"' % | |
| 1123 idl_type) | |
| 1124 extended_attributes = deleter.extended_attributes | |
| 1125 return { | |
| 1126 'is_custom': 'Custom' in extended_attributes, | |
| 1127 'is_raises_exception': 'RaisesException' in extended_attributes, | |
| 1128 'name': DartUtilities.cpp_name(deleter), | |
| 1129 } | |
| 1130 | 1040 |
| 1131 | 1041 |
| 1132 ################################################################################ | 1042 ################################################################################ |
| 1133 # Indexed properties | 1043 # Indexed properties |
| 1134 # http://heycam.github.io/webidl/#idl-indexed-properties | 1044 # http://heycam.github.io/webidl/#idl-indexed-properties |
| 1135 ################################################################################ | 1045 ################################################################################ |
| 1136 | 1046 |
| 1137 def indexed_property_getter(interface): | 1047 def indexed_property_getter(interface): |
| 1138 try: | 1048 try: |
| 1139 # Find indexed property getter, if present; has form: | 1049 # Find indexed property getter, if present; has form: |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1158 # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1, ARG_TYPE
ARG2) | 1068 # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1, ARG_TYPE
ARG2) |
| 1159 setter = next( | 1069 setter = next( |
| 1160 method | 1070 method |
| 1161 for method in interface.operations | 1071 for method in interface.operations |
| 1162 if ('setter' in method.specials and | 1072 if ('setter' in method.specials and |
| 1163 len(method.arguments) == 2 and | 1073 len(method.arguments) == 2 and |
| 1164 str(method.arguments[0].idl_type) == 'unsigned long')) | 1074 str(method.arguments[0].idl_type) == 'unsigned long')) |
| 1165 except StopIteration: | 1075 except StopIteration: |
| 1166 return None | 1076 return None |
| 1167 | 1077 |
| 1168 return property_setter(interface, setter) | 1078 return property_setter(setter) |
| 1169 | |
| 1170 | |
| 1171 def indexed_property_deleter(interface): | |
| 1172 try: | |
| 1173 # Find indexed property deleter, if present; has form: | |
| 1174 # deleter TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG) | |
| 1175 deleter = next( | |
| 1176 method | |
| 1177 for method in interface.operations | |
| 1178 if ('deleter' in method.specials and | |
| 1179 len(method.arguments) == 1 and | |
| 1180 str(method.arguments[0].idl_type) == 'unsigned long')) | |
| 1181 except StopIteration: | |
| 1182 return None | |
| 1183 | |
| 1184 return property_deleter(deleter) | |
| 1185 | 1079 |
| 1186 | 1080 |
| 1187 ################################################################################ | 1081 ################################################################################ |
| 1188 # Named properties | 1082 # Named properties |
| 1189 # http://heycam.github.io/webidl/#idl-named-properties | 1083 # http://heycam.github.io/webidl/#idl-named-properties |
| 1190 ################################################################################ | 1084 ################################################################################ |
| 1191 | 1085 |
| 1192 def named_property_getter(interface): | 1086 def named_property_getter(interface): |
| 1193 try: | 1087 try: |
| 1194 # Find named property getter, if present; has form: | 1088 # Find named property getter, if present; has form: |
| 1195 # getter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1) | 1089 # getter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1) |
| 1196 getter = next( | 1090 getter = next( |
| 1197 method | 1091 method |
| 1198 for method in interface.operations | 1092 for method in interface.operations |
| 1199 if ('getter' in method.specials and | 1093 if ('getter' in method.specials and |
| 1200 len(method.arguments) == 1 and | 1094 len(method.arguments) == 1 and |
| 1201 str(method.arguments[0].idl_type) == 'DOMString')) | 1095 str(method.arguments[0].idl_type) == 'DOMString')) |
| 1202 except StopIteration: | 1096 except StopIteration: |
| 1203 return None | 1097 return None |
| 1204 | 1098 |
| 1205 getter.name = getter.name or 'anonymousNamedGetter' | 1099 getter.name = getter.name or 'anonymousNamedGetter' |
| 1100 |
| 1206 return property_getter(getter, ['propertyName']) | 1101 return property_getter(getter, ['propertyName']) |
| 1207 | 1102 |
| 1208 | 1103 |
| 1209 def named_property_setter(interface): | 1104 def named_property_setter(interface): |
| 1210 try: | 1105 try: |
| 1211 # Find named property setter, if present; has form: | 1106 # Find named property setter, if present; has form: |
| 1212 # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1, ARG_TYPE ARG2
) | 1107 # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1, ARG_TYPE ARG2
) |
| 1213 setter = next( | 1108 setter = next( |
| 1214 method | 1109 method |
| 1215 for method in interface.operations | 1110 for method in interface.operations |
| 1216 if ('setter' in method.specials and | 1111 if ('setter' in method.specials and |
| 1217 len(method.arguments) == 2 and | 1112 len(method.arguments) == 2 and |
| 1218 str(method.arguments[0].idl_type) == 'DOMString')) | 1113 str(method.arguments[0].idl_type) == 'DOMString')) |
| 1219 except StopIteration: | 1114 except StopIteration: |
| 1220 return None | 1115 return None |
| 1221 | 1116 |
| 1222 return property_setter(interface, setter) | 1117 return property_setter(setter) |
| 1223 | 1118 |
| 1224 | 1119 |
| 1225 def named_property_deleter(interface): | 1120 def generate_native_entries_for_specials(interface, context): |
| 1226 try: | 1121 def add(prop, name, arity): |
| 1227 # Find named property deleter, if present; has form: | 1122 if context[prop]: |
| 1228 # deleter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG) | 1123 if 'native_entries' not in context[prop]: |
| 1229 deleter = next( | 1124 context[prop].update({'native_entries': []}) |
| 1230 method | 1125 context[prop]['native_entries'].append( |
| 1231 for method in interface.operations | 1126 DartUtilities.generate_native_entry( |
| 1232 if ('deleter' in method.specials and | 1127 interface.name, name, 'Method', False, arity)) |
| 1233 len(method.arguments) == 1 and | |
| 1234 str(method.arguments[0].idl_type) == 'DOMString')) | |
| 1235 except StopIteration: | |
| 1236 return None | |
| 1237 | 1128 |
| 1238 return property_deleter(deleter) | 1129 pre = ['indexed_property', 'named_property'] |
| 1130 post = [('setter', '__setter__', 2), |
| 1131 ('getter', '__getter__', 1), |
| 1132 ('deleter', '__delete__', 1), |
| 1133 ] |
| 1134 props = [(p1 + "_" + p2, name, arity) |
| 1135 for (p1, (p2, name, arity)) in itertools.product(pre, post)] |
| 1136 for t in props: |
| 1137 add(*t) |
| 1138 |
| 1139 for (p, name, arity) in props: |
| 1140 if context[p]: |
| 1141 if context[p].get('is_custom_property_query'): |
| 1142 add(p, '__propertyQuery__', 1) |
| OLD | NEW |