| 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 |