| Index: client/dom/scripts/systemnative.py
|
| ===================================================================
|
| --- client/dom/scripts/systemnative.py (revision 5796)
|
| +++ client/dom/scripts/systemnative.py (working copy)
|
| @@ -1,840 +0,0 @@
|
| -#!/usr/bin/python
|
| -# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
| -# for details. All rights reserved. Use of this source code is governed by a
|
| -# BSD-style license that can be found in the LICENSE file.
|
| -
|
| -"""This module provides shared functionality for the systems to generate
|
| -native binding from the IDL database."""
|
| -
|
| -import emitter
|
| -import os
|
| -import systemwrapping
|
| -from generator import *
|
| -from systembase import *
|
| -
|
| -class NativeImplementationSystem(System):
|
| -
|
| - def __init__(self, templates, database, emitters, auxiliary_dir, output_dir):
|
| - super(NativeImplementationSystem, self).__init__(
|
| - templates, database, emitters, output_dir)
|
| -
|
| - self._auxiliary_dir = auxiliary_dir
|
| - self._dom_public_files = []
|
| - self._dom_impl_files = []
|
| - self._cpp_header_files = []
|
| - self._cpp_impl_files = []
|
| -
|
| - def InterfaceGenerator(self,
|
| - interface,
|
| - common_prefix,
|
| - super_interface_name,
|
| - source_filter):
|
| - interface_name = interface.id
|
| -
|
| - dart_interface_path = self._FilePathForDartInterface(interface_name)
|
| - self._dom_public_files.append(dart_interface_path)
|
| -
|
| - if IsPureInterface(interface_name):
|
| - return None
|
| -
|
| - dart_impl_path = self._FilePathForDartImplementation(interface_name)
|
| - self._dom_impl_files.append(dart_impl_path)
|
| -
|
| - cpp_header_path = self._FilePathForCppHeader(interface_name)
|
| - self._cpp_header_files.append(cpp_header_path)
|
| -
|
| - cpp_impl_path = self._FilePathForCppImplementation(interface_name)
|
| - self._cpp_impl_files.append(cpp_impl_path)
|
| -
|
| - return NativeImplementationGenerator(self, interface, super_interface_name,
|
| - self._emitters.FileEmitter(dart_impl_path),
|
| - self._emitters.FileEmitter(cpp_header_path),
|
| - self._emitters.FileEmitter(cpp_impl_path),
|
| - self._BaseDefines(interface),
|
| - self._templates)
|
| -
|
| - def ProcessCallback(self, interface, info):
|
| - self._interface = interface
|
| -
|
| - dart_interface_path = self._FilePathForDartInterface(self._interface.id)
|
| - self._dom_public_files.append(dart_interface_path)
|
| -
|
| - cpp_impl_includes = set()
|
| - cpp_header_handlers_emitter = emitter.Emitter()
|
| - cpp_impl_handlers_emitter = emitter.Emitter()
|
| - class_name = 'Dart%s' % self._interface.id
|
| - for operation in interface.operations:
|
| - if operation.type.id == 'void':
|
| - return_type = 'void'
|
| - return_prefix = ''
|
| - else:
|
| - return_type = 'bool'
|
| - return_prefix = 'return '
|
| -
|
| - parameters = []
|
| - arguments = []
|
| - for argument in operation.arguments:
|
| - argument_type_info = GetIDLTypeInfo(argument.type.id)
|
| - parameters.append('%s %s' % (argument_type_info.parameter_type(),
|
| - argument.id))
|
| - arguments.append(argument.id)
|
| - cpp_impl_includes |= set(argument_type_info.conversion_includes())
|
| -
|
| - cpp_header_handlers_emitter.Emit(
|
| - '\n'
|
| - ' virtual $TYPE handleEvent($PARAMETERS);\n',
|
| - TYPE=return_type, PARAMETERS=', '.join(parameters))
|
| -
|
| - cpp_impl_handlers_emitter.Emit(
|
| - '\n'
|
| - '$TYPE $CLASS_NAME::handleEvent($PARAMETERS)\n'
|
| - '{\n'
|
| - ' $(RETURN_PREFIX)m_callback.handleEvent($ARGUMENTS);\n'
|
| - '}\n',
|
| - TYPE=return_type,
|
| - CLASS_NAME=class_name,
|
| - PARAMETERS=', '.join(parameters),
|
| - RETURN_PREFIX=return_prefix,
|
| - ARGUMENTS=', '.join(arguments))
|
| -
|
| - cpp_header_path = self._FilePathForCppHeader(self._interface.id)
|
| - cpp_header_emitter = self._emitters.FileEmitter(cpp_header_path)
|
| - cpp_header_emitter.Emit(
|
| - self._templates.Load('cpp_callback_header.template'),
|
| - INTERFACE=self._interface.id,
|
| - HANDLERS=cpp_header_handlers_emitter.Fragments())
|
| -
|
| - cpp_impl_path = self._FilePathForCppImplementation(self._interface.id)
|
| - self._cpp_impl_files.append(cpp_impl_path)
|
| - cpp_impl_emitter = self._emitters.FileEmitter(cpp_impl_path)
|
| - cpp_impl_emitter.Emit(
|
| - self._templates.Load('cpp_callback_implementation.template'),
|
| - INCLUDES=_GenerateCPPIncludes(cpp_impl_includes),
|
| - INTERFACE=self._interface.id,
|
| - HANDLERS=cpp_impl_handlers_emitter.Fragments())
|
| -
|
| - def GenerateLibraries(self, lib_dir):
|
| - auxiliary_dir = os.path.relpath(self._auxiliary_dir, self._output_dir)
|
| -
|
| - # Generate dom_public.dart.
|
| - self._GenerateLibFile(
|
| - 'dom_public.darttemplate',
|
| - os.path.join(self._output_dir, 'dom_public.dart'),
|
| - self._dom_public_files,
|
| - AUXILIARY_DIR=MassagePath(auxiliary_dir));
|
| -
|
| - # Generate dom_impl.dart.
|
| - self._GenerateLibFile(
|
| - 'dom_impl.darttemplate',
|
| - os.path.join(self._output_dir, 'dom_impl.dart'),
|
| - self._dom_impl_files,
|
| - AUXILIARY_DIR=MassagePath(auxiliary_dir));
|
| -
|
| - # Generate DartDerivedSourcesXX.cpp.
|
| - partitions = 20 # FIXME: this should be configurable.
|
| - sources_count = len(self._cpp_impl_files)
|
| - for i in range(0, partitions):
|
| - derived_sources_path = os.path.join(self._output_dir,
|
| - 'DartDerivedSources%02i.cpp' % (i + 1))
|
| -
|
| - includes_emitter = emitter.Emitter()
|
| - for impl_file in self._cpp_impl_files[i::partitions]:
|
| - path = os.path.relpath(impl_file, os.path.dirname(derived_sources_path))
|
| - includes_emitter.Emit('#include "$PATH"\n', PATH=path)
|
| -
|
| - derived_sources_emitter = self._emitters.FileEmitter(derived_sources_path)
|
| - derived_sources_emitter.Emit(
|
| - self._templates.Load('cpp_derived_sources.template'),
|
| - INCLUDES=includes_emitter.Fragments())
|
| -
|
| - # Generate DartResolver.cpp.
|
| - cpp_resolver_path = os.path.join(self._output_dir, 'DartResolver.cpp')
|
| -
|
| - includes_emitter = emitter.Emitter()
|
| - resolver_body_emitter = emitter.Emitter()
|
| - for file in self._cpp_header_files:
|
| - path = os.path.relpath(file, os.path.dirname(cpp_resolver_path))
|
| - includes_emitter.Emit('#include "$PATH"\n', PATH=path)
|
| - resolver_body_emitter.Emit(
|
| - ' if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argumentCount))\n'
|
| - ' return func;\n',
|
| - CLASS_NAME=os.path.splitext(os.path.basename(path))[0])
|
| -
|
| - cpp_resolver_emitter = self._emitters.FileEmitter(cpp_resolver_path)
|
| - cpp_resolver_emitter.Emit(
|
| - self._templates.Load('cpp_resolver.template'),
|
| - INCLUDES=includes_emitter.Fragments(),
|
| - RESOLVER_BODY=resolver_body_emitter.Fragments())
|
| -
|
| - def Finish(self):
|
| - pass
|
| -
|
| - def _FilePathForDartInterface(self, interface_name):
|
| - return os.path.join(self._output_dir, 'src', 'interface',
|
| - '%s.dart' % interface_name)
|
| -
|
| - def _FilePathForDartImplementation(self, interface_name):
|
| - return os.path.join(self._output_dir, 'dart',
|
| - '%sImplementation.dart' % interface_name)
|
| -
|
| - def _FilePathForDartFactoryProvider(self, interface_name):
|
| - return os.path.join(self._output_dir, 'dart',
|
| - '_%sFactoryProvider.dart' % interface_name)
|
| -
|
| - def _FilePathForDartFactoryProviderImplementation(self, interface_name):
|
| - return os.path.join(self._output_dir, 'dart',
|
| - '%sFactoryProviderImplementation.dart' % interface_name)
|
| -
|
| - def _FilePathForCppHeader(self, interface_name):
|
| - return os.path.join(self._output_dir, 'cpp', 'Dart%s.h' % interface_name)
|
| -
|
| - def _FilePathForCppImplementation(self, interface_name):
|
| - return os.path.join(self._output_dir, 'cpp', 'Dart%s.cpp' % interface_name)
|
| -
|
| -
|
| -class NativeImplementationGenerator(systemwrapping.WrappingInterfaceGenerator):
|
| - """Generates Dart implementation for one DOM IDL interface."""
|
| -
|
| - def __init__(self, system, interface, super_interface,
|
| - dart_impl_emitter, cpp_header_emitter, cpp_impl_emitter,
|
| - base_members, templates):
|
| - """Generates Dart and C++ code for the given interface.
|
| -
|
| - Args:
|
| - system: The NativeImplementationSystem.
|
| - interface: an IDLInterface instance. It is assumed that all types have
|
| - been converted to Dart types (e.g. int, String), unless they are in
|
| - the same package as the interface.
|
| - super_interface: A string or None, the name of the common interface that
|
| - this interface implements, if any.
|
| - dart_impl_emitter: an Emitter for the file containing the Dart
|
| - implementation class.
|
| - cpp_header_emitter: an Emitter for the file containing the C++ header.
|
| - cpp_impl_emitter: an Emitter for the file containing the C++
|
| - implementation.
|
| - base_members: a set of names of members defined in a base class. This is
|
| - used to avoid static member 'overriding' in the generated Dart code.
|
| - """
|
| - self._system = system
|
| - self._interface = interface
|
| - self._super_interface = super_interface
|
| - self._dart_impl_emitter = dart_impl_emitter
|
| - self._cpp_header_emitter = cpp_header_emitter
|
| - self._cpp_impl_emitter = cpp_impl_emitter
|
| - self._base_members = base_members
|
| - self._templates = templates
|
| - self._current_secondary_parent = None
|
| -
|
| - def StartInterface(self):
|
| - self._class_name = self._ImplClassName(self._interface.id)
|
| - self._interface_type_info = GetIDLTypeInfo(self._interface.id)
|
| - self._members_emitter = emitter.Emitter()
|
| - self._cpp_declarations_emitter = emitter.Emitter()
|
| - self._cpp_impl_includes = set()
|
| - self._cpp_definitions_emitter = emitter.Emitter()
|
| - self._cpp_resolver_emitter = emitter.Emitter()
|
| -
|
| - self._GenerateConstructors()
|
| -
|
| - def _GenerateConstructors(self):
|
| - if not self._IsConstructable():
|
| - return
|
| -
|
| - # TODO(antonm): currently we don't have information about number of arguments expected by
|
| - # the constructor, so name only dispatch.
|
| - self._cpp_resolver_emitter.Emit(
|
| - ' if (name == "$(INTERFACE_NAME)_constructor_Callback")\n'
|
| - ' return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n',
|
| - INTERFACE_NAME=self._interface.id)
|
| -
|
| -
|
| - constructor_info = AnalyzeConstructor(self._interface)
|
| - if constructor_info:
|
| - self._EmitFactoryProvider(self._interface.id, constructor_info)
|
| -
|
| - if constructor_info is None:
|
| - # We have a custom implementation for it.
|
| - self._cpp_declarations_emitter.Emit(
|
| - '\n'
|
| - 'void constructorCallback(Dart_NativeArguments);\n')
|
| - return
|
| -
|
| - raises_dom_exceptions = 'ConstructorRaisesException' in self._interface.ext_attrs
|
| - raises_exceptions = raises_dom_exceptions or len(constructor_info.idl_args) > 0
|
| - arguments = []
|
| - parameter_definitions_emitter = emitter.Emitter()
|
| - create_function = 'create'
|
| - if 'NamedConstructor' in self._interface.ext_attrs:
|
| - raises_exceptions = True
|
| - parameter_definitions_emitter.Emit(
|
| - ' DOMWindow* domWindow = DartUtilities::domWindowForCurrentIsolate();\n'
|
| - ' if (!domWindow) {\n'
|
| - ' exception = Dart_NewString("Failed to fetch domWindow");\n'
|
| - ' goto fail;\n'
|
| - ' }\n'
|
| - ' Document* document = domWindow->document();\n')
|
| - self._cpp_impl_includes.add('"DOMWindow.h"')
|
| - arguments.append('document')
|
| - create_function = 'createForJSConstructor'
|
| - if 'CallWith' in self._interface.ext_attrs:
|
| - call_with = self._interface.ext_attrs['CallWith']
|
| - if call_with == 'ScriptExecutionContext':
|
| - raises_exceptions = True
|
| - parameter_definitions_emitter.Emit(
|
| - ' ScriptExecutionContext* context = DartUtilities::scriptExecutionContext();\n'
|
| - ' if (!context) {\n'
|
| - ' exception = Dart_NewString("Failed to create an object");\n'
|
| - ' goto fail;\n'
|
| - ' }\n')
|
| - arguments.append('context')
|
| - else:
|
| - raise Exception('Unsupported CallWith=%s attribute' % call_with)
|
| -
|
| - # Process constructor arguments.
|
| - for (i, arg) in enumerate(constructor_info.idl_args):
|
| - self._GenerateParameterAdapter(parameter_definitions_emitter, arg, i - 1)
|
| - arguments.append(arg.id)
|
| -
|
| - function_expression = '%s::%s' % (self._interface_type_info.native_type(), create_function)
|
| - invocation = self._GenerateWebCoreInvocation(function_expression, arguments,
|
| - self._interface.id, self._interface.ext_attrs, raises_dom_exceptions)
|
| - self._GenerateNativeCallback(callback_name='constructorCallback',
|
| - parameter_definitions=parameter_definitions_emitter.Fragments(),
|
| - needs_receiver=False, invocation=invocation,
|
| - raises_exceptions=raises_exceptions)
|
| -
|
| - def _ImplClassName(self, interface_name):
|
| - return interface_name + 'Implementation'
|
| -
|
| - def _IsConstructable(self):
|
| - # FIXME: support ConstructorTemplate.
|
| - return set(['CustomConstructor', 'V8CustomConstructor', 'Constructor', 'NamedConstructor']) & set(self._interface.ext_attrs)
|
| -
|
| - def _EmitFactoryProvider(self, interface_name, constructor_info):
|
| - factory_provider = '_' + interface_name + 'FactoryProvider'
|
| - implementation_class = interface_name + 'FactoryProviderImplementation'
|
| - implementation_function = 'create' + interface_name
|
| - native_implementation_function = '%s_constructor_Callback' % interface_name
|
| -
|
| - # Emit private factory provider in public library.
|
| - template_file = 'factoryprovider_%s.darttemplate' % interface_name
|
| - template = self._system._templates.TryLoad(template_file)
|
| - if not template:
|
| - template = self._system._templates.Load('factoryprovider.darttemplate')
|
| -
|
| - dart_impl_path = self._system._FilePathForDartFactoryProvider(
|
| - interface_name)
|
| - self._system._dom_public_files.append(dart_impl_path)
|
| -
|
| - emitter = self._system._emitters.FileEmitter(dart_impl_path)
|
| - emitter.Emit(
|
| - template,
|
| - FACTORY_PROVIDER=factory_provider,
|
| - CONSTRUCTOR=interface_name,
|
| - PARAMETERS=constructor_info.ParametersImplementationDeclaration(),
|
| - IMPL_CLASS=implementation_class,
|
| - IMPL_FUNCTION=implementation_function,
|
| - ARGUMENTS=constructor_info.ParametersAsArgumentList())
|
| -
|
| - # Emit public implementation in implementation libary.
|
| - dart_impl_path = self._system._FilePathForDartFactoryProviderImplementation(
|
| - interface_name)
|
| - self._system._dom_impl_files.append(dart_impl_path)
|
| - emitter = self._system._emitters.FileEmitter(dart_impl_path)
|
| - emitter.Emit(
|
| - 'class $IMPL_CLASS {\n'
|
| - ' static $INTERFACE_NAME $IMPL_FUNCTION($PARAMETERS)\n'
|
| - ' native "$NATIVE_NAME";\n'
|
| - '}',
|
| - INTERFACE_NAME=interface_name,
|
| - PARAMETERS=constructor_info.ParametersImplementationDeclaration(),
|
| - IMPL_CLASS=implementation_class,
|
| - IMPL_FUNCTION=implementation_function,
|
| - NATIVE_NAME=native_implementation_function)
|
| -
|
| - def FinishInterface(self):
|
| - base = self._BaseClassName(self._interface)
|
| - self._dart_impl_emitter.Emit(
|
| - self._templates.Load('dart_implementation.darttemplate'),
|
| - CLASS=self._class_name, BASE=base, INTERFACE=self._interface.id,
|
| - MEMBERS=self._members_emitter.Fragments())
|
| -
|
| - self._GenerateCppHeader()
|
| -
|
| - self._cpp_impl_emitter.Emit(
|
| - self._templates.Load('cpp_implementation.template'),
|
| - INTERFACE=self._interface.id,
|
| - INCLUDES=_GenerateCPPIncludes(self._cpp_impl_includes),
|
| - CALLBACKS=self._cpp_definitions_emitter.Fragments(),
|
| - RESOLVER=self._cpp_resolver_emitter.Fragments())
|
| -
|
| - def _GenerateCppHeader(self):
|
| - webcore_includes = _GenerateCPPIncludes(self._interface_type_info.webcore_includes())
|
| -
|
| - if ('CustomToJS' in self._interface.ext_attrs or
|
| - 'CustomToJSObject' in self._interface.ext_attrs or
|
| - 'PureInterface' in self._interface.ext_attrs or
|
| - 'CPPPureInterface' in self._interface.ext_attrs or
|
| - self._interface_type_info.custom_to_dart()):
|
| - to_dart_value_template = (
|
| - 'Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value);\n')
|
| - else:
|
| - to_dart_value_template = (
|
| - 'inline Dart_Handle toDartValue($(WEBCORE_CLASS_NAME)* value)\n'
|
| - '{\n'
|
| - ' return DartDOMWrapper::toDart<Dart$(INTERFACE)>(value);\n'
|
| - '}\n')
|
| - to_dart_value_emitter = emitter.Emitter()
|
| - to_dart_value_emitter.Emit(
|
| - to_dart_value_template,
|
| - INTERFACE=self._interface.id,
|
| - WEBCORE_CLASS_NAME=self._interface_type_info.native_type())
|
| -
|
| - self._cpp_header_emitter.Emit(
|
| - self._templates.Load('cpp_header.template'),
|
| - INTERFACE=self._interface.id,
|
| - WEBCORE_INCLUDES=webcore_includes,
|
| - WEBCORE_CLASS_NAME=self._interface_type_info.native_type(),
|
| - TO_DART_VALUE=to_dart_value_emitter.Fragments(),
|
| - DECLARATIONS=self._cpp_declarations_emitter.Fragments())
|
| -
|
| - def _GenerateCallWithHandling(self, node, parameter_definitions_emitter, arguments):
|
| - if 'CallWith' not in node.ext_attrs:
|
| - return False
|
| -
|
| - call_with = node.ext_attrs['CallWith']
|
| - if call_with == 'ScriptExecutionContext':
|
| - parameter_definitions_emitter.Emit(
|
| - '\n'
|
| - ' ScriptExecutionContext* context = DartUtilities::scriptExecutionContext();\n'
|
| - ' if (!context)\n'
|
| - ' return;\n')
|
| - arguments.append('context')
|
| - return False
|
| -
|
| - if call_with == 'ScriptArguments|CallStack':
|
| - self._cpp_impl_includes.add('"DOMWindow.h"')
|
| - self._cpp_impl_includes.add('"ScriptArguments.h"')
|
| - self._cpp_impl_includes.add('"ScriptCallStack.h"')
|
| - self._cpp_impl_includes.add('"V8Proxy.h"')
|
| - self._cpp_impl_includes.add('"v8.h"')
|
| - parameter_definitions_emitter.Emit(
|
| - '\n'
|
| - ' v8::HandleScope handleScope;\n'
|
| - ' v8::Context::Scope scope(V8Proxy::mainWorldContext(DartUtilities::domWindowForCurrentIsolate()->frame()));\n'
|
| - ' Dart_Handle customArgument = Dart_GetNativeArgument(args, $INDEX);\n'
|
| - ' RefPtr<ScriptArguments> scriptArguments(DartUtilities::createScriptArguments(customArgument, exception));\n'
|
| - ' if (!scriptArguments)\n'
|
| - ' goto fail;\n'
|
| - ' RefPtr<ScriptCallStack> scriptCallStack(DartUtilities::createScriptCallStack());\n'
|
| - ' if (!scriptCallStack->size())\n'
|
| - ' return;\n',
|
| - INDEX=len(node.arguments))
|
| - arguments.extend(['scriptArguments', 'scriptCallStack'])
|
| - return True
|
| -
|
| - return False
|
| -
|
| - def AddAttribute(self, getter, setter):
|
| - # FIXME: Dartium does not support attribute event listeners. However, JS
|
| - # implementation falls back to them when addEventListener is not available.
|
| - # Make sure addEventListener is available in all EventTargets and remove
|
| - # this check.
|
| - if (getter or setter).type.id == 'EventListener':
|
| - return
|
| -
|
| - if 'CheckSecurityForNode' in (getter or setter).ext_attrs:
|
| - # FIXME: exclude from interface as well.
|
| - return
|
| -
|
| - # FIXME: these should go away.
|
| - classes_with_unsupported_custom_getters = [
|
| - 'Clipboard', 'Console', 'Coordinates', 'DeviceMotionEvent',
|
| - 'DeviceOrientationEvent', 'FileReader', 'JavaScriptCallFrame',
|
| - 'HTMLInputElement', 'HTMLOptionsCollection', 'HTMLOutputElement',
|
| - 'ScriptProfileNode', 'WebKitAnimation']
|
| - if (self._interface.id in classes_with_unsupported_custom_getters and
|
| - getter and set(['Custom', 'CustomGetter']) & set(getter.ext_attrs)):
|
| - return
|
| -
|
| - if getter:
|
| - self._AddGetter(getter)
|
| - if setter:
|
| - self._AddSetter(setter)
|
| -
|
| - def _AddGetter(self, attr):
|
| - type_info = GetIDLTypeInfo(attr.type.id)
|
| - dart_declaration = '%s get %s()' % (
|
| - type_info.dart_type(), DartDomNameOfAttribute(attr))
|
| - is_custom = 'Custom' in attr.ext_attrs or 'CustomGetter' in attr.ext_attrs
|
| - cpp_callback_name = self._GenerateNativeBinding(attr.id, 1,
|
| - dart_declaration, 'Getter', is_custom)
|
| - if is_custom:
|
| - return
|
| -
|
| - arguments = []
|
| - parameter_definitions_emitter = emitter.Emitter()
|
| - raises_exceptions = self._GenerateCallWithHandling(attr, parameter_definitions_emitter, arguments)
|
| - raises_exceptions = raises_exceptions or attr.get_raises
|
| -
|
| - if 'Reflect' in attr.ext_attrs:
|
| - webcore_function_name = GetIDLTypeInfo(attr.type.id).webcore_getter_name()
|
| - if 'URL' in attr.ext_attrs:
|
| - if 'NonEmpty' in attr.ext_attrs:
|
| - webcore_function_name = 'getNonEmptyURLAttribute'
|
| - else:
|
| - webcore_function_name = 'getURLAttribute'
|
| - arguments.append(self._GenerateWebCoreReflectionAttributeName(attr))
|
| - else:
|
| - if attr.id == 'operator':
|
| - webcore_function_name = '_operator'
|
| - elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString':
|
| - webcore_function_name = 'svgTarget'
|
| - else:
|
| - webcore_function_name = re.sub(r'^(HTML|URL|JS|XML|XSLT|\w)',
|
| - lambda s: s.group(1).lower(),
|
| - attr.id)
|
| - webcore_function_name = re.sub(r'^(create|exclusive)',
|
| - lambda s: 'is' + s.group(1).capitalize(),
|
| - webcore_function_name)
|
| - if attr.type.id.startswith('SVGAnimated'):
|
| - webcore_function_name += 'Animated'
|
| -
|
| - function_expression = self._GenerateWebCoreFunctionExpression(webcore_function_name, attr)
|
| - invocation = self._GenerateWebCoreInvocation(function_expression,
|
| - arguments, attr.type.id, attr.ext_attrs, attr.get_raises)
|
| - self._GenerateNativeCallback(cpp_callback_name, parameter_definitions_emitter.Fragments(),
|
| - True, invocation, raises_exceptions=raises_exceptions)
|
| -
|
| - def _AddSetter(self, attr):
|
| - type_info = GetIDLTypeInfo(attr.type.id)
|
| - dart_declaration = 'void set %s(%s)' % (
|
| - DartDomNameOfAttribute(attr), type_info.dart_type())
|
| - is_custom = set(['Custom', 'CustomSetter', 'V8CustomSetter']) & set(attr.ext_attrs)
|
| - cpp_callback_name = self._GenerateNativeBinding(attr.id, 2,
|
| - dart_declaration, 'Setter', is_custom)
|
| - if is_custom:
|
| - return
|
| -
|
| - arguments = []
|
| - parameter_definitions_emitter = emitter.Emitter()
|
| - self._GenerateCallWithHandling(attr, parameter_definitions_emitter, arguments)
|
| -
|
| - if 'Reflect' in attr.ext_attrs:
|
| - webcore_function_name = GetIDLTypeInfo(attr.type.id).webcore_setter_name()
|
| - arguments.append(self._GenerateWebCoreReflectionAttributeName(attr))
|
| - else:
|
| - webcore_function_name = re.sub(r'^(xml(?=[A-Z])|\w)',
|
| - lambda s: s.group(1).upper(),
|
| - attr.id)
|
| - webcore_function_name = 'set%s' % webcore_function_name
|
| - if attr.type.id.startswith('SVGAnimated'):
|
| - webcore_function_name += 'Animated'
|
| -
|
| - arguments.append('value')
|
| -
|
| - self._GenerateParameterAdapter(
|
| - parameter_definitions_emitter, attr, 0, adapter_name='value')
|
| - parameter_definitions = parameter_definitions_emitter.Fragments()
|
| -
|
| - function_expression = self._GenerateWebCoreFunctionExpression(webcore_function_name, attr)
|
| - invocation = self._GenerateWebCoreInvocation(function_expression,
|
| - arguments, 'void', attr.ext_attrs, attr.set_raises)
|
| -
|
| - self._GenerateNativeCallback(cpp_callback_name, parameter_definitions_emitter.Fragments(),
|
| - True, invocation, raises_exceptions=True)
|
| -
|
| - def _HasNativeIndexGetter(self, interface):
|
| - return ('CustomIndexedGetter' in interface.ext_attrs or
|
| - 'NumericIndexedGetter' in interface.ext_attrs)
|
| -
|
| - def _EmitNativeIndexGetter(self, interface, element_type):
|
| - dart_declaration = '%s operator[](int index)' % element_type
|
| - self._GenerateNativeBinding('numericIndexGetter', 2, dart_declaration,
|
| - 'Callback', True)
|
| -
|
| - def _EmitNativeIndexSetter(self, interface, element_type):
|
| - dart_declaration = 'void operator[]=(int index, %s value)' % element_type
|
| - self._GenerateNativeBinding('numericIndexSetter', 3, dart_declaration,
|
| - 'Callback', True)
|
| -
|
| - def AddOperation(self, info):
|
| - """
|
| - Arguments:
|
| - info: An OperationInfo object.
|
| - """
|
| -
|
| - if 'CheckSecurityForNode' in info.overloads[0].ext_attrs:
|
| - # FIXME: exclude from interface as well.
|
| - return
|
| -
|
| - if 'Custom' in info.overloads[0].ext_attrs:
|
| - parameters = info.ParametersImplementationDeclaration()
|
| - dart_declaration = '%s %s(%s)' % (info.type_name, info.name, parameters)
|
| - argument_count = 1 + len(info.arg_infos)
|
| - self._GenerateNativeBinding(info.name, argument_count, dart_declaration,
|
| - 'Callback', True)
|
| - return
|
| -
|
| - body = self._members_emitter.Emit(
|
| - '\n'
|
| - ' $TYPE $NAME($PARAMETERS) {\n'
|
| - '$!BODY'
|
| - ' }\n',
|
| - TYPE=info.type_name,
|
| - NAME=info.name,
|
| - PARAMETERS=info.ParametersImplementationDeclaration())
|
| -
|
| - # Process in order of ascending number of arguments to ensure missing
|
| - # optional arguments are processed early.
|
| - overloads = sorted(info.overloads,
|
| - key=lambda overload: len(overload.arguments))
|
| - self._native_version = 0
|
| - fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads)
|
| - if fallthrough:
|
| - body.Emit(' throw "Incorrect number or type of arguments";\n');
|
| -
|
| - def GenerateSingleOperation(self, dispatch_emitter, info, indent, operation):
|
| - """Generates a call to a single operation.
|
| -
|
| - Arguments:
|
| - dispatch_emitter: an dispatch_emitter for the body of a block of code.
|
| - info: the compound information about the operation and its overloads.
|
| - indent: an indentation string for generated code.
|
| - operation: the IDLOperation to call.
|
| - """
|
| -
|
| - self._native_version += 1
|
| - native_name = info.name
|
| - if self._native_version > 1:
|
| - native_name = '%s_%s' % (native_name, self._native_version)
|
| - argument_list = ', '.join([info.arg_infos[i][0]
|
| - for (i, arg) in enumerate(operation.arguments)])
|
| -
|
| - # Generate dispatcher.
|
| - if info.type_name != 'void':
|
| - dispatch_emitter.Emit('$(INDENT)return _$NATIVENAME($ARGS);\n',
|
| - INDENT=indent,
|
| - NATIVENAME=native_name,
|
| - ARGS=argument_list)
|
| - else:
|
| - dispatch_emitter.Emit('$(INDENT)_$NATIVENAME($ARGS);\n'
|
| - '$(INDENT)return;\n',
|
| - INDENT=indent,
|
| - NATIVENAME=native_name,
|
| - ARGS=argument_list)
|
| - # Generate binding.
|
| - dart_declaration = '%s _%s(%s)' % (info.type_name, native_name,
|
| - argument_list)
|
| - is_custom = 'Custom' in operation.ext_attrs
|
| - cpp_callback_name = self._GenerateNativeBinding(
|
| - native_name, 1 + len(operation.arguments), dart_declaration, 'Callback',
|
| - is_custom)
|
| - if is_custom:
|
| - return
|
| -
|
| - # Generate callback.
|
| - webcore_function_name = operation.ext_attrs.get('ImplementedAs', operation.id)
|
| -
|
| - parameter_definitions_emitter = emitter.Emitter()
|
| - arguments = []
|
| - raises_exceptions = self._GenerateCallWithHandling(
|
| - operation, parameter_definitions_emitter, arguments)
|
| - raises_exceptions = raises_exceptions or len(operation.arguments) > 0 or operation.raises
|
| -
|
| - # Process Dart arguments.
|
| - for (i, argument) in enumerate(operation.arguments):
|
| - if (i == len(operation.arguments) - 1 and
|
| - self._interface.id == 'Console' and
|
| - argument.id == 'arg'):
|
| - # FIXME: we are skipping last argument here because it was added in
|
| - # supplemental dart.idl. Cleanup dart.idl and remove this check.
|
| - break
|
| - self._GenerateParameterAdapter(parameter_definitions_emitter, argument, i)
|
| - arguments.append(argument.id)
|
| -
|
| - if operation.id in ['addEventListener', 'removeEventListener']:
|
| - # addEventListener's and removeEventListener's last argument is marked
|
| - # as optional in idl, but is not optional in webcore implementation.
|
| - if len(operation.arguments) == 2:
|
| - arguments.append('false')
|
| -
|
| - if self._interface.id == 'CSSStyleDeclaration' and operation.id == 'setProperty':
|
| - # CSSStyleDeclaration.setProperty priority parameter is optional in Dart
|
| - # idl, but is not optional in webcore implementation.
|
| - if len(operation.arguments) == 2:
|
| - arguments.append('String()')
|
| -
|
| - if 'NeedsUserGestureCheck' in operation.ext_attrs:
|
| - arguments.append('DartUtilities::processingUserGesture')
|
| -
|
| - function_expression = self._GenerateWebCoreFunctionExpression(webcore_function_name, operation)
|
| - invocation = self._GenerateWebCoreInvocation(function_expression, arguments,
|
| - operation.type.id, operation.ext_attrs, operation.raises)
|
| - self._GenerateNativeCallback(cpp_callback_name,
|
| - parameter_definitions=parameter_definitions_emitter.Fragments(),
|
| - needs_receiver=True, invocation=invocation,
|
| - raises_exceptions=raises_exceptions)
|
| -
|
| - def _GenerateNativeCallback(self, callback_name, parameter_definitions,
|
| - needs_receiver, invocation, raises_exceptions):
|
| -
|
| - 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)
|
| -
|
| - body = emitter.Format(
|
| - ' {\n'
|
| - '$PARAMETER_DEFINITIONS'
|
| - '$INVOCATION'
|
| - ' return;\n'
|
| - ' }\n',
|
| - PARAMETER_DEFINITIONS=parameter_definitions,
|
| - INVOCATION=invocation)
|
| -
|
| - if raises_exceptions:
|
| - body = emitter.Format(
|
| - ' Dart_Handle exception;\n'
|
| - '$BODY'
|
| - '\n'
|
| - 'fail:\n'
|
| - ' Dart_ThrowException(exception);\n'
|
| - ' ASSERT_NOT_REACHED();\n',
|
| - BODY=body)
|
| -
|
| - self._cpp_definitions_emitter.Emit(
|
| - '\n'
|
| - 'static void $CALLBACK_NAME(Dart_NativeArguments args)\n'
|
| - '{\n'
|
| - ' DartApiScope dartApiScope;\n'
|
| - '$BODY'
|
| - '}\n',
|
| - CALLBACK_NAME=callback_name,
|
| - BODY=body)
|
| -
|
| - def _GenerateParameterAdapter(self, emitter, idl_node, index,
|
| - adapter_name=None):
|
| - """idl_node is IDLArgument or IDLAttribute."""
|
| - type_info = GetIDLTypeInfo(idl_node.type.id)
|
| - (adapter_type, include_name) = type_info.parameter_adapter_info()
|
| - if include_name:
|
| - self._cpp_impl_includes.add(include_name)
|
| - flags = ''
|
| - if (idl_node.ext_attrs.get('Optional') == 'DefaultIsNullString' or
|
| - 'RequiredCppParameter' in idl_node.ext_attrs):
|
| - flags = ', DartUtilities::ConvertNullToDefaultValue'
|
| - emitter.Emit(
|
| - '\n'
|
| - ' const $ADAPTER_TYPE $NAME(Dart_GetNativeArgument(args, $INDEX)$FLAGS);\n'
|
| - ' if (!$NAME.conversionSuccessful()) {\n'
|
| - ' exception = $NAME.exception();\n'
|
| - ' goto fail;\n'
|
| - ' }\n',
|
| - ADAPTER_TYPE=adapter_type,
|
| - NAME=adapter_name or idl_node.id,
|
| - INDEX=index + 1,
|
| - FLAGS=flags)
|
| -
|
| - def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration,
|
| - native_suffix, is_custom):
|
| - native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix)
|
| - self._members_emitter.Emit(
|
| - '\n'
|
| - ' $DART_DECLARATION native "$NATIVE_BINDING";\n',
|
| - DART_DECLARATION=dart_declaration, NATIVE_BINDING=native_binding)
|
| -
|
| - cpp_callback_name = '%s%s' % (idl_name, native_suffix)
|
| - self._cpp_resolver_emitter.Emit(
|
| - ' if (argumentCount == $ARGC && name == "$NATIVE_BINDING")\n'
|
| - ' return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n',
|
| - ARGC=argument_count,
|
| - NATIVE_BINDING=native_binding,
|
| - INTERFACE_NAME=self._interface.id,
|
| - CPP_CALLBACK_NAME=cpp_callback_name)
|
| -
|
| - if is_custom:
|
| - self._cpp_declarations_emitter.Emit(
|
| - '\n'
|
| - 'void $CPP_CALLBACK_NAME(Dart_NativeArguments);\n',
|
| - CPP_CALLBACK_NAME=cpp_callback_name)
|
| -
|
| - return cpp_callback_name
|
| -
|
| - def _GenerateWebCoreReflectionAttributeName(self, attr):
|
| - namespace = 'HTMLNames'
|
| - svg_exceptions = ['class', 'id', 'onabort', 'onclick', 'onerror', 'onload',
|
| - 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover',
|
| - 'onmouseup', 'onresize', 'onscroll', 'onunload']
|
| - if self._interface.id.startswith('SVG') and not attr.id in svg_exceptions:
|
| - namespace = 'SVGNames'
|
| - self._cpp_impl_includes.add('"%s.h"' % namespace)
|
| -
|
| - 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 != 'void':
|
| - return_type_info = GetIDLTypeInfo(idl_return_type)
|
| - self._cpp_impl_includes |= set(return_type_info.conversion_includes())
|
| -
|
| - # 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.add('"%s.h"' % attributes['ImplementedBy'])
|
| -
|
| - return emitter.Format(invocation_template,
|
| - FUNCTION_CALL='%s(%s)' % (function_expression, ', '.join(arguments)))
|
| -
|
| -def _GenerateCPPIncludes(includes):
|
| - return ''.join(['#include %s\n' % include for include in includes])
|
|
|