#!/usr/bin/env python3
# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
"""This module provides shared functionality for the system to generate
Dart:html APIs from the IDL database."""

import emitter
import logging
import monitored
import os
import re
from collections import OrderedDict
from generator import *
from htmldartgenerator import *
from htmlrenamer import generateCallbackInterface

_logger = logging.getLogger('systemhtml')


def CanUseStaticExtensions(interface, should):
    if not should:
        return False
    static_extension_interfaces = []  # Classes to be migrated
    return interface in static_extension_interfaces


HTML_LIBRARY_NAMES = [
    'html', 'indexed_db', 'svg', 'web_audio', 'web_gl', 'web_sql'
]

_safe_to_ignore_shadowing_members = monitored.Set(
    'systemhtml._safe_to_ignore_shadowing_members', [
        'SVGElement.tabIndex',
        'SVGStyleElement.title',
    ])

_js_custom_members = monitored.Set(
    'systemhtml._js_custom_members',
    [
        'AudioContext.createGain',
        'AudioContext.createScriptProcessor',
        'CanvasRenderingContext2D.drawImage',
        'CanvasRenderingContext2D.fillText',
        'CanvasRenderingContext2D.lineDashOffset',
        'CanvasRenderingContext2D.setLineDash',
        'Console.memory',
        'ConsoleBase.assertCondition',
        'ConsoleBase.clear',
        'ConsoleBase.count',
        'ConsoleBase.countReset',
        'ConsoleBase.debug',
        'ConsoleBase.dir',
        'ConsoleBase.dirxml',
        'ConsoleBase.error',
        'ConsoleBase.group',
        'ConsoleBase.groupCollapsed',
        'ConsoleBase.groupEnd',
        'ConsoleBase.info',
        'ConsoleBase.log',
        'ConsoleBase.markTimeline',
        'ConsoleBase.profile',
        'ConsoleBase.profileEnd',
        'ConsoleBase.table',
        'ConsoleBase.time',
        'ConsoleBase.timeEnd',
        'ConsoleBase.timeStamp',
        'ConsoleBase.trace',
        'ConsoleBase.warn',
        'WebKitCSSKeyframesRule.insertRule',
        'CSSStyleDeclaration.setProperty',
        'CSSStyleDeclaration.__propertyQuery__',
        'Document.createNodeIterator',
        'Document.createTreeWalker',
        'DOMException.name',
        'DOMException.toString',
        # ListMixin already provides this method although the implementation
        # is slower. As this class is obsolete anyway, we ignore the slowdown in
        # DOMStringList performance.
        'DOMStringList.contains',
        'Element.animate',
        'Element.createShadowRoot',
        'Element.insertAdjacentElement',
        'Element.insertAdjacentHTML',
        'Element.insertAdjacentText',
        'Element.remove',
        'Element.shadowRoot',
        'Element.matches',
        'ElementEvents.mouseWheel',
        'ElementEvents.transitionEnd',
        'FileReader.result',
        'HTMLAnchorElement.toString',
        'HTMLAreaElement.toString',
        'HTMLTableElement.createTBody',
        'IDBCursor.next',
        'IDBDatabase.transaction',
        'IDBDatabase.transactionList',
        'IDBDatabase.transactionStore',
        'IDBDatabase.transactionStores',
        'KeyboardEvent.initKeyboardEvent',
        'Location.origin',
        'Location.toString',
        'MouseEvent.offsetX',
        'MouseEvent.offsetY',
        'Navigator.language',
        'Navigator.webkitGetUserMedia',
        'ScriptProcessorNode._setEventListener',
        'URL.createObjectURL',
        'URL.createObjectUrlFromSource',
        'URL.createObjectUrlFromStream',
        'URL.createObjectUrlFromBlob',
        'URL.revokeObjectURL',
        'URL.toString',
        'WheelEvent.deltaMode',
        'Window.cancelAnimationFrame',
        'Window.console',
        'Window.document',
        'Window.indexedDB',
        'Window.location',
        'Window.open',
        'Window.requestAnimationFrame',
        'Window.scrollX',
        'Window.scrollY'
        # 'WorkerContext.indexedDB', # Workers
    ],
    dart2jsOnly=True)

_js_custom_constructors = monitored.Set(
    'systemhtml._js_custom_constructors', [
        'AudioContext',
        'Blob',
        'Comment',
        'MutationObserver',
        'PaymentRequest',
        'RTCIceCandidate',
        'RTCPeerConnection',
        'RTCSessionDescription',
        'SpeechRecognition',
    ],
    dart2jsOnly=True)

# Classes that offer only static methods, and therefore we should suppress
# constructor creation.
_static_classes = set(['Url'])

# Callback typedefs with generic List (List<nnn>) convert to List
_callback_list_generics_mapping = monitored.Set(
    'systemhtml._callback_list_generics_mapping', [
        'List<Entry>',
        'List<IntersectionObserverEntry>',
        'List<MutationRecord>',
        'List<_Report>',
        'List<ResizeObserverEntry>',
    ])


# Information for generating element constructors.
#
# TODO(sra): maybe remove all the argument complexity and use cascades.
#
#   var c = new CanvasElement(width: 100, height: 70);
#   var c = new CanvasElement()..width = 100..height = 70;
#
class ElementConstructorInfo(object):

    def __init__(self,
                 name=None,
                 tag=None,
                 params=[],
                 opt_params=[],
                 factory_provider_name='document'):
        self.name = name  # The constructor name 'h1' in 'HeadingElement.h1'
        self.tag = tag or name  # The HTML or SVG tag
        self.params = params
        self.opt_params = opt_params
        self.factory_provider_name = factory_provider_name

    def ConstructorInfo(self, interface_name):
        info = OperationInfo()
        info.overloads = None
        info.declared_name = interface_name
        info.name = interface_name
        info.constructor_name = self.name
        info.js_name = None
        info.type_name = interface_name
        # optional parameters are always nullable
        info.param_infos = [
            ParamInfo(name=tXn[1],
                      type_id=tXn[0],
                      is_optional=True,
                      is_nullable=True,
                      default_value=None,
                      default_value_is_null=False) for tXn in self.opt_params
        ]
        info.requires_named_arguments = True
        info.factory_parameters = ['"%s"' % self.tag]
        info.pure_dart_constructor = True
        return info


_html_element_constructors = monitored.Dict(
    'systemhtml._html_element_constructors',
    {
        'HTMLAnchorElement':
        ElementConstructorInfo(tag='a', opt_params=[('DOMString', 'href')]),
        'HTMLAreaElement':
        'area',
        'HTMLButtonElement':
        'button',
        'HTMLBRElement':
        'br',
        'HTMLBaseElement':
        'base',
        'HTMLBodyElement':
        'body',
        'HTMLButtonElement':
        'button',
        'HTMLCanvasElement':
        ElementConstructorInfo(
            tag='canvas', opt_params=[('int', 'width'), ('int', 'height')]),
        'HTMLContentElement':
        'content',
        'HTMLDataListElement':
        'datalist',
        'HTMLDListElement':
        'dl',
        'HTMLDetailsElement':
        'details',
        'HTMLDivElement':
        'div',
        'HTMLEmbedElement':
        'embed',
        'HTMLFieldSetElement':
        'fieldset',
        'HTMLFormElement':
        'form',
        'HTMLHRElement':
        'hr',
        'HTMLHeadElement':
        'head',
        'HTMLHeadingElement': [
            ElementConstructorInfo('h1'),
            ElementConstructorInfo('h2'),
            ElementConstructorInfo('h3'),
            ElementConstructorInfo('h4'),
            ElementConstructorInfo('h5'),
            ElementConstructorInfo('h6')
        ],
        'HTMLHtmlElement':
        'html',
        'HTMLIFrameElement':
        'iframe',
        'HTMLImageElement':
        ElementConstructorInfo(
            tag='img',
            opt_params=[('DOMString', 'src'), ('int', 'width'),
                        ('int', 'height')]),
        'HTMLKeygenElement':
        'keygen',
        'HTMLLIElement':
        'li',
        'HTMLLabelElement':
        'label',
        'HTMLLegendElement':
        'legend',
        'HTMLLinkElement':
        'link',
        'HTMLMapElement':
        'map',
        'HTMLMenuElement':
        'menu',
        'HTMLMetaElement':
        'meta',
        'HTMLMeterElement':
        'meter',
        'HTMLOListElement':
        'ol',
        'HTMLObjectElement':
        'object',
        'HTMLOptGroupElement':
        'optgroup',
        'HTMLOutputElement':
        'output',
        'HTMLParagraphElement':
        'p',
        'HTMLParamElement':
        'param',
        'HTMLPreElement':
        'pre',
        'HTMLProgressElement':
        'progress',
        'HTMLQuoteElement':
        'q',
        'HTMLScriptElement':
        'script',
        'HTMLSelectElement':
        'select',
        'HTMLShadowElement':
        'shadow',
        'HTMLSourceElement':
        'source',
        'HTMLSpanElement':
        'span',
        'HTMLStyleElement':
        'style',
        'HTMLTableCaptionElement':
        'caption',
        'HTMLTableCellElement':
        'td',
        'HTMLTableColElement':
        'col',
        'HTMLTableElement':
        'table',
        'HTMLTableRowElement':
        'tr',
        #'HTMLTableSectionElement'  <thead> <tbody> <tfoot>
        'HTMLTemplateElement':
        'template',
        'HTMLTextAreaElement':
        'textarea',
        'HTMLTitleElement':
        'title',
        'HTMLTrackElement':
        'track',
        'HTMLUListElement':
        'ul',
        'HTMLVideoElement':
        'video'
    })

