Backed out 11 changesets (bug 1359269) for Linting failure. CLOSED TREE
authorDorel Luca <dluca@mozilla.com>
Sat, 02 Mar 2019 04:07:00 +0200
changeset 519953 0c70617150d9a41cb2f2f4fafcab9ae50c15ddd1
parent 519952 689c3fe760069f90a24039a4d24986f0d38303ca
child 519954 21deba7e36c509a6ba39e3913d19619bfc38f3a5
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1359269
milestone67.0a1
backs out00461a29f65058cb569c8a75e286d0c1ba6aff63
6c09eccc4bd1ac6feabc803d8bc8d769cc911599
ae30401e7988d753acd0ae8f9086e9129b6bbb1e
8f9509e82439ccd4544624d7f52773698db3ea3c
bfb153c7f9c39160da697d3e2af5bcb7f594547b
1430913c5e9e72775aaa86e8b37be3a15ab73254
4bb00dc53459ed7a25e09f2f4c14fcfd23ca9e9e
7705b1ebb154a5b9ec4eff507043bc9880d49bd3
7fd8a3c1f827da2987586dfee361c1dd528fd009
c3f37539cb314566aef560602fecf68fe2de1602
bb694b612b1ba466b71f22aa1793f7d3149ec945
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
Backed out 11 changesets (bug 1359269) for Linting failure. CLOSED TREE Backed out changeset 00461a29f650 (bug 1359269) Backed out changeset 6c09eccc4bd1 (bug 1359269) Backed out changeset ae30401e7988 (bug 1359269) Backed out changeset 8f9509e82439 (bug 1359269) Backed out changeset bfb153c7f9c3 (bug 1359269) Backed out changeset 1430913c5e9e (bug 1359269) Backed out changeset 4bb00dc53459 (bug 1359269) Backed out changeset 7705b1ebb154 (bug 1359269) Backed out changeset 7fd8a3c1f827 (bug 1359269) Backed out changeset c3f37539cb31 (bug 1359269) Backed out changeset bb694b612b1b (bug 1359269)
dom/bindings/Bindings.conf
dom/bindings/Codegen.py
dom/bindings/GenerateCSS2PropertiesWebIDL.py
dom/bindings/parser/WebIDL.py
dom/bindings/parser/tests/test_attributes_on_types.py
dom/bindings/test/TestBindingHeader.h
dom/bindings/test/TestCodeGen.webidl
dom/bindings/test/TestExampleGen.webidl
dom/bindings/test/TestJSImplGen.webidl
dom/chrome-webidl/InspectorUtils.webidl
dom/imptests/html/dom/test_interfaces.html
dom/webidl/Blob.webidl
dom/webidl/CSSStyleDeclaration.webidl
dom/webidl/CharacterData.webidl
dom/webidl/Element.webidl
dom/webidl/HTMLBodyElement.webidl
dom/webidl/HTMLDocument.webidl
dom/webidl/HTMLElement.webidl
dom/webidl/HTMLFontElement.webidl
dom/webidl/HTMLFrameElement.webidl
dom/webidl/HTMLIFrameElement.webidl
dom/webidl/HTMLImageElement.webidl
dom/webidl/HTMLInputElement.webidl
dom/webidl/HTMLObjectElement.webidl
dom/webidl/HTMLTableCellElement.webidl
dom/webidl/HTMLTableElement.webidl
dom/webidl/HTMLTableRowElement.webidl
dom/webidl/HTMLTextAreaElement.webidl
dom/webidl/IDBIndex.webidl
dom/webidl/IDBObjectStore.webidl
dom/webidl/MediaList.webidl
dom/webidl/ShadowRoot.webidl
dom/webidl/SubtleCrypto.webidl
dom/webidl/WebSocket.webidl
dom/webidl/Window.webidl
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1823,21 +1823,16 @@ DOMInterfaces = {
         'headerFile': 'TestBindingHeader.h',
         'register': False,
         },
 
 'TestCEReactionsInterface' : {
         'headerFile': 'TestBindingHeader.h',
         'register': False,
         },
-
-'TestAttributesOnTypes' : {
-        'headerFile': 'TestBindingHeader.h',
-        'register': False,
-        },
 }
 
 # These are temporary, until they've been converted to use new DOM bindings
 def addExternalIface(iface, nativeType=None, headerFile=None,
                      notflattened=False):
     if iface in DOMInterfaces:
         raise Exception('Interface declared both as WebIDL and External interface')
     domInterface = {
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -4565,16 +4565,19 @@ def recordKeyDeclType(recordType):
 # and holdertype we end up using, because it needs to be able to return the code
 # that will convert those to the actual return value of the callback function.
 def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
                                 isDefinitelyObject=False,
                                 isMember=False,
                                 isOptional=False,
                                 invalidEnumValueFatal=True,
                                 defaultValue=None,
+                                treatNullAs="Default",
+                                isEnforceRange=False,
+                                isClamp=False,
                                 isNullOrUndefined=False,
                                 exceptionCode=None,
                                 lenientFloatCode=None,
                                 allowTreatNonCallableAsNull=False,
                                 isCallbackReturnValue=False,
                                 sourceDescription="value",
                                 nestingLevel=""):
     """
@@ -4642,19 +4645,16 @@ def getJSToNativeConversionInfo(type, de
     assert defaultValue is None or not isOptional
 
     # Also, we should not have a defaultValue if we know we're an object
     assert not isDefinitelyObject or defaultValue is None
 
     # And we can't both be an object and be null or undefined
     assert not isDefinitelyObject or not isNullOrUndefined
 
-    isClamp = type.clamp
-    isEnforceRange = type.enforceRange
-
     # If exceptionCode is not set, we'll just rethrow the exception we got.
     # Note that we can't just set failureCode to exceptionCode, because setting
     # failureCode will prevent pending exceptions from being set in cases when
     # they really should be!
     if exceptionCode is None:
         exceptionCode = "return false;\n"
 
     # Unfortunately, .capitalize() on a string will lowercase things inside the
@@ -5783,20 +5783,16 @@ def getJSToNativeConversionInfo(type, de
         }
         if type.nullable():
             # For nullable strings null becomes a null string.
             treatNullAs = "Null"
             # For nullable strings undefined also becomes a null string.
             undefinedBehavior = "eNull"
         else:
             undefinedBehavior = "eStringify"
-            if type.treatNullAsEmpty:
-                treatNullAs = "EmptyString"
-            else:
-                treatNullAs = "Default"
         nullBehavior = treatAs[treatNullAs]
 
         def getConversionCode(varName):
             normalizeCode = ""
             if type.isUSVString():
                 normalizeCode = "NormalizeUSVString(%s);\n" % varName
 
             conversionCode = fill("""
