Bug 1068740 - Consider putting union types in the binding files where they're used. r=bz.
☠☠ backed out by 7f5287115874 ☠ ☠
authorPeter Van der Beken <peterv@propagandism.org>
Wed, 01 Oct 2014 20:43:26 +0200
changeset 210554 6f411275b7ec5dc953fdabdc198f9af5b8a35ca9
parent 210553 8d198ef0b5596bc4c6c1a72ef9ae3c981025ca65
child 210555 7f5287115874d9efd54ee8d2db40459577e8eddc
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbz
bugs1068740
milestone36.0a1
Bug 1068740 - Consider putting union types in the binding files where they're used. r=bz.
content/html/content/src/HTMLCanvasElement.cpp
content/html/content/src/HTMLFormControlsCollection.cpp
content/html/content/src/HTMLOptionsCollection.h
content/html/content/src/HTMLSelectElement.cpp
content/html/content/src/HTMLTableElement.cpp
content/html/document/src/HTMLAllCollection.cpp
content/media/TextTrackCue.h
content/media/eme/MediaKeySession.h
content/media/eme/MediaKeys.cpp
content/media/eme/MediaKeys.h
dom/base/Console.h
dom/base/SubtleCrypto.h
dom/bindings/Codegen.py
dom/bindings/Configuration.py
dom/bindings/parser/WebIDL.py
dom/bindings/test/TestBindingHeader.h
dom/canvas/CanvasRenderingContext2D.cpp
dom/events/JSEventHandler.cpp
dom/events/MessageEvent.cpp
dom/fetch/Fetch.cpp
dom/fetch/Fetch.h
dom/filesystem/Directory.cpp
dom/indexedDB/IDBRequest.cpp
dom/mobilemessage/DOMMobileMessageError.cpp
dom/mobilemessage/MobileMessageManager.h
dom/telephony/Telephony.cpp
--- a/content/html/content/src/HTMLCanvasElement.cpp
+++ b/content/html/content/src/HTMLCanvasElement.cpp
@@ -9,17 +9,16 @@
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "Layers.h"
 #include "mozilla/Base64.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/dom/CanvasRenderingContext2D.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/HTMLCanvasElementBinding.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "mozilla/dom/MouseEvent.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "nsAttrValueInlines.h"
 #include "nsContentUtils.h"
--- a/content/html/content/src/HTMLFormControlsCollection.cpp
+++ b/content/html/content/src/HTMLFormControlsCollection.cpp
@@ -6,17 +6,16 @@
 
 #include "mozilla/dom/HTMLFormControlsCollection.h"
 
 #include "mozFlushType.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLFormControlsCollectionBinding.h"
 #include "mozilla/dom/HTMLFormElement.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "nsGenericHTMLElement.h" // nsGenericHTMLFormElement
 #include "nsIDocument.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIFormControl.h"
 #include "RadioNodeList.h"
 #include "jsfriendapi.h"
 
