servo: Merge #13044 - Update the WebIDL parser (from nox:webidl); r=Ms2ger
authorAnthony Ramine <n.oxyde@gmail.com>
Fri, 26 Aug 2016 05:26:19 -0500
changeset 339577 f7040799d10a07301a1d58e122effef2bb674dc1
parent 339576 7e961c936de5fb221420cbde2254975379af3685
child 339578 b4e9b1713ca282941b4e193d62bb8a894aa8d3da
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMs2ger
servo: Merge #13044 - Update the WebIDL parser (from nox:webidl); r=Ms2ger Source-Repo: https://github.com/servo/servo Source-Revision: 2ad6a7e612ea627cd90ecc3a120b3fc2bfdafa64
servo/components/script/dom/bindings/codegen/parser/WebIDL.py
servo/components/script/dom/bindings/codegen/parser/abstract.patch
servo/components/script/dom/bindings/codegen/parser/bytestring.patch
servo/components/script/dom/bindings/codegen/parser/callback-location.patch
servo/components/script/dom/bindings/codegen/parser/pref-main-thread.patch
servo/components/script/dom/bindings/codegen/parser/tests/test_securecontext_extended_attribute.py
servo/components/script/dom/bindings/codegen/parser/update.sh
--- a/servo/components/script/dom/bindings/codegen/parser/WebIDL.py
+++ b/servo/components/script/dom/bindings/codegen/parser/WebIDL.py
@@ -1256,20 +1256,17 @@ class IDLInterfaceOrNamespace(IDLObjectW
                     if self.isOnGlobalProtoChain():
                         raise WebIDLError("[Alias] must not be used on a "
                                           "[Global] interface operation",
                                           [member.location])
                     if (member.getExtendedAttribute("Exposed") or
                         member.getExtendedAttribute("ChromeOnly") or
                         member.getExtendedAttribute("Pref") or
                         member.getExtendedAttribute("Func") or
-                        member.getExtendedAttribute("SecureContext") or
-                        member.getExtendedAttribute("AvailableIn") or
-                        member.getExtendedAttribute("CheckAnyPermissions") or
-                        member.getExtendedAttribute("CheckAllPermissions")):
+                        member.getExtendedAttribute("SecureContext")):
                         raise WebIDLError("[Alias] must not be used on a "
                                           "conditionally exposed operation",
                                           [member.location])
                     if member.isStatic():
                         raise WebIDLError("[Alias] must not be used on a "
                                           "static operation",
                                           [member.location])
                     if member.isIdentifierLess():