@@ -6442,16 +6438,19 @@ class CGArgumentConverter(CGThing):
     def define(self):
         typeConversion = getJSToNativeConversionInfo(
             self.argument.type,
             self.descriptorProvider,
             isOptional=(self.argcAndIndex is not None and
                         not self.argument.variadic),
             invalidEnumValueFatal=self.invalidEnumValueFatal,
             defaultValue=self.argument.defaultValue,
+            treatNullAs=self.argument.treatNullAs,
+            isEnforceRange=self.argument.enforceRange,
+            isClamp=self.argument.clamp,
             lenientFloatCode=self.lenientFloatCode,
             isMember="Variadic" if self.argument.variadic else False,
             allowTreatNonCallableAsNull=self.argument.allowTreatNonCallableAsNull(),
             sourceDescription=self.argDescription)
 
         if not self.argument.variadic:
             return instantiateJSToNativeConversion(
                 typeConversion,
@@ -8607,16 +8606,28 @@ class FakeArgument():
     setters look like method calls or for special operations.
     """
     def __init__(self, type, interfaceMember, name="arg", allowTreatNonCallableAsNull=False):
         self.type = type
         self.optional = False
         self.variadic = False
         self.defaultValue = None
         self._allowTreatNonCallableAsNull = allowTreatNonCallableAsNull
+        # For FakeArguments generated by maplike/setlike convenience functions,
+        # we won't have an interfaceMember to pass in.
+        if interfaceMember:
+            self.treatNullAs = interfaceMember.treatNullAs
+        else:
+            self.treatNullAs = "Default"
+        if isinstance(interfaceMember, IDLAttribute):
+            self.enforceRange = interfaceMember.enforceRange
+            self.clamp = interfaceMember.clamp
+        else:
+            self.enforceRange = False
+            self.clamp = False
 
         self.identifier = FakeIdentifier(name)
 
     def allowTreatNonCallableAsNull(self):
         return self._allowTreatNonCallableAsNull
 
     def canHaveMissingValue(self):
         return False
@@ -11308,16 +11319,17 @@ class CGProxySpecialOperation(CGPerSigna
                                     len(arguments), resultVar=resultVar,
                                     objectName="proxy")
 
         if operation.isSetter():
             # arguments[0] is the index or name of the item that we're setting.
             argument = arguments[1]
             info = getJSToNativeConversionInfo(
                 argument.type, descriptor,
+                treatNullAs=argument.treatNullAs,
                 sourceDescription=("value being assigned to %s setter" %
                                    descriptor.interface.identifier.name))
             if argumentHandleValue is None:
                 argumentHandleValue = "desc.value()"
             rootedValue = fill(
                 """
                 JS::Rooted<JS::Value> rootedValue(cx, ${argumentHandleValue});
                 """,
@@ -13306,16 +13318,18 @@ class CGDictionary(CGThing):
         self.dictionary = dictionary
         self.descriptorProvider = descriptorProvider
         self.needToInitIds = len(dictionary.members) > 0
         self.memberInfo = [
             (member,
              getJSToNativeConversionInfo(
                  member.type,
                  descriptorProvider,
+                 isEnforceRange=member.enforceRange,
+                 isClamp=member.clamp,
                  isMember="Dictionary",
                  isOptional=member.canHaveMissingValue(),
                  defaultValue=member.defaultValue,
                  sourceDescription=self.getMemberSourceDescription(member)))
             for member in dictionary.members]
 
         # If we have a union member containing something in the same
         # file as us, bail: the C++ includes won't work out.
@@ -16355,16 +16369,17 @@ class CGCallbackInterface(CGCallback):
             methods.append(initIdsClassMethod(idlist,
                                               iface.identifier.name + "Atoms"))
         CGCallback.__init__(self, iface, descriptor, "CallbackInterface",
                             methods, getters=getters, setters=setters)
 
 
 class FakeMember():
     def __init__(self, name=None):
+        self.treatNullAs = "Default"
         if name is not None:
             self.identifier = FakeIdentifier(name)
 
     def isStatic(self):
         return False
 
     def isAttr(self):
         return False
--- a/dom/bindings/GenerateCSS2PropertiesWebIDL.py
+++ b/dom/bindings/GenerateCSS2PropertiesWebIDL.py
@@ -6,27 +6,27 @@ import sys
 import string
 import argparse
 import runpy
 
 # Generates a line of WebIDL with the given spelling of the property name
 # (whether camelCase, _underscorePrefixed, etc.) and the given array of
 # extended attributes.
 def generateLine(propName, extendedAttrs):
-    return "  [%s] attribute [TreatNullAs=EmptyString] DOMString %s;\n" % (", ".join(extendedAttrs),
+    return "  [%s] attribute DOMString %s;\n" % (", ".join(extendedAttrs),
                                                  propName)
 def generate(output, idlFilename, dataFile):
     propList = runpy.run_path(dataFile)["data"]
     props = ""
     for p in propList:
         if "Internal" in p.flags:
             continue
         # Unfortunately, even some of the getters here are fallible
         # (e.g. on nsComputedDOMStyle).
-        extendedAttrs = ["CEReactions", "Throws",
+        extendedAttrs = ["CEReactions", "Throws", "TreatNullAs=EmptyString",
                          "SetterNeedsSubjectPrincipal=NonSystem"]
         if p.pref is not "":
             extendedAttrs.append('Pref="%s"' % p.pref)
 
         prop = p.method
 
         # webkit properties get a camelcase "webkitFoo" accessor
         # as well as a capitalized "WebkitFoo" alias (added here).
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -415,21 +415,58 @@ class IDLObjectWithIdentifier(IDLObject)
 
         assert isinstance(identifier, IDLUnresolvedIdentifier)
 
         self.identifier = identifier
 
         if parentScope:
             self.resolve(parentScope)
 
+        self.treatNullAs = "Default"
+
     def resolve(self, parentScope):
         assert isinstance(parentScope, IDLScope)
         assert isinstance(self.identifier, IDLUnresolvedIdentifier)
         self.identifier.resolve(parentScope, self)
 
+    def checkForStringHandlingExtendedAttributes(self, attrs,
+                                                 isDictionaryMember=False,
+                                                 isOptional=False):
+        """
+        A helper function to deal with TreatNullAs.  Returns the list
+        of attrs it didn't handle itself.
+        """
+        assert isinstance(self, IDLArgument) or isinstance(self, IDLAttribute)
+        unhandledAttrs = list()
+        for attr in attrs:
+            if not attr.hasValue():
+                unhandledAttrs.append(attr)
+                continue
+
+            identifier = attr.identifier()
+            value = attr.value()
+            if identifier == "TreatNullAs":
+                if not self.type.isDOMString() or self.type.nullable():
+                    raise WebIDLError("[TreatNullAs] is only allowed on "
+                                      "arguments or attributes whose type is "
+                                      "DOMString",
+                                      [self.location])
+                if isDictionaryMember:
+                    raise WebIDLError("[TreatNullAs] is not allowed for "
+                                      "dictionary members", [self.location])
+                if value != 'EmptyString':
+                    raise WebIDLError("[TreatNullAs] must take the identifier "
+                                      "'EmptyString', not '%s'" % value,
+                                      [self.location])
+                self.treatNullAs = value
+            else:
+                unhandledAttrs.append(attr)
+
+        return unhandledAttrs
+
 
 class IDLObjectWithScope(IDLObjectWithIdentifier, IDLScope):
     def __init__(self, location, parentScope, identifier):
         assert isinstance(identifier, IDLUnresolvedIdentifier)
 
         IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier)
         IDLScope.__init__(self, location, parentScope, self.identifier)
 
@@ -2052,25 +2089,19 @@ class IDLType(IDLObject):
         'record',
         'promise',
         )
 
     def __init__(self, location, name):
         IDLObject.__init__(self, location)
         self.name = name
         self.builtin = False
-        self.clamp = False
-        self.treatNullAsEmpty = False
-        self.enforceRange = False
-        self._extendedAttrDict = {}
 
     def __eq__(self, other):
-        return (other and self.builtin == other.builtin and self.name == other.name and
-                          self.clamp == other.clamp and self.enforceRange == other.enforceRange and
-                          self.treatNullAsEmpty == other.treatNullAsEmpty)
+        return other and self.builtin == other.builtin and self.name == other.name
 
     def __ne__(self, other):
         return not self == other
 
     def __str__(self):
         return str(self.name)
 
     def isType(self):
@@ -2186,24 +2217,22 @@ class IDLType(IDLObject):
     def treatNonCallableAsNull(self):
         assert self.tag() == IDLType.Tags.callback
         return self.nullable() and self.inner.callback._treatNonCallableAsNull
 
     def treatNonObjectAsNull(self):
         assert self.tag() == IDLType.Tags.callback
         return self.nullable() and self.inner.callback._treatNonObjectAsNull
 
-    def withExtendedAttributes(self, attrs):
-        if len(attrs) > 0:
-            raise WebIDLError("Extended attributes on types only supported for builtins",
+    def addExtendedAttributes(self, attrs):
+        if len(attrs) != 0:
+            raise WebIDLError("There are no extended attributes that are "
+                              "allowed on types, for now (but this is "
+                              "changing; see bug 1359269)",
                               [attrs[0].location, self.location])
-        return self
-
-    def getExtendedAttribute(self, name):
-        return self._extendedAttrDict.get(name, None)
 
     def resolveType(self, parentScope):
         pass
 
     def unroll(self):
         return self
 
     def isDistinguishableFrom(self, other):
@@ -2214,19 +2243,18 @@ class IDLType(IDLObject):
         return True
 
 
 class IDLUnresolvedType(IDLType):
     """
         Unresolved types are interface types
     """
 
-    def __init__(self, location, name, attrs=[]):
+    def __init__(self, location, name):
         IDLType.__init__(self, location, name)
-        self.extraTypeAttributes = attrs
 
     def isComplete(self):
         return False
 
     def complete(self, scope):
         obj = None
         try:
             obj = scope._lookupIdentifier(self.name)
@@ -2238,27 +2266,24 @@ class IDLUnresolvedType(IDLType):
         if obj.isType():
             print obj
         assert not obj.isType()
         if obj.isTypedef():
             assert self.name.name == obj.identifier.name
             typedefType = IDLTypedefType(self.location, obj.innerType,
                                          obj.identifier)
             assert not typedefType.isComplete()
-            return typedefType.complete(scope).withExtendedAttributes(self.extraTypeAttributes)
+            return typedefType.complete(scope)
         elif obj.isCallback() and not obj.isInterface():
             assert self.name.name == obj.identifier.name
             return IDLCallbackType(self.location, obj)
 
         name = self.name.resolve(scope, None)
         return IDLWrapperType(self.location, obj)
 
-    def withExtendedAttributes(self, attrs):
-        return IDLUnresolvedType(self.location, self.name, attrs)
-
     def isDistinguishableFrom(self, other):
         raise TypeError("Can't tell whether an unresolved type is or is not "
                         "distinguishable from other things")
 
 
 class IDLParametrizedType(IDLType):
     def __init__(self, location, name, innerType):
         IDLType.__init__(self, location, name)
@@ -2756,19 +2781,16 @@ class IDLTypedefType(IDLType):
         return self.inner.unroll()
 
     def isDistinguishableFrom(self, other):
         return self.inner.isDistinguishableFrom(other)
 
     def _getDependentObjects(self):
         return self.inner._getDependentObjects()
 
-    def withExtendedAttributes(self, attrs):
-        return IDLTypedefType(self.location, self.inner.withExtendedAttributes(attrs), self.name)
-
 
 class IDLTypedef(IDLObjectWithIdentifier):
     def __init__(self, location, parentScope, innerType, name):
         # Set self.innerType first, because IDLObjectWithIdentifier.__init__
         # will call our __str__, which wants to use it.
         self.innerType = innerType
         identifier = IDLUnresolvedIdentifier(location, name)
         IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier)
@@ -3078,69 +3100,20 @@ class IDLBuiltinType(IDLType):
         Types.Uint16Array: IDLType.Tags.interface,
         Types.Int32Array: IDLType.Tags.interface,
         Types.Uint32Array: IDLType.Tags.interface,
         Types.Float32Array: IDLType.Tags.interface,
         Types.Float64Array: IDLType.Tags.interface,
         Types.ReadableStream: IDLType.Tags.interface,
     }
 
-    def __init__(self, location, name, type, clamp=False, enforceRange=False, treatNullAsEmpty=False,
-                 attrLocation=[]):
-        """
-        The mutually exclusive clamp/enforceRange/treatNullAsEmpty arguments are used to create instances
-        of this type with the appropriate attributes attached. Use .clamped(), .rangeEnforced(), and .treatNullAs().
-
-        attrLocation is an array of source locations of these attributes for error reporting.
-        """
+    def __init__(self, location, name, type):
         IDLType.__init__(self, location, name)
         self.builtin = True
         self._typeTag = type
-        self._clamped = None
-        self._rangeEnforced = None
-        self._withTreatNullAs = None
-        if self.isNumeric():
-            if clamp:
-                self.clamp = True
-                self.name = "Clamped" + self.name
-                self._extendedAttrDict["Clamp"] = True
-            elif enforceRange:
-                self.enforceRange = True
-                self.name = "RangeEnforced" + self.name
-                self._extendedAttrDict["EnforceRange"] = True
-        elif clamp or enforceRange:
-            raise WebIDLError("Non-numeric types cannot be [Clamp] or [EnforceRange]", attrLocation)
-        if self.isDOMString():
-            if treatNullAsEmpty:
-                self.treatNullAsEmpty = True
-                self.name = "NullIsEmpty" + self.name
-                self._extendedAttrDict["TreatNullAs"] = ["EmptyString"]
-        elif treatNullAsEmpty:
-            raise WebIDLError("Non-string types cannot be [TreatNullAs]", attrLocation)
-
-    def clamped(self, attrLocation):
-        if not self._clamped:
-            self._clamped = IDLBuiltinType(self.location, self.name,
-                                           self._typeTag, clamp=True,
-                                           attrLocation=attrLocation)
-        return self._clamped
-
-    def rangeEnforced(self, attrLocation):
-        if not self._rangeEnforced:
-            self._rangeEnforced = IDLBuiltinType(self.location, self.name,
-                                           self._typeTag, enforceRange=True,
-                                           attrLocation=attrLocation)
-        return self._rangeEnforced
-
-    def withTreatNullAs(self, attrLocation):
-        if not self._withTreatNullAs:
-            self._withTreatNullAs = IDLBuiltinType(self.location, self.name,
-                                           self._typeTag, treatNullAsEmpty=True,
-                                           attrLocation=attrLocation)
-        return self._withTreatNullAs
 
     def isPrimitive(self):
         return self._typeTag <= IDLBuiltinType.Types.double
 
     def isBoolean(self):
         return self._typeTag == IDLBuiltinType.Types.boolean
 
     def isNumeric(self):
@@ -3266,55 +3239,16 @@ class IDLBuiltinType(IDLType):
                  # except ArrayBufferView and the same type of typed
                  # array
                  (self.isTypedArray() and not other.isArrayBufferView() and not
                   (other.isTypedArray() and other.name == self.name)))))
 
     def _getDependentObjects(self):
         return set()
 
-    def withExtendedAttributes(self, attrs):
-        ret = self
-        for attribute in attrs:
-            identifier = attribute.identifier()
-            if identifier == "Clamp":
-                if not attribute.noArguments():
-                    raise WebIDLError("[Clamp] must take no arguments",
-                                      [attribute.location])
-                if ret.enforceRange or self.enforceRange:
-                    raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive",
-                                      [self.location, attribute.location])
-                ret = self.clamped([self.location, attribute.location])
-            elif identifier == "EnforceRange":
-                if not attribute.noArguments():
-                    raise WebIDLError("[EnforceRange] must take no arguments",
-                                      [attribute.location])
-                if ret.clamp or self.clamp:
-                    raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive",
-                                      [self.location, attribute.location])
-                ret = self.rangeEnforced([self.location, attribute.location])
-            elif identifier == "TreatNullAs":
-                if not self.isDOMString():
-                    raise WebIDLError("[TreatNullAs] only allowed on DOMStrings",
-                                      [self.location, attribute.location])
-                assert not self.nullable()
-                if not attribute.hasValue():
-                    raise WebIDLError("[TreatNullAs] must take an identifier argument"
-                                      [attribute.location])
-                value = attribute.value()
-                if value != 'EmptyString':
-                    raise WebIDLError("[TreatNullAs] must take the identifier "
-                                      "'EmptyString', not '%s'" % value,
-                                      [attribute.location])
-                ret = self.withTreatNullAs([self.location, attribute.location])
-            else:
-                raise WebIDLError("Unhandled extended attribute on type",
-                                  [self.location, attribute.location])
-        return ret
-
 BuiltinTypes = {
     IDLBuiltinType.Types.byte:
         IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte",
                        IDLBuiltinType.Types.byte),
     IDLBuiltinType.Types.octet:
         IDLBuiltinType(BuiltinLocation("<builtin type>"), "Octet",
                        IDLBuiltinType.Types.octet),
     IDLBuiltinType.Types.short:
@@ -3519,20 +3453,16 @@ class IDLValue(IDLObject):
             return IDLValue(self.location, type, self.value)
         elif self.type.isString() and type.isUSVString():
             # Allow USVStrings to use default value just like
             # DOMString.  No coercion is required in this case as Codegen.py
             # treats USVString just like DOMString, but with an
             # extra normalization step.
             assert self.type.isDOMString()
             return self
-        elif self.type.isDOMString() and type.treatNullAsEmpty:
-            # TreatNullAsEmpty is a different type for resolution reasons,
-            # however once you have a value it doesn't matter
-            return self
         elif self.type.isString() and type.isByteString():
             # Allow ByteStrings to use a default value like DOMString.
             # No coercion is required as Codegen.py will handle the
             # extra steps. We want to make sure that our string contains
             # only valid characters, so we check that here.
             valid_ascii_lit = " " + string.ascii_letters + string.digits + string.punctuation
             for idx, c in enumerate(self.value):
                 if c not in valid_ascii_lit:
@@ -4164,16 +4094,18 @@ class IDLAttribute(IDLInterfaceMember):
         assert isinstance(type, IDLType)
         self.type = type
         self.readonly = readonly
         self.inherit = inherit
         self._static = static
         self.lenientThis = False
         self._unforgeable = False
         self.stringifier = stringifier
+        self.enforceRange = False
+        self.clamp = False
         self.slotIndices = None
         assert maplikeOrSetlike is None or isinstance(maplikeOrSetlike, IDLMaplikeOrSetlike)
         self.maplikeOrSetlike = maplikeOrSetlike
         self.dependsOn = "Everything"
         self.affects = "Everything"
         self.navigatorObjectGetter = navigatorObjectGetter
         self.bindingAliases = []
 
@@ -4200,19 +4132,16 @@ class IDLAttribute(IDLInterfaceMember):
         if not self.type.isComplete():
             t = self.type.complete(scope)
 
             assert not isinstance(t, IDLUnresolvedType)
             assert not isinstance(t, IDLTypedefType)
             assert not isinstance(t.name, IDLUnresolvedIdentifier)
             self.type = t
 
-        if self.readonly and (self.type.clamp or self.type.enforceRange or self.type.treatNullAsEmpty):
-            raise WebIDLError("A readonly attribute cannot be [Clamp] or [EnforceRange]",
-                              [self.location])
         if self.type.isDictionary() and not self.getExtendedAttribute("Cached"):
             raise WebIDLError("An attribute cannot be of a dictionary type",
                               [self.location])
         if self.type.isSequence() and not self.getExtendedAttribute("Cached"):
             raise WebIDLError("A non-cached attribute cannot be of a sequence "
                               "type", [self.location])
         if self.type.isRecord() and not self.getExtendedAttribute("Cached"):
             raise WebIDLError("A non-cached attribute cannot be of a record "
@@ -4426,16 +4355,26 @@ class IDLAttribute(IDLInterfaceMember):
         elif identifier == "LenientFloat":
             if self.readonly:
                 raise WebIDLError("[LenientFloat] used on a readonly attribute",
                                   [attr.location, self.location])
             if not self.type.includesRestrictedFloat():
                 raise WebIDLError("[LenientFloat] used on an attribute with a "
                                   "non-restricted-float type",
                                   [attr.location, self.location])
+        elif identifier == "EnforceRange":
+            if self.readonly:
+                raise WebIDLError("[EnforceRange] used on a readonly attribute",
+                                  [attr.location, self.location])
+            self.enforceRange = True
+        elif identifier == "Clamp":
+            if self.readonly:
+                raise WebIDLError("[Clamp] used on a readonly attribute",
+                                  [attr.location, self.location])
+            self.clamp = True
         elif identifier == "StoreInSlot":
             if self.getExtendedAttribute("Cached"):
                 raise WebIDLError("[StoreInSlot] and [Cached] must not be "
                                   "specified on the same attribute",
                                   [attr.location, self.location])
         elif identifier == "Cached":
             if self.getExtendedAttribute("StoreInSlot"):
                 raise WebIDLError("[Cached] and [StoreInSlot] must not be "
@@ -4527,16 +4466,20 @@ class IDLAttribute(IDLInterfaceMember):
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
 
     def resolve(self, parentScope):
         assert isinstance(parentScope, IDLScope)
         self.type.resolveType(parentScope)
         IDLObjectWithIdentifier.resolve(self, parentScope)
 
+    def addExtendedAttributes(self, attrs):
+        attrs = self.checkForStringHandlingExtendedAttributes(attrs)
+        IDLInterfaceMember.addExtendedAttributes(self, attrs)
+
     def hasLenientThis(self):
         return self.lenientThis
 
     def isMaplikeOrSetlikeAttr(self):
         """
         True if this attribute was generated from an interface with
         maplike/setlike (e.g. this is the size attribute for
         maplike/setlike)
@@ -4546,40 +4489,58 @@ class IDLAttribute(IDLInterfaceMember):
     def isUnforgeable(self):
         return self._unforgeable
 
     def _getDependentObjects(self):
         return set([self.type])
 
 
 class IDLArgument(IDLObjectWithIdentifier):
-    def __init__(self, location, identifier, type, optional=False, defaultValue=None, variadic=False, dictionaryMember=False, allowTypeAttributes=False):
+    def __init__(self, location, identifier, type, optional=False, defaultValue=None, variadic=False, dictionaryMember=False):
         IDLObjectWithIdentifier.__init__(self, location, None, identifier)
 
         assert isinstance(type, IDLType)
         self.type = type
 
         self.optional = optional
         self.defaultValue = defaultValue
         self.variadic = variadic
         self.dictionaryMember = dictionaryMember
         self._isComplete = False
+        self.enforceRange = False
+        self.clamp = False
         self._allowTreatNonCallableAsNull = False
         self._extendedAttrDict = {}
-        self.allowTypeAttributes = allowTypeAttributes
 
         assert not variadic or optional
         assert not variadic or not defaultValue
 
     def addExtendedAttributes(self, attrs):
+        attrs = self.checkForStringHandlingExtendedAttributes(
+            attrs,
+            isDictionaryMember=self.dictionaryMember,
+            isOptional=self.optional)
         for attribute in attrs:
             identifier = attribute.identifier()
-            if self.allowTypeAttributes and (identifier == "EnforceRange" or identifier == "Clamp" or
-                                             identifier == "TreatNullAs"):
-                self.type = self.type.withExtendedAttributes([attribute])
+            if identifier == "Clamp":
+                if not attribute.noArguments():
+                    raise WebIDLError("[Clamp] must take no arguments",
+                                      [attribute.location])
+                if self.enforceRange:
+                    raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive",
+                                      [self.location])
+                self.clamp = True
+            elif identifier == "EnforceRange":
+                if not attribute.noArguments():
+                    raise WebIDLError("[EnforceRange] must take no arguments",
+                                      [attribute.location])
+                if self.clamp:
+                    raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive",
+                                      [self.location])
+                self.enforceRange = True
             elif identifier == "TreatNonCallableAsNull":
                 self._allowTreatNonCallableAsNull = True
             elif (self.dictionaryMember and
                   (identifier == "ChromeOnly" or identifier == "Func")):
                 if not self.optional:
                     raise WebIDLError("[%s] must not be used on a required "
                                       "dictionary member" % identifier,
                                       [attribute.location])
