| 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 |
| 11 from generator import * | 11 from generator import * |
| 12 from htmldartgenerator import * | 12 from htmldartgenerator import * |
| 13 from idlnode import IDLArgument | 13 from idlnode import IDLArgument |
| 14 from systemhtml import js_support_checks, GetCallbackInfo, HTML_LIBRARY_NAMES | 14 from systemhtml import js_support_checks, GetCallbackInfo, HTML_LIBRARY_NAMES |
| 15 | 15 |
| 16 _cpp_type_map = { |
| 17 ('DataTransferItem', 'webkitGetAsEntry'): 'DataTransferItemFileSystem', |
| 18 ('DOMWindow', 'indexedDB'): 'DOMWindowIndexedDatabase', |
| 19 ('DOMWindow', 'speechSynthesis'): 'DOMWindowSpeechSynthesis', |
| 20 ('DOMWindow', 'webkitNotifications'): 'DOMWindowNotifications', |
| 21 ('DOMWindow', 'storage'): 'DOMWindowQuota', |
| 22 ('DOMWindow', 'webkitStorageInfo'): 'DOMWindowQuota', |
| 23 ('DOMWindow', 'openDatabase'): 'DOMWindowWebDatabase', |
| 24 ('DOMWindow', 'webkitRequestFileSystem'): 'DOMWindowFileSystem', |
| 25 ('DOMWindow', 'webkitResolveLocalFileSystemURL'): 'DOMWindowFileSystem', |
| 26 ('HTMLInputElement', 'webkitEntries'): 'HTMLInputElementFileSystem', |
| 27 ('Navigator', 'doNotTrack'): 'NavigatorDoNotTrack', |
| 28 ('Navigator', 'geolocation'): 'NavigatorGeolocation', |
| 29 ('Navigator', 'webkitPersistentStorage'): 'NavigatorStorageQuota', |
| 30 ('Navigator', 'webkitTemporaryStorage'): 'NavigatorStorageQuota', |
| 31 ('Navigator', 'registerProtocolHandler'): 'NavigatorContentUtils', |
| 32 ('Navigator', 'unregisterProtocolHandler'): 'NavigatorContentUtils', |
| 33 ('Navigator', 'webkitGetUserMedia'): 'NavigatorMediaStream', |
| 34 ('Navigator', 'webkitGetGamepads'): 'NavigatorGamepad', |
| 35 } |
| 36 |
| 37 _cpp_partial_map = {} |
| 38 |
| 39 def _GetCPPPartialNames(interface_name): |
| 40 if not _cpp_partial_map: |
| 41 for (type, member) in _cpp_type_map.keys(): |
| 42 if type not in _cpp_partial_map: |
| 43 _cpp_partial_map[type] = set([]) |
| 44 _cpp_partial_map[type].add(_cpp_type_map[(type, member)]) |
| 45 |
| 46 if interface_name in _cpp_partial_map: |
| 47 return _cpp_partial_map[interface_name] |
| 48 else: |
| 49 return set([]) |
| 50 |
| 51 def _GetCPPTypeName(interface_name, callback_name): |
| 52 # TODO(vsm): We need to track the original IDL file name in order to recover |
| 53 # the proper CPP name. |
| 54 |
| 55 cpp_tuple = (interface_name, callback_name) |
| 56 if cpp_tuple in _cpp_type_map: |
| 57 cpp_type_name = _cpp_type_map[cpp_tuple] |
| 58 else: |
| 59 cpp_type_name = interface_name |
| 60 return cpp_type_name |
| 61 |
| 16 class DartiumBackend(HtmlDartGenerator): | 62 class DartiumBackend(HtmlDartGenerator): |
| 17 """Generates Dart implementation for one DOM IDL interface.""" | 63 """Generates Dart implementation for one DOM IDL interface.""" |
| 18 | 64 |
| 19 def __init__(self, interface, cpp_library_emitter, options): | 65 def __init__(self, interface, cpp_library_emitter, options): |
| 20 super(DartiumBackend, self).__init__(interface, options) | 66 super(DartiumBackend, self).__init__(interface, options) |
| 21 | 67 |
| 22 self._interface = interface | 68 self._interface = interface |
| 23 self._cpp_library_emitter = cpp_library_emitter | 69 self._cpp_library_emitter = cpp_library_emitter |
| 24 self._database = options.database | 70 self._database = options.database |
| 25 self._template_loader = options.templates | 71 self._template_loader = options.templates |
| 26 self._type_registry = options.type_registry | 72 self._type_registry = options.type_registry |
| 27 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) | 73 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) |
| 28 self._metadata = options.metadata | 74 self._metadata = options.metadata |
| 29 | 75 |
| 30 def ImplementsMergedMembers(self): | 76 def ImplementsMergedMembers(self): |
| 31 # We could not add merged functions to implementation class because | 77 # We could not add merged functions to implementation class because |
| 32 # underlying c++ object doesn't implement them. Merged functions are | 78 # underlying c++ object doesn't implement them. Merged functions are |
| 33 # generated on merged interface implementation instead. | 79 # generated on merged interface implementation instead. |
| 34 return False | 80 return False |
| 35 | 81 |
| 36 def CustomJSMembers(self): | 82 def CustomJSMembers(self): |
| 37 return {} | 83 return {} |
| 38 | 84 |
| 39 def GenerateCallback(self, info): | 85 def GenerateCallback(self, info): |
| 40 if IsPureInterface(self._interface.id) or IsCustomType(self._interface.id): | 86 if IsPureInterface(self._interface.id) or IsCustomType(self._interface.id): |
| 41 return | 87 return |
| 42 | 88 |
| 43 cpp_impl_includes = set() | 89 cpp_impl_includes = set(['"' + partial + '.h"' |
| 90 for partial in _GetCPPPartialNames(self._interface.
id)]) |
| 44 cpp_header_handlers_emitter = emitter.Emitter() | 91 cpp_header_handlers_emitter = emitter.Emitter() |
| 45 cpp_impl_handlers_emitter = emitter.Emitter() | 92 cpp_impl_handlers_emitter = emitter.Emitter() |
| 46 class_name = 'Dart%s' % self._interface.id | 93 class_name = 'Dart%s' % self._interface.id |
| 47 for operation in self._interface.operations: | 94 for operation in self._interface.operations: |
| 48 parameters = [] | 95 parameters = [] |
| 49 arguments = [] | 96 arguments = [] |
| 50 conversion_includes = [] | 97 conversion_includes = [] |
| 51 for argument in operation.arguments: | 98 for argument in operation.arguments: |
| 52 argument_type_info = self._TypeInfo(argument.type.id) | 99 argument_type_info = self._TypeInfo(argument.type.id) |
| 53 parameters.append('%s %s' % (argument_type_info.parameter_type(), | 100 parameters.append('%s %s' % (argument_type_info.parameter_type(), |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 self._interface.id, | 169 self._interface.id, |
| 123 self._renamer.GetLibraryName(self._interface)) | 170 self._renamer.GetLibraryName(self._interface)) |
| 124 self._cpp_impl_emitter = self._cpp_library_emitter.CreateSourceEmitter(sel
f._interface.id) | 171 self._cpp_impl_emitter = self._cpp_library_emitter.CreateSourceEmitter(sel
f._interface.id) |
| 125 else: | 172 else: |
| 126 self._cpp_header_emitter = emitter.Emitter() | 173 self._cpp_header_emitter = emitter.Emitter() |
| 127 self._cpp_impl_emitter = emitter.Emitter() | 174 self._cpp_impl_emitter = emitter.Emitter() |
| 128 | 175 |
| 129 self._interface_type_info = self._TypeInfo(self._interface.id) | 176 self._interface_type_info = self._TypeInfo(self._interface.id) |
| 130 self._members_emitter = members_emitter | 177 self._members_emitter = members_emitter |
| 131 self._cpp_declarations_emitter = emitter.Emitter() | 178 self._cpp_declarations_emitter = emitter.Emitter() |
| 132 self._cpp_impl_includes = set() | 179 self._cpp_impl_includes = set(['"' + partial + '.h"' |
| 180 for partial in _GetCPPPartialNames(self._inte
rface.id)]) |
| 133 self._cpp_definitions_emitter = emitter.Emitter() | 181 self._cpp_definitions_emitter = emitter.Emitter() |
| 134 self._cpp_resolver_emitter = emitter.Emitter() | 182 self._cpp_resolver_emitter = emitter.Emitter() |
| 135 | 183 |
| 136 # We need to revisit our treatment of typed arrays, right now | 184 # We need to revisit our treatment of typed arrays, right now |
| 137 # it is full of hacks. | 185 # it is full of hacks. |
| 138 if self._interface.ext_attrs.get('ConstructorTemplate') == 'TypedArray': | 186 if self._interface.ext_attrs.get('ConstructorTemplate') == 'TypedArray': |
| 139 self._cpp_resolver_emitter.Emit( | 187 self._cpp_resolver_emitter.Emit( |
| 140 ' if (name == "$(INTERFACE_NAME)_constructor_Callback")\n' | 188 ' if (name == "$(INTERFACE_NAME)_constructor_Callback")\n' |
| 141 ' return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n'
, | 189 ' return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n'
, |
| 142 INTERFACE_NAME=self._interface.id) | 190 INTERFACE_NAME=self._interface.id) |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 webcore_function_name = 'getNonEmptyURLAttribute' | 398 webcore_function_name = 'getNonEmptyURLAttribute' |
| 351 else: | 399 else: |
| 352 webcore_function_name = 'getURLAttribute' | 400 webcore_function_name = 'getURLAttribute' |
| 353 elif 'ImplementedAs' in attr.ext_attrs: | 401 elif 'ImplementedAs' in attr.ext_attrs: |
| 354 webcore_function_name = attr.ext_attrs['ImplementedAs'] | 402 webcore_function_name = attr.ext_attrs['ImplementedAs'] |
| 355 else: | 403 else: |
| 356 if attr.id == 'operator': | 404 if attr.id == 'operator': |
| 357 webcore_function_name = '_operator' | 405 webcore_function_name = '_operator' |
| 358 elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString': | 406 elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString': |
| 359 webcore_function_name = 'svgTarget' | 407 webcore_function_name = 'svgTarget' |
| 408 elif attr.id == 'CSS': |
| 409 webcore_function_name = 'css' |
| 360 else: | 410 else: |
| 361 webcore_function_name = self._ToWebKitName(attr.id) | 411 webcore_function_name = self._ToWebKitName(attr.id) |
| 362 if attr.type.id.startswith('SVGAnimated'): | 412 if attr.type.id.startswith('SVGAnimated'): |
| 363 webcore_function_name += 'Animated' | 413 webcore_function_name += 'Animated' |
| 364 | 414 |
| 365 function_expression = self._GenerateWebCoreFunctionExpression(webcore_functi
on_name, attr) | 415 function_expression = self._GenerateWebCoreFunctionExpression(webcore_functi
on_name, attr) |
| 366 self._GenerateNativeCallback( | 416 self._GenerateNativeCallback( |
| 367 cpp_callback_name, | 417 cpp_callback_name, |
| 368 True, | 418 True, |
| 369 function_expression, | 419 function_expression, |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 if raises_dom_exception: | 839 if raises_dom_exception: |
| 790 cpp_arguments.append('ec') | 840 cpp_arguments.append('ec') |
| 791 invocation_emitter = body_emitter.Emit( | 841 invocation_emitter = body_emitter.Emit( |
| 792 ' ExceptionCode ec = 0;\n' | 842 ' ExceptionCode ec = 0;\n' |
| 793 '$!INVOCATION' | 843 '$!INVOCATION' |
| 794 ' if (UNLIKELY(ec)) {\n' | 844 ' if (UNLIKELY(ec)) {\n' |
| 795 ' exception = DartDOMWrapper::exceptionCodeToDartException(ec
);\n' | 845 ' exception = DartDOMWrapper::exceptionCodeToDartException(ec
);\n' |
| 796 ' goto fail;\n' | 846 ' goto fail;\n' |
| 797 ' }\n') | 847 ' }\n') |
| 798 | 848 |
| 849 |
| 850 if needs_receiver: |
| 851 interface_name = self._interface_type_info.native_type() |
| 852 print 'Checking ' + interface_name |
| 853 cpp_type_name = _GetCPPTypeName(interface_name, |
| 854 node.id) |
| 855 print 'Found ' + cpp_type_name |
| 856 if interface_name != cpp_type_name: |
| 857 if interface_name == 'DOMWindow' or interface_name == 'Navigator': |
| 858 cpp_arguments.insert(0, 'receiver') |
| 859 else: |
| 860 cpp_arguments.append('receiver') |
| 861 |
| 799 function_call = '%s(%s)' % (function_expression, ', '.join(cpp_arguments)) | 862 function_call = '%s(%s)' % (function_expression, ', '.join(cpp_arguments)) |
| 800 if return_type == 'void': | 863 if return_type == 'void': |
| 801 invocation_emitter.Emit( | 864 invocation_emitter.Emit( |
| 802 ' $FUNCTION_CALL;\n', | 865 ' $FUNCTION_CALL;\n', |
| 803 FUNCTION_CALL=function_call) | 866 FUNCTION_CALL=function_call) |
| 804 else: | 867 else: |
| 805 return_type_info = self._TypeInfo(return_type) | 868 return_type_info = self._TypeInfo(return_type) |
| 806 self._cpp_impl_includes |= set(return_type_info.conversion_includes()) | 869 self._cpp_impl_includes |= set(return_type_info.conversion_includes()) |
| 807 | 870 |
| 808 if return_type_is_nullable: | 871 if return_type_is_nullable: |
| (...skipping 27 matching lines...) Expand all Loading... |
| 836 native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix) | 899 native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix) |
| 837 self._members_emitter.Emit( | 900 self._members_emitter.Emit( |
| 838 '\n' | 901 '\n' |
| 839 ' $METADATA$DART_DECLARATION native "$NATIVE_BINDING";\n', | 902 ' $METADATA$DART_DECLARATION native "$NATIVE_BINDING";\n', |
| 840 DOMINTERFACE=self._interface.id, | 903 DOMINTERFACE=self._interface.id, |
| 841 METADATA=metadata, | 904 METADATA=metadata, |
| 842 DART_DECLARATION=dart_declaration, | 905 DART_DECLARATION=dart_declaration, |
| 843 NATIVE_BINDING=native_binding) | 906 NATIVE_BINDING=native_binding) |
| 844 | 907 |
| 845 cpp_callback_name = '%s%s' % (idl_name, native_suffix) | 908 cpp_callback_name = '%s%s' % (idl_name, native_suffix) |
| 909 |
| 846 self._cpp_resolver_emitter.Emit( | 910 self._cpp_resolver_emitter.Emit( |
| 847 ' if (argumentCount == $ARGC && name == "$NATIVE_BINDING")\n' | 911 ' if (argumentCount == $ARGC && name == "$NATIVE_BINDING")\n' |
| 848 ' return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n', | 912 ' return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n', |
| 849 ARGC=argument_count, | 913 ARGC=argument_count, |
| 850 NATIVE_BINDING=native_binding, | 914 NATIVE_BINDING=native_binding, |
| 851 INTERFACE_NAME=self._interface.id, | 915 INTERFACE_NAME=self._interface.id, |
| 852 CPP_CALLBACK_NAME=cpp_callback_name) | 916 CPP_CALLBACK_NAME=cpp_callback_name) |
| 853 | 917 |
| 854 if is_custom: | 918 if is_custom: |
| 855 self._cpp_declarations_emitter.Emit( | 919 self._cpp_declarations_emitter.Emit( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 869 self._cpp_impl_includes.add('"%s.h"' % namespace) | 933 self._cpp_impl_includes.add('"%s.h"' % namespace) |
| 870 | 934 |
| 871 attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower() | 935 attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower() |
| 872 return 'WebCore::%s::%sAttr' % (namespace, attribute_name) | 936 return 'WebCore::%s::%sAttr' % (namespace, attribute_name) |
| 873 | 937 |
| 874 def _GenerateWebCoreFunctionExpression(self, function_name, idl_node): | 938 def _GenerateWebCoreFunctionExpression(self, function_name, idl_node): |
| 875 if 'ImplementedBy' in idl_node.ext_attrs: | 939 if 'ImplementedBy' in idl_node.ext_attrs: |
| 876 return '%s::%s' % (idl_node.ext_attrs['ImplementedBy'], function_name) | 940 return '%s::%s' % (idl_node.ext_attrs['ImplementedBy'], function_name) |
| 877 if idl_node.is_static: | 941 if idl_node.is_static: |
| 878 return '%s::%s' % (self._interface_type_info.idl_type(), function_name) | 942 return '%s::%s' % (self._interface_type_info.idl_type(), function_name) |
| 879 return '%s%s' % (self._interface_type_info.receiver(), function_name) | 943 interface_name = self._interface_type_info.idl_type() |
| 944 cpp_type_name = _GetCPPTypeName(interface_name, function_name) |
| 945 print 'Gen for ' + interface_name + ' ' + function_name |
| 946 if cpp_type_name == interface_name: |
| 947 return '%s%s' % (self._interface_type_info.receiver(), function_name) |
| 948 else: |
| 949 return '%s::%s' % (cpp_type_name, function_name) |
| 880 | 950 |
| 881 def _IsArgumentOptionalInWebCore(self, operation, argument): | 951 def _IsArgumentOptionalInWebCore(self, operation, argument): |
| 882 if not IsOptional(argument): | 952 if not IsOptional(argument): |
| 883 return False | 953 return False |
| 884 if 'Callback' in argument.ext_attrs: | 954 if 'Callback' in argument.ext_attrs: |
| 885 return False | 955 return False |
| 886 if operation.id in ['addEventListener', 'removeEventListener'] and argument.
id == 'useCapture': | 956 if operation.id in ['addEventListener', 'removeEventListener'] and argument.
id == 'useCapture': |
| 887 return False | 957 return False |
| 888 if 'ForceOptional' in argument.ext_attrs: | 958 if 'ForceOptional' in argument.ext_attrs: |
| 889 return False | 959 return False |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 952 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argu
mentCount))\n' | 1022 ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argu
mentCount))\n' |
| 953 ' return func;\n', | 1023 ' return func;\n', |
| 954 CLASS_NAME=os.path.splitext(os.path.basename(path))[0]) | 1024 CLASS_NAME=os.path.splitext(os.path.basename(path))[0]) |
| 955 | 1025 |
| 956 def _IsOptionalStringArgumentInInitEventMethod(interface, operation, argument): | 1026 def _IsOptionalStringArgumentInInitEventMethod(interface, operation, argument): |
| 957 return ( | 1027 return ( |
| 958 interface.id.endswith('Event') and | 1028 interface.id.endswith('Event') and |
| 959 operation.id.startswith('init') and | 1029 operation.id.startswith('init') and |
| 960 argument.ext_attrs.get('Default') == 'Undefined' and | 1030 argument.ext_attrs.get('Default') == 'Undefined' and |
| 961 argument.type.id == 'DOMString') | 1031 argument.type.id == 'DOMString') |
| OLD | NEW |