_svg_element_constructors = monitored.Dict(
    'systemhtml._svg_element_constructors', {
        'SVGAElement': 'a',
        'SVGAltGlyphElement': 'altGlyph',
        'SVGAnimateElement': 'animate',
        'SVGAnimateMotionElement': 'animateMotion',
        'SVGAnimateTransformElement': 'animateTransform',
        'SVGAnimationElement': 'animation',
        'SVGCircleElement': 'circle',
        'SVGClipPathElement': 'clipPath',
        'SVGCursorElement': 'cursor',
        'SVGDefsElement': 'defs',
        'SVGDescElement': 'desc',
        'SVGEllipseElement': 'ellipse',
        'SVGFEBlendElement': 'feBlend',
        'SVGFEColorMatrixElement': 'feColorMatrix',
        'SVGFEComponentTransferElement': 'feComponentTransfer',
        'SVGFEConvolveMatrixElement': 'feConvolveMatrix',
        'SVGFEDiffuseLightingElement': 'feDiffuseLighting',
        'SVGFEDisplacementMapElement': 'feDisplacementMap',
        'SVGFEDistantLightElement': 'feDistantLight',
        'SVGFEFloodElement': 'feFlood',
        'SVGFEFuncAElement': 'feFuncA',
        'SVGFEFuncBElement': 'feFuncB',
        'SVGFEFuncGElement': 'feFuncG',
        'SVGFEFuncRElement': 'feFuncR',
        'SVGFEGaussianBlurElement': 'feGaussianBlur',
        'SVGFEImageElement': 'feImage',
        'SVGFEMergeElement': 'feMerge',
        'SVGFEMergeNodeElement': 'feMergeNode',
        'SVGFEMorphology': 'feMorphology',
        'SVGFEOffsetElement': 'feOffset',
        'SVGFEPointLightElement': 'fePointLight',
        'SVGFESpecularLightingElement': 'feSpecularLighting',
        'SVGFESpotLightElement': 'feSpotLight',
        'SVGFETileElement': 'feTile',
        'SVGFETurbulenceElement': 'feTurbulence',
        'SVGFilterElement': 'filter',
        'SVGForeignObjectElement': 'foreignObject',
        'SVGGlyphElement': 'glyph',
        'SVGGElement': 'g',
        'SVGHKernElement': 'hkern',
        'SVGImageElement': 'image',
        'SVGLinearGradientElement': 'linearGradient',
        'SVGLineElement': 'line',
        'SVGMarkerElement': 'marker',
        'SVGMaskElement': 'mask',
        'SVGMPathElement': 'mpath',
        'SVGPathElement': 'path',
        'SVGPatternElement': 'pattern',
        'SVGPolygonElement': 'polygon',
        'SVGPolylineElement': 'polyline',
        'SVGRadialGradientElement': 'radialGradient',
        'SVGRectElement': 'rect',
        'SVGScriptElement': 'script',
        'SVGSetElement': 'set',
        'SVGStopElement': 'stop',
        'SVGStyleElement': 'style',
        'SVGSwitchElement': 'switch',
        'SVGSymbolElement': 'symbol',
        'SVGTextElement': 'text',
        'SVGTitleElement': 'title',
        'SVGTRefElement': 'tref',
        'SVGTSpanElement': 'tspan',
        'SVGUseElement': 'use',
        'SVGViewElement': 'view',
        'SVGVKernElement': 'vkern',
    })

_element_constructors = {
    'html': _html_element_constructors,
    'indexed_db': {},
    'svg': _svg_element_constructors,
    'typed_data': {},
    'web_audio': {},
    'web_gl': {},
    'web_sql': {},
}

_factory_ctr_strings = {
    'html': {
        'provider_name': 'document',
        'constructor_name': 'createElement'
    },
    'indexed_db': {
        'provider_name': 'document',
        'constructor_name': 'createElement'
    },
    'svg': {
        'provider_name': '_SvgElementFactoryProvider',
        'constructor_name': 'createSvgElement_tag',
    },
    'typed_data': {
        'provider_name': 'document',
        'constructor_name': 'createElement'
    },
    'web_audio': {
        'provider_name': 'document',
        'constructor_name': 'createElement'
    },
    'web_gl': {
        'provider_name': 'document',
        'constructor_name': 'createElement'
    },
    'web_sql': {
        'provider_name': 'document',
        'constructor_name': 'createElement'
    },
}


def ElementConstructorInfos(typename,
                            element_constructors,
                            factory_provider_name='_Elements'):
    """Returns list of ElementConstructorInfos about the convenience constructors
  for an Element or SvgElement."""
    # TODO(sra): Handle multiple and named constructors.
    if typename not in element_constructors:
        return []
    infos = element_constructors[typename]
    if isinstance(infos, str):
        infos = ElementConstructorInfo(
            tag=infos, factory_provider_name=factory_provider_name)
    if not isinstance(infos, list):
        infos = [infos]
    return infos


# ------------------------------------------------------------------------------
def SvgSupportStr(tagName):
    return 'Svg%s' % ElemSupportStr(tagName)


def ElemSupportStr(tagName):
    return "Element.isTagSupported('%s')" % tagName


_js_support_checks_basic_element_with_constructors = [
    'HTMLContentElement',
    'HTMLDataListElement',
    'HTMLDetailsElement',
    'HTMLEmbedElement',
    'HTMLMeterElement',
    'HTMLObjectElement',
    'HTMLOutputElement',
    'HTMLProgressElement',
    'HTMLTemplateElement',
    'HTMLTrackElement',
]

_js_support_checks_additional_element = [
    # IE creates keygen as Block elements
    'HTMLKeygenElement',
    'SVGAltGlyphElement',
    'SVGAnimateElement',
    'SVGAnimateMotionElement',
    'SVGAnimateTransformElement',
    'SVGCursorElement',
    'SVGFEBlendElement',
    'SVGFEColorMatrixElement',
    'SVGFEComponentTransferElement',
    'SVGFEConvolveMatrixElement',
    'SVGFEDiffuseLightingElement',
    'SVGFEDisplacementMapElement',
    'SVGFEDistantLightElement',
    'SVGFEFloodElement',
    'SVGFEFuncAElement',
    'SVGFEFuncBElement',
    'SVGFEFuncGElement',
    'SVGFEFuncRElement',
    'SVGFEGaussianBlurElement',
    'SVGFEImageElement',
    'SVGFEMergeElement',
    'SVGFEMergeNodeElement',
    'SVGFEMorphology',
    'SVGFEOffsetElement',
    'SVGFEPointLightElement',
    'SVGFESpecularLightingElement',
    'SVGFESpotLightElement',
    'SVGFETileElement',
    'SVGFETurbulenceElement',
    'SVGFilterElement',
    'SVGForeignObjectElement',
    'SVGSetElement',
]

js_support_checks = dict(
    list({
        'Animation':
        "JS('bool', '!!(document.body.animate)')",
        'AudioContext':
        "JS('bool', '!!(window.AudioContext ||"
        " window.webkitAudioContext)')",
        'Crypto':
        "JS('bool', '!!(window.crypto && window.crypto.getRandomValues)')",
        'Database':
        "JS('bool', '!!(window.openDatabase)')",
        'DOMPoint':
        "JS('bool', '!!(window.DOMPoint) || !!(window.WebKitPoint)')",
        'ApplicationCache':
        "JS('bool', '!!(window.applicationCache)')",
        'DOMFileSystem':
        "JS('bool', '!!(window.webkitRequestFileSystem)')",
        'FormData':
        "JS('bool', '!!(window.FormData)')",
        'HashChangeEvent':
        "Device.isEventTypeSupported('HashChangeEvent')",
        'HTMLShadowElement':
        ElemSupportStr('shadow'),
        'HTMLTemplateElement':
        ElemSupportStr('template'),
        'MediaStreamEvent':
        "Device.isEventTypeSupported('MediaStreamEvent')",
        'MediaStreamTrackEvent':
        "Device.isEventTypeSupported('MediaStreamTrackEvent')",
        'MediaSource':
        "JS('bool', '!!(window.MediaSource)')",
        'Notification':
        "JS('bool', '!!(window.Notification)')",
        'Performance':
        "JS('bool', '!!(window.performance)')",
        'SpeechRecognition':
        "JS('bool', '!!(window.SpeechRecognition || "
        "window.webkitSpeechRecognition)')",
        'SVGExternalResourcesRequired':
        ('supported(SvgElement element)',
         "JS('bool', '#.externalResourcesRequired !== undefined && "
         "#.externalResourcesRequired.animVal !== undefined', "
         "element, element)"),
        'SVGLangSpace':
        ('supported(SvgElement element)',
         "JS('bool', '#.xmlspace !== undefined && #.xmllang !== undefined', "
         "element, element)"),
        'TouchList':
        "JS('bool', '!!document.createTouchList')",
        'WebGLRenderingContext':
        "JS('bool', '!!(window.WebGLRenderingContext)')",
        'WebSocket':
        "JS('bool', 'typeof window.WebSocket != \"undefined\"')",
        'Worker':
        "JS('bool', '(typeof window.Worker != \"undefined\")')",
        'XSLTProcessor':
        "JS('bool', '!!(window.XSLTProcessor)')",
    }.items()) + list(
        dict((key,
              SvgSupportStr(_svg_element_constructors[key]) if key.startswith(
                  'SVG') else ElemSupportStr(_html_element_constructors[key]))
             for key in _js_support_checks_basic_element_with_constructors +
             _js_support_checks_additional_element).items()))

# JavaScript element class names of elements for which createElement does not
# always return exactly the right element, either because it might not be
# supported, or some browser does something weird.
_js_unreliable_element_factories = set(
    _js_support_checks_basic_element_with_constructors +
    _js_support_checks_additional_element + [
        'HTMLEmbedElement',
        'HTMLObjectElement',
        'HTMLShadowElement',
        'HTMLTemplateElement',
    ])

# ------------------------------------------------------------------------------