@@ -5849,52 +5810,41 @@ class Parser(Tokenizer):
         """
             DictionaryMembers : ExtendedAttributeList DictionaryMember DictionaryMembers
                              |
         """
         if len(p) == 1:
             # We're at the end of the list
             p[0] = []
             return
+        # Add our extended attributes
         p[2].addExtendedAttributes(p[1])
         p[0] = [p[2]]
         p[0].extend(p[3])
 
-    def p_DictionaryMemberRequired(self, p):
-        """
-            DictionaryMember : REQUIRED TypeWithExtendedAttributes IDENTIFIER SEMICOLON
-        """
-        # These quack a lot like required arguments, so just treat them that way.
+    def p_DictionaryMember(self, p):
+        """
+            DictionaryMember : Required Type IDENTIFIER Default SEMICOLON
+        """
+        # These quack a lot like optional arguments, so just treat them that way.
         t = p[2]
         assert isinstance(t, IDLType)
         identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
+        defaultValue = p[4]
+        optional = not p[1]
+
+        if not optional and defaultValue:
+            raise WebIDLError("Required dictionary members can't have a default value.",
+                              [self.getLocation(p, 4)])
 
         p[0] = IDLArgument(self.getLocation(p, 3), identifier, t,
-                           optional=False,
-                           defaultValue=None, variadic=False,
+                           optional=optional,
+                           defaultValue=defaultValue, variadic=False,
                            dictionaryMember=True)
 
