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 import systembase | 11 import systembase |
12 from generator import * | 12 from generator import * |
13 from systemhtml import HtmlSystemShared | 13 from systemhtml import HtmlSystemShared |
14 | 14 |
15 | 15 |
16 class NativeImplementationSystem(systembase.System): | 16 class NativeImplementationSystem(systembase.System): |
17 | 17 |
18 def __init__(self, templates, database, emitters, output_dir, auxiliary_dir): | 18 def __init__(self, options, auxiliary_dir): |
19 super(NativeImplementationSystem, self).__init__( | 19 super(NativeImplementationSystem, self).__init__(options) |
20 templates, database, emitters, output_dir) | |
21 self._auxiliary_dir = auxiliary_dir | 20 self._auxiliary_dir = auxiliary_dir |
22 self._cpp_header_files = [] | 21 self._cpp_header_files = [] |
23 self._cpp_impl_files = [] | 22 self._cpp_impl_files = [] |
24 self._html_system = HtmlSystemShared(database) | 23 self._html_system = HtmlSystemShared(self._database) |
25 | 24 |
26 def ImplementationGenerator(self, interface): | 25 def ImplementationGenerator(self, interface): |
27 return NativeImplementationGenerator(self, interface) | 26 return NativeImplementationGenerator(self, interface) |
28 | 27 |
29 def ProcessCallback(self, interface, info): | 28 def ProcessCallback(self, interface, info): |
30 self._interface = interface | 29 self._interface = interface |
31 | 30 |
32 if IsPureInterface(self._interface.id): | 31 if IsPureInterface(self._interface.id): |
33 return None | 32 return None |
34 | 33 |
35 cpp_impl_includes = set() | 34 cpp_impl_includes = set() |
36 cpp_header_handlers_emitter = emitter.Emitter() | 35 cpp_header_handlers_emitter = emitter.Emitter() |
37 cpp_impl_handlers_emitter = emitter.Emitter() | 36 cpp_impl_handlers_emitter = emitter.Emitter() |
38 class_name = 'Dart%s' % self._interface.id | 37 class_name = 'Dart%s' % self._interface.id |
39 for operation in interface.operations: | 38 for operation in interface.operations: |
40 if operation.type.id == 'void': | 39 if operation.type.id == 'void': |
41 return_prefix = '' | 40 return_prefix = '' |
42 error_return = '' | 41 error_return = '' |
43 else: | 42 else: |
44 return_prefix = 'return ' | 43 return_prefix = 'return ' |
45 error_return = ' false' | 44 error_return = ' false' |
46 | 45 |
47 parameters = [] | 46 parameters = [] |
48 arguments = [] | 47 arguments = [] |
49 for argument in operation.arguments: | 48 for argument in operation.arguments: |
50 argument_type_info = GetIDLTypeInfo(argument.type.id) | 49 argument_type_info = self._type_registry.TypeInfo(argument.type.id) |
51 parameters.append('%s %s' % (argument_type_info.parameter_type(), | 50 parameters.append('%s %s' % (argument_type_info.parameter_type(), |
52 argument.id)) | 51 argument.id)) |
53 arguments.append(argument_type_info.to_dart_conversion(argument.id)) | 52 arguments.append(argument_type_info.to_dart_conversion(argument.id)) |
54 cpp_impl_includes |= set(argument_type_info.conversion_includes()) | 53 cpp_impl_includes |= set(argument_type_info.conversion_includes()) |
55 | 54 |
56 native_return_type = GetIDLTypeInfo(operation.type.id).native_type() | 55 native_return_type = self._type_registry.TypeInfo(operation.type.id).nativ
e_type() |
57 cpp_header_handlers_emitter.Emit( | 56 cpp_header_handlers_emitter.Emit( |
58 '\n' | 57 '\n' |
59 ' virtual $TYPE handleEvent($PARAMETERS);\n', | 58 ' virtual $TYPE handleEvent($PARAMETERS);\n', |
60 TYPE=native_return_type, PARAMETERS=', '.join(parameters)) | 59 TYPE=native_return_type, PARAMETERS=', '.join(parameters)) |
61 | 60 |
62 arguments_declaration = 'Dart_Handle arguments[] = { %s }' % ', '.join(arg
uments) | 61 arguments_declaration = 'Dart_Handle arguments[] = { %s }' % ', '.join(arg
uments) |
63 if not len(arguments): | 62 if not len(arguments): |
64 arguments_declaration = 'Dart_Handle* arguments = 0' | 63 arguments_declaration = 'Dart_Handle* arguments = 0' |
65 cpp_impl_handlers_emitter.Emit( | 64 cpp_impl_handlers_emitter.Emit( |
66 '\n' | 65 '\n' |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 cpp_header_path = self._system._FilePathForCppHeader(self._interface.id) | 204 cpp_header_path = self._system._FilePathForCppHeader(self._interface.id) |
206 self._system._cpp_header_files.append(cpp_header_path) | 205 self._system._cpp_header_files.append(cpp_header_path) |
207 self._cpp_header_emitter = self._system._emitters.FileEmitter(cpp_header_p
ath) | 206 self._cpp_header_emitter = self._system._emitters.FileEmitter(cpp_header_p
ath) |
208 cpp_impl_path = self._system._FilePathForCppImplementation(self._interface
.id) | 207 cpp_impl_path = self._system._FilePathForCppImplementation(self._interface
.id) |
209 self._system._cpp_impl_files.append(cpp_impl_path) | 208 self._system._cpp_impl_files.append(cpp_impl_path) |
210 self._cpp_impl_emitter = self._system._emitters.FileEmitter(cpp_impl_path) | 209 self._cpp_impl_emitter = self._system._emitters.FileEmitter(cpp_impl_path) |
211 else: | 210 else: |
212 self._cpp_header_emitter = emitter.Emitter() | 211 self._cpp_header_emitter = emitter.Emitter() |
213 self._cpp_impl_emitter = emitter.Emitter() | 212 self._cpp_impl_emitter = emitter.Emitter() |
214 | 213 |
215 self._interface_type_info = GetIDLTypeInfo(self._interface.id) | 214 self._interface_type_info = self._TypeInfo(self._interface.id) |
216 self._members_emitter = emitter.Emitter() | 215 self._members_emitter = emitter.Emitter() |
217 self._cpp_declarations_emitter = emitter.Emitter() | 216 self._cpp_declarations_emitter = emitter.Emitter() |
218 self._cpp_impl_includes = set() | 217 self._cpp_impl_includes = set() |
219 self._cpp_definitions_emitter = emitter.Emitter() | 218 self._cpp_definitions_emitter = emitter.Emitter() |
220 self._cpp_resolver_emitter = emitter.Emitter() | 219 self._cpp_resolver_emitter = emitter.Emitter() |
221 | 220 |
222 self._GenerateConstructors() | 221 self._GenerateConstructors() |
223 return self._members_emitter | 222 return self._members_emitter |
224 | 223 |
225 def _GenerateConstructors(self): | 224 def _GenerateConstructors(self): |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 def AddAttribute(self, attribute, html_name, read_only): | 479 def AddAttribute(self, attribute, html_name, read_only): |
481 if 'CheckSecurityForNode' in attribute.ext_attrs: | 480 if 'CheckSecurityForNode' in attribute.ext_attrs: |
482 # FIXME: exclude from interface as well. | 481 # FIXME: exclude from interface as well. |
483 return | 482 return |
484 | 483 |
485 self._AddGetter(attribute, html_name) | 484 self._AddGetter(attribute, html_name) |
486 if not read_only: | 485 if not read_only: |
487 self._AddSetter(attribute, html_name) | 486 self._AddSetter(attribute, html_name) |
488 | 487 |
489 def _AddGetter(self, attr, html_name): | 488 def _AddGetter(self, attr, html_name): |
490 type_info = GetIDLTypeInfo(attr.type.id) | 489 type_info = self._TypeInfo(attr.type.id) |
491 dart_declaration = '%s get %s()' % (self._DartType(attr.type.id), html_name) | 490 dart_declaration = '%s get %s()' % (self._DartType(attr.type.id), html_name) |
492 is_custom = 'Custom' in attr.ext_attrs or 'CustomGetter' in attr.ext_attrs | 491 is_custom = 'Custom' in attr.ext_attrs or 'CustomGetter' in attr.ext_attrs |
493 cpp_callback_name = self._GenerateNativeBinding(attr.id, 1, | 492 cpp_callback_name = self._GenerateNativeBinding(attr.id, 1, |
494 dart_declaration, 'Getter', is_custom) | 493 dart_declaration, 'Getter', is_custom) |
495 if is_custom: | 494 if is_custom: |
496 return | 495 return |
497 | 496 |
498 arguments = [] | 497 arguments = [] |
499 parameter_definitions_emitter = emitter.Emitter() | 498 parameter_definitions_emitter = emitter.Emitter() |
500 raises_exceptions = self._GenerateCallWithHandling(attr, parameter_definitio
ns_emitter, arguments) | 499 raises_exceptions = self._GenerateCallWithHandling(attr, parameter_definitio
ns_emitter, arguments) |
501 raises_exceptions = raises_exceptions or attr.get_raises | 500 raises_exceptions = raises_exceptions or attr.get_raises |
502 | 501 |
503 if 'Reflect' in attr.ext_attrs: | 502 if 'Reflect' in attr.ext_attrs: |
504 webcore_function_name = GetIDLTypeInfo(attr.type.id).webcore_getter_name() | 503 webcore_function_name = self._TypeInfo(attr.type.id).webcore_getter_name() |
505 if 'URL' in attr.ext_attrs: | 504 if 'URL' in attr.ext_attrs: |
506 if 'NonEmpty' in attr.ext_attrs: | 505 if 'NonEmpty' in attr.ext_attrs: |
507 webcore_function_name = 'getNonEmptyURLAttribute' | 506 webcore_function_name = 'getNonEmptyURLAttribute' |
508 else: | 507 else: |
509 webcore_function_name = 'getURLAttribute' | 508 webcore_function_name = 'getURLAttribute' |
510 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr)) | 509 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr)) |
511 else: | 510 else: |
512 if attr.id == 'operator': | 511 if attr.id == 'operator': |
513 webcore_function_name = '_operator' | 512 webcore_function_name = '_operator' |
514 elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString': | 513 elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString': |
515 webcore_function_name = 'svgTarget' | 514 webcore_function_name = 'svgTarget' |
516 else: | 515 else: |
517 webcore_function_name = _ToWebKitName(attr.id) | 516 webcore_function_name = _ToWebKitName(attr.id) |
518 if attr.type.id.startswith('SVGAnimated'): | 517 if attr.type.id.startswith('SVGAnimated'): |
519 webcore_function_name += 'Animated' | 518 webcore_function_name += 'Animated' |
520 | 519 |
521 function_expression = self._GenerateWebCoreFunctionExpression(webcore_functi
on_name, attr) | 520 function_expression = self._GenerateWebCoreFunctionExpression(webcore_functi
on_name, attr) |
522 invocation = self._GenerateWebCoreInvocation(function_expression, | 521 invocation = self._GenerateWebCoreInvocation(function_expression, |
523 arguments, attr.type.id, attr.ext_attrs, attr.get_raises) | 522 arguments, attr.type.id, attr.ext_attrs, attr.get_raises) |
524 self._GenerateNativeCallback(cpp_callback_name, parameter_definitions_emitte
r.Fragments(), | 523 self._GenerateNativeCallback(cpp_callback_name, parameter_definitions_emitte
r.Fragments(), |
525 True, invocation, raises_exceptions=raises_exceptions) | 524 True, invocation, raises_exceptions=raises_exceptions) |
526 | 525 |
527 def _AddSetter(self, attr, html_name): | 526 def _AddSetter(self, attr, html_name): |
528 type_info = GetIDLTypeInfo(attr.type.id) | 527 type_info = self._TypeInfo(attr.type.id) |
529 dart_declaration = 'void set %s(%s)' % (html_name, self._DartType(attr.type.
id)) | 528 dart_declaration = 'void set %s(%s)' % (html_name, self._DartType(attr.type.
id)) |
530 is_custom = set(['Custom', 'CustomSetter', 'V8CustomSetter']) & set(attr.ext
_attrs) | 529 is_custom = set(['Custom', 'CustomSetter', 'V8CustomSetter']) & set(attr.ext
_attrs) |
531 cpp_callback_name = self._GenerateNativeBinding(attr.id, 2, | 530 cpp_callback_name = self._GenerateNativeBinding(attr.id, 2, |
532 dart_declaration, 'Setter', is_custom) | 531 dart_declaration, 'Setter', is_custom) |
533 if is_custom: | 532 if is_custom: |
534 return | 533 return |
535 | 534 |
536 arguments = [] | 535 arguments = [] |
537 parameter_definitions_emitter = emitter.Emitter() | 536 parameter_definitions_emitter = emitter.Emitter() |
538 self._GenerateCallWithHandling(attr, parameter_definitions_emitter, argument
s) | 537 self._GenerateCallWithHandling(attr, parameter_definitions_emitter, argument
s) |
539 | 538 |
540 if 'Reflect' in attr.ext_attrs: | 539 if 'Reflect' in attr.ext_attrs: |
541 webcore_function_name = GetIDLTypeInfo(attr.type.id).webcore_setter_name() | 540 webcore_function_name = self._TypeInfo(attr.type.id).webcore_setter_name() |
542 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr)) | 541 arguments.append(self._GenerateWebCoreReflectionAttributeName(attr)) |
543 else: | 542 else: |
544 webcore_function_name = re.sub(r'^(xml(?=[A-Z])|\w)', | 543 webcore_function_name = re.sub(r'^(xml(?=[A-Z])|\w)', |
545 lambda s: s.group(1).upper(), | 544 lambda s: s.group(1).upper(), |
546 attr.id) | 545 attr.id) |
547 webcore_function_name = 'set%s' % webcore_function_name | 546 webcore_function_name = 'set%s' % webcore_function_name |
548 if attr.type.id.startswith('SVGAnimated'): | 547 if attr.type.id.startswith('SVGAnimated'): |
549 webcore_function_name += 'Animated' | 548 webcore_function_name += 'Animated' |
550 | 549 |
551 argument_expression = self._GenerateToNative( | 550 argument_expression = self._GenerateToNative( |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 '{\n' | 854 '{\n' |
856 ' DartApiScope dartApiScope;\n' | 855 ' DartApiScope dartApiScope;\n' |
857 '$BODY' | 856 '$BODY' |
858 '}\n', | 857 '}\n', |
859 CALLBACK_NAME=callback_name, | 858 CALLBACK_NAME=callback_name, |
860 BODY=body) | 859 BODY=body) |
861 | 860 |
862 def _GenerateToNative(self, emitter, idl_node, index, | 861 def _GenerateToNative(self, emitter, idl_node, index, |
863 argument_name=None): | 862 argument_name=None): |
864 """idl_node is IDLArgument or IDLAttribute.""" | 863 """idl_node is IDLArgument or IDLAttribute.""" |
865 type_info = GetIDLTypeInfo(idl_node.type.id) | 864 type_info = self._TypeInfo(idl_node.type.id) |
866 self._cpp_impl_includes |= set(type_info.to_native_includes()) | 865 self._cpp_impl_includes |= set(type_info.to_native_includes()) |
867 argument_name = argument_name or idl_node.id | 866 argument_name = argument_name or idl_node.id |
868 handle = 'Dart_GetNativeArgument(args, %i)' % index | 867 handle = 'Dart_GetNativeArgument(args, %i)' % index |
869 return type_info.emit_to_native(emitter, idl_node, argument_name, handle, se
lf._interface.id) | 868 return type_info.emit_to_native(emitter, idl_node, argument_name, handle, se
lf._interface.id) |
870 | 869 |
871 def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration, | 870 def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration, |
872 native_suffix, is_custom): | 871 native_suffix, is_custom): |
873 native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix) | 872 native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix) |
874 self._members_emitter.Emit( | 873 self._members_emitter.Emit( |
875 '\n' | 874 '\n' |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 if 'ImplementedBy' in idl_node.ext_attrs: | 908 if 'ImplementedBy' in idl_node.ext_attrs: |
910 return '%s::%s' % (idl_node.ext_attrs['ImplementedBy'], function_name) | 909 return '%s::%s' % (idl_node.ext_attrs['ImplementedBy'], function_name) |
911 if idl_node.is_static: | 910 if idl_node.is_static: |
912 return '%s::%s' % (self._interface_type_info.idl_type(), function_name) | 911 return '%s::%s' % (self._interface_type_info.idl_type(), function_name) |
913 return '%s%s' % (self._interface_type_info.receiver(), function_name) | 912 return '%s%s' % (self._interface_type_info.receiver(), function_name) |
914 | 913 |
915 def _GenerateWebCoreInvocation(self, function_expression, arguments, | 914 def _GenerateWebCoreInvocation(self, function_expression, arguments, |
916 idl_return_type, attributes, raises_dom_exceptions): | 915 idl_return_type, attributes, raises_dom_exceptions): |
917 invocation_template = ' $FUNCTION_CALL;\n' | 916 invocation_template = ' $FUNCTION_CALL;\n' |
918 if idl_return_type != 'void': | 917 if idl_return_type != 'void': |
919 return_type_info = GetIDLTypeInfo(idl_return_type) | 918 return_type_info = self._TypeInfo(idl_return_type) |
920 self._cpp_impl_includes |= set(return_type_info.conversion_includes()) | 919 self._cpp_impl_includes |= set(return_type_info.conversion_includes()) |
921 | 920 |
922 # Generate to Dart conversion of C++ value. | 921 # Generate to Dart conversion of C++ value. |
923 to_dart_conversion = return_type_info.to_dart_conversion('$FUNCTION_CALL',
self._interface.id, attributes) | 922 to_dart_conversion = return_type_info.to_dart_conversion('$FUNCTION_CALL',
self._interface.id, attributes) |
924 invocation_template = emitter.Format( | 923 invocation_template = emitter.Format( |
925 ' Dart_Handle returnValue = $TO_DART_CONVERSION;\n' | 924 ' Dart_Handle returnValue = $TO_DART_CONVERSION;\n' |
926 ' if (returnValue)\n' | 925 ' if (returnValue)\n' |
927 ' Dart_SetReturnValue(args, returnValue);\n', | 926 ' Dart_SetReturnValue(args, returnValue);\n', |
928 TO_DART_CONVERSION=to_dart_conversion) | 927 TO_DART_CONVERSION=to_dart_conversion) |
929 | 928 |
930 if raises_dom_exceptions: | 929 if raises_dom_exceptions: |
931 # Add 'ec' argument to WebCore invocation and convert DOM exception to Dar
t exception. | 930 # Add 'ec' argument to WebCore invocation and convert DOM exception to Dar
t exception. |
932 arguments.append('ec') | 931 arguments.append('ec') |
933 invocation_template = emitter.Format( | 932 invocation_template = emitter.Format( |
934 ' ExceptionCode ec = 0;\n' | 933 ' ExceptionCode ec = 0;\n' |
935 '$INVOCATION' | 934 '$INVOCATION' |
936 ' if (UNLIKELY(ec)) {\n' | 935 ' if (UNLIKELY(ec)) {\n' |
937 ' exception = DartDOMWrapper::exceptionCodeToDartException(
ec);\n' | 936 ' exception = DartDOMWrapper::exceptionCodeToDartException(
ec);\n' |
938 ' goto fail;\n' | 937 ' goto fail;\n' |
939 ' }\n', | 938 ' }\n', |
940 INVOCATION=invocation_template) | 939 INVOCATION=invocation_template) |
941 | 940 |
942 if 'ImplementedBy' in attributes: | 941 if 'ImplementedBy' in attributes: |
943 arguments.insert(0, 'receiver') | 942 arguments.insert(0, 'receiver') |
944 self._cpp_impl_includes.add('"%s.h"' % attributes['ImplementedBy']) | 943 self._cpp_impl_includes.add('"%s.h"' % attributes['ImplementedBy']) |
945 | 944 |
946 return emitter.Format(invocation_template, | 945 return emitter.Format(invocation_template, |
947 FUNCTION_CALL='%s(%s)' % (function_expression, ', '.join(arguments))) | 946 FUNCTION_CALL='%s(%s)' % (function_expression, ', '.join(arguments))) |
948 | 947 |
| 948 def _TypeInfo(self, type_name): |
| 949 return self._system._type_registry.TypeInfo(type_name) |
| 950 |
949 | 951 |
950 def _GenerateCPPIncludes(includes): | 952 def _GenerateCPPIncludes(includes): |
951 return ''.join(['#include %s\n' % include for include in sorted(includes)]) | 953 return ''.join(['#include %s\n' % include for include in sorted(includes)]) |
952 | 954 |
953 def _FindInHierarchy(database, interface, test): | 955 def _FindInHierarchy(database, interface, test): |
954 if test(interface): | 956 if test(interface): |
955 return interface | 957 return interface |
956 for parent in interface.parents: | 958 for parent in interface.parents: |
957 parent_name = parent.type.id | 959 parent_name = parent.type.id |
958 if not database.HasInterface(parent.type.id): | 960 if not database.HasInterface(parent.type.id): |
959 continue | 961 continue |
960 parent_interface = database.GetInterface(parent.type.id) | 962 parent_interface = database.GetInterface(parent.type.id) |
961 parent_interface = _FindInHierarchy(database, parent_interface, test) | 963 parent_interface = _FindInHierarchy(database, parent_interface, test) |
962 if parent_interface: | 964 if parent_interface: |
963 return parent_interface | 965 return parent_interface |
964 | 966 |
965 def _IsArgumentOptionalInWebCore(argument): | 967 def _IsArgumentOptionalInWebCore(argument): |
966 return IsOptional(argument) and not 'Callback' in argument.ext_attrs | 968 return IsOptional(argument) and not 'Callback' in argument.ext_attrs |
967 | 969 |
968 def _ToWebKitName(name): | 970 def _ToWebKitName(name): |
969 name = name[0].lower() + name[1:] | 971 name = name[0].lower() + name[1:] |
970 name = re.sub(r'^(hTML|uRL|jS|xML|xSLT)', lambda s: s.group(1).lower(), | 972 name = re.sub(r'^(hTML|uRL|jS|xML|xSLT)', lambda s: s.group(1).lower(), |
971 name) | 973 name) |
972 return re.sub(r'^(create|exclusive)', lambda s: 'is' + s.group(1).capitalize()
, | 974 return re.sub(r'^(create|exclusive)', lambda s: 'is' + s.group(1).capitalize()
, |
973 name) | 975 name) |
OLD | NEW |