| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 3 # for details. All rights reserved. Use of this source code is governed by a | 3 # for details. All rights reserved. Use of this source code is governed by a |
| 4 # BSD-style license that can be found in the LICENSE file. | 4 # BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 """This module provides shared functionality for the systems to generate | 6 """This module provides shared functionality for the systems to generate |
| 7 native binding from the IDL database.""" | 7 native binding from the IDL database.""" |
| 8 | 8 |
| 9 import emitter | 9 import emitter |
| 10 import os | 10 import os |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 info: An OperationInfo object. | 542 info: An OperationInfo object. |
| 543 """ | 543 """ |
| 544 | 544 |
| 545 operation = info.operations[0] | 545 operation = info.operations[0] |
| 546 | 546 |
| 547 if 'CheckSecurityForNode' in operation.ext_attrs: | 547 if 'CheckSecurityForNode' in operation.ext_attrs: |
| 548 # FIXME: exclude from interface as well. | 548 # FIXME: exclude from interface as well. |
| 549 return | 549 return |
| 550 | 550 |
| 551 is_custom = 'Custom' in operation.ext_attrs | 551 is_custom = 'Custom' in operation.ext_attrs |
| 552 has_optional_arguments = any(_IsArgumentOptionalInWebCore(argument) for argu
ment in operation.arguments) | 552 has_optional_arguments = any(self._IsArgumentOptionalInWebCore(operation, ar
gument) for argument in operation.arguments) |
| 553 needs_dispatcher = not is_custom and (len(info.operations) > 1 or has_option
al_arguments) | 553 needs_dispatcher = not is_custom and (len(info.operations) > 1 or has_option
al_arguments) |
| 554 | 554 |
| 555 if not needs_dispatcher: | 555 if not needs_dispatcher: |
| 556 type_renamer = self._DartType | 556 type_renamer = self._DartType |
| 557 default_value = 'null' | 557 default_value = 'null' |
| 558 else: | 558 else: |
| 559 type_renamer = lambda x: 'Dynamic' | 559 type_renamer = lambda x: 'Dynamic' |
| 560 default_value = '_null' | 560 default_value = '_null' |
| 561 | 561 |
| 562 dart_declaration = '%s%s %s(%s)' % ( | 562 dart_declaration = '%s%s %s(%s)' % ( |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 argument = operation.arguments[i] | 617 argument = operation.arguments[i] |
| 618 argument_name = argument_names[i] | 618 argument_name = argument_names[i] |
| 619 checks[i] = '(%s is %s || %s === null)' % ( | 619 checks[i] = '(%s is %s || %s === null)' % ( |
| 620 argument_name, self._DartType(argument.type.id), argument_name) | 620 argument_name, self._DartType(argument.type.id), argument_name) |
| 621 GenerateCall(operation, argument_count, checks) | 621 GenerateCall(operation, argument_count, checks) |
| 622 | 622 |
| 623 # TODO: Optimize the dispatch to avoid repeated checks. | 623 # TODO: Optimize the dispatch to avoid repeated checks. |
| 624 if len(operations) > 1: | 624 if len(operations) > 1: |
| 625 for operation in operations: | 625 for operation in operations: |
| 626 for position, argument in enumerate(operation.arguments): | 626 for position, argument in enumerate(operation.arguments): |
| 627 if _IsArgumentOptionalInWebCore(argument): | 627 if self._IsArgumentOptionalInWebCore(operation, argument): |
| 628 GenerateChecksAndCall(operation, position) | 628 GenerateChecksAndCall(operation, position) |
| 629 GenerateChecksAndCall(operation, len(operation.arguments)) | 629 GenerateChecksAndCall(operation, len(operation.arguments)) |
| 630 body.Emit(' throw "Incorrect number or type of arguments";\n'); | 630 body.Emit(' throw "Incorrect number or type of arguments";\n'); |
| 631 else: | 631 else: |
| 632 operation = operations[0] | 632 operation = operations[0] |
| 633 for position, argument in list(enumerate(operation.arguments))[::-1]: | 633 for position, argument in list(enumerate(operation.arguments))[::-1]: |
| 634 if _IsArgumentOptionalInWebCore(argument): | 634 if self._IsArgumentOptionalInWebCore(operation, argument): |
| 635 check = '%s === _null' % argument_names[position] | 635 check = '%s === _null' % argument_names[position] |
| 636 GenerateCall(operation, position, [check]) | 636 GenerateCall(operation, position, [check]) |
| 637 GenerateCall(operation, len(operation.arguments), []) | 637 GenerateCall(operation, len(operation.arguments), []) |
| 638 | 638 |
| 639 def SecondaryContext(self, interface): | 639 def SecondaryContext(self, interface): |
| 640 pass | 640 pass |
| 641 | 641 |
| 642 def _GenerateOperationNativeCallback(self, operation, arguments, cpp_callback_
name): | 642 def _GenerateOperationNativeCallback(self, operation, arguments, cpp_callback_
name): |
| 643 webcore_function_name = operation.ext_attrs.get('ImplementedAs', operation.i
d) | 643 webcore_function_name = operation.ext_attrs.get('ImplementedAs', operation.i
d) |
| 644 function_expression = self._GenerateWebCoreFunctionExpression(webcore_functi
on_name, operation) | 644 function_expression = self._GenerateWebCoreFunctionExpression(webcore_functi
on_name, operation) |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 INDEX=len(arguments) + 1) | 798 INDEX=len(arguments) + 1) |
| 799 | 799 |
| 800 # Emit arguments. | 800 # Emit arguments. |
| 801 start_index = 1 if needs_receiver else 0 | 801 start_index = 1 if needs_receiver else 0 |
| 802 for i, argument in enumerate(arguments): | 802 for i, argument in enumerate(arguments): |
| 803 type_info = self._TypeInfo(argument.type.id) | 803 type_info = self._TypeInfo(argument.type.id) |
| 804 self._cpp_impl_includes |= set(type_info.to_native_includes()) | 804 self._cpp_impl_includes |= set(type_info.to_native_includes()) |
| 805 cpp_arguments.append(type_info.emit_to_native( | 805 cpp_arguments.append(type_info.emit_to_native( |
| 806 body_emitter, | 806 body_emitter, |
| 807 argument, | 807 argument, |
| 808 IsOptional(argument) and not self._IsArgumentOptionalInWebCore(node, a
rgument), |
| 808 # TODO(antonm): all IDs should be renamed when database is generated. | 809 # TODO(antonm): all IDs should be renamed when database is generated. |
| 809 # That will allow to get rid of argument_name argument altogether. | 810 # That will allow to get rid of argument_name argument altogether. |
| 810 DartDomNameOfAttribute(argument), | 811 DartDomNameOfAttribute(argument), |
| 811 'Dart_GetNativeArgument(args, %i)' % (start_index + i), | 812 'Dart_GetNativeArgument(args, %i)' % (start_index + i), |
| 812 self._interface.id)) | 813 self._interface.id)) |
| 813 | 814 |
| 814 body_emitter.Emit('\n') | 815 body_emitter.Emit('\n') |
| 815 | 816 |
| 816 # FIXME: rework in IDLs. | |
| 817 if node.id in ['addEventListener', 'removeEventListener']: | |
| 818 # addEventListener's and removeEventListener's last argument is marked | |
| 819 # as optional in idl, but is not optional in webcore implementation. | |
| 820 if len(arguments) == 2: | |
| 821 cpp_arguments.append('false') | |
| 822 | |
| 823 if self._interface.id == 'CSSStyleDeclaration' and node.id == 'setProperty': | |
| 824 # CSSStyleDeclaration.setProperty priority parameter is optional in Dart | |
| 825 # idl, but is not optional in webcore implementation. | |
| 826 if len(arguments) == 2: | |
| 827 cpp_arguments.append('String()') | |
| 828 | |
| 829 if 'NeedsUserGestureCheck' in ext_attrs: | 817 if 'NeedsUserGestureCheck' in ext_attrs: |
| 830 cpp_arguments.append('DartUtilities::processingUserGesture'); | 818 cpp_arguments.append('DartUtilities::processingUserGesture'); |
| 831 | 819 |
| 832 invocation_emitter = body_emitter | 820 invocation_emitter = body_emitter |
| 833 if raises_dom_exception: | 821 if raises_dom_exception: |
| 834 cpp_arguments.append('ec') | 822 cpp_arguments.append('ec') |
| 835 invocation_emitter = body_emitter.Emit( | 823 invocation_emitter = body_emitter.Emit( |
| 836 ' ExceptionCode ec = 0;\n' | 824 ' ExceptionCode ec = 0;\n' |
| 837 '$!INVOCATION' | 825 '$!INVOCATION' |
| 838 ' if (UNLIKELY(ec)) {\n' | 826 ' if (UNLIKELY(ec)) {\n' |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 897 def _GenerateWebCoreFunctionExpression(self, function_name, idl_node): | 885 def _GenerateWebCoreFunctionExpression(self, function_name, idl_node): |
| 898 if 'ImplementedBy' in idl_node.ext_attrs: | 886 if 'ImplementedBy' in idl_node.ext_attrs: |
| 899 return '%s::%s' % (idl_node.ext_attrs['ImplementedBy'], function_name) | 887 return '%s::%s' % (idl_node.ext_attrs['ImplementedBy'], function_name) |
| 900 if idl_node.is_static: | 888 if idl_node.is_static: |
| 901 return '%s::%s' % (self._interface_type_info.idl_type(), function_name) | 889 return '%s::%s' % (self._interface_type_info.idl_type(), function_name) |
| 902 return '%s%s' % (self._interface_type_info.receiver(), function_name) | 890 return '%s%s' % (self._interface_type_info.receiver(), function_name) |
| 903 | 891 |
| 904 def _TypeInfo(self, type_name): | 892 def _TypeInfo(self, type_name): |
| 905 return self._system._type_registry.TypeInfo(type_name) | 893 return self._system._type_registry.TypeInfo(type_name) |
| 906 | 894 |
| 895 def _IsArgumentOptionalInWebCore(self, operation, argument): |
| 896 if not IsOptional(argument): |
| 897 return False |
| 898 if 'Callback' in argument.ext_attrs: |
| 899 return False |
| 900 if operation.id in ['addEventListener', 'removeEventListener'] and argument.
id == 'useCapture': |
| 901 return False |
| 902 # Another option would be to adjust in IDLs, but let's keep it here for now |
| 903 # as it's a single instance. |
| 904 if self._interface.id == 'CSSStyleDeclaration' and operation.id == 'setPrope
rty' and argument.id == 'priority': |
| 905 return False |
| 906 return True |
| 907 |
| 907 | 908 |
| 908 def _GenerateCPPIncludes(includes): | 909 def _GenerateCPPIncludes(includes): |
| 909 return ''.join(['#include %s\n' % include for include in sorted(includes)]) | 910 return ''.join(['#include %s\n' % include for include in sorted(includes)]) |
| 910 | 911 |
| 911 def _FindInHierarchy(database, interface, test): | 912 def _FindInHierarchy(database, interface, test): |
| 912 if test(interface): | 913 if test(interface): |
| 913 return interface | 914 return interface |
| 914 for parent in interface.parents: | 915 for parent in interface.parents: |
| 915 parent_name = parent.type.id | 916 parent_name = parent.type.id |
| 916 if not database.HasInterface(parent.type.id): | 917 if not database.HasInterface(parent.type.id): |
| 917 continue | 918 continue |
| 918 parent_interface = database.GetInterface(parent.type.id) | 919 parent_interface = database.GetInterface(parent.type.id) |
| 919 parent_interface = _FindInHierarchy(database, parent_interface, test) | 920 parent_interface = _FindInHierarchy(database, parent_interface, test) |
| 920 if parent_interface: | 921 if parent_interface: |
| 921 return parent_interface | 922 return parent_interface |
| 922 | 923 |
| 923 def _IsArgumentOptionalInWebCore(argument): | |
| 924 return IsOptional(argument) and not 'Callback' in argument.ext_attrs | |
| 925 | |
| 926 def _ToWebKitName(name): | 924 def _ToWebKitName(name): |
| 927 name = name[0].lower() + name[1:] | 925 name = name[0].lower() + name[1:] |
| 928 name = re.sub(r'^(hTML|uRL|jS|xML|xSLT)', lambda s: s.group(1).lower(), | 926 name = re.sub(r'^(hTML|uRL|jS|xML|xSLT)', lambda s: s.group(1).lower(), |
| 929 name) | 927 name) |
| 930 return re.sub(r'^(create|exclusive)', lambda s: 'is' + s.group(1).capitalize()
, | 928 return re.sub(r'^(create|exclusive)', lambda s: 'is' + s.group(1).capitalize()
, |
| 931 name) | 929 name) |
| OLD | NEW |