-    def p_DictionaryMember(self, p):
-        """
-            DictionaryMember : Type IDENTIFIER Default SEMICOLON
-        """
-        # These quack a lot like optional arguments, so just treat them that way.
-        t = p[1]
-        assert isinstance(t, IDLType)
-        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
-        defaultValue = p[3]
-
-        # Any attributes that precede this may apply to the type, so
-        # we configure the argument to forward type attributes down instead of producing
-        # a parse error
-        p[0] = IDLArgument(self.getLocation(p, 2), identifier, t,
-                           optional=True,
-                           defaultValue=defaultValue, variadic=False,
-                           dictionaryMember=True, allowTypeAttributes=True)
-
     def p_Default(self, p):
         """
             Default : EQUALS DefaultValue
                     |
         """
         if len(p) > 1:
             p[0] = p[2]
         else:
@@ -5972,17 +5922,17 @@ class Parser(Tokenizer):
         """
             ExceptionMembers : ExtendedAttributeList ExceptionMember ExceptionMembers
                              |
         """
         pass
 
     def p_Typedef(self, p):
         """
-            Typedef : TYPEDEF TypeWithExtendedAttributes IDENTIFIER SEMICOLON
+            Typedef : TYPEDEF Type IDENTIFIER SEMICOLON
         """
         typedef = IDLTypedef(self.getLocation(p, 1), self.globalScope(),
                              p[2], p[3])
         p[0] = typedef
 
     def p_ImplementsStatement(self, p):
         """
             ImplementsStatement : ScopedName IMPLEMENTS ScopedName SEMICOLON
@@ -6065,48 +6015,48 @@ class Parser(Tokenizer):
                                                              | Setlike
                                                              | Iterable
                                                              | Operation
         """
         p[0] = p[1]
 
     def p_Iterable(self, p):
         """
-            Iterable : ITERABLE LT TypeWithExtendedAttributes GT SEMICOLON
-                     | ITERABLE LT TypeWithExtendedAttributes COMMA TypeWithExtendedAttributes GT SEMICOLON
+            Iterable : ITERABLE LT Type GT SEMICOLON
+                     | ITERABLE LT Type COMMA Type GT SEMICOLON
         """
         location = self.getLocation(p, 2)
         identifier = IDLUnresolvedIdentifier(location, "__iterable",
                                              allowDoubleUnderscore=True)
         if (len(p) > 6):
             keyType = p[3]
             valueType = p[5]
         else:
             keyType = None
             valueType = p[3]
 
         p[0] = IDLIterable(location, identifier, keyType, valueType, self.globalScope())
 
     def p_Setlike(self, p):
         """
-            Setlike : ReadOnly SETLIKE LT TypeWithExtendedAttributes GT SEMICOLON
+            Setlike : ReadOnly SETLIKE LT Type GT SEMICOLON
         """
         readonly = p[1]
         maplikeOrSetlikeType = p[2]
         location = self.getLocation(p, 2)
         identifier = IDLUnresolvedIdentifier(location, "__setlike",
                                              allowDoubleUnderscore=True)
         keyType = p[4]
         valueType = keyType
         p[0] = IDLMaplikeOrSetlike(location, identifier, maplikeOrSetlikeType,
                                    readonly, keyType, valueType)
 
     def p_Maplike(self, p):
         """
-            Maplike : ReadOnly MAPLIKE LT TypeWithExtendedAttributes COMMA TypeWithExtendedAttributes GT SEMICOLON
+            Maplike : ReadOnly MAPLIKE LT Type COMMA Type GT SEMICOLON
         """
         readonly = p[1]
         maplikeOrSetlikeType = p[2]
         location = self.getLocation(p, 2)
         identifier = IDLUnresolvedIdentifier(location, "__maplike",
                                              allowDoubleUnderscore=True)
         keyType = p[4]
         valueType = p[6]
@@ -6134,17 +6084,17 @@ class Parser(Tokenizer):
         """
             Attribute : AttributeRest
         """
         (location, identifier, type, readonly) = p[1]
         p[0] = IDLAttribute(location, identifier, type, readonly, inherit=False)
 
     def p_AttributeRest(self, p):
         """
-            AttributeRest : ReadOnly ATTRIBUTE TypeWithExtendedAttributes AttributeName SEMICOLON
+            AttributeRest : ReadOnly ATTRIBUTE Type AttributeName SEMICOLON
         """
         location = self.getLocation(p, 2)
         readonly = p[1]
         t = p[3]
         identifier = IDLUnresolvedIdentifier(self.getLocation(p, 4), p[4])
         p[0] = (location, identifier, t, readonly)
 
     def p_ReadOnly(self, p):
@@ -6388,57 +6338,42 @@ class Parser(Tokenizer):
     def p_ArgumentsEmpty(self, p):
         """
             Arguments :
         """
         p[0] = []
 
     def p_Argument(self, p):
         """
-            Argument : ExtendedAttributeList ArgumentRest
-        """
-        p[0] = p[2]
-        p[0].addExtendedAttributes(p[1])
-
-    def p_ArgumentRestOptional(self, p):
-        """
-            ArgumentRest : OPTIONAL TypeWithExtendedAttributes ArgumentName Default
-        """
-        t = p[2]
+            Argument : ExtendedAttributeList Optional Type Ellipsis ArgumentName Default
+        """
+        t = p[3]
         assert isinstance(t, IDLType)
-        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
-
-        defaultValue = p[4]
-
+        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 5), p[5])
+
+        optional = p[2]
+        variadic = p[4]
+        defaultValue = p[6]
+
+        if not optional and defaultValue:
+            raise WebIDLError("Mandatory arguments can't have a default value.",
+                              [self.getLocation(p, 6)])
 
         # We can't test t.isAny() here and give it a default value as needed,
         # since at this point t is not a fully resolved type yet (e.g. it might
         # be a typedef).  We'll handle the 'any' case in IDLArgument.complete.
 
-        p[0] = IDLArgument(self.getLocation(p, 3), identifier, t, True, defaultValue, False)
-
-    def p_ArgumentRest(self, p):
-        """
-            ArgumentRest : Type Ellipsis ArgumentName
-        """
-        t = p[1]
-        assert isinstance(t, IDLType)
-        identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
-
-        variadic = p[2]
-
-        # We can't test t.isAny() here and give it a default value as needed,
-        # since at this point t is not a fully resolved type yet (e.g. it might
-        # be a typedef).  We'll handle the 'any' case in IDLArgument.complete.
-
-        # variadic implies optional
-        # Any attributes that precede this may apply to the type, so
-        # we configure the argument to forward type attributes down instead of producing
-        # a parse error
-        p[0] = IDLArgument(self.getLocation(p, 3), identifier, t, variadic, None, variadic, allowTypeAttributes=True)
+        if variadic:
+            if optional:
+                raise WebIDLError("Variadic arguments should not be marked optional.",
+                                  [self.getLocation(p, 2)])
+            optional = variadic
+
+        p[0] = IDLArgument(self.getLocation(p, 5), identifier, t, optional, defaultValue, variadic)
+        p[0].addExtendedAttributes(p[1])
 
     def p_ArgumentName(self, p):
         """
             ArgumentName : IDENTIFIER
                          | ATTRIBUTE
                          | CALLBACK
                          | CONST
                          | DELETER
@@ -6467,16 +6402,40 @@ class Parser(Tokenizer):
 
     def p_AttributeName(self, p):
         """
             AttributeName : IDENTIFIER
                           | REQUIRED
         """
         p[0] = p[1]
 
+    def p_Optional(self, p):
+        """
+            Optional : OPTIONAL
+        """
+        p[0] = True
+
+    def p_OptionalEmpty(self, p):
+        """
+            Optional :
+        """
+        p[0] = False
+
+    def p_Required(self, p):
+        """
+            Required : REQUIRED
+        """
+        p[0] = True
+
+    def p_RequiredEmpty(self, p):
+        """
+            Required :
+        """
+        p[0] = False
+
     def p_Ellipsis(self, p):
         """
             Ellipsis : ELLIPSIS
         """
         p[0] = True
 
     def p_EllipsisEmpty(self, p):
         """
@@ -6607,22 +6566,16 @@ class Parser(Tokenizer):
         p[0] = p[1]
 
     def p_TypeUnionType(self, p):
         """
             Type : UnionType Null
         """
         p[0] = self.handleNullable(p[1], p[2])
 
-    def p_TypeWithExtendedAttributes(self, p):
-        """
-            TypeWithExtendedAttributes : ExtendedAttributeList Type
-        """
-        p[0] = p[2].withExtendedAttributes(p[1])
-
     def p_SingleTypeNonAnyType(self, p):
         """
             SingleType : NonAnyType
         """
         p[0] = p[1]
 
     def p_SingleTypeAnyType(self, p):
         """
@@ -6635,19 +6588,19 @@ class Parser(Tokenizer):
             UnionType : LPAREN UnionMemberType OR UnionMemberType UnionMemberTypes RPAREN
         """
         types = [p[2], p[4]]
         types.extend(p[5])
         p[0] = IDLUnionType(self.getLocation(p, 1), types)
 
     def p_UnionMemberTypeNonAnyType(self, p):
         """
-            UnionMemberType : ExtendedAttributeList NonAnyType
-        """
-        p[0] = p[2].withExtendedAttributes(p[1])
+            UnionMemberType : NonAnyType
+        """
+        p[0] = p[1]
 
     def p_UnionMemberType(self, p):
         """
             UnionMemberType : UnionType Null
         """
         p[0] = self.handleNullable(p[1], p[2])
 
     def p_UnionMemberTypes(self, p):
