#!/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 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('convertNativePromiseToDartFuture', '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) 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(
            '\n  @DocsEditable()\n'
            '  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 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):
    """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)

  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):
            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
