Bug 928150 - Move the LenientFloat check from handleExtendedAttribute to IDLMethod.validate, confirming that it has at least one overload with double arguments; r?bz draft
authorThomas Wisniewski <wisniewskit@gmail.com>
Tue, 03 Oct 2017 12:18:21 -0400
changeset 683733 03e7ae178bc3dfd267d20b75006e40713c06b2b3
parent 683653 b6ba3e919f561bfabbf4bec7f0f53a23c360adee
child 683734 9a412538b0741fa993e3a0d3d00ca8d177362eb1
push id85450
push userwisniewskit@gmail.com
push dateFri, 20 Oct 2017 04:13:07 +0000
reviewersbz
bugs928150
milestone58.0a1
Bug 928150 - Move the LenientFloat check from handleExtendedAttribute to IDLMethod.validate, confirming that it has at least one overload with double arguments; r?bz MozReview-Commit-ID: 57v2eO56uXx
dom/bindings/parser/WebIDL.py
dom/bindings/parser/tests/test_float_types.py
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -4943,16 +4943,26 @@ class IDLMethod(IDLInterfaceMember, IDLS
                               "legacycaller.",
                               [overloadWithPromiseReturnType.location])
 
         if self.getExtendedAttribute("StaticClassOverride") and not \
            (self.identifier.scope.isJSImplemented() and self.isStatic()):
             raise WebIDLError("StaticClassOverride can be applied to static"
                               " methods on JS-implemented classes only.",
                               [self.location])
+        if self.getExtendedAttribute("LenientFloat"):
+            assert len(self.signatures()) >= 1
+            found = False
+            for sig in self.signatures():
+                if any(arg.type.includesRestrictedFloat() for arg in sig[1]):
+                    found = True
+            if not found:
+                raise WebIDLError("[LenientFloat] used on an operation with no "
+                                  "restricted float type arguments",
+                                  [self.location])
 
     def overloadsForArgCount(self, argc):
         return [overload for overload in self._overloads if
                 len(overload.arguments) == argc or
                 (len(overload.arguments) > argc and
                  all(arg.optional for arg in overload.arguments[argc:])) or
                 (len(overload.arguments) < argc and
                  len(overload.arguments) > 0 and
@@ -5020,20 +5030,16 @@ class IDLMethod(IDLInterfaceMember, IDLS
                               [attr.location, self.location])
         elif identifier == "LenientFloat":
             # This is called before we've done overload resolution
             assert len(self.signatures()) == 1
             sig = self.signatures()[0]
             if not sig[0].isVoid():
                 raise WebIDLError("[LenientFloat] used on a non-void method",
                                   [attr.location, self.location])
-            if not any(arg.type.includesRestrictedFloat() for arg in sig[1]):
-                raise WebIDLError("[LenientFloat] used on an operation with no "
-                                  "restricted float type arguments",
-                                  [attr.location, self.location])
         elif identifier == "Exposed":
             convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames)
         elif (identifier == "CrossOriginCallable" or
               identifier == "WebGLHandlesContextLoss"):
             # Known no-argument attributes.
             if not attr.noArguments():
                 raise WebIDLError("[%s] must take no arguments" % identifier,
                                   [attr.location])
--- a/dom/bindings/parser/tests/test_float_types.py
+++ b/dom/bindings/parser/tests/test_float_types.py
@@ -76,45 +76,64 @@ def WebIDLTest(parser, harness):
     threw = False
     try:
         parser.parse("""
             interface FloatTypes {
               [LenientFloat]
               void m(unrestricted float arg);
             };
         """)
+        parser.finish()
     except Exception, x:
         threw = True
-    harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args")
+    harness.ok(threw, "[LenientFloat] only allowed if at least one overload has unrestricted float args")
 
     parser = parser.reset()
     threw = False
     try:
         parser.parse("""
             interface FloatTypes {
               [LenientFloat]
               void m(sequence<unrestricted float> arg);
             };
         """)
+        parser.finish()
     except Exception, x:
         threw = True
-    harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (2)")
+    harness.ok(threw, "[LenientFloat] only allowed if at least one overload has unrestricted float args (2)")
 
     parser = parser.reset()
     threw = False
     try:
         parser.parse("""
             interface FloatTypes {
               [LenientFloat]
               void m((unrestricted float or FloatTypes) arg);
             };
         """)
+        parser.finish()
     except Exception, x:
         threw = True
-    harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (3)")
+    harness.ok(threw, "[LenientFloat] only allowed if at least one overload has unrestricted float args (3)")
+
+    parser = parser.reset()
+    threw = False
+    try:
+        parser.parse("""
+            interface FloatTypes {
+              [LenientFloat]
+              void m(optional sequence<unrestricted float> transform);
+              [LenientFloat]
+              void m(double a);
+            };
+        """)
+        parser.finish()
+    except Exception, x:
+        threw = True
+    harness.ok(not threw, "[LenientFloat] only allowed if at least one overload has unrestricted float args (4)")
 
     parser = parser.reset()
     threw = False
     try:
         parser.parse("""
             interface FloatTypes {
               [LenientFloat]
               readonly attribute float foo;