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 # coding=utf-8 |
3 # | 3 # |
4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
6 # met: | 6 # met: |
7 # | 7 # |
8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 'minimum_number_of_required_arguments': minimum_number_of_required_argum
ents, | 373 'minimum_number_of_required_arguments': minimum_number_of_required_argum
ents, |
374 'name': name, | 374 'name': name, |
375 } | 375 } |
376 | 376 |
377 | 377 |
378 def is_use_spec_algorithm(effective_overloads_by_length): | 378 def is_use_spec_algorithm(effective_overloads_by_length): |
379 # FIXME: temporary function so can switch incrementally | 379 # FIXME: temporary function so can switch incrementally |
380 # Use spec algorithm if: | 380 # Use spec algorithm if: |
381 # * method is not variadic, | 381 # * method is not variadic, |
382 # * no distinguishing type is unsupported: | 382 # * no distinguishing type is unsupported: |
383 # non-wrapper, array, callback interface, enumeration, boolean, string, nu
llable, | 383 # non-wrapper, array, callback interface, boolean, nullable, |
384 # * all distinguishing types are distinct, and | 384 # * all distinguishing types are distinct, and |
385 # * all distinguishing arguments are required (not optional). | 385 # * all distinguishing arguments are required (not optional). |
386 def is_unsupported_type(idl_type): | 386 def is_unsupported_type(idl_type): |
387 return ((idl_type.is_interface_type and not idl_type.is_wrapper_type) or | 387 return ((idl_type.is_interface_type and not idl_type.is_wrapper_type) or |
388 idl_type.array_or_sequence_type or | 388 idl_type.array_or_sequence_type or |
389 idl_type.is_callback_interface or | 389 idl_type.is_callback_interface or |
390 idl_type.is_enum or | 390 idl_type.name == 'Boolean' or |
391 idl_type.name in ('Boolean', 'String') or | |
392 idl_type.is_nullable) | 391 idl_type.is_nullable) |
393 | 392 |
394 for _, effective_overloads in effective_overloads_by_length: | 393 for _, effective_overloads in effective_overloads_by_length: |
395 methods = [effective_overload[0] | 394 methods = [effective_overload[0] |
396 for effective_overload in effective_overloads] | 395 for effective_overload in effective_overloads] |
397 if any(method['is_variadic'] for method in methods): | 396 if any(method['is_variadic'] for method in methods): |
398 return False | 397 return False |
399 | 398 |
400 if len(effective_overloads) == 1: | 399 if len(effective_overloads) == 1: |
401 # No distinguishing type, since resolved by length | 400 # No distinguishing type, since resolved by length |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 # Note: This is the argument that will be used to resolve which | 628 # Note: This is the argument that will be used to resolve which |
630 # overload is selected. | 629 # overload is selected. |
631 cpp_value = 'info[%s]' % index | 630 cpp_value = 'info[%s]' % index |
632 | 631 |
633 # Extract argument and IDL type to simplify accessing these in each loop. | 632 # Extract argument and IDL type to simplify accessing these in each loop. |
634 # FIXME: mostly just need type, but need argument itself for optionality | 633 # FIXME: mostly just need type, but need argument itself for optionality |
635 arguments = [method['arguments'][index] for method in methods] | 634 arguments = [method['arguments'][index] for method in methods] |
636 idl_types = [argument['idl_type_object'] for argument in arguments] | 635 idl_types = [argument['idl_type_object'] for argument in arguments] |
637 idl_types_methods = zip(idl_types, methods) | 636 idl_types_methods = zip(idl_types, methods) |
638 | 637 |
639 # We can't do a single loop through all methods or simply sort them, because | 638 # We can’t do a single loop through all methods or simply sort them, because |
640 # a method may be listed in multiple steps of the resolution algorithm, and | 639 # a method may be listed in multiple steps of the resolution algorithm, and |
641 # which test to apply differs depending on the step. | 640 # which test to apply differs depending on the step. |
642 # Instead, we need to loop through all methods at each step, filtering to | 641 # |
643 # matches and generating an appropriate test. | 642 # Instead, we need to go through all methods at each step, either finding |
644 for idl_type, method in idl_types_methods: | 643 # first match (if only one test is allowed) or filtering to matches (if |
645 # 4. Otherwise: if V is a platform object – but not a platform array | 644 # multiple tests are allowed), and generating an appropriate tests. |
646 # object – and there is an entry in S that has one of the following | |
647 # types at position i of its type list, | |
648 # • an interface type that V implements | |
649 # (We distinguish wrapper types from built-in interface types.) | |
650 if idl_type.is_wrapper_type: | |
651 test = 'V8{idl_type}::hasInstance({cpp_value}, info.GetIsolate())'.f
ormat(idl_type=idl_type.base_type, cpp_value=cpp_value) | |
652 yield test, method | |
653 | 645 |
654 # FIXME: not needed yet | 646 # 4. Otherwise: if V is a platform object – but not a platform array |
655 # for idl_type, method in idl_types_methods: | 647 # object – and there is an entry in S that has one of the following |
656 # # 10. Otherwise: if V is a Number value, and there is an entry in S | 648 # types at position i of its type list, |
657 # # that has one of the following types at position i of its type | 649 # • an interface type that V implements |
658 # # list, | 650 # (Unlike most of these tests, this can return multiple methods, since we |
659 # # • a numeric type | 651 # test if it implements an interface. Thus we need a for loop, not a next.) |
660 # if idl_type.is_numeric_type: | 652 # (We distinguish wrapper types from built-in interface types.) |
661 # test = '%s->IsNumber()' % cpp_value | 653 for idl_type, method in ((idl_type, method) |
662 # yield test, method | 654 for idl_type, method in idl_types_methods |
| 655 if idl_type.is_wrapper_type): |
| 656 test = 'V8{idl_type}::hasInstance({cpp_value}, info.GetIsolate())'.forma
t(idl_type=idl_type.base_type, cpp_value=cpp_value) |
| 657 yield test, method |
663 | 658 |
664 for idl_type, method in idl_types_methods: | 659 # (Check for exact type matches before performing automatic type conversion; |
665 # 12. Otherwise: if there is an entry in S that has one of the | 660 # only needed if distinguishing between primitive types.) |
666 # following types at position i of its type list, | 661 if len([idl_type.is_primitive_type for idl_type in idl_types]) > 1: |
667 # • a numeric type | 662 # (Only needed if match in step 11, otherwise redundant.) |
668 if idl_type.is_numeric_type: | 663 if any(idl_type.name == 'String' or idl_type.is_enum |
669 yield 'true', method | 664 for idl_type in idl_types): |
| 665 # 10. Otherwise: if V is a Number value, and there is an entry in S |
| 666 # that has one of the following types at position i of its type |
| 667 # list, |
| 668 # • a numeric type |
| 669 try: |
| 670 method = next(method for idl_type, method in idl_types_methods |
| 671 if idl_type.is_numeric_type) |
| 672 test = '%s->IsNumber()' % cpp_value |
| 673 yield test, method |
| 674 except StopIteration: |
| 675 pass |
| 676 |
| 677 # (Perform automatic type conversion, in order. If any of these match, |
| 678 # that’s the end, and no other tests are needed.) |
| 679 |
| 680 # 11. Otherwise: if there is an entry in S that has one of the following |
| 681 # types at position i of its type list, |
| 682 # • DOMString |
| 683 # • an enumeration type |
| 684 try: |
| 685 method = next(method for idl_type, method in idl_types_methods |
| 686 if idl_type.name == 'String' or idl_type.is_enum) |
| 687 yield 'true', method |
| 688 return |
| 689 except StopIteration: |
| 690 pass |
| 691 |
| 692 # 12. Otherwise: if there is an entry in S that has one of the following |
| 693 # types at position i of its type list, |
| 694 # • a numeric type |
| 695 try: |
| 696 method = next(method for idl_type, method in idl_types_methods |
| 697 if idl_type.is_numeric_type) |
| 698 yield 'true', method |
| 699 return |
| 700 except StopIteration: |
| 701 pass |
670 | 702 |
671 | 703 |
672 def overload_resolution_expression(method): | 704 def overload_resolution_expression(method): |
673 # Expression is an OR of ANDs: each term in the OR corresponds to a | 705 # Expression is an OR of ANDs: each term in the OR corresponds to a |
674 # possible argument count for a given method, with type checks. | 706 # possible argument count for a given method, with type checks. |
675 # FIXME: Blink's overload resolution algorithm is incorrect, per: | 707 # FIXME: Blink's overload resolution algorithm is incorrect, per: |
676 # Implement WebIDL overload resolution algorithm. http://crbug.com/293561 | 708 # Implement WebIDL overload resolution algorithm. http://crbug.com/293561 |
677 # | 709 # |
678 # Currently if distinguishing non-primitive type from primitive type, | 710 # Currently if distinguishing non-primitive type from primitive type, |
679 # (e.g., sequence<DOMString> from DOMString or Dictionary from double) | 711 # (e.g., sequence<DOMString> from DOMString or Dictionary from double) |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1059 deleter = next( | 1091 deleter = next( |
1060 method | 1092 method |
1061 for method in interface.operations | 1093 for method in interface.operations |
1062 if ('deleter' in method.specials and | 1094 if ('deleter' in method.specials and |
1063 len(method.arguments) == 1 and | 1095 len(method.arguments) == 1 and |
1064 str(method.arguments[0].idl_type) == 'DOMString')) | 1096 str(method.arguments[0].idl_type) == 'DOMString')) |
1065 except StopIteration: | 1097 except StopIteration: |
1066 return None | 1098 return None |
1067 | 1099 |
1068 return property_deleter(deleter) | 1100 return property_deleter(deleter) |
OLD | NEW |