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 | 645 |
647 # types at position i of its type list, | 646 # 4. Otherwise: if V is a platform object – but not a platform array |
648 # • an interface type that V implements | 647 # object – and there is an entry in S that has one of the following |
649 # (We distinguish wrapper types from built-in interface types.) | 648 # types at position i of its type list, |
650 if idl_type.is_wrapper_type: | 649 # • an interface type that V implements |
651 test = 'V8{idl_type}::hasInstance({cpp_value}, info.GetIsolate())'.f ormat(idl_type=idl_type.base_type, cpp_value=cpp_value) | 650 # (We distinguish wrapper types from built-in interface types.) |
651 for idl_type, method in ((idl_type, method) | |
652 for idl_type, method in idl_types_methods | |
653 if idl_type.is_wrapper_type): | |
654 test = 'V8{idl_type}::hasInstance({cpp_value}, info.GetIsolate())'.forma t(idl_type=idl_type.base_type, cpp_value=cpp_value) | |
655 yield test, method | |
haraken
2014/05/14 06:09:03
Why do you not need a try-catch block here?
Nils Barth (inactive)
2014/05/14 06:28:15
Because this can return multiple matches.
Added co
| |
656 | |
657 # (Check for exact type matches before performing automatic type conversion; | |
658 # only needed if distinguishing between primitive types.) | |
659 | |
660 # 10. Otherwise: if V is a Number value, and there is an entry in S that has | |
661 # one of the following types at position i of its type list, | |
662 # • a numeric type | |
663 if any(idl_type.name == 'String' or idl_type.is_enum | |
haraken
2014/05/14 06:09:03
I wonder why you need to check string or enum here
Nils Barth (inactive)
2014/05/14 06:28:15
It's only needed if there's a match in step 11, ot
| |
664 for idl_type in idl_types): | |
665 try: | |
666 method = next(method for idl_type, method in idl_types_methods | |
667 if idl_type.is_numeric_type) | |
668 test = '%s->IsNumber()' % cpp_value | |
652 yield test, method | 669 yield test, method |
670 except StopIteration: | |
671 pass | |
653 | 672 |
654 # FIXME: not needed yet | 673 # (Perform automatic type conversion, in order. If any of these match, |
655 # for idl_type, method in idl_types_methods: | 674 # that’s the end, and no other tests are needed.) |
656 # # 10. Otherwise: if V is a Number value, and there is an entry in S | |
657 # # that has one of the following types at position i of its type | |
658 # # list, | |
659 # # • a numeric type | |
660 # if idl_type.is_numeric_type: | |
661 # test = '%s->IsNumber()' % cpp_value | |
662 # yield test, method | |
663 | 675 |
664 for idl_type, method in idl_types_methods: | 676 # 11. Otherwise: if there is an entry in S that has one of the following |
665 # 12. Otherwise: if there is an entry in S that has one of the | 677 # types at position i of its type list, |
666 # following types at position i of its type list, | 678 # • DOMString |
667 # • a numeric type | 679 # • an enumeration type |
668 if idl_type.is_numeric_type: | 680 try: |
Jens Widell
2014/05/14 05:19:31
You could skip the 'try' and "move" the controlled
Nils Barth (inactive)
2014/05/14 06:28:15
While that seems simpler, I'm following the order
| |
669 yield 'true', method | 681 method = next(method for idl_type, method in idl_types_methods |
682 if idl_type.name == 'String' or idl_type.is_enum) | |
683 yield 'true', method | |
684 return | |
685 except StopIteration: | |
686 pass | |
687 | |
688 # 12. Otherwise: if there is an entry in S that has one of the following | |
689 # types at position i of its type list, | |
690 # • a numeric type | |
haraken
2014/05/14 06:09:03
I'm curious why the step 11 and 12 are separated.
Nils Barth (inactive)
2014/05/14 06:28:15
Because they're different in the spec, and splitti
| |
691 try: | |
692 method = next(method for idl_type, method in idl_types_methods | |
693 if idl_type.is_numeric_type) | |
694 yield 'true', method | |
695 return | |
696 except StopIteration: | |
697 pass | |
670 | 698 |
671 | 699 |
672 def overload_resolution_expression(method): | 700 def overload_resolution_expression(method): |
673 # Expression is an OR of ANDs: each term in the OR corresponds to a | 701 # 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. | 702 # possible argument count for a given method, with type checks. |
675 # FIXME: Blink's overload resolution algorithm is incorrect, per: | 703 # FIXME: Blink's overload resolution algorithm is incorrect, per: |
676 # Implement WebIDL overload resolution algorithm. http://crbug.com/293561 | 704 # Implement WebIDL overload resolution algorithm. http://crbug.com/293561 |
677 # | 705 # |
678 # Currently if distinguishing non-primitive type from primitive type, | 706 # Currently if distinguishing non-primitive type from primitive type, |
679 # (e.g., sequence<DOMString> from DOMString or Dictionary from double) | 707 # (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( | 1087 deleter = next( |
1060 method | 1088 method |
1061 for method in interface.operations | 1089 for method in interface.operations |
1062 if ('deleter' in method.specials and | 1090 if ('deleter' in method.specials and |
1063 len(method.arguments) == 1 and | 1091 len(method.arguments) == 1 and |
1064 str(method.arguments[0].idl_type) == 'DOMString')) | 1092 str(method.arguments[0].idl_type) == 'DOMString')) |
1065 except StopIteration: | 1093 except StopIteration: |
1066 return None | 1094 return None |
1067 | 1095 |
1068 return property_deleter(deleter) | 1096 return property_deleter(deleter) |
OLD | NEW |