@@ -6687,33 +6640,33 @@ class Parser(Tokenizer):
     def p_NonAnyTypeStringType(self, p):
         """
             NonAnyType : StringType Null
         """
         p[0] = self.handleNullable(p[1], p[2])
 
     def p_NonAnyTypeSequenceType(self, p):
         """
-            NonAnyType : SEQUENCE LT TypeWithExtendedAttributes GT Null
+            NonAnyType : SEQUENCE LT Type GT Null
         """
         innerType = p[3]
         type = IDLSequenceType(self.getLocation(p, 1), innerType)
         p[0] = self.handleNullable(type, p[5])
 
     # Note: Promise<void> is allowed, so we want to parametrize on ReturnType,
     # not Type.  Promise types can't be null, hence no "Null" in there.
     def p_NonAnyTypePromiseType(self, p):
         """
             NonAnyType : PROMISE LT ReturnType GT
         """
         p[0] = IDLPromiseType(self.getLocation(p, 1), p[3])
 
     def p_NonAnyTypeRecordType(self, p):
         """
-            NonAnyType : RECORD LT StringType COMMA TypeWithExtendedAttributes GT Null
+            NonAnyType : RECORD LT StringType COMMA Type GT Null
         """
         keyType = p[3]
         valueType = p[5]
         type = IDLRecordType(self.getLocation(p, 1), keyType, valueType)
         p[0] = self.handleNullable(type, p[7])
 
     def p_NonAnyTypeScopedName(self, p):
         """
deleted file mode 100644
--- a/dom/bindings/parser/tests/test_attributes_on_types.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# Import the WebIDL module, so we can do isinstance checks and whatnot
-import WebIDL
-
-def WebIDLTest(parser, harness):
-    # Basic functionality
-    threw = False
-    try:
-        parser.parse("""
-            typedef [EnforceRange] long Foo;
-            typedef [Clamp] long Bar;
-            typedef [TreatNullAs=EmptyString] DOMString Baz;
-            dictionary A {
-                required [EnforceRange] long a;
-                required [Clamp] long b;
-                required [TreatNullAs=EmptyString] DOMString c;
-                [ChromeOnly, EnforceRange] long d;
-                Foo e;
-            };
-            interface B {
-                attribute Foo typedefFoo;
-                attribute [EnforceRange] long foo;
-                attribute [Clamp] long bar;
-                attribute [TreatNullAs=EmptyString] DOMString baz;
-                void method([EnforceRange] long foo, [Clamp] long bar,
-                            [TreatNullAs=EmptyString] DOMString baz);
-                void method2(optional [EnforceRange] long foo, optional [Clamp] long bar,
-                             optional [TreatNullAs=EmptyString] DOMString baz);
-            };
-            interface Setlike {
-                setlike<[Clamp] long>;
-            };
-            interface Maplike {
-                maplike<[Clamp] long, [EnforceRange] long>;
-            };
-            interface Iterable {
-                iterable<[Clamp] long, [EnforceRange] long>;
-            };
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(not threw, "Should not have thrown on parsing normal")
-    if not threw:
-        harness.check(results[0].innerType.enforceRange, True, "Foo is [EnforceRange]")
-        harness.check(results[1].innerType.clamp, True, "Bar is [Clamp]")
-        harness.check(results[2].innerType.treatNullAsEmpty, True, "Baz is [TreatNullAs=EmptyString]")
-        A = results[3]
-        harness.check(A.members[0].type.enforceRange, True, "A.a is [EnforceRange]")
-        harness.check(A.members[1].type.clamp, True, "A.b is [Clamp]")
-        harness.check(A.members[2].type.treatNullAsEmpty, True, "A.c is [TreatNullAs=EmptyString]")
-        harness.check(A.members[3].type.enforceRange, True, "A.d is [EnforceRange]")
-        harness.check(A.members[4].type.enforceRange, True, "A.e is [EnforceRange]")
-        B = results[4]
-        harness.check(B.members[0].type.enforceRange, True, "B.typedefFoo is [EnforceRange]")
-        harness.check(B.members[1].type.enforceRange, True, "B.foo is [EnforceRange]")
-        harness.check(B.members[2].type.clamp, True, "B.bar is [Clamp]")
-        harness.check(B.members[3].type.treatNullAsEmpty, True, "B.baz is [TreatNullAs=EmptyString]")
-        method = B.members[4].signatures()[0][1]
-        harness.check(method[0].type.enforceRange, True, "foo argument of method is [EnforceRange]")
-        harness.check(method[1].type.clamp, True, "bar argument of method is [Clamp]")
-        harness.check(method[2].type.treatNullAsEmpty, True, "baz argument of method is [TreatNullAs=EmptyString]")
-        method2 = B.members[5].signatures()[0][1]
-        harness.check(method[0].type.enforceRange, True, "foo argument of method2 is [EnforceRange]")
-        harness.check(method[1].type.clamp, True, "bar argument of method2 is [Clamp]")
-        harness.check(method[2].type.treatNullAsEmpty, True, "baz argument of method2 is [TreatNullAs=EmptyString]")
-
-    ATTRIBUTES = [("[Clamp]", "long"), ("[EnforceRange]", "long"), ("[TreatNullAs=EmptyString]", "DOMString")]
-    TEMPLATES = [
-        ("required dictionary members", """
-            dictionary Foo {
-                %s required %s foo;
-            };
-        """),
-        ("optional arguments", """
-            interface Foo {
-                void foo(%s optional %s foo);
-            };
-        """),
-        ("typedefs", """
-            %s typedef %s foo;
-        """),
-        ("attributes", """
-            interface Foo {
-            %s attribute %s foo;
-            };
-        """),
-        ("readonly attributes", """
-            interface Foo {
-                readonly attribute %s %s foo;
-            };
-        """),
-        ("readonly unresolved attributes", """
-            interface Foo {
-              readonly attribute Bar baz;
-            };
-            typedef %s %s Bar;
-        """)              
-    ];
-
-    for (name, template) in TEMPLATES:
-        parser = parser.reset()
-        threw = False
-        try:
-            parser.parse(template % ("", "long"))
-            parser.finish()
-        except:
-            threw = True
-        harness.ok(not threw, "Template for %s parses without attributes" % name)
-        for (attribute, type) in ATTRIBUTES:
-            parser = parser.reset()
-            threw = False
-            try:
-                parser.parse(template % (attribute, type))
-                parser.finish()
-            except:
-                threw = True
-            harness.ok(threw,
-                       "Should not allow %s on %s" % (attribute, name))
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            typedef [Clamp, EnforceRange] long Foo;
-        """)
-        parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow mixing [Clamp] and [EnforceRange]")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            typedef [EnforceRange, Clamp] long Foo;
-        """)
-        parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow mixing [Clamp] and [EnforceRange]")
-
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            typedef [Clamp] long Foo;
-            typedef [EnforceRange] Foo bar;
-        """)
-        parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow mixing [Clamp] and [EnforceRange] via typedefs")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            typedef [EnforceRange] long Foo;
-            typedef [Clamp] Foo bar;
-        """)
-        parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow mixing [Clamp] and [EnforceRange] via typedefs")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            typedef [Clamp] DOMString Foo;
-        """)
-        parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow [Clamp] on DOMString")
-
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            typedef [EnforceRange] DOMString Foo;
-        """)
-        parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow [EnforceRange] on DOMString")
-
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            typedef [TreatNullAs=EmptyString] long Foo;
-        """)
-        parser.finish()
-    except:
-        threw = True
-
-    harness.ok(threw, "Should not allow [TreatNullAs] on long")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            interface Foo {
-               void foo([Clamp] Bar arg);
-            };
-            typedef long Bar;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-    harness.ok(not threw, "Should allow type attributes on unresolved types")
-    harness.check(results[0].members[0].signatures()[0][1][0].type.clamp, True,
-                  "Unresolved types with type attributes should correctly resolve with attributes")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            interface Foo {
-               void foo(Bar arg);
-            };
-            typedef [Clamp] long Bar;
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-    harness.ok(not threw, "Should allow type attributes on typedefs")
-    harness.check(results[0].members[0].signatures()[0][1][0].type.clamp, True,
-                  "Unresolved types that resolve to typedefs with attributes should correctly resolve with attributes")
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -1578,27 +1578,12 @@ class TestCEReactionsInterface : public 
   int32_t IndexedGetter(uint32_t, bool&);
   void IndexedSetter(uint32_t, int32_t);
   void NamedDeleter(const nsAString&, bool&);
   void NamedGetter(const nsAString&, bool&, nsString&);
   void NamedSetter(const nsAString&, const nsAString&);
   void GetSupportedNames(nsTArray<nsString>&);
 };
 
-class TestAttributesOnTypes : public nsISupports, public nsWrapperCache {
- public:
-  NS_DECL_ISUPPORTS
-
-  // We need a GetParentObject and GetDocGroup to make binding codegen happy
-  virtual nsISupports* GetParentObject();
-
-  void Foo(uint8_t arg);
-  void Bar(uint8_t arg);
-  void Baz(const nsAString& arg);
-  uint8_t SomeAttr();
-  void SetSomeAttr(uint8_t);
-  void ArgWithAttr(uint8_t arg1, const Optional<uint8_t>& arg2);
-};
-
 }  // namespace dom
 }  // namespace mozilla
 
 #endif /* TestBindingHeader_h */
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -778,18 +778,18 @@ interface TestInterface {
   void passDictContainingSequence(optional DictContainingSequence arg);
   DictContainingSequence receiveDictContainingSequence();
   void passVariadicDictionary(Dict... arg);
 
   // EnforceRange/Clamp tests
   void dontEnforceRangeOrClamp(byte arg);
   void doEnforceRange([EnforceRange] byte arg);
   void doClamp([Clamp] byte arg);
-  attribute [EnforceRange] byte enforcedByte;
-  attribute [Clamp] byte clampedByte;
+  [EnforceRange] attribute byte enforcedByte;
+  [Clamp] attribute byte clampedByte;
 
   // Typedefs
   const myLong myLongConstant = 5;
   void exerciseTypedefInterfaces1(AnotherNameForTestInterface arg);
   AnotherNameForTestInterface exerciseTypedefInterfaces2(NullableTestInterface arg);
   void exerciseTypedefInterfaces3(YetAnotherNameForTestInterface arg);
 
   // Deprecated methods and attributes
@@ -1310,31 +1310,8 @@ interface TestHTMLConstructorInterface {
 interface TestCEReactionsInterface {
   [CEReactions] setter void (unsigned long index, long item);
   [CEReactions] setter void (DOMString name, DOMString item);
   [CEReactions] deleter void (DOMString name);
   getter long item(unsigned long index);
   getter DOMString (DOMString name);
   readonly attribute unsigned long length;
 };
-
-typedef [EnforceRange] octet OctetRange;
-typedef [Clamp] octet OctetClamp;
-typedef [TreatNullAs=EmptyString] DOMString NullEmptyString;
-
-dictionary TestAttributesOnDictionaryMembers {
-  [Clamp] octet a;
-  [ChromeOnly, Clamp] octet b;
-  required [Clamp] octet c;
-  [ChromeOnly] octet d;
-  // ChromeOnly doesn't mix with required, so we can't
-  // test [ChromeOnly] required [Clamp] octet e
-};
-
-interface TestAttributesOnTypes {
-  void foo(OctetClamp thingy);
-  void bar(OctetRange thingy);
-  void baz(NullEmptyString thingy);
-  attribute [Clamp] octet someAttr;
-  void argWithAttr([Clamp] octet arg0, optional [Clamp] octet arg1);
-  // There aren't any argument-only attributes that we can test here,
-  // TreatNonCallableAsNull isn't compatible with Clamp-able types
-};
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -617,18 +617,18 @@ interface TestExampleInterface {
   void passDictContainingSequence(optional DictContainingSequence arg);
   DictContainingSequence receiveDictContainingSequence();
   void passVariadicDictionary(Dict... arg);
 
   // EnforceRange/Clamp tests
   void dontEnforceRangeOrClamp(byte arg);
   void doEnforceRange([EnforceRange] byte arg);
   void doClamp([Clamp] byte arg);
-  attribute [EnforceRange] byte enforcedByte;
-  attribute [Clamp] byte clampedByte;
+  [EnforceRange] attribute byte enforcedByte;
+  [Clamp] attribute byte clampedByte;
 
   // Typedefs
   const myLong myLongConstant = 5;
   void exerciseTypedefInterfaces1(AnotherNameForTestInterface arg);
   AnotherNameForTestInterface exerciseTypedefInterfaces2(NullableTestInterface arg);
   void exerciseTypedefInterfaces3(YetAnotherNameForTestInterface arg);
 
   // Deprecated methods and attributes
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -632,18 +632,18 @@ interface TestJSImplInterface {
   void passDictContainingSequence(optional DictContainingSequence arg);
   DictContainingSequence receiveDictContainingSequence();
   void passVariadicDictionary(Dict... arg);
 
   // EnforceRange/Clamp tests
   void dontEnforceRangeOrClamp(byte arg);
   void doEnforceRange([EnforceRange] byte arg);
   void doClamp([Clamp] byte arg);
-  attribute [EnforceRange] byte enforcedByte;
-  attribute [Clamp] byte clampedByte;
+  [EnforceRange] attribute byte enforcedByte;
+  [Clamp] attribute byte clampedByte;
 
   // Typedefs
   const myLong myLongConstant = 5;
   void exerciseTypedefInterfaces1(AnotherNameForTestJSImplInterface arg);
   AnotherNameForTestJSImplInterface exerciseTypedefInterfaces2(NullableTestJSImplInterface arg);
   void exerciseTypedefInterfaces3(YetAnotherNameForTestJSImplInterface arg);
 
   // Deprecated methods and attributes
--- a/dom/chrome-webidl/InspectorUtils.webidl
+++ b/dom/chrome-webidl/InspectorUtils.webidl
@@ -10,31 +10,31 @@
  * See InspectorUtils.h for documentation on these methods.
  */
 [Func="nsContentUtils::IsCallerChromeOrFuzzingEnabled"]
 namespace InspectorUtils {
   // documentOnly tells whether user and UA sheets should get included.
   sequence<StyleSheet> getAllStyleSheets(Document document, optional boolean documentOnly = false);
   sequence<CSSStyleRule> getCSSStyleRules(
     Element element,
-    optional [TreatNullAs=EmptyString] DOMString pseudo = "");
+    [TreatNullAs=EmptyString] optional DOMString pseudo = "");
   unsigned long getRuleLine(CSSRule rule);
   unsigned long getRuleColumn(CSSRule rule);
   unsigned long getRelativeRuleLine(CSSRule rule);
   boolean hasRulesModifiedByCSSOM(CSSStyleSheet sheet);
   unsigned long getSelectorCount(CSSStyleRule rule);
   [Throws] DOMString getSelectorText(CSSStyleRule rule,
                                      unsigned long selectorIndex);
   [Throws] unsigned long long getSpecificity(CSSStyleRule rule,
                                              unsigned long selectorIndex);
   [Throws] boolean selectorMatchesElement(
       Element element,
       CSSStyleRule rule,
       unsigned long selectorIndex,
-      optional [TreatNullAs=EmptyString] DOMString pseudo = "");
+      [TreatNullAs=EmptyString] optional DOMString pseudo = "");
   boolean isInheritedProperty(DOMString property);
   sequence<DOMString> getCSSPropertyNames(optional PropertyNamesOptions options);
   sequence<PropertyPref> getCSSPropertyPrefs();
   [Throws] sequence<DOMString> getCSSValuesForProperty(DOMString property);
   [Throws] DOMString rgbToColorName(octet r, octet g, octet b);
   InspectorRGBATuple? colorToRGBA(DOMString colorString);
   boolean isValidCSSColor(DOMString colorString);
   [Throws] sequence<DOMString> getSubpropertiesForCSSProperty(DOMString property);
--- a/dom/imptests/html/dom/test_interfaces.html
+++ b/dom/imptests/html/dom/test_interfaces.html
@@ -272,17 +272,17 @@ interface Attr {
            attribute DOMString value;
 
   readonly attribute DOMString name;
   readonly attribute DOMString? namespaceURI;
   readonly attribute DOMString? prefix;
 };
 
 interface CharacterData : Node {
-  attribute [TreatNullAs=EmptyString] DOMString data;
+  [TreatNullAs=EmptyString] attribute DOMString data;
   readonly attribute unsigned long length;
   DOMString substringData(unsigned long offset, unsigned long count);
   void appendData(DOMString data);
   void insertData(unsigned long offset, DOMString data);
   void deleteData(unsigned long offset, unsigned long count);
   void replaceData(unsigned long offset, unsigned long count, DOMString data);
 };
 
--- a/dom/webidl/Blob.webidl
+++ b/dom/webidl/Blob.webidl
@@ -20,18 +20,18 @@ interface Blob {
   [GetterThrows]
   readonly attribute unsigned long long size;
 
   readonly attribute DOMString type;
 
   //slice Blob into byte-ranged chunks
 
   [Throws]
-  Blob slice(optional [Clamp] long long start,
-             optional [Clamp] long long end,
+  Blob slice([Clamp] optional long long start,
+             [Clamp] optional long long end,
              optional DOMString contentType);
 };
 
 enum EndingTypes { "transparent", "native" };
 
 dictionary BlobPropertyBag {
   DOMString type = "";
   EndingTypes endings = "transparent";
--- a/dom/webidl/CSSStyleDeclaration.webidl
+++ b/dom/webidl/CSSStyleDeclaration.webidl
@@ -19,14 +19,14 @@ interface CSSStyleDeclaration {
 
   [Throws, ChromeOnly]
   sequence<DOMString> getCSSImageURLs(DOMString property);
 
   [Throws]
   DOMString getPropertyValue(DOMString property);
   DOMString getPropertyPriority(DOMString property);
   [CEReactions, NeedsSubjectPrincipal=NonSystem, Throws]
-  void setProperty(DOMString property, [TreatNullAs=EmptyString] DOMString value, optional [TreatNullAs=EmptyString] DOMString priority = "");
+  void setProperty(DOMString property, [TreatNullAs=EmptyString] DOMString value, [TreatNullAs=EmptyString] optional DOMString priority = "");
   [CEReactions, Throws]
   DOMString removeProperty(DOMString property);
 
   readonly attribute CSSRule? parentRule;
 };
--- a/dom/webidl/CharacterData.webidl
+++ b/dom/webidl/CharacterData.webidl
@@ -6,18 +6,18 @@
  * The origin of this IDL file is
  * http://dom.spec.whatwg.org/#characterdata
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface CharacterData : Node {
-  [Pure, SetterThrows]
-  attribute [TreatNullAs=EmptyString] DOMString data;
+  [TreatNullAs=EmptyString, Pure, SetterThrows]
+  attribute DOMString data;
   [Pure]
   readonly attribute unsigned long length;
   [Throws]
   DOMString substringData(unsigned long offset, unsigned long count);
   [Throws]
   void appendData(DOMString data);
   [Throws]
   void insertData(unsigned long offset, DOMString data);
--- a/dom/webidl/Element.webidl
+++ b/dom/webidl/Element.webidl
@@ -199,20 +199,20 @@ partial interface Element {
   [ChromeOnly] readonly attribute long scrollTopMin;
                readonly attribute long scrollTopMax;
   [ChromeOnly] readonly attribute long scrollLeftMin;
                readonly attribute long scrollLeftMax;
 };
 
 // http://domparsing.spec.whatwg.org/#extensions-to-the-element-interface
 partial interface Element {
-  [CEReactions, SetterNeedsSubjectPrincipal=NonSystem, Pure, SetterThrows, GetterCanOOM]
-  attribute [TreatNullAs=EmptyString] DOMString innerHTML;
-  [CEReactions, Pure, SetterThrows]
-  attribute [TreatNullAs=EmptyString] DOMString outerHTML;
+  [CEReactions, SetterNeedsSubjectPrincipal=NonSystem, Pure, SetterThrows, GetterCanOOM, TreatNullAs=EmptyString]
+  attribute DOMString innerHTML;
+  [CEReactions, Pure,SetterThrows,TreatNullAs=EmptyString]
+  attribute DOMString outerHTML;
   [CEReactions, Throws]
   void insertAdjacentHTML(DOMString position, DOMString text);
 };
 
 // http://www.w3.org/TR/selectors-api/#interface-definitions
 partial interface Element {
   [Throws, Pure]
   Element?  querySelector(DOMString selectors);
--- a/dom/webidl/HTMLBodyElement.webidl
+++ b/dom/webidl/HTMLBodyElement.webidl
@@ -11,23 +11,23 @@
  * and create derivative works of this document.
  */
 
 [HTMLConstructor]
 interface HTMLBodyElement : HTMLElement {
 };
 
 partial interface HTMLBodyElement {
-  [CEReactions, SetterThrows]
-  attribute [TreatNullAs=EmptyString] DOMString text;
-  [CEReactions, SetterThrows]
-  attribute [TreatNullAs=EmptyString] DOMString link;
-  [CEReactions, SetterThrows]
-  attribute [TreatNullAs=EmptyString] DOMString vLink;
-  [CEReactions, SetterThrows]
-  attribute [TreatNullAs=EmptyString] DOMString aLink;
-  [CEReactions, SetterThrows]
-  attribute [TreatNullAs=EmptyString] DOMString bgColor;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+  attribute DOMString text;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+  attribute DOMString link;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+  attribute DOMString vLink;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+  attribute DOMString aLink;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+  attribute DOMString bgColor;
   [CEReactions, SetterThrows]
   attribute DOMString background;
 };
 
 HTMLBodyElement implements WindowEventHandlers;
--- a/dom/webidl/HTMLDocument.webidl
+++ b/dom/webidl/HTMLDocument.webidl
@@ -37,21 +37,21 @@ interface HTMLDocument : Document {
   boolean queryCommandIndeterm(DOMString commandId);
   [Throws]
   boolean queryCommandState(DOMString commandId);
   [NeedsCallerType]
   boolean queryCommandSupported(DOMString commandId);
   [Throws]
   DOMString queryCommandValue(DOMString commandId);
 
-  [CEReactions] attribute [TreatNullAs=EmptyString] DOMString fgColor;
-  [CEReactions] attribute [TreatNullAs=EmptyString] DOMString linkColor;
-  [CEReactions] attribute [TreatNullAs=EmptyString] DOMString vlinkColor;
-  [CEReactions] attribute [TreatNullAs=EmptyString] DOMString alinkColor;
-  [CEReactions] attribute [TreatNullAs=EmptyString] DOMString bgColor;
+  [CEReactions, TreatNullAs=EmptyString] attribute DOMString fgColor;
+  [CEReactions, TreatNullAs=EmptyString] attribute DOMString linkColor;
+  [CEReactions, TreatNullAs=EmptyString] attribute DOMString vlinkColor;
+  [CEReactions, TreatNullAs=EmptyString] attribute DOMString alinkColor;
+  [CEReactions, TreatNullAs=EmptyString] attribute DOMString bgColor;
 
   void clear();
 
   readonly attribute HTMLAllCollection all;
 
   // @deprecated These are old Netscape 4 methods. Do not use,
   //             the implementation is no-op.
   // XXXbz do we actually need these anymore?
--- a/dom/webidl/HTMLElement.webidl
+++ b/dom/webidl/HTMLElement.webidl
@@ -20,18 +20,18 @@ interface HTMLElement : Element {
   [CEReactions]
            attribute DOMString lang;
   //         attribute boolean translate;
   [CEReactions, SetterThrows, Pure]
            attribute DOMString dir;
   [Constant]
   readonly attribute DOMStringMap dataset;
 
-  [CEReactions, GetterThrows, Pure]
-           attribute [TreatNullAs=EmptyString] DOMString innerText;
+  [CEReactions, GetterThrows, Pure, TreatNullAs=EmptyString]
+           attribute DOMString innerText;
 
   // user interaction
   [CEReactions, SetterThrows, Pure]
            attribute boolean hidden;
   [NeedsCallerType]
   void click();
   [CEReactions, SetterThrows, Pure]
            attribute long tabIndex;
--- a/dom/webidl/HTMLFontElement.webidl
+++ b/dom/webidl/HTMLFontElement.webidl
@@ -8,12 +8,12 @@
  *
  * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
  * Opera Software ASA. You are granted a license to use, reproduce
  * and create derivative works of this document.
  */
 
 [HTMLConstructor]
 interface HTMLFontElement : HTMLElement {
-  [CEReactions, SetterThrows] attribute [TreatNullAs=EmptyString] DOMString color;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows] attribute DOMString color;
   [CEReactions, SetterThrows]                          attribute DOMString face;
   [CEReactions, SetterThrows]                          attribute DOMString size;
 };
--- a/dom/webidl/HTMLFrameElement.webidl
+++ b/dom/webidl/HTMLFrameElement.webidl
@@ -24,15 +24,15 @@ interface HTMLFrameElement : HTMLElement
            [CEReactions, SetterThrows]
            attribute DOMString longDesc;
            [CEReactions, SetterThrows]
            attribute boolean noResize;
   [NeedsSubjectPrincipal]
   readonly attribute Document? contentDocument;
   readonly attribute WindowProxy? contentWindow;
 
-  [CEReactions, SetterThrows]
-  attribute [TreatNullAs=EmptyString] DOMString marginHeight;
-  [CEReactions, SetterThrows]
-  attribute [TreatNullAs=EmptyString] DOMString marginWidth;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+  attribute DOMString marginHeight;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+  attribute DOMString marginWidth;
 };
 
 HTMLFrameElement implements MozFrameLoaderOwner;
--- a/dom/webidl/HTMLIFrameElement.webidl
+++ b/dom/webidl/HTMLIFrameElement.webidl
@@ -44,20 +44,20 @@ partial interface HTMLIFrameElement {
            attribute DOMString align;
   [CEReactions, SetterThrows, Pure]
            attribute DOMString scrolling;
   [CEReactions, SetterThrows, Pure]
            attribute DOMString frameBorder;
   [CEReactions, SetterThrows, Pure]
            attribute DOMString longDesc;
 
-  [CEReactions, SetterThrows, Pure]
-           attribute [TreatNullAs=EmptyString] DOMString marginHeight;
-  [CEReactions, SetterThrows, Pure]
-           attribute [TreatNullAs=EmptyString] DOMString marginWidth;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows, Pure]
+           attribute DOMString marginHeight;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows, Pure]
+           attribute DOMString marginWidth;
 };
 
 partial interface HTMLIFrameElement {
   // GetSVGDocument
   [NeedsSubjectPrincipal]
   Document? getSVGDocument();
 };
 
--- a/dom/webidl/HTMLImageElement.webidl
+++ b/dom/webidl/HTMLImageElement.webidl
@@ -52,17 +52,17 @@ partial interface HTMLImageElement {
            attribute DOMString align;
            [CEReactions, SetterThrows]
            attribute unsigned long hspace;
            [CEReactions, SetterThrows]
            attribute unsigned long vspace;
            [CEReactions, SetterThrows]
            attribute DOMString longDesc;
 
-  [CEReactions, SetterThrows] attribute [TreatNullAs=EmptyString] DOMString border;
+  [CEReactions, TreatNullAs=EmptyString,SetterThrows] attribute DOMString border;
 };
 
 // [Update me: not in whatwg spec yet]
 // http://picture.responsiveimages.org/#the-img-element
 partial interface HTMLImageElement {
            [CEReactions, SetterThrows]
            attribute DOMString sizes;
   readonly attribute DOMString currentSrc;
--- a/dom/webidl/HTMLInputElement.webidl
+++ b/dom/webidl/HTMLInputElement.webidl
@@ -85,18 +85,18 @@ interface HTMLInputElement : HTMLElement
   [CEReactions, Pure, SetterNeedsSubjectPrincipal=NonSystem, SetterThrows]
            attribute DOMString src;
   [CEReactions, Pure, SetterThrows]
            attribute DOMString step;
   [CEReactions, Pure, SetterThrows]
            attribute DOMString type;
   [CEReactions, Pure, SetterThrows]
            attribute DOMString defaultValue;
-  [CEReactions, Pure, SetterThrows, NeedsCallerType]
-           attribute [TreatNullAs=EmptyString] DOMString value;
+  [CEReactions, Pure, TreatNullAs=EmptyString, SetterThrows, NeedsCallerType]
+           attribute DOMString value;
   [Throws, Func="HTMLInputElement::ValueAsDateEnabled"]
            attribute Date? valueAsDate;
   [Pure, SetterThrows]
            attribute unrestricted double valueAsNumber;
   [CEReactions, SetterThrows]
            attribute unsigned long width;
 
   [Throws]
--- a/dom/webidl/HTMLObjectElement.webidl
+++ b/dom/webidl/HTMLObjectElement.webidl
@@ -63,18 +63,18 @@ partial interface HTMLObjectElement {
            attribute DOMString standby;
   [CEReactions, Pure, SetterThrows]
            attribute unsigned long vspace;
   [CEReactions, Pure, SetterThrows]
            attribute DOMString codeBase;
   [CEReactions, Pure, SetterThrows]
            attribute DOMString codeType;
 
-  [CEReactions, Pure, SetterThrows]
-           attribute [TreatNullAs=EmptyString] DOMString border;
+  [CEReactions, TreatNullAs=EmptyString, Pure, SetterThrows]
+           attribute DOMString border;
 };
 
 partial interface HTMLObjectElement {
   // GetSVGDocument
   [NeedsSubjectPrincipal]
   Document? getSVGDocument();
 };
 
--- a/dom/webidl/HTMLTableCellElement.webidl
+++ b/dom/webidl/HTMLTableCellElement.webidl
@@ -43,11 +43,11 @@ partial interface HTMLTableCellElement {
            attribute DOMString ch;
            [CEReactions, SetterThrows]
            attribute DOMString chOff;
            [CEReactions, SetterThrows]
            attribute boolean noWrap;
            [CEReactions, SetterThrows]
            attribute DOMString vAlign;
 
-           [CEReactions, SetterThrows]
-           attribute [TreatNullAs=EmptyString] DOMString bgColor;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+           attribute DOMString bgColor;
 };
--- a/dom/webidl/HTMLTableElement.webidl
+++ b/dom/webidl/HTMLTableElement.webidl
@@ -48,15 +48,15 @@ partial interface HTMLTableElement {
            attribute DOMString frame;
            [CEReactions, SetterThrows]
            attribute DOMString rules;
            [CEReactions, SetterThrows]
            attribute DOMString summary;
            [CEReactions, SetterThrows]
            attribute DOMString width;
 
-  [CEReactions, SetterThrows]
-           attribute [TreatNullAs=EmptyString] DOMString bgColor;
-  [CEReactions, SetterThrows]
-           attribute [TreatNullAs=EmptyString] DOMString cellPadding;
-  [CEReactions, SetterThrows]
-           attribute [TreatNullAs=EmptyString] DOMString cellSpacing;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+           attribute DOMString bgColor;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+           attribute DOMString cellPadding;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+           attribute DOMString cellSpacing;
 };
--- a/dom/webidl/HTMLTableRowElement.webidl
+++ b/dom/webidl/HTMLTableRowElement.webidl
@@ -27,11 +27,11 @@ partial interface HTMLTableRowElement {
            attribute DOMString align;
            [CEReactions, SetterThrows]
            attribute DOMString ch;
            [CEReactions, SetterThrows]
            attribute DOMString chOff;
            [CEReactions, SetterThrows]
            attribute DOMString vAlign;
 
-  [CEReactions, SetterThrows]
-           attribute [TreatNullAs=EmptyString] DOMString bgColor;
+  [CEReactions, TreatNullAs=EmptyString, SetterThrows]
+           attribute DOMString bgColor;
 };
--- a/dom/webidl/HTMLTextAreaElement.webidl
+++ b/dom/webidl/HTMLTextAreaElement.webidl
@@ -44,17 +44,17 @@ interface HTMLTextAreaElement : HTMLElem
            attribute unsigned long rows;
   [CEReactions, SetterThrows, Pure]
            attribute DOMString wrap;
 
   [Constant]
   readonly attribute DOMString type;
   [CEReactions, Throws, Pure]
            attribute DOMString defaultValue;
-  [CEReactions, SetterThrows] attribute [TreatNullAs=EmptyString] DOMString value;
+  [CEReactions, SetterThrows, TreatNullAs=EmptyString] attribute DOMString value;
   readonly attribute unsigned long textLength;
 
   readonly attribute boolean willValidate;
   readonly attribute ValidityState validity;
   [Throws]
   readonly attribute DOMString validationMessage;
   boolean checkValidity();
   boolean reportValidity();
--- a/dom/webidl/IDBIndex.webidl
+++ b/dom/webidl/IDBIndex.webidl
@@ -53,19 +53,19 @@ interface IDBIndex {
     IDBRequest getKey (any key);
 
     [Throws]
     IDBRequest count (optional any key);
 };
 
 partial interface IDBIndex {
     [Throws]
-    IDBRequest mozGetAll (optional any key, optional [EnforceRange] unsigned long limit);
+    IDBRequest mozGetAll (optional any key, [EnforceRange] optional unsigned long limit);
 
     [Throws]
-    IDBRequest mozGetAllKeys (optional any key, optional [EnforceRange] unsigned long limit);
+    IDBRequest mozGetAllKeys (optional any key, [EnforceRange] optional unsigned long limit);
 
     [Throws]
-    IDBRequest getAll (optional any key, optional [EnforceRange] unsigned long limit);
+    IDBRequest getAll (optional any key, [EnforceRange] optional unsigned long limit);
 
     [Throws]
-    IDBRequest getAllKeys (optional any key, optional [EnforceRange] unsigned long limit);
+    IDBRequest getAllKeys (optional any key, [EnforceRange] optional unsigned long limit);
 };
--- a/dom/webidl/IDBObjectStore.webidl
+++ b/dom/webidl/IDBObjectStore.webidl
@@ -56,19 +56,19 @@ interface IDBObjectStore {
 
     [Throws]
     IDBRequest count (optional any key);
 };
 
 partial interface IDBObjectStore {
     // Success fires IDBTransactionEvent, result == array of values for given keys
     [Throws]
-    IDBRequest mozGetAll (optional any key, optional [EnforceRange] unsigned long limit);
+    IDBRequest mozGetAll (optional any key, [EnforceRange] optional unsigned long limit);
 
     [Throws]
-    IDBRequest getAll (optional any key, optional [EnforceRange] unsigned long limit);
+    IDBRequest getAll (optional any key, [EnforceRange] optional unsigned long limit);
 
     [Throws]
-    IDBRequest getAllKeys (optional any key, optional [EnforceRange] unsigned long limit);
+    IDBRequest getAllKeys (optional any key, [EnforceRange] optional unsigned long limit);
 
     [Throws]
     IDBRequest openKeyCursor (optional any range, optional IDBCursorDirection direction = "next");
 };
--- a/dom/webidl/MediaList.webidl
+++ b/dom/webidl/MediaList.webidl
@@ -8,17 +8,18 @@
 interface MediaList {
   // Bug 824857: no support for stringifier attributes yet.
   //   [TreatNullAs=EmptyString]
   // stringifier attribute DOMString        mediaText;
 
   // Bug 824857 should remove this.
   stringifier;
 
-           attribute [TreatNullAs=EmptyString] DOMString        mediaText;
+  [TreatNullAs=EmptyString]
+           attribute DOMString        mediaText;
 
   readonly attribute unsigned long    length;
   getter DOMString?  item(unsigned long index);
   [Throws]
   void               deleteMedium(DOMString oldMedium);
   [Throws]
   void               appendMedium(DOMString newMedium);
 };
--- a/dom/webidl/ShadowRoot.webidl
+++ b/dom/webidl/ShadowRoot.webidl
@@ -23,18 +23,18 @@ interface ShadowRoot : DocumentFragment
   readonly attribute ShadowRootMode mode;
   readonly attribute Element host;
 
   // [deprecated] Shadow DOM v0
   Element? getElementById(DOMString elementId);
   HTMLCollection getElementsByTagName(DOMString localName);
   HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
   HTMLCollection getElementsByClassName(DOMString classNames);
-  [CEReactions, SetterThrows]
-  attribute [TreatNullAs=EmptyString] DOMString innerHTML;
+  [CEReactions, SetterThrows, TreatNullAs=EmptyString]
+  attribute DOMString innerHTML;
 
   // When JS invokes importNode or createElement, the binding code needs to
   // create a reflector, and so invoking those methods directly on the content
   // document would cause the reflector to be created in the content scope,
   // at which point it would be difficult to move into the UA Widget scope.
   // As such, these methods allow UA widget code to simultaneously create nodes
   // and associate them with the UA widget tree, so that the reflectors get
   // created in the right scope.
--- a/dom/webidl/SubtleCrypto.webidl
+++ b/dom/webidl/SubtleCrypto.webidl
@@ -19,73 +19,73 @@ dictionary Algorithm {
 };
 
 dictionary AesCbcParams : Algorithm {
   required BufferSource iv;
 };
 
 dictionary AesCtrParams : Algorithm {
   required BufferSource counter;
-  required [EnforceRange] octet length;
+  [EnforceRange] required octet length;
 };
 
 dictionary AesGcmParams : Algorithm {
   required BufferSource iv;
   BufferSource additionalData;
   [EnforceRange] octet tagLength;
 };
 
 dictionary HmacImportParams : Algorithm {
   required AlgorithmIdentifier hash;
 };
 
 dictionary Pbkdf2Params : Algorithm {
   required BufferSource salt;
-  required [EnforceRange] unsigned long iterations;
+  [EnforceRange] required unsigned long iterations;
   required AlgorithmIdentifier hash;
 };
 
 dictionary RsaHashedImportParams {
   required AlgorithmIdentifier hash;
 };
 
 dictionary AesKeyGenParams : Algorithm {
-  required [EnforceRange] unsigned short length;
+  [EnforceRange] required unsigned short length;
 };
 
 dictionary HmacKeyGenParams : Algorithm {
   required AlgorithmIdentifier hash;
   [EnforceRange] unsigned long length;
 };
 
 dictionary RsaHashedKeyGenParams : Algorithm {
-  required [EnforceRange] unsigned long modulusLength;
+  [EnforceRange] required unsigned long modulusLength;
   required BigInteger publicExponent;
   required AlgorithmIdentifier hash;
 };
 
 dictionary RsaOaepParams : Algorithm {
   BufferSource label;
 };
 
 dictionary RsaPssParams : Algorithm {
-  required [EnforceRange] unsigned long saltLength;
+  [EnforceRange] required unsigned long saltLength;
 };
 
 dictionary DhKeyGenParams : Algorithm {
   required BigInteger prime;
   required BigInteger generator;
 };
 
 dictionary EcKeyGenParams : Algorithm {
   required NamedCurve namedCurve;
 };
 
 dictionary AesDerivedKeyParams : Algorithm {
-  required [EnforceRange] unsigned long length;
+  [EnforceRange] required unsigned long length;
 };
 
 dictionary HmacDerivedKeyParams : HmacImportParams {
   [EnforceRange] unsigned long length;
 };
 
 dictionary EcdhKeyDeriveParams : Algorithm {
   required CryptoKey public;
--- a/dom/webidl/WebSocket.webidl
+++ b/dom/webidl/WebSocket.webidl
@@ -38,17 +38,17 @@ interface WebSocket : EventTarget {
 
   attribute EventHandler onclose;
 
   readonly attribute DOMString extensions;
 
   readonly attribute DOMString protocol;
 
   [Throws]
-  void close(optional [Clamp] unsigned short code, optional DOMString reason);
+  void close([Clamp] optional unsigned short code, optional DOMString reason);
 
   // messaging
 
   attribute EventHandler onmessage;
 
   attribute BinaryType binaryType;
 
   [Throws]
--- a/dom/webidl/Window.webidl
+++ b/dom/webidl/Window.webidl
@@ -58,17 +58,17 @@ typedef OfflineResourceList ApplicationC
   [Replaceable, CrossOriginReadable] readonly attribute unsigned long length;
   //[Unforgeable, Throws, CrossOriginReadable] readonly attribute WindowProxy top;
   [Unforgeable, Throws, CrossOriginReadable] readonly attribute WindowProxy? top;
   [Throws, CrossOriginReadable] attribute any opener;
   //[Throws] readonly attribute WindowProxy parent;
   [Replaceable, Throws, CrossOriginReadable] readonly attribute WindowProxy? parent;
   [Throws, NeedsSubjectPrincipal] readonly attribute Element? frameElement;
   //[Throws] WindowProxy? open(optional USVString url = "about:blank", optional DOMString target = "_blank", [TreatNullAs=EmptyString] optional DOMString features = "");
-  [Throws] WindowProxy? open(optional DOMString url = "", optional DOMString target = "", optional [TreatNullAs=EmptyString] DOMString features = "");
+  [Throws] WindowProxy? open(optional DOMString url = "", optional DOMString target = "", [TreatNullAs=EmptyString] optional DOMString features = "");
   getter object (DOMString name);
 
   // the user agent
   readonly attribute Navigator navigator;
 #ifdef HAVE_SIDEBAR
   [Replaceable, Throws] readonly attribute External external;
 #endif
   [Throws, Pref="browser.cache.offline.enable", Func="nsGlobalWindowInner::OfflineCacheAllowedForContext"] readonly attribute ApplicationCache applicationCache;