--- a/content/html/content/src/HTMLOptionsCollection.h
+++ b/content/html/content/src/HTMLOptionsCollection.h
@@ -6,28 +6,29 @@
 #define mozilla_dom_HTMLOptionsCollection_h
 
 #include "mozilla/Attributes.h"
 #include "nsIHTMLCollection.h"
 #include "nsIDOMHTMLOptionsCollection.h"
 #include "nsWrapperCache.h"
 
 #include "mozilla/dom/HTMLOptionElement.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "mozilla/ErrorResult.h"
 #include "nsCOMPtr.h"
 #include "nsError.h"
 #include "nsGenericHTMLElement.h"
 #include "nsTArray.h"
 
 class nsIDOMHTMLOptionElement;
 
 namespace mozilla {
 namespace dom {
 
+class HTMLElementOrLong;
+class HTMLOptionElementOrHTMLOptGroupElement;
 class HTMLSelectElement;
 
 /**
  * The collection of options in the select (what you get back when you do
  * select.options in DOM)
  */
 class HTMLOptionsCollection MOZ_FINAL : public nsIHTMLCollection
                                       , public nsIDOMHTMLOptionsCollection
--- a/content/html/content/src/HTMLSelectElement.cpp
+++ b/content/html/content/src/HTMLSelectElement.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLOptGroupElement.h"
 #include "mozilla/dom/HTMLOptionElement.h"
 #include "mozilla/dom/HTMLSelectElementBinding.h"
+#include "mozilla/dom/UnionTypes.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentList.h"
 #include "nsError.h"
 #include "nsFormSubmission.h"
 #include "nsGkAtoms.h"
 #include "nsIComboboxControlFrame.h"
 #include "nsIDocument.h"
 #include "nsIFormControlFrame.h"
--- a/content/html/content/src/HTMLTableElement.cpp
+++ b/content/html/content/src/HTMLTableElement.cpp
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLTableElement.h"
 #include "nsAttrValueInlines.h"
 #include "nsRuleData.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsMappedAttributes.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "mozilla/dom/HTMLCollectionBinding.h"
 #include "mozilla/dom/HTMLTableElementBinding.h"
 #include "nsContentUtils.h"
 #include "jsfriendapi.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Table)
 
 namespace mozilla {
--- a/content/html/document/src/HTMLAllCollection.cpp
+++ b/content/html/document/src/HTMLAllCollection.cpp
@@ -3,17 +3,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLAllCollection.h"
 
 #include "mozilla/dom/HTMLAllCollectionBinding.h"
 #include "mozilla/dom/Nullable.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "nsHTMLDocument.h"
 
 namespace mozilla {
 namespace dom {
 
 HTMLAllCollection::HTMLAllCollection(nsHTMLDocument* aDocument)
   : mDocument(aDocument)
 {
--- a/content/media/TextTrackCue.h
+++ b/content/media/TextTrackCue.h
@@ -10,17 +10,16 @@
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/DocumentFragment.h"
 #include "mozilla/dom/VTTCueBinding.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIWebVTTParserWrapper.h"
 #include "mozilla/StaticPtr.h"
 #include "nsIDocument.h"
 #include "mozilla/dom/HTMLDivElement.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "mozilla/dom/TextTrack.h"
 
 namespace mozilla {
 namespace dom {
 
 class HTMLTrackElement;
 class TextTrackRegion;
 
--- a/content/media/eme/MediaKeySession.h
+++ b/content/media/eme/MediaKeySession.h
@@ -13,26 +13,26 @@
 #include "mozilla/DOMEventTargetHelper.h"
 #include "nsCOMPtr.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/dom/Date.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/MediaKeySessionBinding.h"
 #include "mozilla/dom/MediaKeysBinding.h"
-#include "mozilla/dom/UnionTypes.h"
 
 struct JSContext;
 
 namespace mozilla {
 
 class CDMProxy;
 
 namespace dom {
 
+class ArrayBufferViewOrArrayBuffer;
 class MediaKeyError;
 
 class MediaKeySession MOZ_FINAL : public DOMEventTargetHelper
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaKeySession,
                                            DOMEventTargetHelper)
--- a/content/media/eme/MediaKeys.cpp
+++ b/content/media/eme/MediaKeys.cpp
@@ -6,16 +6,17 @@
 
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/MediaKeys.h"
 #include "mozilla/dom/MediaKeysBinding.h"
 #include "mozilla/dom/MediaKeyMessageEvent.h"
 #include "mozilla/dom/MediaKeyError.h"
 #include "mozilla/dom/MediaKeySession.h"
 #include "mozilla/dom/DOMException.h"
+#include "mozilla/dom/UnionTypes.h"
 #include "mozilla/CDMProxy.h"
 #include "mozilla/EMELog.h"
 #include "nsContentUtils.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "mozilla/Preferences.h"
 #include "nsContentTypeParser.h"
 #ifdef MOZ_FMP4
 #include "MP4Decoder.h"
--- a/content/media/eme/MediaKeys.h
+++ b/content/media/eme/MediaKeys.h
@@ -12,25 +12,25 @@
 #include "nsISupports.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/RefPtr.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsRefPtrHashtable.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/MediaKeysBinding.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "mozIGeckoMediaPluginService.h"
 
 namespace mozilla {
 
 class CDMProxy;
 
 namespace dom {
 
+class ArrayBufferViewOrArrayBuffer;
 class MediaKeySession;
 class HTMLMediaElement;
 
 typedef nsRefPtrHashtable<nsStringHashKey, MediaKeySession> KeySessionHashMap;
 typedef nsRefPtrHashtable<nsUint32HashKey, dom::Promise> PromiseHashMap;
 typedef nsRefPtrHashtable<nsUint32HashKey, MediaKeySession> PendingKeySessionsHashMap;
 typedef uint32_t PromiseId;
 
--- a/dom/base/Console.h
+++ b/dom/base/Console.h
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_Console_h
 #define mozilla_dom_Console_h
 
 #include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/dom/UnionConversions.h"
 #include "mozilla/ErrorResult.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsIObserver.h"
 #include "nsITimer.h"
 #include "nsWrapperCache.h"
 
--- a/dom/base/SubtleCrypto.h
+++ b/dom/base/SubtleCrypto.h
@@ -5,23 +5,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_SubtleCrypto_h
 #define mozilla_dom_SubtleCrypto_h
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 #include "nsPIDOMWindow.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "mozilla/dom/CryptoKey.h"
 #include "js/TypeDecls.h"
 
 namespace mozilla {
 namespace dom {
 
+class ObjectOrString;
 class Promise;
 
 typedef ArrayBufferViewOrArrayBuffer CryptoOperationData;
 
 class SubtleCrypto MOZ_FINAL : public nsISupports,
                                public nsWrapperCache
 {
   ~SubtleCrypto() {}
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -5,18 +5,18 @@
 # Common codegen classes.
 
 import os
 import re
 import string
 import math
 import textwrap
 
-from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLUndefinedValue, IDLEmptySequenceValue
-from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, Descriptor
+from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLUndefinedValue, IDLEmptySequenceValue, IDLDictionary
+from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, getAllTypes, Descriptor
 
 AUTOGENERATED_WARNING_COMMENT = \
     "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
 ADDPROPERTY_HOOK_NAME = '_addProperty'
 FINALIZE_HOOK_NAME = '_finalize'
 OBJECT_MOVED_HOOK_NAME = '_objectMoved'
 CONSTRUCT_HOOK_NAME = '_constructor'
 LEGACYCALLER_HOOK_NAME = '_legacycaller'
@@ -1004,36 +1004,16 @@ def getRelevantProviders(descriptor, con
         return [descriptor]
     # Do both the non-worker and worker versions
     return [
         config.getDescriptorProvider(False),
         config.getDescriptorProvider(True)
     ]
 
 
-def getAllTypes(descriptors, dictionaries, callbacks):
-    """
-    Generate all the types we're dealing with.  For each type, a tuple
-    containing type, descriptor, dictionary is yielded.  The
-    descriptor and dictionary can be None if the type does not come
-    from a descriptor or dictionary; they will never both be non-None.
-    """
-    for d in descriptors:
-        if d.interface.isExternal():
-            continue
-        for t in getTypesFromDescriptor(d):
-            yield (t, d, None)
-    for dictionary in dictionaries:
-        for t in getTypesFromDictionary(dictionary):
-            yield (t, None, dictionary)
-    for callback in callbacks:
-        for t in getTypesFromCallback(callback):
-            yield (t, None, None)
-
-
 class CGHeaders(CGWrapper):
     """
     Generates the appropriate include statements.
     """
     def __init__(self, descriptors, dictionaries, callbacks,
                  callbackDescriptors,
                  declareIncludes, defineIncludes, prefix, child,
                  config=None, jsImplementedDescriptors=[]):
@@ -1101,22 +1081,21 @@ class CGHeaders(CGWrapper):
             else:
                 headerSet = bindingHeaders
             if t.nullable():
                 # Need to make sure that Nullable as a dictionary
                 # member works.
                 headerSet.add("mozilla/dom/Nullable.h")
             unrolled = t.unroll()
             if unrolled.isUnion():
-                # UnionConversions.h includes UnionTypes.h
-                bindingHeaders.add("mozilla/dom/UnionConversions.h")
-                if dictionary:
-                    # Our dictionary definition is in the header and
-                    # needs the union type.
-                    declareIncludes.add("mozilla/dom/UnionTypes.h")
+                if len(config.filenamesPerUnion[unrolled.name]) > 1:
+                    headerSet.add("mozilla/dom/UnionTypes.h")
+                    bindingHeaders.add("mozilla/dom/UnionConversions.h")
+                else:
+                    headerSet.add(self.getDeclarationFilename(unrolled))
             elif unrolled.isDate():
                 if dictionary or jsImplementedDescriptors:
                     declareIncludes.add("mozilla/dom/Date.h")
                 else:
                     bindingHeaders.add("mozilla/dom/Date.h")
             elif unrolled.isInterface():
                 if unrolled.isSpiderMonkeyInterface():
                     bindingHeaders.add("jsfriendapi.h")
@@ -1252,53 +1231,52 @@ class CGHeaders(CGWrapper):
 
 
 def SortedDictValues(d):
     """
     Returns a list of values from the dict sorted by key.
     """
     return [v for k, v in sorted(d.items())]
 
-
-def UnionTypes(descriptors, dictionaries, callbacks, config):
-    """
+def UnionsForFile(config, webIDLFile):
+    """
+    Returns a list of tuples each containing two elements (type and descriptor)
+    for all union types that are only used in webIDLFile. If webIDLFile is None
+    this will return the list of tuples for union types that are used in more
+    than one WebIDL file.
+    """
+    return config.unionsPerFilename.get(webIDLFile, [])
+
+def UnionTypes(unionTypes, config):
+    """
+    The unionTypes argument should be a list of tuples, each containing two
+    elements: a union type and a descriptor. This is typically the list
+    generated by UnionsForFile.
+
     Returns a tuple containing a set of header filenames to include in
-    UnionTypes.h, a set of header filenames to include in UnionTypes.cpp, a set
+    the header for the types in unionTypes, a set of header filenames to
+    include in the implementation file for the types in unionTypes, a set
     of tuples containing a type declaration and a boolean if the type is a
-    struct for member types of the unions and a CGList containing CGUnionStructs
-    for every union.
-    """
-
-    # Now find all the things we'll need as arguments and return values because
-    # we need to wrap or unwrap them.
+    struct for member types of the union, a list of traverse methods,
+    unlink methods and a list of union types. These last three lists only
+    contain unique union types.
+    """
+
     headers = set()
-    implheaders = set(["UnionTypes.h"])
+    implheaders = set()
     declarations = set()
     unionStructs = dict()
-    owningUnionStructs = dict()
     traverseMethods = dict()
     unlinkMethods = dict()
 
-    for t, descriptor, dictionary in getAllTypes(descriptors, dictionaries, callbacks):
-        # Add info for the given type.  descriptor and dictionary, if present, are
-        # used to figure out what to do with interface types.
-        assert not descriptor or not dictionary
-
-        t = t.unroll()
-        while t.isMozMap():
-            t = t.inner.unroll()
-        if not t.isUnion():
-            continue
+    for (t, descriptor) in unionTypes:
         name = str(t)
         if name not in unionStructs:
             providers = getRelevantProviders(descriptor, config)
-            # FIXME: Unions are broken in workers.  See bug 809899.
-            unionStructs[name] = CGUnionStruct(t, providers[0])
-            owningUnionStructs[name] = CGUnionStruct(t, providers[0],
-                                                     ownsMembers=True)
+            unionStructs[name] = t
 
             def addHeadersForType(f):
                 if f.nullable():
                     headers.add("mozilla/dom/Nullable.h")
                 isSequence = f.isSequence()
                 f = f.unroll()
                 if f.isInterface():
                     if f.isSpiderMonkeyInterface():
@@ -1339,55 +1317,51 @@ def UnionTypes(descriptors, dictionaries
                     # the right header to be able to Release() in our inlined
                     # code.
                     headers.add(CGHeaders.getDeclarationFilename(f))
                 elif f.isMozMap():
                     headers.add("mozilla/dom/MozMap.h")
                     # And add headers for the type we're parametrized over
                     addHeadersForType(f.inner)
 
+            if len(config.filenamesPerUnion[t.name]) > 0:
+                implheaders.add("mozilla/dom/UnionTypes.h")
+            else:
+                implheaders.add(CGHeaders.getDeclarationFilename(t))
             for f in t.flatMemberTypes:
                 assert not f.nullable()
                 addHeadersForType(f)
 
             if idlTypeNeedsCycleCollection(t):
                 declarations.add(("mozilla::dom::%s" % CGUnionStruct.unionTypeName(t, True), False))
                 traverseMethods[name] = CGCycleCollectionTraverseForOwningUnionMethod(t)
                 unlinkMethods[name] = CGCycleCollectionUnlinkForOwningUnionMethod(t)
 
     # The order of items in CGList is important.
     # Since the union structs friend the unlinkMethods, the forward-declaration
     # for these methods should come before the class declaration. Otherwise
     # some compilers treat the friend declaration as a forward-declaration in
     # the class scope.
     return (headers, implheaders, declarations,
-            CGList(SortedDictValues(traverseMethods) +
-                   SortedDictValues(unlinkMethods) +
-                   SortedDictValues(unionStructs) +
-                   SortedDictValues(owningUnionStructs),
-                   "\n"))
-
-
-def UnionConversions(descriptors, dictionaries, callbacks, config):
-    """
-    Returns a CGThing to declare all union argument conversion helper structs.
-    """
-    # Now find all the things we'll need as arguments because we
-    # need to unwrap them.
+            SortedDictValues(traverseMethods), SortedDictValues(unlinkMethods),
+            SortedDictValues(unionStructs))
+
+def UnionConversions(unionTypes, config):
+    """
+    The unionTypes argument should be a list of tuples, each containing two
+    elements: a union type and a descriptor. This is typically the list
+    generated by UnionsForFile.
+
+    Returns a tuple containing a list of headers and a CGThing to declare all
+    union argument conversion helper structs.
+    """
     headers = set()
     unionConversions = dict()
 
-    for t, descriptor, dictionary in getAllTypes(descriptors, dictionaries, callbacks):
-        # Add info for the given type.  descriptor and dictionary, if passed, are
-        # used to figure out what to do with interface types.
-        assert not descriptor or not dictionary
-
-        t = t.unroll()
-        if not t.isUnion():
-            continue
+    for (t, descriptor) in unionTypes:
         name = str(t)
         if name not in unionConversions:
             providers = getRelevantProviders(descriptor, config)
             unionConversions[name] = CGUnionConversionStruct(t, providers[0])
             def addHeadersForType(f, providers):
                 f = f.unroll()
                 if f.isInterface():
                     if f.isSpiderMonkeyInterface():
@@ -3591,16 +3565,19 @@ class CGCycleCollectionTraverseForOwning
     def __init__(self, type):
         self.type = type
         args = [Argument("nsCycleCollectionTraversalCallback&", "aCallback"),
                 Argument("%s&" % CGUnionStruct.unionTypeName(type, True), "aUnion"),
                 Argument("const char*", "aName"),
                 Argument("uint32_t", "aFlags", "0")]
         CGAbstractMethod.__init__(self, None, "ImplCycleCollectionTraverse", "void", args)
 
+    def deps(self):
+        return self.type.getDeps()
+
     def definition_body(self):
         memberNames = [getUnionMemberName(t)
                        for t in self.type.flatMemberTypes
                        if idlTypeNeedsCycleCollection(t)]
         assert memberNames
 
         conditionTemplate = 'aUnion.Is%s()'
         functionCallTemplate = 'ImplCycleCollectionTraverse(aCallback, aUnion.GetAs%s(), "m%s", aFlags);\n'
@@ -3612,19 +3589,23 @@ class CGCycleCollectionTraverseForOwning
         return CGElseChain(ifStaments).define()
 
 
 class CGCycleCollectionUnlinkForOwningUnionMethod(CGAbstractMethod):
     """
     ImplCycleCollectionUnlink for owning union type.
     """
     def __init__(self, type):
+        self.type = type
         args = [Argument("%s&" % CGUnionStruct.unionTypeName(type, True), "aUnion")]
         CGAbstractMethod.__init__(self, None, "ImplCycleCollectionUnlink", "void", args)
 
+    def deps(self):
+        return self.type.getDeps()
+
     def definition_body(self):
         return "aUnion.Uninit();\n"
 
 
 builtinNames = {
     IDLType.Tags.bool: 'bool',
     IDLType.Tags.int8: 'int8_t',
     IDLType.Tags.int16: 'int16_t',
@@ -8687,16 +8668,19 @@ class CGUnionStruct(CGThing):
         self.struct = self.getStruct()
 
     def declare(self):
         return self.struct.declare()
 
     def define(self):
         return self.struct.define()
 
+    def deps(self):
+        return self.type.getDeps()
+
     def getStruct(self):
 
         members = [ClassMember("mType", "Type", body="eUninitialized"),
                    ClassMember("mValue", "Value")]
         ctor = ClassConstructor([], bodyInHeader=True, visibility="public",
                                 explicit=True)
 
         methods = []
@@ -9044,17 +9028,19 @@ class CGUnionConversionStruct(CGThing):
 
         return CGClass(structName + "Argument",
                        members=members,
                        constructors=[ctor],
                        methods=methods,
                        disallowCopyConstruction=True).declare()
 
     def define(self):
-        return "\n"
+        return ""
+    def deps(self):
+        return set()
 
 
 class ClassItem:
     """ Use with CGClass """
     def __init__(self, name, visibility):
         self.name = name
         self.visibility = visibility
 
@@ -11855,33 +11841,16 @@ class CGDictionary(CGThing):
         return ("'%s' member of %s" %
                 (member.identifier.name, self.dictionary.identifier.name))
 
     @staticmethod
     def makeIdName(name):
         return IDLToCIdentifier(name) + "_id"
 
     @staticmethod
-    def getDictionaryDependenciesFromType(type):
-        if type.isDictionary():
-            return set([type.unroll().inner])
-        if type.isSequence() or type.isArray():
-            return CGDictionary.getDictionaryDependenciesFromType(type.unroll())
-        return set()
-
-    @staticmethod
-    def getDictionaryDependencies(dictionary):
-        deps = set()
-        if dictionary.parent:
-            deps.add(dictionary.parent)
-        for member in dictionary.members:
-            deps |= CGDictionary.getDictionaryDependenciesFromType(member.type)
-        return deps
-
-    @staticmethod
     def isDictionaryCopyConstructible(dictionary):
         if (dictionary.parent and
             not CGDictionary.isDictionaryCopyConstructible(dictionary.parent)):
             return False
         return all(isTypeCopyConstructible(m.type) for m in dictionary.members)
 
 
 class CGRegisterWorkerBindings(CGAbstractMethod):
@@ -12164,16 +12133,31 @@ class CGBindingRoot(CGThing):
             'mozilla/ErrorResult.h',
             ),
             True)
 
         descriptors = config.getDescriptors(webIDLFile=webIDLFile,
                                             hasInterfaceOrInterfacePrototypeObject=True,
                                             skipGen=False)
 
+        unionTypes = UnionsForFile(config, webIDLFile)
+
+        (unionHeaders, unionImplheaders, unionDeclarations, traverseMethods,
+         unlinkMethods, unionStructs) = UnionTypes(unionTypes, config)
+
+        (unionConversionHeaders, unionConversions) = UnionConversions(unionTypes,
+                                                                      config)
+
+        bindingDeclareHeaders.update(dict.fromkeys(unionHeaders, True))
+        bindingHeaders.update(dict.fromkeys(unionImplheaders, True))
+        bindingDeclareHeaders.update(dict.fromkeys(unionConversionHeaders, True))
+
+        bindingDeclareHeaders["UnionMember.h"] = len(unionStructs) > 0
+        bindingDeclareHeaders["BindingUtils.h"] = len(unionStructs) > 0
+
         def descriptorHasCrossOriginProperties(desc):
             def hasCrossOriginProperty(m):
                 props = memberProperties(m, desc)
                 return (props.isCrossOriginMethod or
                         props.isCrossOriginGetter or
                         props.isCrossOriginSetter)
 
             return any(hasCrossOriginProperty(m) for m in desc.interface.members)
@@ -12275,25 +12259,65 @@ class CGBindingRoot(CGThing):
         bindingHeaders["mozilla/dom/BindingDeclarations.h"] = (
             not hasCode and enums)
 
         bindingHeaders["WrapperFactory.h"] = descriptors
         bindingHeaders["mozilla/dom/DOMJSClass.h"] = descriptors
         bindingHeaders["mozilla/dom/ScriptSettings.h"] = dictionaries # AutoJSAPI
         bindingHeaders["xpcpublic.h"] = dictionaries ## xpc::UnprivilegedJunkScope
 
+        cgthings.extend(traverseMethods)
+        cgthings.extend(unlinkMethods)
+
         # Do codegen for all the dictionaries.  We have to be a bit careful
         # here, because we have to generate these in order from least derived
         # to most derived so that class inheritance works out.  We also have to
         # generate members before the dictionary that contains them.
-        cgthings.extend([CGDictionary(d, config.getDescriptorProvider(False))
-                         for d in
-                         dependencySortObjects(dictionaries,
-                                               CGDictionary.getDictionaryDependencies,
-                                               lambda d: d.identifier.name)])
+
+        def getDependenciesFromType(type):
+            if type.isDictionary():
+                return set([type.unroll().inner])
+            if type.isSequence() or type.isArray():
+                return getDependenciesFromType(type.unroll())
+            if type.isUnion():
+                return set([type.unroll()])
+            return set()
+
+        def getDependencies(unionTypeOrDictionary):
+            if isinstance(unionTypeOrDictionary, IDLDictionary):
+                deps = set()
+                if unionTypeOrDictionary.parent:
+                    deps.add(unionTypeOrDictionary.parent)
+                for member in unionTypeOrDictionary.members:
+                    deps |= getDependenciesFromType(member.type)
+                return deps
+
+            assert unionTypeOrDictionary.isType() and unionTypeOrDictionary.isUnion()
+            deps = set()
+            for member in unionTypeOrDictionary.flatMemberTypes:
+                deps |= getDependenciesFromType(member)
+            return deps
+
+        def getName(unionTypeOrDictionary):
+            if isinstance(unionTypeOrDictionary, IDLDictionary):
+                return unionTypeOrDictionary.identifier.name
+
+            assert unionTypeOrDictionary.isType() and unionTypeOrDictionary.isUnion()
+            return unionTypeOrDictionary.name
+
+        for t in dependencySortObjects(dictionaries + unionStructs, getDependencies, getName):
+            if t.isDictionary():
+                cgthings.append(CGDictionary(t, config.getDescriptorProvider(False)))
+            else:
+                assert t.isUnion()
+                # FIXME: Unions are broken in workers.  See bug 809899.
+                cgthings.append(CGUnionStruct(t, config.getDescriptorProvider(False)))
+                cgthings.append(CGUnionStruct(t, config.getDescriptorProvider(False), True))
+
+        cgthings.append(unionConversions)
 
         # Do codegen for all the callbacks.
         cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(False))
                         for c in mainCallbacks)
 
         cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(True))
                         for c in workerCallbacks if c not in mainCallbacks)
 
@@ -12316,20 +12340,25 @@ class CGBindingRoot(CGThing):
 
         # And make sure we have the right number of newlines at the end
         curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")
 
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'],
                                  CGWrapper(curr, pre="\n"))
 
+        builder = ForwardDeclarationBuilder()
+        for className, isStruct in unionDeclarations:
+            builder.add(className, isStruct=isStruct)
+
         curr = CGList([CGForwardDeclarations(config, descriptors,
                                              mainCallbacks, workerCallbacks,
                                              dictionaries,
                                              callbackDescriptors + jsImplemented),
+                       builder.build(),
                        curr],
                       "\n")
 
         # Add header includes.
         bindingHeaders = [header
                           for header, include in bindingHeaders.iteritems()
                           if include]
         bindingDeclareHeaders = [header
@@ -14399,78 +14428,58 @@ class GlobalGenRoots():
         # Add include guards.
         curr = CGIncludeGuard('RegisterWorkerBindings', curr)
 
         # Done.
         return curr
 
     @staticmethod
     def UnionTypes(config):
-
-        (includes, implincludes,
-         declarations, unions) = UnionTypes(config.getDescriptors(),
-                                            config.getDictionaries(),
-                                            config.getCallbacks(),
-                                            config)
+        unionTypes = UnionsForFile(config, None)
+        (includes, implincludes, declarations,
+         traverseMethods, unlinkMethods,
+         unionStructs) = UnionTypes(unionTypes, config)
+
+        unions = CGList(traverseMethods +
+                        unlinkMethods +
+                        [CGUnionStruct(t, config.getDescriptorProvider(False)) for t in unionStructs] +
+                        [CGUnionStruct(t, config.getDescriptorProvider(False), True) for t in unionStructs],
+                        "\n")
+
         includes.add("mozilla/dom/OwningNonNull.h")
         includes.add("mozilla/dom/UnionMember.h")
         includes.add("mozilla/dom/BindingDeclarations.h")
         # Need BindingUtils.h for FakeString
         includes.add("mozilla/dom/BindingUtils.h")
         implincludes.add("mozilla/dom/PrimitiveConversions.h")
 
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'], unions)
 
         curr = CGWrapper(curr, post='\n')
 
-        namespaces = []
-        stack = [CGList([])]
-        for clazz, isStruct in sorted(declarations):
-            elements = clazz.split("::")
-            clazz = CGClassForwardDeclare(elements.pop(), isStruct=isStruct)
-            i = 0
-            if len(elements) > 0:
-                common = min(len(namespaces), len(elements))
-                while i < common and namespaces[i] == elements[i]:
-                    i += 1
-
-            # pop all the namespaces that should be closed
-            namespaces = namespaces[:i]
-
-            # add all the namespaces that should be opened
-            for j, namespace in enumerate(elements[i:]):
-                namespaces.append(namespace)
-                # every CGNamespace that we add holds a CGList
-                list = CGList([])
-                # add the new namespace to the list on top of the stack
-                stack[i + j].append(CGNamespace(namespace, list))
-                # set the top of the namespace stack to the list of the new
-                # namespace
-                stack[i + j + 1:] = [list]
-
-            stack[len(elements)].append(clazz)
-
-        curr = CGList([stack[0], curr], "\n")
+        builder = ForwardDeclarationBuilder()
+        for className, isStruct in declarations:
+            builder.add(className, isStruct=isStruct)
+
+        curr = CGList([builder.build(), curr], "\n")
 
         curr = CGHeaders([], [], [], [], includes, implincludes, 'UnionTypes',
                          curr)
 
         # Add include guards.
         curr = CGIncludeGuard('UnionTypes', curr)
 
         # Done.
         return curr
 
     @staticmethod
     def UnionConversions(config):
-
-        headers, unions = UnionConversions(config.getDescriptors(),
-                                           config.getDictionaries(),
-                                           config.getCallbacks(),
+        unionTypes = UnionsForFile(config, None)
+        headers, unions = UnionConversions(unionTypes,
                                            config)
 
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'], unions)
 
         curr = CGWrapper(curr, post='\n')
 
         headers.update(["nsDebug.h", "mozilla/dom/UnionTypes.h"])
@@ -14981,17 +14990,17 @@ class CGEventRoot(CGThing):
                                   'mozilla/dom/BindingUtils.h',
                               ],
                               [
                                   "%s.h" % interfaceName,
                                   "js/GCAPI.h",
                                   'mozilla/dom/Nullable.h',
                                   'nsDOMQS.h'
                               ],
-                              "", self.root)
+                              "", self.root, config)
 
         # And now some include guards
         self.root = CGIncludeGuard(interfaceName, self.root)
 
         self.root = CGWrapper(self.root, pre=AUTOGENERATED_WARNING_COMMENT)
 
         self.root = CGWrapper(self.root, pre=dedent("""
             /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -1,14 +1,15 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from WebIDL import IDLInterface, IDLExternalInterface, IDLImplementsStatement
 import os
+from collections import defaultdict
 
 autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n"
 
 class Configuration:
     """
     Represents global configuration state based on IDL parse data and
     the configuration file.
     """
@@ -112,16 +113,62 @@ class Configuration:
                            self.getDescriptors(workers=True, isExternal=False, skipGen=False)):
             workerTypes |= set(getFlatTypes(getTypesFromDescriptor(descriptor)))
         (workerCallbacks, workerDictionaries) = findCallbacksAndDictionaries(workerTypes)
 
         self.dictionaries = [d for d in parseData if d.isDictionary()]
         self.callbacks = [c for c in parseData if
                           c.isCallback() and not c.isInterface()]
 
+        # Dictionary mapping from a union type name to a set of filenames where
+        # union types with that name are used.
+        self.filenamesPerUnion = defaultdict(set)
+
+        # Dictionary mapping from a filename to a list of tuples containing a
+        # type and descriptor for the union types used in that file. If a union
+        # type is used in multiple files then it will be added to the list
+        # for the None key. Note that the list contains a tuple for every use of
+        # a union type, so there can be multiple tuples with union types that
+        # have the same name.
+        self.unionsPerFilename = defaultdict(list)
+
+        for (t, descriptor, _) in getAllTypes(self.descriptors, self.dictionaries, self.callbacks):
+            if t.isMozMap():
+                t = t.inner
+            t = t.unroll()
+            if t.isUnion():
+                filenamesForUnion = self.filenamesPerUnion[t.name]
+                if t.filename() not in filenamesForUnion:
+                    if len(filenamesForUnion) == 0:
+                        # This is the first file that we found a union with this
+                        # name in, record the union as part of the file.
+                        uniqueFilenameForUnion = t.filename()
+                    else:
+                        # We already found a file that contains a union with
+                        # this name.
+                        if len(filenamesForUnion) == 1:
+                            # This is the first time we found a union with this
+                            # name in another file.
+                            for f in filenamesForUnion:
+                                # Filter out unions with this name from the
+                                # unions for the file where we previously found
+                                # them.
+                                unionsForFilename = self.unionsPerFilename[f]
+                                unionsForFilename = filter(lambda u: u[0].name != t.name,
+                                                           unionsForFilename)
+                                if len(unionsForFilename) == 0:
+                                    del self.unionsPerFilename[f]
+                                else:
+                                    self.unionsPerFilename[f] = unionsForFilename
+                        # Unions with this name appear in multiple files, record
+                        # the filename as None, so that we can detect that.
+                        uniqueFilenameForUnion = None
+                    self.unionsPerFilename[uniqueFilenameForUnion].append((t, descriptor))
+                    filenamesForUnion.add(t.filename())
+
         def flagWorkerOrMainThread(items, main, worker):
             for item in items:
                 if item in main:
                     item.setUserData("mainThread", True)
                 if item in worker:
                     item.setUserData("workers", True)
         flagWorkerOrMainThread(self.callbacks, mainCallbacks, workerCallbacks)
 
@@ -707,8 +754,27 @@ def findCallbacksAndDictionaries(inputTy
                     d = d.parent
         if len(unhandledTypes) != 0:
             doFindCallbacksAndDictionaries(unhandledTypes, callbacks, dictionaries)
 
     retCallbacks = set()
     retDictionaries = set()
     doFindCallbacksAndDictionaries(inputTypes, retCallbacks, retDictionaries)
     return (retCallbacks, retDictionaries)
+
+def getAllTypes(descriptors, dictionaries, callbacks):
+    """
+    Generate all the types we're dealing with.  For each type, a tuple
+    containing type, descriptor, dictionary is yielded.  The
+    descriptor and dictionary can be None if the type does not come
+    from a descriptor or dictionary; they will never both be non-None.
+    """
+    for d in descriptors:
+        if d.interface.isExternal():
+            continue
+        for t in getTypesFromDescriptor(d):
+            yield (t, d, None)
+    for dictionary in dictionaries:
+        for t in getTypesFromDictionary(dictionary):
+            yield (t, None, dictionary)
+    for callback in callbacks:
+        for t in getTypesFromCallback(callback):
+            yield (t, None, None)
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -2053,16 +2053,20 @@ class IDLUnionType(IDLType):
         self.hasNullableType = False
         self.hasDictionaryType = False
         self.flatMemberTypes = None
         self.builtin = False
 
     def __eq__(self, other):
         return isinstance(other, IDLUnionType) and self.memberTypes == other.memberTypes
 
+    def __hash__(self):
+        assert self.isComplete()
+        return self.name.__hash__()
+
     def isVoid(self):
         return False
 
     def isUnion(self):
         return True
 
     def isSerializable(self):
         return all(m.isSerializable() for m in self.memberTypes)
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -6,17 +6,16 @@
 
 #ifndef TestBindingHeader_h
 #define TestBindingHeader_h
 
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Date.h"
 #include "mozilla/dom/MozMap.h"
 #include "mozilla/dom/TypedArray.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "mozilla/ErrorResult.h"
 #include "nsCOMPtr.h"
 #include "nsGenericHTMLElement.h"
 #include "nsWrapperCache.h"
 
 // Forward declare this before we include TestCodeGenBinding.h, because that header relies on including
 // this one for it, for ParentDict. Hopefully it won't begin to rely on it in more fundamental ways.
 namespace mozilla {
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -93,17 +93,16 @@
 #include "mozilla/unused.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsWrapperCacheInlines.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/SVGMatrix.h"
 #include "mozilla/dom/TextMetrics.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "mozilla/dom/SVGMatrix.h"
 #include "mozilla/FloatingPoint.h"
 #include "nsGlobalWindow.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 #include "SVGContentUtils.h"
 #include "SVGImageContext.h"
 #include "nsIScreenManager.h"
--- a/dom/events/JSEventHandler.cpp
+++ b/dom/events/JSEventHandler.cpp
@@ -18,17 +18,16 @@
 #include "nsDOMJSUtils.h"
 #include "WorkerPrivate.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/CycleCollectedJSRuntime.h"
 #include "mozilla/HoldDropJSObjects.h"
 #include "mozilla/JSEventHandler.h"
 #include "mozilla/Likely.h"
 #include "mozilla/dom/ErrorEvent.h"
-#include "mozilla/dom/UnionTypes.h"
 
 namespace mozilla {
 
 using namespace dom;
 
 JSEventHandler::JSEventHandler(nsISupports* aTarget,
                                nsIAtom* aType,
                                const TypedEventHandler& aTypedHandler)
--- a/dom/events/MessageEvent.cpp
+++ b/dom/events/MessageEvent.cpp
@@ -3,17 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/MessageEvent.h"
 #include "mozilla/dom/MessageEventBinding.h"
 #include "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/MessagePortBinding.h"
 #include "mozilla/dom/MessagePortList.h"
-#include "mozilla/dom/UnionTypes.h"
 
 #include "mozilla/HoldDropJSObjects.h"
 #include "jsapi.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(MessageEvent)
--- a/dom/fetch/Fetch.cpp
+++ b/dom/fetch/Fetch.cpp
@@ -6,16 +6,17 @@
 #include "Fetch.h"
 
 #include "nsIStringStream.h"
 #include "nsIUnicodeEncoder.h"
 
 #include "nsStringStream.h"
 
 #include "mozilla/dom/EncodingUtils.h"
+#include "mozilla/dom/FetchBinding.h"
 #include "mozilla/dom/URLSearchParams.h"
 
 namespace mozilla {
 namespace dom {
 
 nsresult
 ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrScalarValueStringOrURLSearchParams& aBodyInit,
                           nsIInputStream** aStream,
--- a/dom/fetch/Fetch.h
+++ b/dom/fetch/Fetch.h
@@ -1,23 +1,26 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_Fetch_h
 #define mozilla_dom_Fetch_h
 
-#include "mozilla/dom/UnionTypes.h"
+#include "nsError.h"
 
+class nsCString;
 class nsIInputStream;
 
 namespace mozilla {
 namespace dom {
 
+class OwningArrayBufferOrArrayBufferViewOrScalarValueStringOrURLSearchParams;
+
 /*
  * Creates an nsIInputStream based on the fetch specifications 'extract a byte
  * stream algorithm' - http://fetch.spec.whatwg.org/#concept-bodyinit-extract.
  * Stores content type in out param aContentType.
  */
 nsresult
 ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrScalarValueStringOrURLSearchParams& aBodyInit,
                           nsIInputStream** aStream,
--- a/dom/filesystem/Directory.cpp
+++ b/dom/filesystem/Directory.cpp
@@ -12,17 +12,16 @@
 #include "GetFileOrDirectoryTask.h"
 #include "RemoveTask.h"
 
 #include "nsCharSeparatedTokenizer.h"
 #include "nsString.h"
 #include "mozilla/dom/DirectoryBinding.h"
 #include "mozilla/dom/FileSystemBase.h"
 #include "mozilla/dom/FileSystemUtils.h"
-#include "mozilla/dom/UnionTypes.h"
 
 // Resolve the name collision of Microsoft's API name with macros defined in
 // Windows header files. Undefine the macro of CreateDirectory to avoid
 // Directory#CreateDirectory being replaced by Directory#CreateDirectoryW.
 #ifdef CreateDirectory
 #undef CreateDirectory
 #endif
 // Undefine the macro of CreateFile to avoid Directory#CreateFile being replaced
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -16,17 +16,16 @@
 #include "IDBTransaction.h"
 #include "mozilla/ContentEvents.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/dom/DOMError.h"
 #include "mozilla/dom/ErrorEventBinding.h"
 #include "mozilla/dom/IDBOpenDBRequestBinding.h"
 #include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsIScriptContext.h"
 #include "nsJSUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsString.h"
 #include "ReportInternalError.h"
 
--- a/dom/mobilemessage/DOMMobileMessageError.cpp
+++ b/dom/mobilemessage/DOMMobileMessageError.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DOMMobileMessageError.h"
 #include "mozilla/dom/DOMMobileMessageErrorBinding.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "nsIDOMMozMmsMessage.h"
 #include "nsIDOMMozSmsMessage.h"
 
 using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(DOMMobileMessageError)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMMobileMessageError, DOMError)
--- a/dom/mobilemessage/MobileMessageManager.h
+++ b/dom/mobilemessage/MobileMessageManager.h
@@ -2,32 +2,32 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_mobilemessage_MobileMessageManager_h
 #define mozilla_dom_mobilemessage_MobileMessageManager_h
 
 #include "mozilla/Attributes.h"
-#include "mozilla/dom/UnionTypes.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "nsIObserver.h"
 
 class nsISmsService;
 class nsIDOMMozSmsMessage;
 class nsIDOMMozMmsMessage;
 
 namespace mozilla {
 namespace dom {
 
 class DOMRequest;
 class DOMCursor;
 struct MmsParameters;
 struct MmsSendParameters;
 struct MobileMessageFilter;
+class OwningLongOrMozSmsMessageOrMozMmsMessage;
 struct SmsSendParameters;
 
 class MobileMessageManager MOZ_FINAL : public DOMEventTargetHelper
                                      , public nsIObserver
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIOBSERVER
--- a/dom/telephony/Telephony.cpp
+++ b/dom/telephony/Telephony.cpp
@@ -6,17 +6,16 @@
 
 #include "Telephony.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/CallEvent.h"
 #include "mozilla/dom/MozMobileConnectionBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/TelephonyBinding.h"
-#include "mozilla/dom/UnionTypes.h"
 
 #include "nsCharSeparatedTokenizer.h"
 #include "nsContentUtils.h"
 #include "nsIPermissionManager.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsPIDOMWindow.h"
 #include "nsServiceManagerUtils.h"