class HtmlDartInterfaceGenerator(object):
    """Generates dart interface and implementation for the DOM IDL interface."""

    def __init__(self, options, library_emitter, event_generator,
                 prototype_event_generator, interface, backend):
        self._renamer = options.renamer
        self._database = options.database
        self._template_loader = options.templates
        self._type_registry = options.type_registry
        self._options = options
        self._library_emitter = library_emitter
        self._event_generator = event_generator
        self._prototype_event_generator = prototype_event_generator
        self._interface = interface
        self._backend = backend
        self._interface_type_info = self._type_registry.TypeInfo(
            self._interface.id)
        self._library_name = self._renamer.GetLibraryName(self._interface)
        self._metadata = options.metadata

    def Generate(self):
        if IsCustomType(self._interface.id):
            pass
        elif 'Callback' in self._interface.ext_attrs:
            if len(GetCallbackHandlers(self._interface)) > 0:
                self.GenerateCallback()
            elif generateCallbackInterface(self._interface.id):
                self.GenerateInterface()
            else:
                return
        else:
            self.GenerateInterface()

    def GenerateCallback(self):
        """Generates a typedef for the callback interface."""
        typedef_name = self._renamer.RenameInterface(self._interface)
        if not typedef_name:
            return

        info = GetCallbackInfo(self._interface)
        code = self._library_emitter.FileEmitter(self._interface.id,
                                                 self._library_name)
        code.Emit(self._template_loader.Load('callback.darttemplate'))

        annotations = self._metadata.GetFormattedMetadata(
            self._library_name, self._interface)

        params = info.ParametersAsDeclaration(self._DartType)

        types = params.split()
        if len(types) > 0:
            mapType = types[0] in _callback_list_generics_mapping
            if mapType is True:
                types[0] = 'List'
                params = " ".join(types)

        code.Emit(
            '$(ANNOTATIONS)typedef void $NAME($PARAMS);\n',
            ANNOTATIONS=annotations,
            NAME=typedef_name,
            PARAMS=params)
        self._backend.GenerateCallback(info)

    def GenerateInterface(self):
        interface_name = self._interface_type_info.interface_name()

        implementation_name = self._interface_type_info.implementation_name()
        self._library_emitter.AddTypeEntry(
            self._library_name, self._interface.id, implementation_name)

        factory_provider = None
        if interface_name in interface_factories:
            factory_provider = interface_factories[interface_name]
        factory_constructor_name = None

        constructors = []
        if interface_name in _static_classes:
            constructor_info = None
        else:
            constructor_info = AnalyzeConstructor(self._interface)
        if constructor_info:
            constructors.append(constructor_info)
            # TODO(antonm): consider removing it later.
            factory_provider = interface_name

        # HTML Elements and SVG Elements have convenience constructors.
        infos = ElementConstructorInfos(
            self._interface.id,
            _element_constructors[self._library_name],
            factory_provider_name=_factory_ctr_strings[self._library_name]
            ['provider_name'])

        if infos:
            factory_constructor_name = _factory_ctr_strings[
                self._library_name]['constructor_name']

        for info in infos:
            constructors.append(info.ConstructorInfo(self._interface.id))
            if factory_provider and factory_provider != info.factory_provider_name:
                _logger.warn('Conflicting factory provider names: %s != %s' %
                             (factory_provider, info.factory_provider_name))
            factory_provider = info.factory_provider_name

        implementation_emitter = self._ImplementationEmitter()

        base_type_info = None
        if self._interface.parents:
            supertype = self._interface.parents[0].type.id
            if not IsDartCollectionType(supertype) and not IsPureInterface(
                    supertype, self._database):
                base_type_info = self._type_registry.TypeInfo(supertype)

        if base_type_info:
            base_class = base_type_info.implementation_name()
        else:
            base_class = self._backend.RootClassName()

        implements = self._backend.AdditionalImplementedInterfaces()
        for parent in self._interface.parents:
            parent_type_info = self._type_registry.TypeInfo(parent.type.id)
            if parent_type_info.interface_name() != base_class and \
                parent_type_info != base_type_info:
                implements.append(parent_type_info.interface_name())

        secure_base_name = self._backend.SecureBaseName(interface_name)
        if secure_base_name:
            implements.append(secure_base_name)

        implements_str = ''
        if implements:
            # Get rid of duplicates using OrderedDict.
            implements = list(OrderedDict([(i, None) for i in implements]))
            implements_str = ' implements ' + ', '.join(implements)

        mixins = self._backend.Mixins()

        mixins_str = ''
        if mixins:
            mixins_str = ' with ' + ', '.join(mixins)
            if not base_class:
                base_class = 'JavaScriptObject'
            elif (base_class == 'NativeFieldWrapperClass2' and
                  self._options.dart_js_interop and
                  not (isinstance(self._backend, Dart2JSBackend))):
                base_class = 'DartHtmlDomObject'

        annotations = self._metadata.GetFormattedMetadata(
            self._library_name, self._interface, None, '')

        class_modifiers = ''
        if (self._renamer.ShouldSuppressInterface(self._interface) or
                IsPureInterface(self._interface.id, self._database)):
            # XMLHttpRequestProgressEvent can't be abstract we need to instantiate
            # for JsInterop.
            if (not (isinstance(self._backend, Dart2JSBackend)) and
                (self._interface.id == 'XMLHttpRequestProgressEvent' or
                 self._interface.id == 'DOMStringMap')):
                # Suppress abstract for XMLHttpRequestProgressEvent and DOMStringMap
                # for Dartium.  Need to be able to instantiate the class; can't be abstract.
                class_modifiers = ''
            else:
                # For Dartium w/ JsInterop these suppressed interfaces are needed to
                # instantiate the internal classes.
                if (self._renamer.ShouldSuppressInterface(self._interface) and
                        not (isinstance(self._backend, Dart2JSBackend)) and
                        self._options.dart_js_interop):
                    class_modifiers = ''
                else:
                    class_modifiers = 'abstract '

        native_spec = ''
        if not IsPureInterface(self._interface.id, self._database):
            native_spec = self._backend.NativeSpec()

        class_name = self._interface_type_info.implementation_name()

        js_interop_wrapper = '''

  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  {0}.internal_() : super.internal_();

'''.format(class_name)
        if base_class == 'NativeFieldWrapperClass2' or base_class == 'DartHtmlDomObject':
            js_interop_wrapper = '''

  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  {0}.internal_() {{ }}
'''.format(class_name)
            # Change to use the synthesized class so we can construct with a mixin
            # classes prefixed with name of NativeFieldWrapperClass2 don't have a
            # default constructor so classes with mixins can't be new'd.
            if (self._options.templates._conditions['DARTIUM'] and
                    self._options.dart_js_interop and
                (self._interface.id == 'NamedNodeMap' or
                 self._interface.id == 'CSSStyleDeclaration')):
                base_class = 'DartHtmlDomObject'

        maplikeKeyType = ''
        maplikeValueType = ''
        if self._interface.isMaplike:
            maplikeKeyType = self._type_registry.\
                _TypeInfo(self._interface.maplike_key_value[0].id).dart_type()
            maplikeValueType = 'dynamic'
            mixins_str = " with MapMixin<%s, %s>" % (maplikeKeyType,
                                                     maplikeValueType)

        implementation_members_emitter = implementation_emitter.Emit(
            self._backend.ImplementationTemplate(),
            LIBRARYNAME='dart.dom.%s' % self._library_name,
            ANNOTATIONS=annotations,
            CLASS_MODIFIERS=class_modifiers,
            CLASSNAME=class_name,
            EXTENDS=' extends %s' % base_class if base_class else '',
            IMPLEMENTS=implements_str,
            MIXINS=mixins_str,
            DOMNAME=self._interface.doc_js_name,
            NATIVESPEC=native_spec,
            KEYTYPE=maplikeKeyType,
            VALUETYPE=maplikeValueType,
            NULLABLE='?',
            NULLSAFECAST=True,
            NULLASSERT='!')
        if self._interface.doc_js_name is 'RadioNodeList':
            print(self._backend.ImplementationTemplate())
            print(implementation_members_emitter)
        stream_getter_signatures_emitter = None
        element_stream_getters_emitter = None
        class_members_emitter = None
        if type(implementation_members_emitter) == tuple:
            # We add event stream getters for both Element and ElementList, so in
            # impl_Element.darttemplate, we have two additional "holes" for emitters
            # to fill in, with small variations. These store these specialized
            # emitters.
            if (len(implementation_members_emitter) == 3):
                stream_getter_signatures_emitter = \
                    implementation_members_emitter[0]
                element_stream_getters_emitter = implementation_members_emitter[
                    1]
                implementation_members_emitter = \
                    implementation_members_emitter[2]

            # We add special emitters for classes migrated to static type extensions
            elif (len(implementation_members_emitter) == 2):
                class_members_emitter = \
                    implementation_members_emitter[0]
                implementation_members_emitter = \
                    implementation_members_emitter[1]
        self._backend.StartInterface(implementation_members_emitter)
        self._backend.EmitHelpers(base_class, class_members_emitter)
        self._event_generator.EmitStreamProviders(
            self._interface, self._backend.CustomJSMembers(),
            implementation_members_emitter, self._library_name)
        self._prototype_event_generator.CollectStreamProviders(
            self._interface, self._backend.CustomJSMembers(),
            self._library_name)
        self._backend.AddConstructors(constructors, factory_provider,
                                      factory_constructor_name,
                                      class_members_emitter)

        isElement = False
        for parent in self._database.Hierarchy(self._interface):
            if parent.id == 'Element':
                isElement = True

        # Write out the JsInterop code.
        if (implementation_members_emitter and
                self._options.templates._conditions['DARTIUM'] and
                self._options.dart_js_interop and
                not IsPureInterface(self._interface.id, self._database)):
            implementation_members_emitter.Emit(js_interop_wrapper)

        if isElement and self._interface.id != 'Element':
            implementation_members_emitter.Emit(
                '  /**\n'
                '   * Constructor instantiated by the DOM when a custom element has been created.\n'
                '   *\n'
                '   * This can only be called by subclasses from their created constructor.\n'
                '   */\n'
                '  $CLASSNAME.created() : super.created();\n',
                CLASSNAME=self._interface_type_info.implementation_name())

        self._backend.EmitSupportCheck()

        merged_interface = self._interface_type_info.merged_interface()
        if merged_interface:
            self._backend.AddMembers(
                self._database.GetInterface(merged_interface),
                not self._backend.ImplementsMergedMembers())

        self._backend.AddMembers(self._interface, False,
                                 self._options.dart_js_interop)
        self._backend.AddSecondaryMembers(self._interface)
        self._event_generator.EmitStreamGetters(
            self._interface, [], implementation_members_emitter,
            self._library_name, stream_getter_signatures_emitter,
            element_stream_getters_emitter)
        self._prototype_event_generator.CollectStreamGetters(
            self._interface, [], self._library_name)
        self._backend.FinishInterface()

    def _ImplementationEmitter(self):
        basename = self._interface_type_info.implementation_name()
        if (self._interface_type_info.merged_into() and
                self._backend.ImplementsMergedMembers()):
            # Merged members are implemented in target interface implementation.
            return emitter.Emitter()
        return self._library_emitter.FileEmitter(basename, self._library_name)

    def _DartType(self, type_name):
        return self._type_registry.DartType(type_name)


