Repository: w3c/webidl2.js
Pull request #148 (2018-05-06 11:31:57)

Refactor simple_extended_attr();
This PR:

1. avoids checking `(` twice in different if-branches
2. removes old MapClass related variable and comment
3. throws if an identifier list is empty

marcoscaceres: about Travis being busted... do you have a link to where you saw that "repo not valid" error? I'm trying to get it working again.  
marcoscaceres: NM! found it! Reactivate it.... so weird.  
marcoscaceres: Still stuck tho.. not sure what to do. We can try sending some more empty commits, and see if that kicks it off again. I don't seem to have the option to restart the tests on the branch, as it's not showing up on travis. Any suggestions? 
saschanaz: Reopening worked!
marcoscaceres: Oh, awesome! Feel free to merge the PRs and release. 

Patch:
diff --git a/lib/webidl2.js b/lib/webidl2.js
index ef047df..024158a 100644
--- a/lib/webidl2.js
+++ b/lib/webidl2.js
@@ -396,7 +396,7 @@
     function argument_list(store) {
       const ret = [];
       const arg = argument(store ? ret : null);
-      if (!arg) return;
+      if (!arg) return ret;
       ret.push(arg);
       while (true) {
         all_ws(store ? ret : null);
@@ -412,7 +412,7 @@
       if (!name) return;
       const ret = {
         name: name.value,
-        "arguments": null,
+        arguments: null,
         type: "extended-attribute",
         rhs: null
       };
@@ -424,36 +424,24 @@
           consume(FLOAT) ||
           consume(INT) ||
           consume(STR);
-        if (!ret.rhs && consume(OTHER, "(")) {
+      }
+      all_ws();
+      if (consume(OTHER, "(")) {
+        if (eq && !ret.rhs) {
           // [Exposed=(Window,Worker)]
-          const rhs_list = [];
-          const id = consume(ID);
-          if (id) {
-            rhs_list.push(id.value);
-          }
-          identifiers(rhs_list);
-          consume(OTHER, ")") || error("Unexpected token in extended attribute argument list or type pair");
           ret.rhs = {
             type: "identifier-list",
-            value: rhs_list
+            value: identifiers()
           };
         }
-        if (!ret.rhs) return error("No right hand side to extended attribute assignment");
-      }
-      all_ws();
-      if (consume(OTHER, "(")) {
-        let args, pair;
-        // [Constructor(DOMString str)]
-        if (args = argument_list(store)) {
-          ret["arguments"] = args;
-        }
-        // [Constructor()]
         else {
-          ret["arguments"] = [];
+          // [NamedConstructor=Audio(DOMString src)] or [Constructor(DOMString str)]
+          ret.arguments = argument_list(store);
         }
         all_ws();
         consume(OTHER, ")") || error("Unexpected token in extended attribute argument list");
       }
+      if (eq && !ret.rhs) error("No right hand side to extended attribute assignment");
       return ret;
     }
 
@@ -536,7 +524,7 @@
       ret.name = name ? name.value : null;
       all_ws();
       consume(OTHER, "(") || error("Invalid operation");
-      ret["arguments"] = argument_list(store) || [];
+      ret.arguments = argument_list(store);
       all_ws();
       consume(OTHER, ")") || error("Unterminated operation");
       all_ws();
@@ -562,7 +550,7 @@
       ret.idlType = return_type();
       all_ws();
       consume(OTHER, "(") || error("No arguments in callback");
-      ret["arguments"] = argument_list(store) || [];
+      ret.arguments = argument_list(store);
       all_ws();
       consume(OTHER, ")") || error("Unterminated callback");
       all_ws();
@@ -671,7 +659,13 @@
         error("Unterminated stringifier");
     }
 
-    function identifiers(arr) {
+    function identifiers() {
+      const arr = [];
+      const id = consume(ID);
+      if (id) {
+        arr.push(id.value);
+      }
+      else error("Expected identifiers but not found");
       while (true) {
         all_ws();
         if (consume(OTHER, ",")) {
@@ -680,6 +674,7 @@
           arr.push(name.value);
         } else break;
       }
+      return arr;
     }
 
     function iterable_type() {


Test patch:
diff --git a/test/invalid/idl/extattr-empty-ids.widl b/test/invalid/idl/extattr-empty-ids.widl
new file mode 100644
index 0000000..93c48c3
--- /dev/null
+++ b/test/invalid/idl/extattr-empty-ids.widl
@@ -0,0 +1,2 @@
+[Exposed=()]
+interface Unexposed {};
diff --git a/test/invalid/json/extattr-empty-ids.json b/test/invalid/json/extattr-empty-ids.json
new file mode 100644
index 0000000..4337f1e
--- /dev/null
+++ b/test/invalid/json/extattr-empty-ids.json
@@ -0,0 +1,4 @@
+{
+    "message": "Got an error before parsing any named definition: Expected identifiers but not found",
+    "line": 1
+}