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 234868 6f411275b7ec5dc953fdabdc198f9af5b8a35ca9
parent 234867 8d198ef0b5596bc4c6c1a72ef9ae3c981025ca65
child 234869 7f5287115874d9efd54ee8d2db40459577e8eddc
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1068740
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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"