# ------------------------------------------------------------------------------
''' TODO(terry): Current idl_parser (Chrome) doesn't keep the Promise type e.g.,
                 Promise<T> in the AST so there is no way to pull this out.  Need
                 to investigate getting the Chrome folks to fix.  However, they
                 don't use this in the C++ code generation and don't have a need
                 for this feature.  For now I have a table that maps to the
                 parameterized Promise type.
'''
promise_attributes = monitored.Dict(
    'systemhtml.promise_attr_type', {
        "Animation.finished": {
            "type": "Animation",
            "creates": "Animation"
        },
        "Animation.ready": {
            "type": "Animation",
            "creates": "Animation"
        },
        "BeforeInstallPromptEvent.userChoice": {
            "type": "dictionary"
        },
        "FontFace.loaded": {
            "type": "FontFace",
            "creates": "FontFace"
        },
        "FontFaceSet.ready": {
            "type": "FontFaceSet",
            "creates": "FontFaceSet"
        },
        "MediaKeySession.closed": {
            "type": "void"
        },
        "PresentationReceiver.connectionList": {
            "type": "PresentationConnectionList",
            "creates": "PresentationConnectionList"
        },
        "ServiceWorkerContainer.ready": {
            "type": "ServiceWorkerRegistration",
            "creates": "ServiceWorkerRegistration"
        },
    })

promise_operations = monitored.Dict(
    'systemhtml.promise_oper_type', {
        "Clipboard.read": {
            "type": "DataTransfer",
            "creates": "DataTransfer"
        },
        "Clipboard.readText": {
            "type": "String"
        },
        "FontFace.load": {
            "type": "FontFace",
            "creates": "FontFace"
        },
        "FontFaceSet.load": {
            "type": "List<dynamic>"
        },
        "OffscreenCanvas.load": {
            "type": "Blob",
            "creates": "Blob"
        },
        "BackgroundFetchManager.fetch": {
            "type": "BackgroundFetchRegistration",
            "creates": "BackgroundFetchRegistration"
        },
        "BackgroundFetchManager.get": {
            "type": "BackgroundFetchRegistration",
            "creates": "BackgroundFetchRegistration"
        },
        "BackgroundFetchManager.getIds": {
            "type": "List<dynamic>"
        },
        "BackgroundFetchRegistration.abort": {
            "type": "bool"
        },
        "SyncManager.getTags": {
            "type": "List<dynamic>"
        },
        "BudgetService.getCost": {
            "type": "double"
        },
        "BudgetService.getBudget": {
            "type": "BudgetState",
            "creates": "BudgetState"
        },
        "BudgetService.reserve": {
            "type": "bool"
        },
        "Body.blob": {
            "type": "Blob",
            "creates": "Blob"
        },
        "Body.formData": {
            "type": "FormData",
            "creates": "FormData"
        },
        "Body.text": {
            "type": "String"
        },
        "ImageCapture.getPhotoCapabilities": {
            "type": "PhotoCapabilities",
            "creates": "PhotoCapabilities"
        },
        "ImageCapture.getPhotoSettings": {
            "type": "dictionary"
        },
        "ImageCapture.takePhoto": {
            "type": "Blob",
            "creates": "Blob"
        },
        "ImageCapture.grabFrame": {
            "type": "ImageBitmap",
            "creates": "ImageBitmap"
        },
        "Navigator.getInstalledRelatedApps": {
            "type": "RelatedApplication",
            "creates": "RelatedApplication"
        },
        "OffscreenCanvas.convertToBlob": {
            "type": "Blob",
            "creates": "Blob"
        },
        "MediaCapabilities.decodingInfo": {
            "type": "MediaCapabilitiesInfo",
            "creates": "MediaCapabilitiesInfo"
        },
        "MediaCapabilities.encodingInfo": {
            "type": "MediaCapabilitiesInfo",
            "creates": "MediaCapabilitiesInfo"
        },
        "MediaDevices.enumerateDevices": {
            "type": "List<dynamic>"
        },
        "MediaDevices.getUserMedia": {
            "type": "MediaStream",
            "creates": "MediaStream"
        },
        "ServiceWorkerRegistration.getNotifications": {
            "type": "List<dynamic>"
        },
        "PaymentInstruments.delete": {
            "type": "bool"
        },
        "PaymentInstruments.get": {
            "type": "dictionary"
        },
        "PaymentInstruments.keys": {
            "type": "List<dynamic>"
        },
        "PaymentInstrumentshas.": {
            "type": "bool"
        },
        "PaymentRequest.show": {
            "type": "PaymentResponse",
            "creates": "PaymentResponse"
        },
        "PaymentRequest.canMakePayment": {
            "type": "bool"
        },
        "PaymentRequestEvent.openWindow": {
            "type": "WindowClient",
            "creates": "WindowClient"
        },
        "RTCPeerConnection.createOffer": {
            "type": "RtcSessionDescription",
            "creates": "RtcSessionDescription"
        },
        "RTCPeerConnection.createAnswer": {
            "type": "RtcSessionDescription",
            "creates": "RtcSessionDescription"
        },
        "RTCPeerConnection.getStats": {
            "type": "RtcStatsReport",
            "maplike": "RTCStatsReport",
            "creates": "RtcStatsReport"
        },
        "RTCPeerConnection.generateCertificate": {
            "type": "RtcCertificate",
            "creates": "RtcCertificate"
        },
        "Permissions.query": {
            "type": "PermissionStatus",
            "creates": "PermissionStatus"
        },
        "Permissions.request": {
            "type": "PermissionStatus",
            "creates": "PermissionStatus"
        },
        "Permissions.revoke": {
            "type": "PermissionStatus",
            "creates": "PermissionStatus"
        },
        "Permissions.requestAll": {
            "type": "PermissionStatus",
            "creates": "PermissionStatus"
        },
        "PresentationRequest.start": {
            "type": "PresentationConnection",
            "creates": "PresentationConnection"
        },
        "PresentationRequest.reconnect": {
            "type": "PresentationConnection",
            "creates": "PresentationConnection"
        },
        "PresentationRequest.getAvailability": {
            "type": "PresentationAvailability",
            "creates": "PresentationAvailability"
        },
        "PushManager.subscribe": {
            "type": "PushSubscription",
            "creates": "PushSubscription"
        },
        "PushManager.getSubscription": {
            "type": "PushSubscription",
            "creates": "PushSubscription"
        },
        "PushSubscription.unsubscribe": {
            "type": "bool"
        },
        "StorageManager.persisted": {
            "type": "bool"
        },
        "StorageManager.persist": {
            "type": "bool"
        },
        "StorageManager.estimate": {
            "type": "dictionary"
        },
        "RemotePlayback.watchAvailability": {
            "type": "int"
        },
        "Clients.matchAll": {
            "type": "List<dynamic>"
        },
        "Clients.openWindow": {
            "type": "WindowClient",
            "creates": "WindowClient"
        },
        "NavigationPreloadManager.getState": {
            "type": "dictionary"
        },
        "ServiceWorkerContainer.register": {
            "type": "ServiceWorkerRegistration",
            "creates": "ServiceWorkerRegistration"
        },
        "ServiceWorkerContainer.getRegistration": {
            "type": "ServiceWorkerRegistration",
            "creates": "ServiceWorkerRegistration"
        },
        "ServiceWorkerContainer.getRegistrations": {
            "type": "List<dynamic>"
        },
        "ServiceWorkerGlobalScope.fetch": {
            "creates": "_Response"
        },
        "ServiceWorkerRegistration.unregister": {
            "type": "bool"
        },
        "WindowClient.focus": {
            "type": "WindowClient",
            "creates": "WindowClient"
        },
        "WindowClient.navigate": {
            "type": "WindowClient",
            "creates": "WindowClient"
        },
        "BarcodeDetector.detect": {
            "type": "List<dynamic>"
        },
        "FaceDetector.detect": {
            "type": "List<dynamic>"
        },
        "TextDetector.detect": {
            "type": "List<dynamic>"
        },
        "BaseAudioContext.decodeAudioData": {
            "type": "AudioBuffer",
            "creates": "AudioBuffer"
        },
        "OfflineAudioContext.startRendering": {
            "type": "AudioBuffer",
            "creates": "AudioBuffer"
        },
        "CacheStorage.match": {
            "creates": "_Response"
        },
        "CacheStorage.open": {
            "creates": "_Cache"
        },
        "CredentialsContainer.create": {
            "creates": "Credential"
        },
        "CredentialsContainer.get": {
            "creates": "Credential"
        },
        "CredentialsContainer.store": {
            "creates": "Credential"
        },
        "FetchEvent.preloadResponse": {
            "creates": "_Response"
        },
        "MediaKeySystemAccess.createMediaKeys": {
            "creates": "MediaKeys"
        },
        "Navigator.getVRDisplays": {
            "creates": "VRDisplay"
        },
        "Navigator.requestMediaKeySystemAccess": {
            "creates": "MediaKeySystemAccess"
        },
        "VRSession.requestFrameOfReference": {
            "creates": "VRFrameOfReference"
        },
        "Window.fetch": {
            "creates": "_Response"
        },
        "WorkerGlobalScope.fetch": {
            "creates": "_Response"
        },
    })

promise_generateCall = monitored.Set('systemhtml.promise_generateCall', [
    "Navigator.requestKeyboardLock",
])


def _IsPromiseOperationGenerateCall(interface_operation):
    return interface_operation in promise_generateCall


def _GetPromiseOperationType(interface_operation):
    if interface_operation in promise_operations:
        return promise_operations[interface_operation]
    return None


def _GetPromiseAttributeType(interface_operation):
    if interface_operation in promise_attributes:
        return promise_attributes[interface_operation]
    return None

# Compatibility is used to help determine attribute nullability i.e. if the
# attribute is not compatible across all browsers, the getter/setter is marked
# as nullable. There are cases where the attribute belongs to a class that
# implements an interface whose methods are not in the IDL, however.
# Since attribute getters need to match their overridden method declaration,
# there are conflicts when the overriding method is not compatible, the
# overriding method is, and they're not already nullable. This dict marks the
# attributes where there is a conflict that cannot be resolved with code
# generation or within src/template files.
compat_conflicts = {
    # These interfaces implement Rectangle, which is a Dart interface. In order
    # to match the interface of Rectangle, they must be marked as non-nullable.
    'DOMRectReadOnly': ['bottom', 'height', 'left', 'right', 'top', 'width'],
    'DOMRect': ['height', 'width'],
}