@@ -1285,27 +1282,21 @@ class IDLInterfaceOrNamespace(IDLObjectW
                             raise WebIDLError("[Alias=%s] has same name as "
                                               "interface member" % alias,
                                               [member.location, m.location])
                         if m.isMethod() and m != member and alias in m.aliases:
                             raise WebIDLError("duplicate [Alias=%s] definitions" %
                                               alias,
                                               [member.location, m.location])
 
-        for attribute in ["CheckAnyPermissions", "CheckAllPermissions"]:
-            if (self.getExtendedAttribute(attribute) and
-                self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
-                raise WebIDLError("[%s] used on an interface that is "
-                                  "not %s-only" %
-                                  (attribute, self.parentScope.primaryGlobalName),
-                                  [self.location])
-
         # Conditional exposure makes no sense for interfaces with no
         # interface object, unless they're navigator properties.
-        if (self.isExposedConditionally() and
+        # And SecureContext makes sense for interfaces with no interface object,
+        # since it is also propagated to interface members.
+        if (self.isExposedConditionally(exclusions=["SecureContext"]) and
             not self.hasInterfaceObject() and
             not self.isNavigatorProperty()):
             raise WebIDLError("Interface with no interface object is "
                               "exposed conditionally",
                               [self.location])
 
         # Value iterators are only allowed on interfaces with indexed getters,
         # and pair iterators are only allowed on interfaces without indexed
@@ -1533,18 +1524,18 @@ class IDLInterfaceOrNamespace(IDLObjectW
 
     def hasMembersInSlots(self):
         return self._ownMembersInSlots != 0
 
     conditionExtendedAttributes = [ "Pref", "ChromeOnly", "Func", "AvailableIn",
                                     "SecureContext",
                                     "CheckAnyPermissions",
                                     "CheckAllPermissions" ]
-    def isExposedConditionally(self):
-        return any(self.getExtendedAttribute(a) for a in self.conditionExtendedAttributes)
+    def isExposedConditionally(self, exclusions=[]):
+        return any(((not a in exclusions) and self.getExtendedAttribute(a)) for a in self.conditionExtendedAttributes)
 
 class IDLInterface(IDLInterfaceOrNamespace):
     def __init__(self, location, parentScope, name, parent, members,
                  isKnownNonPartial):
         IDLInterfaceOrNamespace.__init__(self, location, parentScope, name,
                                          parent, members, isKnownNonPartial)
 
     def __str__(self):
@@ -1710,20 +1701,17 @@ class IDLInterface(IDLInterfaceOrNamespa
                                       [attr.location])
             elif identifier == "Exposed":
                 convertExposedAttrToGlobalNameSet(attr,
                                                   self._exposureGlobalNames)
             elif (identifier == "Pref" or
                   identifier == "JSImplementation" or
                   identifier == "HeaderFile" or
                   identifier == "NavigatorProperty" or
-                  identifier == "AvailableIn" or
                   identifier == "Func" or
-                  identifier == "CheckAnyPermissions" or
-                  identifier == "CheckAllPermissions" or
                   identifier == "Deprecated"):
                 # Known extended attributes that take a string value
                 if not attr.hasValue():
                     raise WebIDLError("[%s] must have a value" % identifier,
                                       [attr.location])
             else:
                 raise WebIDLError("Unknown extended attribute %s on interface" % identifier,
                                   [attr.location])
@@ -3539,24 +3527,16 @@ class IDLInterfaceMember(IDLObjectWithId
     def finish(self, scope):
         # We better be exposed _somewhere_.
         if (len(self._exposureGlobalNames) == 0):
             print self.identifier.name
         assert len(self._exposureGlobalNames) != 0
         IDLExposureMixins.finish(self, scope)
 
     def validate(self):
-        for attribute in ["CheckAnyPermissions", "CheckAllPermissions"]:
-            if (self.getExtendedAttribute(attribute) and
-                self.exposureSet != set([self._globalScope.primaryGlobalName])):
-                raise WebIDLError("[%s] used on an interface member that is "
-                                  "not %s-only" %
-                                  (attribute, self.parentScope.primaryGlobalName),
-                                  [self.location])
-
         if self.isAttr() or self.isMethod():
             if self.affects == "Everything" and self.dependsOn != "Everything":
                 raise WebIDLError("Interface member is flagged as affecting "
                                   "everything but not depending on everything. "
                                   "That seems rather unlikely.",
                                   [self.location])
 
         if self.getExtendedAttribute("NewObject"):
@@ -3963,20 +3943,17 @@ class IDLConst(IDLInterfaceMember):
 
     def handleExtendedAttribute(self, attr):
         identifier = attr.identifier()
         if identifier == "Exposed":
             convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames)
         elif (identifier == "Pref" or
               identifier == "ChromeOnly" or
               identifier == "Func" or
-              identifier == "SecureContext" or
-              identifier == "AvailableIn" or
-              identifier == "CheckAnyPermissions" or
-              identifier == "CheckAllPermissions"):
+              identifier == "SecureContext"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
             raise WebIDLError("Unknown extended attribute %s on constant" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
 
     def _getDependentObjects(self):
@@ -4306,21 +4283,18 @@ class IDLAttribute(IDLInterfaceMember):
               identifier == "Deprecated" or
               identifier == "SetterThrows" or
               identifier == "Throws" or
               identifier == "GetterThrows" or
               identifier == "ChromeOnly" or
               identifier == "Func" or
               identifier == "SecureContext" or
               identifier == "Frozen" or
-              identifier == "AvailableIn" or
               identifier == "NewObject" or
               identifier == "UnsafeInPrerendering" or
-              identifier == "CheckAnyPermissions" or
-              identifier == "CheckAllPermissions" or
               identifier == "BinaryName"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
             raise WebIDLError("Unknown extended attribute %s on attribute" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
 
@@ -5032,19 +5006,16 @@ class IDLMethod(IDLInterfaceMember, IDLS
         elif (identifier == "Throws" or
               identifier == "NewObject" or
               identifier == "ChromeOnly" or
               identifier == "UnsafeInPrerendering" or
               identifier == "Pref" or
               identifier == "Deprecated" or
               identifier == "Func" or
               identifier == "SecureContext" or
-              identifier == "AvailableIn" or
-              identifier == "CheckAnyPermissions" or
-              identifier == "CheckAllPermissions" or
               identifier == "BinaryName" or
               identifier == "StaticClassOverride"):
             # Known attributes that we don't need to do anything with here
             pass
         else:
             raise WebIDLError("Unknown extended attribute %s on method" % identifier,
                               [attr.location])
         IDLInterfaceMember.handleExtendedAttribute(self, attr)
new file mode 100644
--- /dev/null
+++ b/servo/components/script/dom/bindings/codegen/parser/abstract.patch
@@ -0,0 +1,12 @@
+--- WebIDL.py
++++ WebIDL.py
+@@ -1416,7 +1416,8 @@
+                   identifier == "LegacyEventInit" or
+                   identifier == "ProbablyShortLivingObject" or
+                   identifier == "LegacyUnenumerableNamedProperties" or
+-                  identifier == "NonOrdinaryGetPrototypeOf"):
++                  identifier == "NonOrdinaryGetPrototypeOf" or
++                  identifier == "Abstract"):
+                 # Known extended attributes that do not take values
+                 if not attr.noArguments():
+                     raise WebIDLError("[%s] must take no arguments" % identifier,
new file mode 100644
--- /dev/null
+++ b/servo/components/script/dom/bindings/codegen/parser/bytestring.patch
@@ -0,0 +1,29 @@
+--- WebIDL.py
++++ WebIDL.py
+@@ -3391,6 +3391,11 @@ class IDLValue(IDLObject):
+             # extra normalization step.
+             assert self.type.isDOMString()
+             return self
++        elif self.type.isString() and type.isByteString():
++            # Allow ByteStrings to use default value just like
++            # DOMString.  No coercion is required here.
++            assert self.type.isDOMString()
++            return self
+         raise WebIDLError("Cannot coerce type %s to type %s." %
+                           (self.type, type), [location])
+
+@@ -5759,6 +5764,14 @@ class Parser(Tokenizer):
+         booleanType = BuiltinTypes[IDLBuiltinType.Types.boolean]
+         p[0] = IDLValue(location, booleanType, p[1])
+
++    def p_ConstValueByteString(self, p):
++        """
++            ConstValue : BYTESTRING
++        """
++        location = self.getLocation(p, 1)
++        bytestringType = BuiltinTypes[IDLBuiltinType.Types.bytestring]
++        p[0] = IDLValue(location, bytestringType, p[1])
++
+     def p_ConstValueInteger(self, p):
+         """
+             ConstValue : INTEGER
--- a/servo/components/script/dom/bindings/codegen/parser/callback-location.patch
+++ b/servo/components/script/dom/bindings/codegen/parser/callback-location.patch
@@ -1,12 +1,12 @@
 diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py
 index da32340..81c52b7 100644
---- a/components/script/dom/bindings/codegen/parser/WebIDL.py
-+++ b/components/script/dom/bindings/codegen/parser/WebIDL.py
+--- WebIDL.py
++++ WebIDL.py
 @@ -2170,7 +2170,7 @@ class IDLUnresolvedType(IDLType):
              return typedefType.complete(scope)
          elif obj.isCallback() and not obj.isInterface():
              assert self.name.name == obj.identifier.name
 -            return IDLCallbackType(self.location, obj)
 +            return IDLCallbackType(obj.location, obj)
 
          if self._promiseInnerType and not self._promiseInnerType.isComplete():
@@ -14,9 +14,9 @@ index da32340..81c52b7 100644
 @@ -6521,7 +6521,7 @@ class Parser(Tokenizer):
                      type = IDLTypedefType(self.getLocation(p, 1), obj.innerType,
                                            obj.identifier.name)
                  elif obj.isCallback() and not obj.isInterface():
 -                    type = IDLCallbackType(self.getLocation(p, 1), obj)
 +                    type = IDLCallbackType(obj.location, obj)
                  else:
                      type = IDLWrapperType(self.getLocation(p, 1), p[1])
-                 p[0] = self.handleModifiers(type, p[2])
\ No newline at end of file
+                 p[0] = self.handleModifiers(type, p[2])
--- a/servo/components/script/dom/bindings/codegen/parser/pref-main-thread.patch
+++ b/servo/components/script/dom/bindings/codegen/parser/pref-main-thread.patch
@@ -1,28 +1,28 @@
 --- WebIDL.py
 +++ WebIDL.py
 @@ -1239,12 +1239,6 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
                                                alias,
-                                               [member.location, m.location])
+                                               [member.location, m.location]) 
  
 -        if (self.getExtendedAttribute("Pref") and
 -            self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
 -            raise WebIDLError("[Pref] used on an interface that is not %s-only" %
 -                              self.parentScope.primaryGlobalName,
 -                              [self.location])
 -
-         for attribute in ["CheckAnyPermissions", "CheckAllPermissions"]:
-             if (self.getExtendedAttribute(attribute) and
-                 self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
+         # Conditional exposure makes no sense for interfaces with no
+         # interface object, unless they're navigator properties.
+         # And SecureContext makes sense for interfaces with no interface object,
 @@ -3459,12 +3453,6 @@ class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
          IDLExposureMixins.finish(self, scope)
  
      def validate(self):
 -        if (self.getExtendedAttribute("Pref") and
 -            self.exposureSet != set([self._globalScope.primaryGlobalName])):
 -            raise WebIDLError("[Pref] used on an interface member that is not "
 -                              "%s-only" % self._globalScope.primaryGlobalName,
 -                              [self.location])
 -
-         for attribute in ["CheckAnyPermissions", "CheckAllPermissions"]:
-             if (self.getExtendedAttribute(attribute) and
-                 self.exposureSet != set([self._globalScope.primaryGlobalName])):
+         if self.isAttr() or self.isMethod():
+             if self.affects == "Everything" and self.dependsOn != "Everything":
+                 raise WebIDLError("Interface member is flagged as affecting "
--- a/servo/components/script/dom/bindings/codegen/parser/tests/test_securecontext_extended_attribute.py
+++ b/servo/components/script/dom/bindings/codegen/parser/tests/test_securecontext_extended_attribute.py
@@ -311,8 +311,22 @@ def WebIDLTest(parser, harness):
                "[SecureContext] should propagate from interface to constant members even when other members are copied from a non-[SecureContext] interface")
     harness.ok(results[0].members[1].getExtendedAttribute("SecureContext") is None,
                "Constants copied from non-[SecureContext] interface should not be [SecureContext]")
     harness.ok(results[0].members[2].getExtendedAttribute("SecureContext") is None,
                "Attributes copied from non-[SecureContext] interface should not be [SecureContext]")
     harness.ok(results[0].members[3].getExtendedAttribute("SecureContext") is None,
                "Methods copied from non-[SecureContext] interface should not be [SecureContext]")
  
+    # Test SecureContext and NoInterfaceObject
+    parser = parser.reset()
+    parser.parse("""
+        [NoInterfaceObject, SecureContext]
+        interface TestSecureContextNoInterfaceObject {
+          void testSecureMethod(byte foo);
+        };
+    """)
+    results = parser.finish()
+    harness.check(len(results[0].members), 1, "TestSecureContextNoInterfaceObject should have only one member")
+    harness.ok(results[0].getExtendedAttribute("SecureContext"),
+      "Interface should have [SecureContext] extended attribute")
+    harness.ok(results[0].members[0].getExtendedAttribute("SecureContext"),
+      "Interface member should have [SecureContext] extended attribute")
--- a/servo/components/script/dom/bindings/codegen/parser/update.sh
+++ b/servo/components/script/dom/bindings/codegen/parser/update.sh
@@ -1,11 +1,12 @@
 wget https://hg.mozilla.org/mozilla-central/raw-file/tip/dom/bindings/parser/WebIDL.py -O WebIDL.py
 patch < abstract.patch
 patch < debug.patch
 patch < pref-main-thread.patch
 patch < callback-location.patch
+patch < bytestring.patch
 
 wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz
 rm -r tests
 mkdir tests
 tar xvpf tests.tar.gz  -C tests --strip-components=5
 rm tests.tar.gz WebIDL.py.orig