Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: bindings/dart/scripts/dart_interface.py

Issue 959933002: Move IDLs to 39 roll (Closed) Base URL: https://dart.googlecode.com/svn/third_party/WebCore
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « bindings/dart/scripts/dart_dictionary.py ('k') | bindings/dart/scripts/dart_methods.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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)
OLDNEW
« no previous file with comments | « bindings/dart/scripts/dart_dictionary.py ('k') | bindings/dart/scripts/dart_methods.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698