class Dart2JSBackend(HtmlDartGenerator):
    """Generates a dart2js class for the dart:html library from a DOM IDL
  interface.
  """

    def __init__(self,
                 interface,
                 options,
                 logging_level=logging.WARNING,
                 generate_static_extensions=False):
        super(Dart2JSBackend, self).__init__(interface, options, False, _logger)

        self._generate_static_extensions = generate_static_extensions
        self._database = options.database
        self._template_loader = options.templates
        self._type_registry = options.type_registry
        self._renamer = options.renamer
        self._metadata = options.metadata
        self._interface_type_info = self._type_registry.TypeInfo(
            self._interface.id)
        self._interface_name = self._interface_type_info.interface_name()
        self._current_secondary_parent = None
        self._library_name = self._renamer.GetLibraryName(self._interface)
        # Global constants for all WebGLRenderingContextBase, WebGL2RenderingContextBase, WebGLDrawBuffers
        self._gl_constants = []
        _logger.setLevel(logging_level)

    def ImplementsMergedMembers(self):
        return True

    def GenerateCallback(self, info):
        pass

    def AdditionalImplementedInterfaces(self):
        implements = super(Dart2JSBackend,
                           self).AdditionalImplementedInterfaces()
        if self._interface_type_info.list_item_type() and self.HasIndexedGetter(
        ):
            item_type = self._type_registry.TypeInfo(
                self._interface_type_info.list_item_type()).dart_type()
            if self._interface_type_info.list_item_type_nullable():
                item_type += '?'
            implements.append('JavaScriptIndexingBehavior<%s>' % item_type)
        return implements

    def NativeSpec(self):
        native_spec = MakeNativeSpec(self._interface.javascript_binding_name)
        return '@Native("%s")\n' % native_spec

    def ImplementationTemplate(self):
        template_file = ('impl_%s.darttemplate' % self._interface.doc_js_name)
        template_file_content = self._template_loader.TryLoad(template_file)
        if not (template_file_content):
            if self._interface.isMaplike and self._interface.isMaplike_ro:
                # TODO(terry): There are no mutable maplikes yet.
                template_file_content = self._template_loader.Load(
                    'dart2js_maplike_impl.darttemplate')

            else:
                if CanUseStaticExtensions(self._interface_name,
                                          self._generate_static_extensions):
                    template_file_content = self._template_loader.Load(
                        'dart2js_static_extension_impl.darttemplate')
                else:
                    template_file_content = self._template_loader.Load(
                        'dart2js_impl.darttemplate')
        return template_file_content

    def StartInterface(self, members_emitter):
        self._members_emitter = members_emitter

    def FinishInterface(self):
        pass

    def HasSupportCheck(self):
        return self._interface.doc_js_name in js_support_checks

    def GetSupportCheck(self):
        """Return a tuple of the support check function signature and the support
    test itself. If no parameters are supplied, we assume the default."""
        if self._interface.doc_js_name in _js_support_checks_additional_element:
            if self._interface.doc_js_name in _svg_element_constructors:
                lib_prefix = 'Svg'
                constructors = _svg_element_constructors
            else:
                lib_prefix = ''
                constructors = _html_element_constructors
            return (js_support_checks.get(self._interface.doc_js_name) +
                    " && (new %sElement.tag('%s') is %s)" %
                    (lib_prefix, constructors[self._interface.doc_js_name],
                     self._renamer.RenameInterface(self._interface)))
        return js_support_checks.get(self._interface.doc_js_name)

    def GenerateCustomFactory(self, constructor_info):
        # Custom factory will be taken from the template.
        return self._interface.doc_js_name in _js_custom_constructors

    def MakeFactoryCall(self, factory, method, arguments, constructor_info):
        if factory is 'document' and method is 'createElement' \
            and not ',' in arguments \
            and not self._HasUnreliableFactoryConstructor():
            return emitter.Format(
                "JS$CAST("
                "'returns:$INTERFACE_NAME;creates:$INTERFACE_NAME;new:true',"
                " '#.$METHOD(#)', $FACTORY, $ARGUMENTS)",
                CAST='<' + self._interface_type_info.interface_name() + '>',
                INTERFACE_NAME=self._interface_type_info.interface_name(),
                FACTORY=factory,
                METHOD=method,
                ARGUMENTS=arguments)
        return emitter.Format('$FACTORY.$METHOD($ARGUMENTS)$CAST',
                              FACTORY=factory,
                              METHOD=method,
                              ARGUMENTS=arguments,
                              CAST=' as ' +
                              self._interface_type_info.interface_name())

    def _HasUnreliableFactoryConstructor(self):
        return self._interface.doc_js_name in _js_unreliable_element_factories

    def IsConstructorArgumentOptional(self, argument):
        return argument.optional

    def EmitStaticFactoryOverload(self, constructor_info, name, arguments,
                                  emitter):
        if self._interface_type_info.has_generated_interface():
            # Use dart_type name, we're generating.
            interface_name = self._interface_type_info.interface_name()
        else:
            # Use the implementation name the interface is suppressed.
            interface_name = self._interface_type_info.implementation_name()

        index = len(arguments)
        arguments = constructor_info.ParametersAsArgumentList(index)
        if arguments:
            arguments = ', ' + arguments
        (emitter if (emitter != None) else self._members_emitter).Emit(
            "  static $INTERFACE_NAME $NAME($PARAMETERS) => "
            "JS('$INTERFACE_NAME', 'new $CTOR_NAME($PLACEHOLDERS)'$ARGUMENTS);\n",
            INTERFACE_NAME=interface_name,
            NAME=name,
            # TODO(antonm): add types to parameters.
            PARAMETERS=constructor_info.ParametersAsArgumentList(index),
            CTOR_NAME=constructor_info.name or self._interface.doc_js_name,
            PLACEHOLDERS=','.join(['#'] * index),
            ARGUMENTS=arguments)

    def SecondaryContext(self, interface):
        if interface is not self._current_secondary_parent:
            self._current_secondary_parent = interface
            self._members_emitter.Emit(
                '\n  // From $WHERE\n', WHERE=interface.id)

    def HasIndexedGetter(self):
        ext_attrs = self._interface.ext_attrs
        has_indexed_getter = 'CustomIndexedGetter' in ext_attrs
        for operation in self._interface.operations:
            if operation.id == 'item' and 'getter' in operation.specials \
                and not self._OperationRequiresConversions(operation):
                has_indexed_getter = True
                break
            if operation.id == '__getter__' and 'getter' in operation.specials \
                and not self._OperationRequiresConversions(operation):
                has_indexed_getter = True
                break
        return has_indexed_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; }
        #

        has_indexed_getter = self.HasIndexedGetter()

        indexed_getter = False
        indexed_getter_nullable = nullable
        if has_indexed_getter:
            indexed_getter = ('JS("%s%s", "#[#]", this, index)' %
                              (self.SecureOutputType(element_type),
                               "|Null" if nullable else ""))
        else:
            for op in self._interface.operations:
                if op.id == 'getItem':
                    indexed_getter = 'this.getItem(index)'
                    indexed_getter_nullable = OperationTypeIsNullable(op)
                    break
            if not indexed_getter:
                for op in self._interface.operations:
                    if op.id == 'item':
                        indexed_getter = 'this.item(index)'
                        indexed_getter_nullable = OperationTypeIsNullable(op)
                        break

        if indexed_getter:
            self._members_emitter.Emit(
                '\n'
                '  $TYPE operator[](int index) {\n'
                '    if (JS("bool", "# >>> 0 !== # || # >= #", index,\n'
                '        index, index, length))\n'
                '      throw new IndexError.withLength(index, length, indexable: this);\n'
                '    return $INDEXED_GETTER$NULLASSERT;\n'
                '  }',
                INDEXED_GETTER=indexed_getter,
                TYPE=self.SecureOutputType(element_type,
                                           is_dart_type=False,
                                           can_narrow_type=True,
                                           nullable=nullable),
                # If the type of the operation is not nullable but the getter
                # is, we must assert non-null.
                NULLASSERT='!' if not nullable and indexed_getter_nullable \
                    else '')

        if 'CustomIndexedSetter' in self._interface.ext_attrs:
            self._members_emitter.Emit(
                '\n'
                '  void operator[]=(int index, $TYPE$NULLABLE value) {'
                ' JS("void", "#[#] = #", this, index, value); }',
                TYPE=self._NarrowInputType(element_type),
                NULLABLE='?' if nullable else '')
        else:
            theType = self._NarrowInputType(element_type)
            if theType == 'DomRectList':
                theType = ''

            self._members_emitter.Emit(
                '\n'
                '  void operator[]=(int index, $TYPE$NULLABLE value) {\n'
                '    throw new UnsupportedError("Cannot assign element of immutable List.");\n'
                '  }\n',
                TYPE=theType,
                NULLABLE='?' if nullable else '')

        self.EmitListMixin(self._DartType(element_type), nullable)

    def EmitAttribute(self, attribute, html_name, read_only):
        if self._HasCustomImplementation(attribute.id):
            return

        if IsPureInterface(self._interface.id, self._database):
            self._AddAttributeUsingProperties(attribute, html_name, read_only)
            return

        output_type = self.SecureOutputType(attribute.type.id,
                                            can_narrow_type=read_only,
                                            nullable=attribute.type.nullable)

        rename = self._RenamingAnnotation(attribute.id, html_name)
        metadata = self._Metadata(attribute.type.id, attribute.id, output_type,
            attribute.type.nullable)

        is_compat = self._mdn_reader.is_compatible(attribute)

        # If the attribute is shadowing, we can't generate a shadowing
        # getter or setter (Issue 1633).
        # TODO(sra): _FindShadowedAttribute does not take into account the html
        # renaming. We should be looking for another attribute that has the
        # same html_name. Two attributes with the same IDL name might not match
        # if one is renamed.
        # TODO(srujzs): Determine if logic behind shadowing is still true here
        # and below with the transition to natives.
        (super_attribute,
         super_attribute_interface) = self._FindShadowedAttribute(attribute)

        if super_attribute:
            if is_compat is None:
                # If there is no compatibility info on this attribute, we use
                # the parent attribute's compatibility info.
                is_compat = self._mdn_reader.is_compatible(super_attribute)
                self._mdn_reader.set_compatible(attribute, is_compat)
            if read_only or self._SafeToIgnoreShadowingMember(html_name):
                if attribute.type.id == super_attribute.type.id:
                    # Compatible attribute, use the superclass property.  This
                    # works because JavaScript will do its own dynamic dispatch.

                    # Nullability is determined by attribute compatibility.
                    nullable = not is_compat or attribute.type.nullable
                    self._members_emitter.Emit(
                        '\n'
                        '  // Use implementation from $SUPER.\n'
                        '  // $GET_TYPE get $NAME native;\n'
                        '  // void set $NAME($SET_TYPE value) native;\n',
                        SUPER=super_attribute_interface,
                        NAME=html_name,
                        GET_TYPE=self.SecureOutputType(attribute.type.id,
                            can_narrow_type=read_only,
                            nullable=nullable),
                        SET_TYPE=self.SecureOutputType(attribute.type.id,
                            can_narrow_type=read_only,
                            nullable=nullable or \
                                'TreatNullAs' in attribute.ext_attrs))
                    return
            self._members_emitter.Emit('\n  // Shadowing definition.')
            self._AddAttributeUsingProperties(attribute, html_name, read_only,
                rename, metadata)
            return

        # If the attribute is shadowed incompatibly in a subclass then we also
        # can't just generate it as a getter/setter. In particular, this happens
        # with DomMatrixReadOnly and its subclass DomMatrix. Force the
        # superclass to generate getters. Hardcoding the known problem classes
        # for now.
        # TODO(alanknight): Fix this more generally.
        if (self._interface.id == 'DOMMatrixReadOnly' or
                self._interface.id == 'DOMPointReadOnly' or
                self._interface.id == 'DOMRectReadOnly'):
            self._AddAttributeUsingProperties(attribute, html_name, read_only,
                rename, metadata)
            return

        # If the type has a conversion we need a getter or setter to contain the
        # conversion code.
        if (self._OutputConversion(attribute.type.id, attribute.id) or
                self._InputConversion(attribute.type.id, attribute.id)):
            self._AddAttributeUsingProperties(attribute, html_name, read_only,
                rename, metadata)
            return

        input_type = self._NarrowInputType(attribute.type.id)
        if attribute.type.nullable or not is_compat:
            input_type += '?'
        if not read_only:
            if attribute.type.id == 'Promise':
                _logger.warn('R/W member is a Promise: %s.%s' %
                             (self._interface.id, html_name))
            self._AddAttributeUsingProperties(attribute, html_name, read_only,
                                              rename, metadata)
        else:
            if attribute.type.id == 'Promise':
                lookupOp = "%s.%s" % (self._interface.id, html_name)
                promiseFound = _GetPromiseAttributeType(lookupOp)
                promiseType = 'Future'
                promiseCall = 'promiseToFuture'
                type_description = ''
                if promiseFound is not (None):
                    paramType = promiseFound.get('type')
                    if 'maplike' in promiseFound:
                        promiseCall = 'promiseToFuture<dynamic>'
                        promiseType = 'Future'
                    elif paramType == 'dictionary':
                        # It's a dictionary so return as a Map.
                        promiseCall = 'promiseToFutureAsMap'
                        output_conversion = self._OutputConversion("Dictionary",
                                                                   None)
                        nullability = '?' if output_conversion.nullable_output \
                            else ''
                        promiseType = 'Future<Map<String, dynamic>' + \
                            nullability + '>'
                    elif paramType:
                        promiseCall = 'promiseToFuture<%s>' % paramType
                        promiseType = 'Future<%s>' % paramType

                    if 'creates' in promiseFound:
                        createsType = promiseFound['creates']
                        type_description = 'creates:%s;' % createsType

                if attribute.type.nullable:
                    promiseType += '?'

                template = '\n  $RENAME$(ANNOTATIONS)$TYPE get $NAME => '\
                    '$PROMISE_CALL(JS("$TYPE_DESC", "#.$NAME", this));\n'

                self._members_emitter.Emit(
                    template,
                    RENAME=rename,
                    ANNOTATIONS=metadata,
                    TYPE=promiseType,
                    PROMISE_CALL=promiseCall,
                    TYPE_DESC=type_description,
                    NAME=html_name,)
            else:
                # Need to use a getter for list.length properties so we can
                # add a setter which throws an exception, satisfying List
                # API.
                if self._interface_type_info.list_item_type() and \
                    html_name == 'length':
                    template = (
                        '\n  $RENAME$(ANNOTATIONS)$TYPE get $NAME => ' +
                        'JS("$TYPE", "#.$NAME", this);\n')
                    self._members_emitter.Emit(
                        template,
                        RENAME=rename,
                        ANNOTATIONS=metadata,
                        NAME=html_name,
                        TYPE=input_type
                        if output_type == 'double' else output_type)
                else:
                    # Transform to native getters/setters.
                    # TODO(srujzs): Should the logic for types and doubles from
                    # above and before stay the same here?
                    self._AddAttributeUsingProperties(attribute, html_name,
                        read_only, rename, metadata)

    def _IsACompatibilityConflict(self, interface, attr):
        if interface in compat_conflicts and attr.id in compat_conflicts[
                interface]:
            is_compat = self._mdn_reader.is_compatible(attr)
            if is_compat or attr.type.nullable:
                # Only attributes that are not compatible and not nullable
                # belong in this list.
                raise ValueError(
                    interface + '.' + attr.id +
                    ' has no conflict between compatibility and nullability.')
            else:
                return True
        return False

    def _AddAttributeUsingProperties(self, attribute, html_name, read_only,
                                     rename=None, metadata=None):
        self._AddRenamingGetter(attribute, html_name, rename, metadata)
        if not read_only:
            # No metadata for setters.
            self._AddRenamingSetter(attribute, html_name, rename)

    def _AddRenamingGetter(self, attr, html_name, rename, metadata):
        conversion = self._OutputConversion(attr.type.id, attr.id)
        if conversion:
            return self._AddConvertingGetter(attr, html_name, conversion)
        # If the attribute is incompatible, it must be marked nullable.
        is_compat = self._mdn_reader.is_compatible(attr)
        return_type = self.SecureOutputType(attr.type.id,
                                            nullable=(not is_compat) or
                                            attr.type.nullable)
        native_type = self._NarrowToImplementationType(attr.type.id)
        non_null_return_type = self.SecureOutputType(attr.type.id,
                                                     nullable=False)
        if self._IsACompatibilityConflict(self._interface.id, attr):
            if not rename:
                rename = '@JSName(\'%s\')' % html_name
            template = """\n
                // The following getter is incompatible with some browsers but
                // must be made non-nullable to match the overridden method.
                \n  $RENAME
                \n  $METADATA
                \n  $STATIC $TYPE get _$HTML_NAME native;
                \n
                \n  $STATIC $NONNULLTYPE get $HTML_NAME => _$HTML_NAME$NULLASSERT;"""
        else:
            if CanUseStaticExtensions(self._interface_name,
                                      self._generate_static_extensions):
                template = """\n $RENAME
                    \n $METADATA
                    \n $STATIC $TYPE get $HTML_NAME => js_util.getProperty(this, '$JSNAME');
                    \n"""
            else:
                template = """\n  $RENAME
                    \n  $METADATA
                    \n  $STATIC $TYPE get $HTML_NAME native;
                    \n"""
        self._members_emitter.Emit(template,
                                   RENAME=rename if rename else '',
                                   METADATA=metadata if metadata else '',
                                   HTML_NAME=html_name,
                                   STATIC='static' if attr.is_static else '',
                                   TYPE=return_type,
                                   NULLASSERT='!',
                                   NONNULLTYPE=non_null_return_type,
                                   JSNAME=rename if rename else html_name)

    def _AddRenamingSetter(self, attr, html_name, rename):
        conversion = self._InputConversion(attr.type.id, attr.id)
        if conversion:
            return self._AddConvertingSetter(attr, html_name, conversion)
        nullable_type = attr.type.nullable or 'TreatNullAs' in attr.ext_attrs
        # If this attr has an output conversion, it is possible that there is a
        # converting getter. We need to make sure the setter type matches the
        # getter type.
        conversion = self._OutputConversion(attr.type.id, attr.id)
        # If the attribute is incompatible, it must be marked nullable.
        is_compat = self._mdn_reader.is_compatible(attr)
        if (conversion and conversion.nullable_output) or not is_compat:
            nullable_type = True
        if self._IsACompatibilityConflict(self._interface.id, attr):
            # Force non-nullable if it's a manual conflict.
            nullable_type = False
        if CanUseStaticExtensions(self._interface_name,
                                  self._generate_static_extensions):
            template = """\n $RENAME
                \n $STATIC set $HTML_NAME($TYPE value)
                 => js_util.setProperty(this, '$JSNAME', value);
                \n"""
        else:
            template = """\n  $RENAME
                \n $STATIC set $HTML_NAME($TYPE value) native;
                \n"""
        self._members_emitter.Emit(template,
                                   RENAME=rename if rename else '',
                                   HTML_NAME=html_name,
                                   STATIC='static ' if attr.is_static else '',
                                   TYPE=self.SecureOutputType(
                                       attr.type.id, nullable=nullable_type),
                                   JSNAME=rename if rename else html_name)

    def _AddConvertingGetter(self, attr, html_name, conversion):
        # dynamic should not be marked with ?
        nullable_out = conversion.nullable_output and \
            not conversion.output_type == 'dynamic'
        # Nullability is determined by attribute compatibility.
        is_compat = self._mdn_reader.is_compatible(attr)
        nullable_in = (not is_compat or attr.type.nullable) and \
            not conversion.input_type == 'dynamic'
        self._members_emitter.Emit(
            '\n  $(METADATA)$RETURN_TYPE$NULLABLE_OUT get $HTML_NAME => '
            '$CONVERT(this._get_$(HTML_NAME)$NULLASSERT);'
            "\n  @JSName('$NAME')"
            '\n  $(JS_METADATA)$NATIVE_TYPE$NULLABLE_IN get _get_$HTML_NAME native;'
            '\n',
            METADATA=self._metadata.GetFormattedMetadata(
                self._library_name, self._interface, html_name, '  '),
            JS_METADATA=self._Metadata(attr.type.id, html_name,
                                       conversion.input_type,
                                       conversion.nullable_output),
            CONVERT=conversion.function_name,
            HTML_NAME=html_name,
            NAME=attr.id,
            RETURN_TYPE=conversion.output_type,
            NULLABLE_OUT='?' if nullable_out else '',
            NATIVE_TYPE=conversion.input_type,
            NULLABLE_IN='?' if nullable_in else '',
            NULLASSERT='!' if nullable_in and \
                not conversion.nullable_input else '')

    def _AddConvertingSetter(self, attr, html_name, conversion):
        # If the attribute is incompatible, it must be marked nullable.
        is_compat = self._mdn_reader.is_compatible(attr)
        # If the attribute is nullable, the setter should be nullable.
        nullable_in = ((attr.type.nullable or 'TreatNullAs' in attr.ext_attrs) \
            and not conversion.input_type == 'dynamic') or not is_compat
        nullable_out = conversion.nullable_output and \
            not conversion.output_type == 'dynamic'
        self._members_emitter.Emit(
            # TODO(sra): Use metadata to provide native name.
            '\n  set $HTML_NAME($INPUT_TYPE$NULLABLE_IN value) {'
            '\n    this._set_$HTML_NAME = $CONVERT(value$NULLASSERT);'
            '\n  }'
            '\n  set _set_$HTML_NAME(/*$NATIVE_TYPE$NULLABLE_OUT*/ value) {'
            '\n    JS("void", "#.$NAME = #", this, value);'
            '\n  }'
            '\n',
            CONVERT=conversion.function_name,
            HTML_NAME=html_name,
            NAME=attr.id,
            INPUT_TYPE=conversion.input_type,
            NULLABLE_IN='?' if nullable_in else '',
            NATIVE_TYPE=conversion.output_type,
            NULLABLE_OUT='?' if nullable_out else '',
            NULLASSERT='!' if nullable_in and \
                not conversion.nullable_input else '')

    def AmendIndexer(self, element_type):
        pass

    def RootClassName(self):
        return 'JavaScriptObject'

    def OmitOperationOverrides(self):
        return True

    def EmitOperation(self, info, html_name, dart_js_interop=False):
        """
    Arguments:
      info: An OperationInfo object.
    """
        if self._HasCustomImplementation(info.name):
            return

        if IsPureInterface(self._interface.id, self._database):
            self._AddInterfaceOperation(info, html_name)
        elif info.callback_args:
            self._AddFutureifiedOperation(info, html_name)
        else:
            if any(
                    self._OperationRequiresConversions(op)
                    for op in info.overloads):
                lookupOp = "%s.%s" % (self._interface.id, html_name)
                if (_GetPromiseOperationType(lookupOp) or info.type_name == 'Promise') and \
                  not _IsPromiseOperationGenerateCall(lookupOp):
                    self._AddDirectNativeOperation(info, html_name)
                else:
                    # Any conversions needed?
                    self._AddOperationWithConversions(info, html_name)
            else:
                self._AddDirectNativeOperation(info, html_name)

    def _computeResultType(self, checkType):
        # TODO(terry): Work around bug in dart2js compiler e.g.,
        #     typedef void CustomElementConstructor();
        #     CustomElementConstructor registerElement(String type, [Map options])
        # Needs to become:
        #     Function registerElement(String type, [Map options])
        resultType = checkType
        if self._database.HasInterface(resultType):
            resultInterface = self._database.GetInterface(resultType)
            if 'Callback' in resultInterface.ext_attrs:
                resultType = 'Function'
        return resultType

    def _zeroArgs(self, argsNames):
        return 'JS("$TYPE_DESC", "#.$JSNAME()", this)'

    def _manyArgs(self, numberArgs, argsNames):
        argsPound = "#" if numberArgs == 1 else ("#, " * numberArgs)[:-2]
        template = '    JS("$TYPE_DESC", "#.$JSNAME(%s)", this, %s)'
        return template % (argsPound, argsNames)

    """ If argument conversionsMapToDictionary is a list first entry is argument
      name and second entry signals if argument is optional (True). """

    def _promiseToFutureCode(self, argsNames, conversionsMapToDictionary=None):
        numberArgs = argsNames.count(',') + 1
        jsCall = self._zeroArgs(argsNames) if len(argsNames) == 0 else \
            self._manyArgs(numberArgs, argsNames)

        futureTemplate = []
        if conversionsMapToDictionary is None:
            futureTemplate = [
                '\n'
                '  $RENAME$METADATA$MODIFIERS $TYPE $NAME($PARAMS) => $PROMISE_CALL(',
                jsCall, ');\n'
            ]
        else:
            mapArg = conversionsMapToDictionary[0]
            tempVariable = '%s_dict' % mapArg
            mapArgOptional = conversionsMapToDictionary[1]

            if argsNames.endswith('%s' % mapArg):
                argsNames = '%s_dict' % argsNames
                jsCall = self._zeroArgs(argsNames) if len(argsNames) == 0 else \
                    self._manyArgs(numberArgs, argsNames)
            if mapArgOptional:
                futureTemplate = [
                    # We will need to convert the Map argument to a Dictionary, test if mapArg is there (optional) then convert.
                    '\n'
                    '  $RENAME$METADATA$MODIFIERS $TYPE $NAME($PARAMS) {\n',
                    '    var ',
                    tempVariable,
                    ' = null;\n',
                    '    if (',
                    mapArg,
                    ' != null) {\n',
                    '      ',
                    tempVariable,
                    ' = convertDartToNative_Dictionary(',
                    mapArg,
                    ');\n',
                    '    }\n',
                    '    return $PROMISE_CALL(',
                    jsCall,
                    ');\n',
                    '  }\n'
                ]
            else:
                futureTemplate = [
                    # We will need to convert the Map argument to a Dictionary, the Map argument is not optional.
                    '\n'
                    '  $RENAME$METADATA$MODIFIERS $TYPE $NAME($PARAMS) {\n',
                    '    var ',
                    tempVariable,
                    ' = convertDartToNative_Dictionary(',
                    mapArg,
                    ');\n',
                    '    return $PROMISE_CALL(',
                    jsCall,
                    ');\n',
                    '  }\n'
                ]

        return "".join(futureTemplate)

    def _AddDirectNativeOperation(self, info, html_name):
        force_optional = True if html_name.startswith('_') else False
        resultType = self._computeResultType(info.type_name)

        if info.type_name == 'Promise' and not (force_optional):
            lookupOp = "%s.%s" % (self._interface.id, html_name)
            promiseFound = _GetPromiseOperationType(lookupOp)
            promiseType = 'Future'
            promiseCall = 'promiseToFuture'
            type_description = ''
            if promiseFound is not (None):
                paramType = promiseFound.get('type')
                if 'maplike' in promiseFound:
                    if paramType == 'dictionary':
                        promiseCall = 'promiseToFuture<dynamic>'
                        promiseType = 'Future'
                    elif paramType:
                        promiseCall = 'promiseToFuture<%s>' % paramType
                        promiseType = 'Future<%s>' % paramType
                elif paramType == 'dictionary':
                    # It's a dictionary so return as a Map.
                    promiseCall = 'promiseToFutureAsMap'
                    output_conversion = self._OutputConversion("Dictionary",
                                                               None)
                    nullability = '?' if output_conversion.nullable_output \
                        else ''
                    promiseType = 'Future<Map<String, dynamic>' + \
                        nullability + '>'
                elif paramType:
                    promiseCall = 'promiseToFuture<%s>' % paramType
                    promiseType = 'Future<%s>' % paramType

                if 'creates' in promiseFound:
                    createsType = promiseFound['creates']
                    type_description = 'creates:%s;' % createsType

            argsNames = info.ParametersAsArgumentList()
            dictionary_argument = info.dictionaryArgumentName()
            codeTemplate = self._promiseToFutureCode(argsNames,
                                                     dictionary_argument)
            if info.type_nullable:
                promiseType += '?'
            self._members_emitter.Emit(
                codeTemplate,
                RENAME=self._RenamingAnnotation(info.declared_name, html_name),
                METADATA=self._Metadata(info.type_name, info.declared_name,
                                        self.SecureOutputType(info.type_name,
                                            nullable=info.type_nullable),
                                        info.type_nullable),
                MODIFIERS='static ' if info.IsStatic() else '',
                TYPE=promiseType,
                PROMISE_CALL=promiseCall,
                NAME=html_name,
                TYPE_DESC=type_description,
                JSNAME=info.declared_name,
                PARAMS=info.ParametersAsDeclaration(self._NarrowInputType,
                                                    force_optional))
        else:
            self._members_emitter.Emit(
                '\n'
                '  $RENAME$METADATA$MODIFIERS$TYPE $NAME($PARAMS) => '\
                'js_util.callMethod(this, \'$JSNAME\', [$ARGS]);\n'
                if CanUseStaticExtensions(self._interface_name, self._generate_static_extensions) else
                '\n  $RENAME$METADATA$MODIFIERS$TYPE $NAME($PARAMS) native;\n',
                RENAME=self._RenamingAnnotation(info.declared_name, html_name),
                METADATA=self._Metadata(
                    info.type_name, info.declared_name,
                    self.SecureOutputType(info.type_name,
                                          nullable=info.type_nullable),
                    info.type_nullable),
                MODIFIERS='static ' if info.IsStatic() else '',
                TYPE=self.SecureOutputType(resultType,
                                           can_narrow_type=True,
                                           nullable=info.type_nullable),
                NAME=html_name,
                PARAMS=info.ParametersAsDeclaration(self._NarrowInputType,
                                                    force_optional),
                ARGS=info.ParametersAsArgumentList(),
                JSNAME=info.declared_name if info.declared_name != html_name else html_name)

    def _AddOperationWithConversions(self, info, html_name):
        # Assert all operations have same return type.
        assert len(set([op.type.id for op in info.operations])) == 1

        resultType = self._computeResultType(info.type_name)

        output_conversion = self._OutputConversion(resultType,
                                                   info.declared_name)
        if output_conversion:
            return_type = output_conversion.output_type
            native_return_type = output_conversion.input_type
        else:
            return_type = resultType if resultType == 'Function' else self._NarrowInputType(
                resultType)
            native_return_type = return_type

        parameter_names = [param_info.name for param_info in info.param_infos]
        parameter_types = [
            self._InputType(param_info.type_id, info)
            for param_info in info.param_infos
        ]
        operations = info.operations

        def InputType(type_name):
            return self._InputType(type_name, info)

        def GenerateCall(stmts_emitter, call_emitter, version, operation,
                         argument_count):
            target = '_%s_%d' % (html_name[1:] if html_name.startswith('_') else
                                 html_name, version)

            (target_parameters, arguments,
             calling_params) = self._ConvertArgumentTypes(
                 stmts_emitter, operation.arguments, argument_count, info)

            argument_list = ', '.join(arguments)
            # TODO(sra): If the native method has zero type checks, we can 'inline' is
            # and call it directly with a JS-expression.
            call = '%s(%s)' % (target, argument_list)

            if output_conversion:
                call = '%s(%s)' % (output_conversion.function_name, call)
                if output_conversion.nullable_output and not info.type_nullable:
                    # Return type of operation is not nullable while conversion
                    # is, so we need to assert non-null.
                    call += '!'

            call_emitter.Emit(call)

            if (native_return_type == 'Future'):
                hashArgs = ''
                if argument_count > 0:
                    if argument_count < 20:
                        hashArgs = '#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#' [:
                                                                                argument_count
                                                                                *
                                                                                2
                                                                                -
                                                                                1]
                    else:
                        print(
                            "ERROR: Arguments exceede 20 - please fix Python code to handle more."
                        )
                self._members_emitter.Emit(
                    '  $RENAME$METADATA$MODIFIERS$TYPE$TARGET($PARAMS) =>\n'
                    '      promiseToFuture(JS("", "#.$JSNAME($HASH_STR)"'\
                    ', this$CALLING_PARAMS));\n',
                    RENAME=self._RenamingAnnotation(info.declared_name, target),
                    METADATA=self._Metadata(info.type_name, info.declared_name,
                                            None, info.type_nullable),
                    MODIFIERS='static ' if info.IsStatic() else '',
                    TYPE=TypeOrNothing(native_return_type,
                        nullable=info.type_nullable),
                    TARGET=target,
                    PARAMS=', '.join(target_parameters),
                    JSNAME=operation.id,
                    HASH_STR=hashArgs,
                    CALLING_PARAMS=calling_params)
            else:
                self._members_emitter.Emit(
                    '  $RENAME$METADATA$MODIFIERS$TYPE$TARGET($PARAMS) native;\n',
                    RENAME=self._RenamingAnnotation(info.declared_name, target),
                    METADATA=self._Metadata(info.type_name, info.declared_name,
                                            None, info.type_nullable),
                    MODIFIERS='static ' if info.IsStatic() else '',
                    TYPE=TypeOrNothing(native_return_type,
                        nullable=info.type_nullable),
                    TARGET=target,
                    PARAMS=', '.join(target_parameters))

        # private methods don't need named arguments.
        full_name = '%s.%s' % (self._interface.id, info.declared_name)
        force_optional = False if hasNamedFormals(full_name) and not (
            html_name.startswith('_')) else True

        nullsafe_return_type = return_type;
        if info.type_nullable:
            nullsafe_return_type += '?'

        declaration = '%s%s%s %s(%s)' % (
            self._Metadata(info.type_name, info.declared_name, return_type,
                info.type_nullable),
            'static ' if info.IsStatic() else '', nullsafe_return_type,
            html_name, info.ParametersAsDeclaration(InputType, force_optional))
        self._GenerateDispatcherBody(
            info,
            operations,
            declaration,
            GenerateCall,
            IsOptional,
            can_omit_type_check=lambda type, pos: type == parameter_types[pos])

    def _AddInterfaceOperation(self, info, html_name):
        self._members_emitter.Emit(
            '\n'
            '  $TYPE $NAME($PARAMS);\n',
            TYPE=self.SecureOutputType(info.type_name, can_narrow_type=True,
                nullable=info.type_nullable),
            NAME=html_name,
            PARAMS=info.ParametersAsDeclaration(self._NarrowInputType))

    def _OperationRequiresConversions(self, operation):
        return (self._OperationRequiresOutputConversion(operation) or
                self._OperationRequiresInputConversions(operation))

    def _OperationRequiresOutputConversion(self, operation):
        return self._OutputConversion(operation.type.id, operation.id)

    def _OperationRequiresInputConversions(self, operation):
        return any(
            self._InputConversion(arg.type.id, operation.id)
            for arg in operation.arguments)

    def _OutputConversion(self, idl_type, member):
        return FindConversion(idl_type, 'get', self._interface.id, member)

    def _InputConversion(self, idl_type, member):
        return FindConversion(idl_type, 'set', self._interface.id, member)

    def _HasCustomImplementation(self, member_name):
        member_name = '%s.%s' % (self._interface.doc_js_name, member_name)
        return member_name in _js_custom_members

    def _SafeToIgnoreShadowingMember(self, member_name):
        member_name = '%s.%s' % (self._interface.doc_js_name, member_name)
        return member_name in _safe_to_ignore_shadowing_members

    def _RenamingAnnotation(self, idl_name, member_name):
        if member_name != idl_name:
            return "@JSName('%s')\n  " % idl_name
        return ''

    def _Metadata(self, idl_type, idl_member_name, dart_type, nullable,
            indent='  '):
        anns = self._metadata.GetDart2JSMetadata(
            idl_type, self._library_name, self._interface, idl_member_name)

        if not self._metadata.AnyConversionAnnotations(
                idl_type, self._interface.id, idl_member_name):
            return_type = self.SecureOutputType(idl_type)
            native_type = self._NarrowToImplementationType(idl_type)

            null_union = '' if not nullable else '|Null'
            if native_type != return_type:
                anns = anns + [
                    "@Returns('%s%s')" % (native_type, null_union),
                    "@Creates('%s')" % native_type,
                ]
        if dart_type == 'dynamic' or dart_type == 'Object?':
            # We emit non-nullable Object annotations but exclude nullable
            # Object annotations since that's the default.

            def js_type_annotation(ann):
                return re.search('^@.*Returns', ann) or re.search(
                    '^@.*Creates', ann)

            if not list(filter(js_type_annotation, anns)):
                _logger.warn('Member with wildcard native type: %s.%s' %
                             (self._interface.id, idl_member_name))

        return self._metadata.FormatMetadata(anns, indent)

    def CustomJSMembers(self):
        return _js_custom_members

    def _FindShadowedAttribute(self, attr):
        """Returns (attribute, superinterface) or (None, None)."""

        def FindInParent(interface):
            """Returns matching attribute in parent, or None."""
            if interface.parents:
                parent = interface.parents[0]
                if IsDartCollectionType(parent.type.id):
                    return (None, None)
                if IsPureInterface(parent.type.id, self._database):
                    return (None, None)
                if self._database.HasInterface(parent.type.id):
                    interfaces_to_search_in = []
                    parent_interface_name = parent.type.id
                    interfaces_to_search_in.append(parent_interface_name)
                    parent_type_info = self._type_registry.TypeInfo(
                        parent_interface_name)
                    if parent_type_info.merged_into():
                        # IDL parent was merged into another interface, which became a
                        # parent interface in Dart.
                        parent_interface_name = parent_type_info.merged_into()
                        interfaces_to_search_in.append(parent_interface_name)
                    elif parent_type_info.merged_interface():
                        # IDL parent has another interface that was merged into it.
                        interfaces_to_search_in.append(
                            parent_type_info.merged_interface())

                    for interface_name in interfaces_to_search_in:
                        interface = self._database.GetInterface(interface_name)
                        attr2 = FindMatchingAttribute(interface, attr)
                        if attr2:
                            return (attr2, parent_interface_name)

                    return FindInParent(
                        self._database.GetInterface(parent_interface_name))
            return (None, None)

        return FindInParent(self._interface) if attr else (None, None)


