Chromium Code Reviews| Index: client/dom/scripts/systemnative.py |
| diff --git a/client/dom/scripts/systemnative.py b/client/dom/scripts/systemnative.py |
| index 13a9d92cd5af7da1d9cf9662b455687368e9eacc..9172c261678ccef7a017a1e36118bb5b386011d4 100644 |
| --- a/client/dom/scripts/systemnative.py |
| +++ b/client/dom/scripts/systemnative.py |
| @@ -276,7 +276,6 @@ class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator): |
| raises_dom_exceptions = 'ConstructorRaisesException' in self._interface.ext_attrs |
| raises_dart_exceptions = raises_dom_exceptions or len(constructor_info.idl_args) > 0 |
| - type_info = GetIDLTypeInfo(self._interface) |
| arguments = [] |
| parameter_definitions_emitter = emitter.Emitter() |
| if 'CallWith' in self._interface.ext_attrs: |
| @@ -298,16 +297,13 @@ class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator): |
| self._GenerateParameterAdapter(parameter_definitions_emitter, arg, i - 1) |
| arguments.append(arg.id) |
| - self._GenerateNativeCallback( |
| - callback_name='constructorCallback', |
| - idl_node=self._interface, |
| + function_expression = '%s::create' % self._interface_type_info.native_type() |
| + invocation = self._GenerateWebCoreInvocation(function_expression, arguments, |
| + self._interface, self._interface.ext_attrs, raises_dom_exceptions) |
| + self._GenerateNativeCallback(callback_name='constructorCallback', |
|
antonm
2012/02/27 13:17:33
nit: I'd prefer to callback_name='...' on a separa
|
| parameter_definitions=parameter_definitions_emitter.Fragments(), |
| - needs_receiver=False, function_name='%s::create' % type_info.native_type(), |
| - arguments=arguments, |
| - idl_return_type=self._interface, |
| - raises_dart_exceptions=raises_dart_exceptions, |
| - raises_dom_exceptions=raises_dom_exceptions) |
| - |
| + needs_receiver=False, invocation=invocation, |
| + raises_exceptions=raises_dart_exceptions) |
| def _ImplClassName(self, interface_name): |
| return interface_name + 'Implementation' |
| @@ -377,10 +373,6 @@ class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator): |
| if (getter or setter).type.id == 'EventListener': |
| return |
| - # FIXME: support 'ImplementedBy'. |
| - if 'ImplementedBy' in (getter or setter).ext_attrs: |
| - return |
| - |
| # FIXME: these should go away. |
| classes_with_unsupported_custom_getters = [ |
| 'Clipboard', 'Console', 'Coordinates', 'DeviceMotionEvent', |
| @@ -428,10 +420,11 @@ class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator): |
| if attr.type.id.startswith('SVGAnimated'): |
| webcore_function_name += 'Animated' |
| - self._GenerateNativeCallback(cpp_callback_name, attr, '', |
| - True, webcore_function_name, arguments, idl_return_type=attr.type, |
| - raises_dart_exceptions=attr.get_raises, |
| - raises_dom_exceptions=attr.get_raises) |
| + function_expression = self._GenerateWebCoreFunctionExpression(webcore_function_name, attr) |
| + invocation = self._GenerateWebCoreInvocation(function_expression, |
| + arguments, attr.type, attr.ext_attrs, attr.get_raises) |
| + self._GenerateNativeCallback(cpp_callback_name, '', True, invocation, |
| + raises_exceptions=attr.get_raises) |
| def _AddSetter(self, attr): |
| dart_declaration = 'void set %s(%s)' % (attr.id, attr.type.id) |
| @@ -454,13 +447,17 @@ class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator): |
| webcore_function_name += 'Animated' |
| arguments.append(attr.id) |
| + |
| parameter_definitions_emitter = emitter.Emitter() |
| self._GenerateParameterAdapter(parameter_definitions_emitter, attr, 0) |
| parameter_definitions = parameter_definitions_emitter.Fragments() |
| - self._GenerateNativeCallback(cpp_callback_name, attr, parameter_definitions, |
| - True, webcore_function_name, arguments, idl_return_type=None, |
| - raises_dart_exceptions=True, |
| - raises_dom_exceptions=attr.set_raises) |
| + |
| + function_expression = self._GenerateWebCoreFunctionExpression(webcore_function_name, attr) |
| + invocation = self._GenerateWebCoreInvocation(function_expression, |
| + arguments, None, attr.ext_attrs, attr.set_raises) |
| + |
| + self._GenerateNativeCallback(cpp_callback_name, parameter_definitions, |
| + True, invocation, raises_exceptions=True) |
| def _HasNativeIndexGetter(self, interface): |
| return ('CustomIndexedGetter' in interface.ext_attrs or |
| @@ -518,10 +515,6 @@ class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator): |
| operation: the IDLOperation to call. |
| """ |
| - # FIXME: support ImplementedBy callbacks. |
| - if 'ImplementedBy' in operation.ext_attrs: |
| - return |
| - |
| for op in self._interface.operations: |
| if op.id != operation.id or len(op.arguments) <= len(operation.arguments): |
| continue |
| @@ -562,9 +555,7 @@ class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator): |
| return |
| # Generate callback. |
| - webcore_function_name = operation.id |
| - if 'ImplementedAs' in operation.ext_attrs: |
| - webcore_function_name = operation.ext_attrs['ImplementedAs'] |
| + webcore_function_name = operation.ext_attrs.get('ImplementedAs', operation.id) |
| parameter_definitions_emitter = emitter.Emitter() |
| raises_dart_exceptions = len(operation.arguments) > 0 or operation.raises |
| @@ -620,105 +611,54 @@ class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator): |
| arguments.append('String()') |
| if 'NeedsUserGestureCheck' in operation.ext_attrs: |
| - arguments.extend('DartUtilities::processingUserGesture') |
| + arguments.append('DartUtilities::processingUserGesture') |
| - parameter_definitions = parameter_definitions_emitter.Fragments() |
| - self._GenerateNativeCallback(cpp_callback_name, operation, parameter_definitions, |
| - True, webcore_function_name, arguments, idl_return_type=operation.type, |
| - raises_dart_exceptions=raises_dart_exceptions, |
| - raises_dom_exceptions=operation.raises) |
| - |
| - def _GenerateNativeCallback(self, callback_name, idl_node, |
| - parameter_definitions, needs_receiver, function_name, arguments, idl_return_type, |
| - raises_dart_exceptions, raises_dom_exceptions): |
| - if raises_dom_exceptions: |
| - arguments.append('ec') |
| - prefix = '' |
| - if needs_receiver: prefix = self._interface_type_info.receiver() |
| - callback = '%s%s(%s)' % (prefix, function_name, ', '.join(arguments)) |
| - |
| - nested_templates = [] |
| - if idl_return_type and idl_return_type.id != 'void': |
| - return_type_info = GetIDLTypeInfo(idl_return_type) |
| - conversion_cast = return_type_info.conversion_cast('$BODY') |
| - if isinstance(return_type_info, SVGTearOffIDLTypeInfo): |
| - svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix', |
| - 'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform'] |
| - conversion_cast = '%s::create($BODY)' |
| - if self._interface.id.startswith('SVGAnimated'): |
| - conversion_cast = 'static_cast<%s*>($BODY)' |
| - elif return_type_info.idl_type() == 'SVGStringList': |
| - conversion_cast = '%s::create(receiver, $BODY)' |
| - elif self._interface.id.endswith('List'): |
| - conversion_cast = 'static_cast<%s*>($BODY.get())' |
| - elif return_type_info.idl_type() in svg_primitive_types: |
| - conversion_cast = '%s::create($BODY)' |
| - else: |
| - conversion_cast = 'static_cast<%s*>($BODY)' |
| - conversion_cast = conversion_cast % return_type_info.native_type() |
| - nested_templates.append(conversion_cast) |
| + function_expression = self._GenerateWebCoreFunctionExpression(webcore_function_name, operation) |
| + invocation = self._GenerateWebCoreInvocation(function_expression, arguments, |
| + operation.type, operation.ext_attrs, operation.raises) |
| + self._GenerateNativeCallback(cpp_callback_name, |
| + parameter_definitions=parameter_definitions_emitter.Fragments(), |
| + needs_receiver=True, invocation=invocation, |
| + raises_exceptions=raises_dart_exceptions) |
| - if return_type_info.conversion_include(): |
| - self._cpp_impl_includes[return_type_info.conversion_include()] = 1 |
| - if (return_type_info.idl_type() in ['DOMString', 'AtomicString'] and |
| - 'TreatReturnedNullStringAs' in idl_node.ext_attrs): |
| - nested_templates.append('$BODY, ConvertDefaultToNull') |
| - nested_templates.append( |
| - ' Dart_Handle returnValue = toDartValue($BODY);\n' |
| - ' if (returnValue)\n' |
| - ' Dart_SetReturnValue(args, returnValue);\n') |
| - else: |
| - nested_templates.append(' $BODY;\n') |
| + def _GenerateNativeCallback(self, callback_name, parameter_definitions, |
| + needs_receiver, invocation, raises_exceptions): |
| - if raises_dom_exceptions: |
| - nested_templates.append( |
| - ' ExceptionCode ec = 0;\n' |
| - '$BODY' |
| - ' if (UNLIKELY(ec)) {\n' |
| - ' exception = DartDOMWrapper::exceptionCodeToDartException(ec);\n' |
| - ' goto fail;\n' |
| - ' }\n') |
| + if needs_receiver: |
| + parameter_definitions = emitter.Format( |
| + ' $WEBCORE_CLASS_NAME* receiver = DartDOMWrapper::receiver< $WEBCORE_CLASS_NAME >(args);\n' |
| + ' $PARAMETER_DEFINITIONS\n', |
| + WEBCORE_CLASS_NAME=self._interface_type_info.native_type(), |
| + PARAMETER_DEFINITIONS=parameter_definitions) |
| - nested_templates.append( |
| + body = emitter.Format( |
| ' {\n' |
| '$PARAMETER_DEFINITIONS' |
| - '$BODY' |
| + '$INVOCATION' |
| ' return;\n' |
| - ' }\n') |
| + ' }\n', |
| + PARAMETER_DEFINITIONS=parameter_definitions, |
| + INVOCATION=invocation) |
| - if raises_dart_exceptions: |
| - nested_templates.append( |
| + if raises_exceptions: |
| + body = emitter.Format( |
| ' Dart_Handle exception;\n' |
| '$BODY' |
| '\n' |
| 'fail:\n' |
| ' Dart_ThrowException(exception);\n' |
| - ' ASSERT_NOT_REACHED();\n') |
| + ' ASSERT_NOT_REACHED();\n', |
| + BODY=body) |
| - nested_templates.append( |
| + self._cpp_definitions_emitter.Emit( |
| '\n' |
| 'static void $CALLBACK_NAME(Dart_NativeArguments args)\n' |
| '{\n' |
| ' DartApiScope dartApiScope;\n' |
| '$BODY' |
| - '}\n') |
| - |
| - template_parameters = { |
| - 'CALLBACK_NAME': callback_name, |
| - 'WEBCORE_CLASS_NAME': self._interface_type_info.native_type(), |
| - 'PARAMETER_DEFINITIONS': parameter_definitions, |
| - } |
| - if needs_receiver: |
| - template_parameters['PARAMETER_DEFINITIONS'] = emitter.Format( |
| - ' $WEBCORE_CLASS_NAME* receiver = DartDOMWrapper::receiver< $WEBCORE_CLASS_NAME >(args);\n' |
| - ' $PARAMETER_DEFINITIONS\n', |
| - **template_parameters) |
| - |
| - for template in nested_templates: |
| - template_parameters['BODY'] = callback |
| - callback = emitter.Format(template, **template_parameters) |
| - |
| - self._cpp_definitions_emitter.Emit(callback) |
| + '}\n', |
| + CALLBACK_NAME=callback_name, |
| + BODY=body) |
| def _GenerateParameterAdapter(self, emitter, idl_argument, index): |
| type_info = GetIDLTypeInfo(idl_argument.type) |
| @@ -776,3 +716,65 @@ class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator): |
| attribute_name = attr.ext_attrs['Reflect'] or attr.id.lower() |
| return 'WebCore::%s::%sAttr' % (namespace, attribute_name) |
| + |
| + def _GenerateWebCoreFunctionExpression(self, function_name, idl_node): |
| + if 'ImplementedBy' in idl_node.ext_attrs: |
| + return '%s::%s' % (idl_node.ext_attrs['ImplementedBy'], function_name) |
| + return '%s%s' % (self._interface_type_info.receiver(), function_name) |
| + |
| + def _GenerateWebCoreInvocation(self, function_expression, arguments, |
| + idl_return_type, attributes, raises_dom_exceptions): |
| + invocation_template = ' $FUNCTION_CALL;\n' |
| + if idl_return_type and idl_return_type.id != 'void': |
| + return_type_info = GetIDLTypeInfo(idl_return_type) |
| + if return_type_info.conversion_include(): |
| + self._cpp_impl_includes[return_type_info.conversion_include()] = 1 |
| + |
| + # Generate C++ cast based on idl return type. |
| + conversion_cast = return_type_info.conversion_cast('$FUNCTION_CALL') |
| + if isinstance(return_type_info, SVGTearOffIDLTypeInfo): |
| + svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix', |
| + 'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform'] |
| + conversion_cast = '%s::create($FUNCTION_CALL)' |
| + if self._interface.id.startswith('SVGAnimated'): |
| + conversion_cast = 'static_cast<%s*>($FUNCTION_CALL)' |
| + elif return_type_info.idl_type() == 'SVGStringList': |
| + conversion_cast = '%s::create(receiver, $FUNCTION_CALL)' |
| + elif self._interface.id.endswith('List'): |
| + conversion_cast = 'static_cast<%s*>($FUNCTION_CALL.get())' |
| + elif return_type_info.idl_type() in svg_primitive_types: |
| + conversion_cast = '%s::create($FUNCTION_CALL)' |
| + else: |
| + conversion_cast = 'static_cast<%s*>($FUNCTION_CALL)' |
| + conversion_cast = conversion_cast % return_type_info.native_type() |
| + |
| + # Generate to Dart conversion of C++ value. |
| + conversion_arguments = [conversion_cast] |
| + if (return_type_info.idl_type() in ['DOMString', 'AtomicString'] and |
| + 'TreatReturnedNullStringAs' in attributes): |
| + conversion_arguments.append('ConvertDefaultToNull') |
| + |
| + invocation_template = emitter.Format( |
| + ' Dart_Handle returnValue = toDartValue($ARGUMENTS);\n' |
| + ' if (returnValue)\n' |
| + ' Dart_SetReturnValue(args, returnValue);\n', |
| + ARGUMENTS=', '.join(conversion_arguments)) |
| + |
| + if raises_dom_exceptions: |
| + # Add 'ec' argument to WebCore invocation and convert DOM exception to Dart exception. |
| + arguments.append('ec') |
| + invocation_template = emitter.Format( |
| + ' ExceptionCode ec = 0;\n' |
| + '$INVOCATION' |
| + ' if (UNLIKELY(ec)) {\n' |
| + ' exception = DartDOMWrapper::exceptionCodeToDartException(ec);\n' |
| + ' goto fail;\n' |
| + ' }\n', |
| + INVOCATION=invocation_template) |
| + |
| + if 'ImplementedBy' in attributes: |
| + arguments.insert(0, 'receiver') |
| + self._cpp_impl_includes[attributes['ImplementedBy']] = 1 |
| + |
| + return emitter.Format(invocation_template, |
| + FUNCTION_CALL='%s(%s)' % (function_expression, ', '.join(arguments))) |