#!/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, 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