# ------------------------------------------------------------------------------


class DartLibraryEmitter():

    def __init__(self, multiemitter, dart_sources_dir, dart_libraries):
        self._multiemitter = multiemitter
        self._dart_sources_dir = dart_sources_dir
        self._path_to_emitter = {}
        self._dart_libraries = dart_libraries

    def FileEmitter(self, basename, library_name, template=None):
        aux_dir = os.path.join(self._dart_sources_dir, library_name)
        path = os.path.join(aux_dir, '%s.dart' % basename)
        if not path in self._path_to_emitter:
            emitter = self._multiemitter.FileEmitter(path)
            if not template is None:
                emitter = emitter.Emit(template)
            self._path_to_emitter[path] = emitter

            self._dart_libraries.AddFile(basename, library_name, path)
        return self._path_to_emitter[path]

    def AddTypeEntry(self, basename, idl_name, dart_name):
        self._dart_libraries.AddTypeEntry(basename, idl_name, dart_name)

    def EmitLibraries(self, auxiliary_dir, dart_js_interop):
        self._dart_libraries.Emit(self._multiemitter, auxiliary_dir)


# ------------------------------------------------------------------------------
class DartLibrary():

    def __init__(self, name, template_loader, library_type, output_dir,
                 dart_js_interop):
        self._template = template_loader.Load(
            '%s_%s.darttemplate' % (name, library_type))
        self._dart_path = os.path.join(output_dir,
                                       '%s_%s.dart' % (name, library_type))
        self._paths = []
        self._typeMap = {}
        self._dart_js_interop = dart_js_interop

    def AddFile(self, path):
        self._paths.append(path)

    def AddTypeEntry(self, idl_name, dart_name):
        self._typeMap[idl_name] = dart_name

    def Emit(self, emitter, auxiliary_dir):

        def massage_path(path):
            # The most robust way to emit path separators is to use / always.
            return path.replace('\\', '/')

        library_emitter = emitter.FileEmitter(self._dart_path)
        library_file_dir = os.path.dirname(self._dart_path)
        auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir)
        emitters = library_emitter.Emit(
            self._template,
            AUXILIARY_DIR=massage_path(auxiliary_dir),
            NULLABLE='?')
        if isinstance(emitters, tuple):
            imports_emitter, map_emitter = emitters
        else:
            imports_emitter, map_emitter = emitters, None

        for path in sorted(self._paths):
            relpath = os.path.relpath(path, library_file_dir)
            imports_emitter.Emit("part '$PATH';\n", PATH=massage_path(relpath))

        # Emit the $!TYPE_MAP
        if map_emitter:
            items = list(self._typeMap.items())
            items.sort()
            for (idl_name, dart_name) in items:
                map_emitter.Emit(
                    "  '$IDL_NAME': () => $DART_NAME.instanceRuntimeType,\n",
                    IDL_NAME=idl_name,
                    DART_NAME=dart_name)


# ------------------------------------------------------------------------------


class DartLibraries():

    def __init__(self, libraries, template_loader, library_type, output_dir,
                 dart_js_interop):
        self._libraries = {}
        for library_name in libraries:
            self._libraries[library_name] = DartLibrary(
                library_name, template_loader, library_type, output_dir,
                dart_js_interop)

    def AddFile(self, basename, library_name, path):
        self._libraries[library_name].AddFile(path)

    def AddTypeEntry(self, library_name, idl_name, dart_name):
        self._libraries[library_name].AddTypeEntry(idl_name, dart_name)

    def Emit(self, emitter, auxiliary_dir):
        for lib in self._libraries.values():
            lib.Emit(emitter, auxiliary_dir)
