text: #!/usr/bin/env python3
  # 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 logging
  import os
  from generator import *
  from htmldartgenerator import *
  from idlnode import IDLArgument, IDLAttribute, IDLEnum, IDLMember
  from systemhtml import js_support_checks, GetCallbackInfo, HTML_LIBRARY_NAMES
  
  _logger = logging.getLogger('systemnative')
  
  # TODO(vsm): This should be recoverable from IDL, but we appear to not
  # track the necessary info.
  _url_utils = [
      'hash', 'host', 'hostname', 'origin', 'password', 'pathname', 'port',
      'protocol', 'search', 'username'
  ]
  
  _promise_to_future = Conversion('promiseToFuture', 'dynamic', 'Future')
  
  
  def array_type(data_type):
      matched = re.match(r'([\w\d_\s]+)\[\]', data_type)
      if not matched:
          return None
      return matched.group(1)
  
  
  _sequence_matcher = re.compile('sequence\<(.+)\>')
  
  
  def TypeIdToBlinkName(interface_id, database):
      # Maybe should use the type_registry here?
      if database.HasEnum(interface_id):
          return "DOMString"  # All enums are strings.
  
      seq_match = _sequence_matcher.match(interface_id)
      if seq_match is not None:
          t = TypeIdToBlinkName(seq_match.group(1), database)
          return "sequence<%s>" % t
  
      arr_match = array_type(interface_id)
      if arr_match is not None:
          t = TypeIdToBlinkName(arr_match, database)
          return "%s[]" % t
  
      return interface_id
  
  
  def DeriveQualifiedName(library_name, name):
      return library_name + "." + name
  
  
  def DeriveBlinkClassName(name):
      return "Blink" + name
  
  
  _type_encoding_map = {
      'long long': "ll",
      'unsigned long': "ul",
      'unsigned long long': "ull",
      'unsigned short': "us",
  }
  
  
  def EncodeType(t):
  
      seq_match = _sequence_matcher.match(t)
      if seq_match is not None:
          t2 = EncodeType(seq_match.group(1))
          t = "SEQ_%s_SEQ" % t2
          return t
  
      arr_match = array_type(t)
      if arr_match is not None:
          t = EncodeType(arr_match)
          return "A_%s_A" % t
  
      return _type_encoding_map.get(t) or t
  
  
  class DartiumBackend(HtmlDartGenerator):
      """Generates Dart implementation for one DOM IDL interface."""
  
      def __init__(self, interface, cpp_library_emitter, options, loggerParent):
          super(DartiumBackend, self).__init__(interface, options, True,
                                               loggerParent)
  
          self._interface = interface
          self._cpp_library_emitter = cpp_library_emitter
          self._database = options.database
          self._template_loader = options.templates
          self._type_registry = options.type_registry
          self._interface_type_info = self._type_registry.TypeInfo(
              self._interface.id)
          self._metadata = options.metadata
          # These get initialized by StartInterface
          self._cpp_header_emitter = None
          self._cpp_impl_emitter = None
          self._members_emitter = None
          self._cpp_declarations_emitter = None
          self._cpp_impl_includes = None
          self._cpp_definitions_emitter = None
          self._cpp_resolver_emitter = None
          self._dart_js_interop = options.dart_js_interop
          _logger.setLevel(loggerParent.level)
  
      def ImplementsMergedMembers(self):
          # We could not add merged functions to implementation class because
          # underlying c++ object doesn't implement them. Merged functions are
          # generated on merged interface implementation instead.
          return False
  
      def CustomJSMembers(self):
          return {}
  
      def _OutputConversion(self, idl_type, member):
          conversion = FindConversion(idl_type, 'get', self._interface.id, member)
          # TODO(jacobr) handle promise consistently in dart2js and dartium.
          if idl_type == 'Promise':
              return _promise_to_future
          if conversion:
              if conversion.function_name in ('convertNativeToDart_DateTime',
                                              'convertNativeToDart_ImageData'):
                  return None
          return conversion
  
      def _InputConversion(self, idl_type, member):
          return FindConversion(idl_type, 'set', self._interface.id, member)
  
      def GenerateCallback(self, info):
          return None
  
      def ImplementationTemplate(self):
          template = None
          interface_name = self._interface.doc_js_name
          if interface_name == self._interface.id or not self._database.HasInterface(
                  interface_name):
              template_file = 'impl_%s.darttemplate' % interface_name
              template = self._template_loader.TryLoad(template_file)
          if not template:
              template = self._template_loader.Load(
                  'dart_implementation.darttemplate')
          return template
  
      def RootClassName(self):
          return 'DartHtmlDomObject'
  
      # This code matches up with the _generate_native_entry code in
      # dart_utilities.py in the dartium repository.  Any changes to this
      # should have matching changes on that end.
      def DeriveNativeEntry(self, name, kind, count):
          interface_id = self._interface.id
          database = self._database
          tag = ""
          if kind == 'Getter':
              tag = "%s_Getter" % name
              blink_entry = tag
          elif kind == 'Setter':
              tag = "%s_Setter" % name
              blink_entry = tag
          elif kind == 'Constructor':
              tag = "constructorCallback"
              blink_entry = tag
          elif kind == 'Method':
              tag = "%s_Callback" % name
              blink_entry = tag
  
          interface_id = TypeIdToBlinkName(interface_id, database)
  
          def mkPublic(s):
              if s.startswith("_") or s.startswith("$"):
                  return "$" + s
              return s
  
          if count is not None:
              arity = str(count)
              dart_name = mkPublic("_".join([tag, arity]))
          else:
              dart_name = mkPublic(tag)
          resolver_string = "_".join([interface_id, tag])
  
          return (dart_name, resolver_string)
  
      def DeriveNativeName(self, name, suffix=""):
          fields = ['$' + name]
          if suffix != "":
              fields.append(suffix)
          return "_".join(fields)
  
      def DeriveQualifiedBlinkName(self, interface_name, name):
          blinkClass = DeriveQualifiedName("_blink",
                                           DeriveBlinkClassName(interface_name))
          blinkInstance = DeriveQualifiedName(blinkClass, "instance")
          return DeriveQualifiedName(blinkInstance, name + "_")
  
      def NativeSpec(self):
          return ''
  
      def StartInterface(self, members_emitter):
          # Create emitters for c++ implementation.
          if not IsPureInterface(self._interface.id, self._database) and \
              not IsCustomType(self._interface.id):
              self._cpp_header_emitter = self._cpp_library_emitter.CreateHeaderEmitter(
                  self._interface.id,
                  self._renamer.GetLibraryName(self._interface))
              self._cpp_impl_emitter = \
                self._cpp_library_emitter.CreateSourceEmitter(self._interface.id)
          else:
              self._cpp_header_emitter = emitter.Emitter()
              self._cpp_impl_emitter = emitter.Emitter()
  
          self._interface_type_info = self._TypeInfo(self._interface.id)
          self._members_emitter = members_emitter
  
          self._cpp_declarations_emitter = emitter.Emitter()
  
          # This is a hack to work around a strange C++ compile error that we weren't
          # able to track down the true cause of.
          if self._interface.id == 'Timing':
              self._cpp_impl_includes.add('"core/animation/TimedItem.h"')
  
          self._cpp_definitions_emitter = emitter.Emitter()
          self._cpp_resolver_emitter = emitter.Emitter()
  
          # We need to revisit our treatment of typed arrays, right now
          # it is full of hacks.
          if self._interface.ext_attrs.get('ConstructorTemplate') == 'TypedArray':
              self._cpp_resolver_emitter.Emit(
                  '    if (name == "$(INTERFACE_NAME)_constructor_Callback")\n'
                  '        return Dart$(INTERFACE_NAME)Internal::constructorCallback;\n',
                  INTERFACE_NAME=self._interface.id)
  
              self._cpp_impl_includes.add('"DartArrayBufferViewCustom.h"')
              self._cpp_definitions_emitter.Emit(
                  '\n'
                  'static void constructorCallback(Dart_NativeArguments args)\n'
                  '{\n'
                  '    WebCore::DartArrayBufferViewInternal::constructWebGLArray<Dart$(INTERFACE_NAME)>(args);\n'
                  '}\n',
                  INTERFACE_NAME=self._interface.id)
  
      def _EmitConstructorInfrastructure(self,
                                         constructor_info,
                                         cpp_prefix,
                                         cpp_suffix,
                                         factory_method_name,
                                         arguments=None,
                                         emit_to_native=False,
                                         is_custom=False):
  
          constructor_callback_cpp_name = cpp_prefix + cpp_suffix
  
          if arguments is None:
              arguments = constructor_info.idl_args[0]
              argument_count = len(arguments)
          else:
              argument_count = len(arguments)
  
          typed_formals = constructor_info.ParametersAsArgumentList(
              argument_count)
          parameters = constructor_info.ParametersAsStringOfVariables(
              argument_count)
          interface_name = self._interface_type_info.interface_name()
  
          dart_native_name, constructor_callback_id = \
              self.DeriveNativeEntry(cpp_suffix, 'Constructor', argument_count)
  
          # Then we emit the impedance matching wrapper to call out to the
          # toplevel wrapper
          if not emit_to_native:
              toplevel_name = \
                  self.DeriveQualifiedBlinkName(self._interface.id,
                                                dart_native_name)
              self._members_emitter.Emit(
                  '  static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) => '
                  '$TOPLEVEL_NAME($OUTPARAMETERS);\n',
                  INTERFACE_NAME=self._interface_type_info.interface_name(),
                  FACTORY_METHOD_NAME=factory_method_name,
                  PARAMETERS=typed_formals,
                  TOPLEVEL_NAME=toplevel_name,
                  OUTPARAMETERS=parameters)
  
          self._cpp_resolver_emitter.Emit(
              '    if (name == "$ID")\n'
              '        return Dart$(WEBKIT_INTERFACE_NAME)Internal::$CPP_CALLBACK;\n',
              ID=constructor_callback_id,
              WEBKIT_INTERFACE_NAME=self._interface.id,
              CPP_CALLBACK=constructor_callback_cpp_name)
  
      def GenerateCustomFactory(self, constructor_info):
          if 'CustomConstructor' not in self._interface.ext_attrs:
              return False
  
          annotations = self._metadata.GetFormattedMetadata(
              self._library_name, self._interface, self._interface.id, '  ')
  
          self._members_emitter.Emit(
              '\n  $(ANNOTATIONS)factory $CTOR($PARAMS) => _create($FACTORY_PARAMS);\n',
              ANNOTATIONS=annotations,
              CTOR=constructor_info._ConstructorFullName(self._DartType),
              PARAMS=constructor_info.ParametersAsDeclaration(self._DartType),
              FACTORY_PARAMS= \
                  constructor_info.ParametersAsArgumentList())
  
          # MutationObserver has custom _create.  TODO(terry): Consider table but this is only one.
          if self._interface.id != 'MutationObserver':
              constructor_callback_cpp_name = 'constructorCallback'
              self._EmitConstructorInfrastructure(
                  constructor_info,
                  "",
                  constructor_callback_cpp_name,
                  '_create',
                  is_custom=True)
  
              self._cpp_declarations_emitter.Emit(
                  '\n'
                  'void $CPP_CALLBACK(Dart_NativeArguments);\n',
                  CPP_CALLBACK=constructor_callback_cpp_name)
  
          return True
  
      def IsConstructorArgumentOptional(self, argument):
          return IsOptional(argument)
  
      def MakeFactoryCall(self, factory, method, arguments, constructor_info):
          return emitter.Format(
              '$FACTORY.$METHOD($ARGUMENTS)',
              FACTORY=factory,
              METHOD=method,
              ARGUMENTS=arguments)
  
      def EmitStaticFactoryOverload(self, constructor_info, name, arguments):
          constructor_callback_cpp_name = name + 'constructorCallback'
          self._EmitConstructorInfrastructure(
              constructor_info,
              name,
              'constructorCallback',
              name,
              arguments,
              emit_to_native=True,
              is_custom=False)
  
          ext_attrs = self._interface.ext_attrs
  
          create_function = 'create'
          if 'NamedConstructor' in ext_attrs:
              create_function = 'createForJSConstructor'
          function_expression = '%s::%s' % (
              self._interface_type_info.native_type(), create_function)
  
      def HasSupportCheck(self):
          # Need to omit a support check if it is conditional in JS.
          return self._interface.doc_js_name in js_support_checks
  
      def GetSupportCheck(self):
          # Assume that everything is supported on Dartium.
          value = js_support_checks.get(self._interface.doc_js_name)
          if type(value) == tuple:
              return (value[0], 'true')
          else:
              return 'true'
  
      def FinishInterface(self):
          interface = self._interface
          if interface.parents:
              supertype = '%sClassId' % interface.parents[0].type.id
          else:
              supertype = '-1'
  
          self._GenerateCPPHeader()
  
          self._cpp_impl_emitter.Emit(
              self._template_loader.Load('cpp_implementation.template'),
              INTERFACE=self._interface.id,
              SUPER_INTERFACE=supertype,
              INCLUDES=self._GenerateCPPIncludes(self._cpp_impl_includes),
              CALLBACKS=self._cpp_definitions_emitter.Fragments(),
              RESOLVER=self._cpp_resolver_emitter.Fragments(),
              WEBCORE_CLASS_NAME=self._interface_type_info.native_type(),
              WEBCORE_CLASS_NAME_ESCAPED=self._interface_type_info.native_type().
              replace('<', '_').replace('>', '_'),
              DART_IMPLEMENTATION_CLASS=self._interface_type_info.
              implementation_name(),
              DART_IMPLEMENTATION_LIBRARY_ID='Dart%sLibraryId' %
              self._renamer.GetLibraryId(self._interface))
  
      def _GenerateCPPHeader(self):
          to_native_emitter = emitter.Emitter()
          if self._interface_type_info.custom_to_native():
              return_type = 'PassRefPtr<NativeType>'
              to_native_body = ';'
              to_native_arg_body = ';'
          else:
              return_type = 'NativeType*'
              to_native_body = emitter.Format(
                  '\n'
                  '    {\n'
                  '        DartDOMData* domData = DartDOMData::current();\n'
                  '        return DartDOMWrapper::unwrapDartWrapper<Dart$INTERFACE>(domData, handle, exception);\n'
                  '    }',
                  INTERFACE=self._interface.id)
              to_native_arg_body = emitter.Format(
                  '\n'
                  '    {\n'
                  '        return DartDOMWrapper::unwrapDartWrapper<Dart$INTERFACE>(args, index, exception);\n'
                  '    }',
                  INTERFACE=self._interface.id)
  
          to_native_emitter.Emit(
              '    static $RETURN_TYPE toNative(Dart_Handle handle, Dart_Handle& exception)$TO_NATIVE_BODY\n'
              '\n'
              '    static $RETURN_TYPE toNativeWithNullCheck(Dart_Handle handle, Dart_Handle& exception)\n'
              '    {\n'
              '        return Dart_IsNull(handle) ? 0 : toNative(handle, exception);\n'
              '    }\n'
              '\n'
              '    static $RETURN_TYPE toNative(Dart_NativeArguments args, int index, Dart_Handle& exception)$TO_NATIVE_ARG_BODY\n'
              '\n'
              '    static $RETURN_TYPE toNativeWithNullCheck(Dart_NativeArguments args, int index, Dart_Handle& exception)\n'
              '    {\n'
              '        // toNative accounts for Null objects also.\n'
              '        return toNative(args, index, exception);\n'
              '    }\n',
              RETURN_TYPE=return_type,
              TO_NATIVE_BODY=to_native_body,
              TO_NATIVE_ARG_BODY=to_native_arg_body,
              INTERFACE=self._interface.id)
  
          to_dart_emitter = emitter.Emitter()
  
          ext_attrs = self._interface.ext_attrs
  
          to_dart_emitter.Emit(
              '    static Dart_Handle toDart(NativeType* value)\n'
              '    {\n'
              '        if (!value)\n'
              '            return Dart_Null();\n'
              '        DartDOMData* domData = DartDOMData::current();\n'
              '        Dart_WeakPersistentHandle result =\n'
              '            DartDOMWrapper::lookupWrapper<Dart$(INTERFACE)>(domData, value);\n'
              '        if (result)\n'
              '            return Dart_HandleFromWeakPersistent(result);\n'
              '        return createWrapper(domData, value);\n'
              '    }\n'
              '    static void returnToDart(Dart_NativeArguments args,\n'
              '                             NativeType* value,\n'
              '                             bool autoDartScope = true)\n'
              '    {\n'
              '        if (value) {\n'
              '            DartDOMData* domData = static_cast<DartDOMData*>(\n'
              '                Dart_GetNativeIsolateData(args));\n'
              '            Dart_WeakPersistentHandle result =\n'
              '                DartDOMWrapper::lookupWrapper<Dart$(INTERFACE)>(domData, value);\n'
              '            if (result)\n'
              '                Dart_SetWeakHandleReturnValue(args, result);\n'
              '            else {\n'
              '                if (autoDartScope) {\n'
              '                    Dart_SetReturnValue(args, createWrapper(domData, value));\n'
              '                } else {\n'
              '                    DartApiScope apiScope;\n'
              '                    Dart_SetReturnValue(args, createWrapper(domData, value));\n'
              '               }\n'
              '            }\n'
              '        }\n'
              '    }\n',
              INTERFACE=self._interface.id)
  
          if ('CustomToV8' in ext_attrs or 'PureInterface' in ext_attrs or
                  'CPPPureInterface' in ext_attrs or
                  'SpecialWrapFor' in ext_attrs or
              ('Custom' in ext_attrs and ext_attrs['Custom'] == 'Wrap') or
              ('Custom' in ext_attrs and ext_attrs['Custom'] == 'ToV8') or
                  self._interface_type_info.custom_to_dart()):
              to_dart_emitter.Emit(
                  '    static Dart_Handle createWrapper(DartDOMData* domData, NativeType* value);\n'
              )
          else:
              to_dart_emitter.Emit(
                  '    static Dart_Handle createWrapper(DartDOMData* domData, NativeType* value)\n'
                  '    {\n'
                  '        return DartDOMWrapper::createWrapper<Dart$(INTERFACE)>(domData, value, Dart$(INTERFACE)::dartClassId);\n'
                  '    }\n',
                  INTERFACE=self._interface.id)
  
          webcore_includes = self._GenerateCPPIncludes(
              self._interface_type_info.webcore_includes())
  
          is_node_test = lambda interface: interface.id == 'Node'
          is_active_test = lambda interface: 'ActiveDOMObject' in interface.ext_attrs
          is_event_target_test = lambda interface: 'EventTarget' in interface.ext_attrs
  
          def TypeCheckHelper(test):
              return 'true' if any(
                  map(test, self._database.Hierarchy(
                      self._interface))) else 'false'
  
          to_active_emitter = emitter.Emitter()
          to_node_emitter = emitter.Emitter()
          to_event_target_emitter = emitter.Emitter()
  
          if (any(map(is_active_test,
                      self._database.Hierarchy(self._interface)))):
              to_active_emitter.Emit('return toNative(value);')
          else:
              to_active_emitter.Emit('return 0;')
  
          if (any(map(is_node_test, self._database.Hierarchy(self._interface)))):
              to_node_emitter.Emit('return toNative(value);')
          else:
              to_node_emitter.Emit('return 0;')
  
          if (any(
                  map(is_event_target_test,
                      self._database.Hierarchy(self._interface)))):
              to_event_target_emitter.Emit('return toNative(value);')
          else:
              to_event_target_emitter.Emit('return 0;')
  
          v8_interface_include = ''
          # V8AbstractWorker.h does not exist so we have to hard code this case.
          if self._interface.id != 'AbstractWorker':
              # FIXME: We need this to access the WrapperTypeInfo.
              v8_interface_include = '#include "V8%s.h"' % (self._interface.id)
  
          self._cpp_header_emitter.Emit(
              self._template_loader.Load('cpp_header.template'),
              INTERFACE=self._interface.id,
              WEBCORE_INCLUDES=webcore_includes,
              V8_INTERFACE_INCLUDE=v8_interface_include,
              WEBCORE_CLASS_NAME=self._interface_type_info.native_type(),
              WEBCORE_CLASS_NAME_ESCAPED=self._interface_type_info.native_type().
              replace('<', '_').replace('>', '_'),
              DECLARATIONS=self._cpp_declarations_emitter.Fragments(),
              IS_NODE=TypeCheckHelper(is_node_test),
              IS_ACTIVE=TypeCheckHelper(is_active_test),
              IS_EVENT_TARGET=TypeCheckHelper(is_event_target_test),
              TO_NODE=to_node_emitter.Fragments(),
              TO_ACTIVE=to_active_emitter.Fragments(),
              TO_EVENT_TARGET=to_event_target_emitter.Fragments(),
              TO_NATIVE=to_native_emitter.Fragments(),
              TO_DART=to_dart_emitter.Fragments())
  
      def EmitAttribute(self, attribute, html_name, read_only):
          self._AddGetter(attribute, html_name, read_only)
          if not read_only:
              self._AddSetter(attribute, html_name)
  
      def _GenerateAutoSetupScope(self, idl_name, native_suffix):
          return None
  
      def _AddGetter(self, attr, html_name, read_only):
          # Temporary hack to force dart:scalarlist clamped array for ImageData.data.
          # TODO(antonm): solve in principled way.
          if self._interface.id == 'ImageData' and html_name == 'data':
              html_name = '_data'
          type_info = self._TypeInfo(attr.type.id)
  
          return_type = self.SecureOutputType(
              attr.type.id, False, False if self._dart_use_blink else True)
          dictionary_returned = False
          # Return type for dictionary is any (untyped).
          if attr.type.id == 'Dictionary':
              return_type = ''
              dictionary_returned = True
  
          parameters = []
          dart_declaration = '%s get %s' % (return_type, html_name)
          is_custom = _IsCustom(attr) and (_IsCustomValue(attr, None) or
                                           _IsCustomValue(attr, 'Getter'))
  
          # Operation uses blink?
          wrap_unwrap_list = []
          return_wrap_jso = False
          if self._dart_use_blink:
              # Unwrap the type to get the JsObject if Type is:
              #
              #    - known IDL type
              #    - type_id is None then it's probably a union type or overloaded
              #      it's a dynamic/any type
              #    - type is Object
              #
              # JsObject maybe stored in the Dart class.
              return_wrap_jso = wrap_return_type_blink(return_type, attr.type.id,
                                                       self._type_registry)
          wrap_unwrap_list.append(return_wrap_jso)  # wrap_jso the returned object
          wrap_unwrap_list.append(self._dart_use_blink)
  
          # This seems to have been replaced with Custom=Getter (see above), but
          # check to be sure we don't see the old syntax
          assert (not ('CustomGetter' in attr.ext_attrs))
          native_suffix = 'Getter'
          auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix)
          native_entry = \
              self.DeriveNativeEntry(attr.id, 'Getter', None)
          output_conversion = self._OutputConversion(attr.type.id, attr.id)
  
          cpp_callback_name = self._GenerateNativeBinding(
              attr.id,
              1,
              dart_declaration,
              attr.is_static,
              return_type,
              parameters,
              native_suffix,
              is_custom,
              auto_scope_setup,
              native_entry=native_entry,
              wrap_unwrap_list=wrap_unwrap_list,
              dictionary_return=dictionary_returned,
              output_conversion=output_conversion)
          if is_custom:
              return
  
          if 'Reflect' in attr.ext_attrs:
              webcore_function_name = self._TypeInfo(
                  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'
          elif 'ImplementedAs' in attr.ext_attrs:
              webcore_function_name = attr.ext_attrs['ImplementedAs']
          else:
              if attr.id == 'operator':
                  webcore_function_name = '_operator'
              elif attr.id == 'target' and attr.type.id == 'SVGAnimatedString':
                  webcore_function_name = 'svgTarget'
              elif attr.id == 'CSS':
                  webcore_function_name = 'css'
              else:
                  webcore_function_name = self._ToWebKitName(attr.id)
  
          function_expression = self._GenerateWebCoreFunctionExpression(
              webcore_function_name, attr)
          raises = ('RaisesException' in attr.ext_attrs and
                    attr.ext_attrs['RaisesException'] != 'Setter')
  
      def _AddSetter(self, attr, html_name):
          return_type = 'void'
          ptype = self._DartType(attr.type.id)
  
          type_info = self._TypeInfo(attr.type.id)
  
          # Is the setter value a DartClass (that has a JsObject) or the type is
          # None (it's a dynamic/any type) then unwrap_jso before passing to blink.
          parameters = ['value']
  
          dart_declaration = 'set %s(%s value)' % (html_name, ptype)
          is_custom = _IsCustom(attr) and (_IsCustomValue(attr, None) or
                                           _IsCustomValue(attr, 'Setter'))
          # This seems to have been replaced with Custom=Setter (see above), but
          # check to be sure we don't see the old syntax
          assert (not ('CustomSetter' in attr.ext_attrs))
          assert (not ('V8CustomSetter' in attr.ext_attrs))
          native_suffix = 'Setter'
          auto_scope_setup = self._GenerateAutoSetupScope(attr.id, native_suffix)
          native_entry = \
              self.DeriveNativeEntry(attr.id, 'Setter', None)
  
          # setters return no object and if blink this must be unwrapped.?
          wrap_unwrap_list = [False, self._dart_use_blink]
  
          cpp_callback_name = self._GenerateNativeBinding(
              attr.id,
              2,
              dart_declaration,
              attr.is_static,
              return_type,
              parameters,
              native_suffix,
              is_custom,
              auto_scope_setup,
              native_entry=native_entry,
              wrap_unwrap_list=wrap_unwrap_list)
          if is_custom:
              return
  
          if 'Reflect' in attr.ext_attrs:
              webcore_function_name = self._TypeInfo(
                  attr.type.id).webcore_setter_name()
          else:
              if 'ImplementedAs' in attr.ext_attrs:
                  attr_name = attr.ext_attrs['ImplementedAs']
              else:
                  attr_name = attr.id
              webcore_function_name = re.sub(r'^(xml|css|(?=[A-Z])|\w)',
                                             lambda s: s.group(1).upper(),
                                             attr_name)
              webcore_function_name = 'set%s' % webcore_function_name
  
          function_expression = self._GenerateWebCoreFunctionExpression(
              webcore_function_name, attr)
          raises = ('RaisesException' in attr.ext_attrs and
                    attr.ext_attrs['RaisesException'] != 'Getter')
  
      def AddIndexer(self, element_type, nullable):
          """Adds all the methods required to complete implementation of List."""
          # We would like to simply inherit the implementation of everything except
          # length, [], and maybe []=.  It is possible to extend from a base
          # array implementation class only when there is no other implementation
          # inheritance.  There might be no implementation inheritance other than
          # DOMBaseWrapper for many classes, but there might be some where the
          # array-ness is introduced by a non-root interface:
          #
          #   interface Y extends X, List<T> ...
          #
          # In the non-root case we have to choose between:
          #
          #   class YImpl extends XImpl { add List<T> methods; }
          #
          # and
          #
          #   class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
          #
          dart_element_type = self._DartType(element_type)
          if self._HasNativeIndexGetter():
              self._EmitNativeIndexGetter(dart_element_type)
          elif self._HasExplicitIndexedGetter():
              self._EmitExplicitIndexedGetter(dart_element_type)
          else:
              is_custom = any((op.id == 'item' and _IsCustom(op))
                              for op in self._interface.operations)
  
              output_conversion = self._OutputConversion(element_type, 'item')
              conversion_name = ''
              if output_conversion:
                  conversion_name = output_conversion.function_name
  
              # First emit a toplevel function to do the native call
              # Calls to this are emitted elsewhere,
              dart_native_name, resolver_string = \
                  self.DeriveNativeEntry("item", 'Method', 1)
  
              # Emit the method which calls the toplevel function, along with
              # the [] operator.
              dart_qualified_name = \
                  self.DeriveQualifiedBlinkName(self._interface.id,
                                                dart_native_name)
  
              type_info = self._TypeInfo(element_type)
              blinkNativeIndexed = """
    $TYPE operator[](int index) {
      if (index < 0 || index >= length)
        throw new RangeError.index(index, this);
      return _nativeIndexedGetter(index);
    }
  
    $TYPE _nativeIndexedGetter(int index) => $(CONVERSION_NAME)($(DART_NATIVE_NAME)(this, index));
  """
              blinkNativeIndexedGetter = \
                  ' $(DART_NATIVE_NAME)(this, index);\n'
              self._members_emitter.Emit(
                  blinkNativeIndexed,
                  DART_NATIVE_NAME=dart_qualified_name,
                  TYPE=self.SecureOutputType(element_type),
                  INTERFACE=self._interface.id,
                  CONVERSION_NAME=conversion_name)
  
          if self._HasNativeIndexSetter():
              self._EmitNativeIndexSetter(dart_element_type)
          else:
              self._members_emitter.Emit(
                  '\n'
                  '  void operator[]=(int index, $TYPE value) {\n'
                  '    throw new UnsupportedError("Cannot assign element of immutable List.");\n'
                  '  }\n',
                  TYPE=dart_element_type)
  
          self.EmitListMixin(dart_element_type, nullable)
  
      def AmendIndexer(self, element_type):
          # If interface is marked as having native indexed
          # getter or setter, we must emit overrides as it's not
          # guaranteed that the corresponding methods in C++ would be
          # virtual.  For example, as of time of writing, even though
          # Uint8ClampedArray inherits from Uint8Array, ::set method
          # is not virtual and accessing it through Uint8Array pointer
          # would lead to wrong semantics (modulo vs. clamping.)
          dart_element_type = self._DartType(element_type)
  
          if self._HasNativeIndexGetter():
              self._EmitNativeIndexGetter(dart_element_type)
          if self._HasNativeIndexSetter():
              self._EmitNativeIndexSetter(dart_element_type)
  
      def _HasNativeIndexGetter(self):
          return 'CustomIndexedGetter' in self._interface.ext_attrs
  
      def _EmitNativeIndexGetter(self, element_type):
          return_type = self.SecureOutputType(element_type, True)
          parameters = ['index']
          dart_declaration = '%s operator[](int index)' % return_type
          self._GenerateNativeBinding('numericIndexGetter', 2, dart_declaration,
                                      False, return_type, parameters, 'Callback',
                                      True, False)
  
      def _HasExplicitIndexedGetter(self):
          return any(op.id == 'getItem' for op in self._interface.operations)
  
      def _EmitExplicitIndexedGetter(self, dart_element_type):
          if any(op.id == 'getItem' for op in self._interface.operations):
              indexed_getter = 'getItem'
  
          self._members_emitter.Emit(
              '\n'
              '  $TYPE operator[](int index) {\n'
              '    if (index < 0 || index >= length)\n'
              '      throw new RangeError.index(index, this);\n'
              '    return $INDEXED_GETTER(index);\n'
              '  }\n',
              TYPE=dart_element_type,
              INDEXED_GETTER=indexed_getter)
  
      def _HasNativeIndexSetter(self):
          return 'CustomIndexedSetter' in self._interface.ext_attrs
  
      def _EmitNativeIndexSetter(self, element_type):
          return_type = 'void'
          formals = ', '.join(['int index', '%s value' % element_type])
          parameters = ['index', 'value']
          dart_declaration = 'void operator[]=(%s)' % formals
          self._GenerateNativeBinding('numericIndexSetter', 3, dart_declaration,
                                      False, return_type, parameters, 'Callback',
                                      True, False)
  
      def _ChangePrivateOpMapArgToAny(self, operations):
          # TODO(terry): Hack to map any operations marked as private to not
          #              handle converting Map to native (JsObject) the public
          #              members that call the private method will have done
          #              conversions.
          for operation in operations:
              for arg in operation.arguments:
                  type = arg.type
                  if type.id == 'Dictionary':
                      type.id = 'any'
  
      def EmitOperation(self, info, html_name, dart_js_interop=False):
          """
      Arguments:
        info: An OperationInfo object.
      """
          if self._renamer.isPrivate(self._interface, info.operations[0].id):
              # Any private operations with Maps parameters changed to any type.
              # The public method that delegates to this private operation has already
              # converted from Map to native (JsObject) e.g., Element.animate.
              self._ChangePrivateOpMapArgToAny(info.operations)
  
          return_type = self.SecureOutputType(info.type_name, False,
                                              False if dart_js_interop else True)
  
          formals = info.ParametersAsDeclaration(self._DartType)
  
          parameters = info.ParametersAsListOfVariables(
              None, self._type_registry if self._dart_use_blink else None,
              dart_js_interop, self)
  
          operation = info.operations[0]
  
          output_conversion = self._OutputConversion(operation.type.id,
                                                     operation.id)
  
          dictionary_returned = False
          # Return type for dictionary is any (untyped).
          if operation.type.id == 'Dictionary':
              return_type = ''
              dictionary_returned = True
  
          dart_declaration = '%s%s %s(%s)' % ('static ' if info.IsStatic() else
                                              '', return_type, html_name, formals)
  
          is_custom = _IsCustom(operation)
          has_optional_arguments = any(
              IsOptional(argument) for argument in operation.arguments)
          needs_dispatcher = not is_custom and (len(info.operations) > 1 or
                                                has_optional_arguments)
  
          # Operation uses blink?
          wrap_unwrap_list = []
          return_wrap_jso = False
          # return type wrapped?
          if self._dart_use_blink:
              # Wrap the type to store the JsObject if Type is:
              #
              #      it's a dynamic/any type
              #    - type is Object
              #
              # JsObject maybe stored in the Dart class.
              return_wrap_jso = wrap_return_type_blink(
                  return_type, info.type_name, self._type_registry)
              return_type_info = self._type_registry.TypeInfo(info.type_name)
          # wrap_jso the returned object
          wrap_unwrap_list.append(return_wrap_jso)
          wrap_unwrap_list.append(self._dart_use_blink)
  
          if info.callback_args:
              self._AddFutureifiedOperation(info, html_name)
          elif not needs_dispatcher:
              # Bind directly to native implementation
              argument_count = (0 if info.IsStatic() else 1) + len(
                  info.param_infos)
              native_suffix = 'Callback'
              auto_scope_setup = self._GenerateAutoSetupScope(
                  info.name, native_suffix)
              native_entry = \
                  self.DeriveNativeEntry(operation.id, 'Method', len(info.param_infos))
              cpp_callback_name = self._GenerateNativeBinding(
                  info.name,
                  argument_count,
                  dart_declaration,
                  info.IsStatic(),
                  return_type,
                  parameters,
                  native_suffix,
                  is_custom,
                  auto_scope_setup,
                  native_entry=native_entry,
                  wrap_unwrap_list=wrap_unwrap_list,
                  dictionary_return=dictionary_returned,
                  output_conversion=output_conversion)
              if not is_custom:
                  self._GenerateOperationNativeCallback(
                      operation, operation.arguments, cpp_callback_name,
                      auto_scope_setup)
          else:
              self._GenerateDispatcher(info, info.operations, dart_declaration,
                                       html_name)
  
      def _GenerateDispatcher(self, info, operations, dart_declaration,
                              html_name):
  
          def GenerateCall(stmts_emitter, call_emitter, version, operation,
                           argument_count):
              native_suffix = 'Callback'
              actuals = info.ParametersAsListOfVariables(
                  argument_count,
                  self._type_registry if self._dart_use_blink else None,
                  self._dart_js_interop, self)
              actuals_s = ", ".join(actuals)
              formals = actuals
              return_type = self.SecureOutputType(operation.type.id)
  
              return_wrap_jso = False
              if self._dart_use_blink:
                  return_wrap_jso = wrap_return_type_blink(
                      return_type, info.type_name, self._type_registry)
  
              native_suffix = 'Callback'
              is_custom = _IsCustom(operation)
              base_name = '_%s_%s' % (operation.id, version)
              static = True
              if not operation.is_static:
                  actuals = ['this'] + actuals
                  formals = ['mthis'] + formals
              actuals_s = ", ".join(actuals)
              formals_s = ", ".join(formals)
              dart_declaration = '%s(%s)' % (base_name, formals_s)
              native_entry = \
                  self.DeriveNativeEntry(operation.id, 'Method', argument_count)
              overload_base_name = native_entry[0]
              overload_name = \
                  self.DeriveQualifiedBlinkName(self._interface.id,
                                                overload_base_name)
              call_emitter.Emit(
                  '$NAME($ARGS)', NAME=overload_name, ARGS=actuals_s)
              auto_scope_setup = \
                self._GenerateAutoSetupScope(base_name, native_suffix)
              cpp_callback_name = self._GenerateNativeBinding(
                  base_name, (0 if static else 1) + argument_count,
                  dart_declaration,
                  static,
                  return_type,
                  formals,
                  native_suffix,
                  is_custom,
                  auto_scope_setup,
                  emit_metadata=False,
                  emit_to_native=True,
                  native_entry=native_entry)
              if not is_custom:
                  self._GenerateOperationNativeCallback(
                      operation, operation.arguments[:argument_count],
                      cpp_callback_name, auto_scope_setup)
  
          self._GenerateDispatcherBody(info, operations, dart_declaration,
                                       GenerateCall, IsOptional)
  
      def SecondaryContext(self, interface):
          pass
  
      def _GenerateOperationNativeCallback(self,
                                           operation,
                                           arguments,
                                           cpp_callback_name,
                                           auto_scope_setup=True):
          webcore_function_name = operation.ext_attrs.get('ImplementedAs',
                                                          operation.id)
  
          function_expression = self._GenerateWebCoreFunctionExpression(
              webcore_function_name, operation, cpp_callback_name)
  
      def _GenerateNativeBinding(self,
                                 idl_name,
                                 argument_count,
                                 dart_declaration,
                                 static,
                                 return_type,
                                 parameters,
                                 native_suffix,
                                 is_custom,
                                 auto_scope_setup=True,
                                 emit_metadata=True,
                                 emit_to_native=False,
                                 native_entry=None,
                                 wrap_unwrap_list=[],
                                 dictionary_return=False,
                                 output_conversion=None):
          metadata = []
          if emit_metadata:
              metadata = self._metadata.GetFormattedMetadata(
                  self._renamer.GetLibraryName(self._interface), self._interface,
                  idl_name, '  ')
  
          if (native_entry):
              dart_native_name, native_binding = native_entry
          else:
              dart_native_name = \
                  self.DeriveNativeName(idl_name, native_suffix)
              native_binding_id = self._interface.id
              native_binding_id = TypeIdToBlinkName(native_binding_id,
                                                    self._database)
              native_binding = \
                  '%s_%s_%s' % (native_binding_id, idl_name, native_suffix)
  
          if not static:
              formals = ", ".join(['mthis'] + parameters)
              actuals = ", ".join(['this'] + parameters)
          else:
              formals = ", ".join(parameters)
              actuals = ", ".join(parameters)
  
          if not emit_to_native:
              caller_emitter = self._members_emitter
              full_dart_name = \
                  self.DeriveQualifiedBlinkName(self._interface.id,
                                                dart_native_name)
              if IsPureInterface(self._interface.id, self._database):
                  caller_emitter.Emit('\n'
                                      '  $METADATA$DART_DECLARATION;\n',
                                      METADATA=metadata,
                                      DART_DECLARATION=dart_declaration)
              else:
                  emit_template = '''
    $METADATA$DART_DECLARATION => $DART_NAME($ACTUALS);
    '''
                  if output_conversion and not dictionary_return:
                      conversion_template = '''
    $METADATA$DART_DECLARATION => %s($DART_NAME($ACTUALS));
    '''
                      emit_template = conversion_template % output_conversion.function_name
  
                  elif wrap_unwrap_list and wrap_unwrap_list[0]:
                      if return_type == 'Rectangle':
                          jso_util_method = 'make_dart_rectangle'
                      elif wrap_unwrap_list[0]:
                          jso_util_method = ''
  
                      if dictionary_return:
                          emit_jso_template = '''
    $METADATA$DART_DECLARATION => convertNativeDictionaryToDartDictionary(%s($DART_NAME($ACTUALS)));
    '''
                      else:
                          emit_jso_template = '''
    $METADATA$DART_DECLARATION => %s($DART_NAME($ACTUALS));
    '''
                      emit_template = emit_jso_template % jso_util_method
  
                  if caller_emitter:
                      caller_emitter.Emit(
                          emit_template,
                          METADATA=metadata,
                          DART_DECLARATION=dart_declaration,
                          DART_NAME=full_dart_name,
                          ACTUALS=actuals)
          cpp_callback_name = '%s%s' % (idl_name, native_suffix)
  
          self._cpp_resolver_emitter.Emit(
              '    if (argumentCount == $ARGC && name == "$NATIVE_BINDING") {\n'
              '        *autoSetupScope = $AUTO_SCOPE_SETUP;\n'
              '        return Dart$(INTERFACE_NAME)Internal::$CPP_CALLBACK_NAME;\n'
              '    }\n',
              ARGC=argument_count,
              NATIVE_BINDING=native_binding,
              INTERFACE_NAME=self._interface.id,
              AUTO_SCOPE_SETUP='true' if auto_scope_setup else 'false',
              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 _IsStatic(self, attribute_name):
          return False
  
      def _GenerateWebCoreFunctionExpression(self,
                                             function_name,
                                             idl_node,
                                             cpp_callback_name=None):
          return None
  
      def _IsArgumentOptionalInWebCore(self, operation, argument):
          if not IsOptional(argument):
              return False
          if 'Callback' in argument.ext_attrs:
              return False
          if operation.id in ['addEventListener', 'removeEventListener'
                             ] and argument.id == 'useCapture':
              return False
          if 'DartForceOptional' in argument.ext_attrs:
              return False
          if argument.type.id == 'Dictionary':
              return False
          return True
  
      def _GenerateCPPIncludes(self, includes):
          return None
  
      def _ToWebKitName(self, name):
          name = name[0].lower() + name[1:]
          name = re.sub(r'^(hTML|uRL|jS|xML|xSLT)', lambda s: s.group(1).lower(),
                        name)
          return re.sub(r'^(create|exclusive)',
                        lambda s: 'is' + s.group(1).capitalize(), name)
  
  
  class CPPLibraryEmitter():
  
      def __init__(self, emitters, cpp_sources_dir):
          self._emitters = emitters
          self._cpp_sources_dir = cpp_sources_dir
          self._library_headers = dict((lib, []) for lib in HTML_LIBRARY_NAMES)
          self._sources_list = []
  
      def CreateHeaderEmitter(self,
                              interface_name,
                              library_name,
                              is_callback=False):
          path = os.path.join(self._cpp_sources_dir, 'Dart%s.h' % interface_name)
          if not is_callback:
              self._library_headers[library_name].append(path)
          return self._emitters.FileEmitter(path)
  
      def CreateSourceEmitter(self, interface_name):
          path = os.path.join(self._cpp_sources_dir,
                              'Dart%s.cpp' % interface_name)
          self._sources_list.append(path)
          return self._emitters.FileEmitter(path)
  
      def EmitDerivedSources(self, template, output_dir):
          partitions = 20  # FIXME: this should be configurable.
          sources_count = len(self._sources_list)
          for i in range(0, partitions):
              file_path = os.path.join(output_dir,
                                       'DartDerivedSources%02i.cpp' % (i + 1))
              includes_emitter = self._emitters.FileEmitter(file_path).Emit(
                  template)
              for source_file in self._sources_list[i::partitions]:
                  path = os.path.relpath(source_file, output_dir)
                  includes_emitter.Emit('#include "$PATH"\n', PATH=path)
  
      def EmitResolver(self, template, output_dir):
          for library_name in self._library_headers.keys():
              file_path = os.path.join(output_dir,
                                       '%s_DartResolver.cpp' % library_name)
              includes_emitter, body_emitter = self._emitters.FileEmitter(
                  file_path).Emit(
                      template, LIBRARY_NAME=library_name)
  
              headers = self._library_headers[library_name]
              for header_file in headers:
                  path = os.path.relpath(header_file, output_dir)
                  includes_emitter.Emit('#include "$PATH"\n', PATH=path)
                  body_emitter.Emit(
                      '    if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argumentCount, autoSetupScope))\n'
                      '        return func;\n',
                      CLASS_NAME=os.path.splitext(os.path.basename(path))[0])
  
      def EmitClassIdTable(self, database, output_dir, type_registry, renamer):
  
          def HasConverters(interface):
              is_node_test = lambda interface: interface.id == 'Node'
              is_active_test = lambda interface: 'ActiveDOMObject' in interface.ext_attrs
              is_event_target_test = lambda interface: 'EventTarget' in interface.ext_attrs
  
              return (
                  any(map(is_node_test, database.Hierarchy(interface))) or
                  any(map(is_active_test, database.Hierarchy(interface))) or
                  any(map(is_event_target_test, database.Hierarchy(interface))))
  
          path = os.path.join(output_dir, 'DartWebkitClassIds.h')
          e = self._emitters.FileEmitter(path)
          e.Emit(
              '// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file\n'
          )
          e.Emit(
              '// for details. All rights reserved. Use of this source code is governed by a\n'
          )
          e.Emit('// BSD-style license that can be found in the LICENSE file.\n')
          e.Emit('// WARNING: Do not edit - generated code.\n')
          e.Emit('// See dart/tools/dom/scripts/systemnative.py\n')
          e.Emit('\n')
          e.Emit('#ifndef DartWebkitClassIds_h\n')
          e.Emit('#define DartWebkitClassIds_h\n')
          e.Emit('\n')
          e.Emit('namespace WebCore {\n')
          e.Emit('\n')
          e.Emit('enum {\n')
          e.Emit('    _InvalidClassId = 0,\n')
          e.Emit('    _HistoryCrossFrameClassId,\n')
          e.Emit('    _LocationCrossFrameClassId,\n')
          e.Emit('    _DOMWindowCrossFrameClassId,\n')
          e.Emit('    _DateTimeClassId,\n')
          e.Emit('    _JsObjectClassId,\n')
          e.Emit('    _JsFunctionClassId,\n')
          e.Emit('    _JsArrayClassId,\n')
          e.Emit(
              '    // New types that are not auto-generated should be added here.\n'
          )
          e.Emit('\n')
          for interface in database.GetInterfaces():
              e.Emit('    %sClassId,\n' % interface.id)
          e.Emit('    NumWebkitClassIds\n')
          e.Emit('};\n')
          e.Emit(
              'class ActiveDOMObject;\n'
              'class EventTarget;\n'
              'class Node;\n'
              'typedef ActiveDOMObject* (*ToActiveDOMObject)(void* value);\n'
              'typedef EventTarget* (*ToEventTarget)(void* value);\n'
              'typedef Node* (*ToNode)(void* value);\n'
              'typedef struct {\n'
              '    const char* class_name;\n'
              '    int library_id;\n'
              '    int base_class_id;\n'
              '    ToActiveDOMObject toActiveDOMObject;\n'
              '    ToEventTarget toEventTarget;\n'
              '    ToNode toNode;\n'
              '} DartWrapperTypeInfo;\n'
              'typedef DartWrapperTypeInfo _DartWebkitClassInfo[NumWebkitClassIds];\n'
              '\n'
              'extern _DartWebkitClassInfo DartWebkitClassInfo;\n'
              '\n'
              '} // namespace WebCore\n'
              '#endif // DartWebkitClassIds_h\n')
  
          path = os.path.join(output_dir, 'DartWebkitClassIds.cpp')
          e = self._emitters.FileEmitter(path)
          e.Emit(
              '// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file\n'
          )
          e.Emit(
              '// for details. All rights reserved. Use of this source code is governed by a\n'
          )
          e.Emit('// BSD-style license that can be found in the LICENSE file.\n')
          e.Emit('// WARNING: Do not edit - generated code.\n')
          e.Emit('// See dart/tools/dom/scripts/systemnative.py\n')
          e.Emit('\n')
          e.Emit('#include "config.h"\n')
          e.Emit('#include "DartWebkitClassIds.h"\n')
          e.Emit('\n')
          e.Emit('#include "bindings/dart/DartLibraryIds.h"\n')
          for interface in database.GetInterfaces():
              if HasConverters(interface):
                  e.Emit('#include "Dart%s.h"\n' % interface.id)
          e.Emit('\n')
  
          e.Emit('namespace WebCore {\n')
  
          e.Emit('\n')
  
          e.Emit(
              'ActiveDOMObject* toNullActiveDOMObject(void* value) { return 0; }\n'
          )
          e.Emit('EventTarget* toNullEventTarget(void* value) { return 0; }\n')
          e.Emit('Node* toNullNode(void* value) { return 0; }\n')
  
          e.Emit("_DartWebkitClassInfo DartWebkitClassInfo = {\n")
  
          e.Emit('    {\n'
                 '        "_InvalidClassId", -1, -1,\n'
                 '        toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
                 '    },\n')
          e.Emit('    {\n'
                 '        "_HistoryCrossFrame", DartHtmlLibraryId, -1,\n'
                 '        toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
                 '    },\n')
          e.Emit('    {\n'
                 '        "_LocationCrossFrame", DartHtmlLibraryId, -1,\n'
                 '        toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
                 '    },\n')
          e.Emit('    {\n'
                 '        "_DOMWindowCrossFrame", DartHtmlLibraryId, -1,\n'
                 '        toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
                 '    },\n')
          e.Emit('    {\n'
                 '        "DateTime", DartCoreLibraryId, -1,\n'
                 '        toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
                 '    },\n')
          e.Emit('    {\n'
                 '        "JsObject", DartJsLibraryId, -1,\n'
                 '        toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
                 '    },\n')
          e.Emit('    {\n'
                 '        "JsFunction", DartJsLibraryId, _JsObjectClassId,\n'
                 '        toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
                 '    },\n')
          e.Emit('    {\n'
                 '        "JsArray", DartJsLibraryId, _JsObjectClassId,\n'
                 '        toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
                 '    },\n')
          e.Emit(
              '    // New types that are not auto-generated should be added here.\n'
          )
          for interface in database.GetInterfaces():
              name = interface.id
              type_info = type_registry.TypeInfo(name)
              type_info.native_type().replace('<', '_').replace('>', '_')
              e.Emit('    {\n')
              e.Emit('        "%s", ' % type_info.implementation_name())
              e.Emit('Dart%sLibraryId, ' % renamer.GetLibraryId(interface))
              if interface.parents:
                  supertype = interface.parents[0].type.id
                  e.Emit('%sClassId,\n' % supertype)
              else:
                  e.Emit(' -1,\n')
              if HasConverters(interface):
                  e.Emit(
                      '        Dart%s::toActiveDOMObject, Dart%s::toEventTarget,'
                      ' Dart%s::toNode\n' % (name, name, name))
              else:
                  e.Emit(
                      '        toNullActiveDOMObject, toNullEventTarget, toNullNode\n'
                  )
              e.Emit('    },\n')
  
          e.Emit("};\n")
          e.Emit('\n')
          e.Emit('} // namespace WebCore\n')
  
  
  def _IsOptionalStringArgumentInInitEventMethod(interface, operation, argument):
      return (interface.id.endswith('Event') and
              operation.id.startswith('init') and
              argument.default_value == 'Undefined' and
              argument.type.id == 'DOMString')
  
  
  def _IsCustom(op_or_attr):
      assert (isinstance(op_or_attr, IDLMember))
      return 'Custom' in op_or_attr.ext_attrs or 'DartCustom' in op_or_attr.ext_attrs
  
  
  def _IsCustomValue(op_or_attr, value):
      if _IsCustom(op_or_attr):
          return op_or_attr.ext_attrs.get('Custom') == value \
                 or op_or_attr.ext_attrs.get('DartCustom') == value
      return False
  