Repository: w3c/webidl2.js
Pull request #75 (2017-07-01 02:00:53)

Support TypeWithExtendedAttributes on generics
... which includes `sequence`, `FrozenArray` and `record`. `Promise` is intentionally not supported because of [the spec](https://heycam.github.io/webidl/#idl-types):

```
PromiseType ::
    Promise < ReturnType >
```


Patch:
diff --git a/lib/webidl2.js b/lib/webidl2.js
index f41e0c5..9805ae1 100644
--- a/lib/webidl2.js
+++ b/lib/webidl2.js
@@ -195,7 +195,7 @@
           var types = [];
           do {
             all_ws();
-            types.push(type() || error("Error parsing generic type " + value));
+            types.push(type_with_extended_attributes() || error("Error parsing generic type " + value));
             all_ws();
           }
           while (consume(OTHER, ","));
@@ -206,6 +206,9 @@
             if (!/^(DOMString|USVString|ByteString)$/.test(types[0].idlType)) {
               error("Record key must be DOMString, USVString, or ByteString");
             }
+            if (types[0].extAttrs) error("Record key cannot have extended attribute");
+          } else if (value === "Promise") {
+            if (types[0].extAttrs) error("Promise type cannot have extended attribute");
           }
           ret.idlType = types.length === 1 ? types[0] : types;
           all_ws();


Test patch:
diff --git a/test/invalid/idl/promise-with-extended-attribute.widl b/test/invalid/idl/promise-with-extended-attribute.widl
new file mode 100644
index 0000000..0ce171f
--- /dev/null
+++ b/test/invalid/idl/promise-with-extended-attribute.widl
@@ -0,0 +1,3 @@
+interface Foo {
+  Promise<[XAttr] DOMString> foo(any param);
+};
diff --git a/test/invalid/idl/record-key-with-extended-attribute.widl b/test/invalid/idl/record-key-with-extended-attribute.widl
new file mode 100644
index 0000000..c11eb74
--- /dev/null
+++ b/test/invalid/idl/record-key-with-extended-attribute.widl
@@ -0,0 +1,3 @@
+interface Foo {
+  void foo(record<[XAttr] DOMString, any> param);
+};
diff --git a/test/invalid/json/promise-with-extended-attribute.json b/test/invalid/json/promise-with-extended-attribute.json
new file mode 100644
index 0000000..e9623ce
--- /dev/null
+++ b/test/invalid/json/promise-with-extended-attribute.json
@@ -0,0 +1,4 @@
+{
+    "message": "Promise type cannot have extended attribute",
+    "line": 2
+}
diff --git a/test/invalid/json/record-key-with-extended-attribute.json b/test/invalid/json/record-key-with-extended-attribute.json
new file mode 100644
index 0000000..3945825
--- /dev/null
+++ b/test/invalid/json/record-key-with-extended-attribute.json
@@ -0,0 +1,4 @@
+{
+    "message": "Record key cannot have extended attribute",
+    "line": 2
+}
diff --git a/test/syntax/idl/iterable.widl b/test/syntax/idl/iterable.widl
index c7dfafa..da8eb71 100644
--- a/test/syntax/idl/iterable.widl
+++ b/test/syntax/idl/iterable.widl
@@ -4,4 +4,8 @@ interface IterableOne {
 
 interface IterableTwo {
 	iterable<short, double?>;
+};
+
+interface IterableThree {
+	iterable<[XAttr] long>;
 };
\ No newline at end of file
diff --git a/test/syntax/idl/maplike.widl b/test/syntax/idl/maplike.widl
index 7b79b38..ab710ee 100644
--- a/test/syntax/idl/maplike.widl
+++ b/test/syntax/idl/maplike.widl
@@ -5,3 +5,9 @@ interface MapLike {
 interface ReadOnlyMapLike {
 	readonly maplike<long, float>;
 };
+
+// Extracted from https://heycam.github.io/webidl/#idl-type-extended-attribute-associated-with on 2017-07-01
+
+interface I {
+    maplike<[XAttr2] DOMString, [XAttr3] long>;
+};
diff --git a/test/syntax/idl/record.widl b/test/syntax/idl/record.widl
index 6cdedb2..c8d9343 100644
--- a/test/syntax/idl/record.widl
+++ b/test/syntax/idl/record.widl
@@ -6,3 +6,7 @@ interface Foo {
   // Make sure record can still be registered as a type.
   record baz();
 };
+
+interface Bar {
+  record<DOMString, [XAttr] float> bar();
+};
diff --git a/test/syntax/idl/sequence.widl b/test/syntax/idl/sequence.widl
index 6ba0d39..d31056c 100644
--- a/test/syntax/idl/sequence.widl
+++ b/test/syntax/idl/sequence.widl
@@ -9,4 +9,10 @@ interface Canvas {
 // Make sure sequence can still be registered as a type.
 interface Foo {
   sequence bar();
-};
\ No newline at end of file
+};
+
+// Extracted from https://heycam.github.io/webidl/#idl-type-extended-attribute-associated-with on 2017-07-01
+
+interface I {
+    void f1(sequence<[XAttr] long> arg);
+};
diff --git a/test/syntax/idl/setlike.widl b/test/syntax/idl/setlike.widl
index 890e8e5..f03bb58 100644
--- a/test/syntax/idl/setlike.widl
+++ b/test/syntax/idl/setlike.widl
@@ -5,3 +5,7 @@ interface SetLike {
 interface ReadOnlySetLike {
 	readonly setlike<long>;
 };
+
+interface SetLikeExt {
+	setlike<[XAttr] long>;
+};
\ No newline at end of file
diff --git a/test/syntax/json/iterable.json b/test/syntax/json/iterable.json
index 2614b89..ecec327 100644
--- a/test/syntax/json/iterable.json
+++ b/test/syntax/json/iterable.json
@@ -47,6 +47,32 @@
         ],
         "inheritance": null,
         "extAttrs": []
+    },
+    {
+        "type": "interface",
+        "name": "IterableThree",
+        "partial": false,
+        "members": [
+            {
+                "type": "iterable",
+                "idlType": {
+                    "sequence": false,
+                    "generic": null,
+                    "nullable": false,
+                    "union": false,
+                    "idlType": "long",
+                    "extAttrs": [
+                        {
+                            "name": "XAttr",
+                            "arguments": null
+                        }
+                    ]
+                },
+                "extAttrs": []
+            }
+        ],
+        "inheritance": null,
+        "extAttrs": []
     }
 ]
 
diff --git a/test/syntax/json/maplike.json b/test/syntax/json/maplike.json
index 85451cb..106f170 100644
--- a/test/syntax/json/maplike.json
+++ b/test/syntax/json/maplike.json
@@ -58,6 +58,48 @@
         ],
         "inheritance": null,
         "extAttrs": []
+    },
+    {
+        "type": "interface",
+        "name": "I",
+        "partial": false,
+        "members": [
+            {
+                "type": "maplike",
+                "idlType": [
+                    {
+                        "sequence": false,
+                        "generic": null,
+                        "nullable": false,
+                        "union": false,
+                        "idlType": "DOMString",
+                        "extAttrs": [
+                            {
+                                "name": "XAttr2",
+                                "arguments": null
+                            }
+                        ]
+                    },
+                    {
+                        "sequence": false,
+                        "generic": null,
+                        "nullable": false,
+                        "union": false,
+                        "idlType": "long",
+                        "extAttrs": [
+                            {
+                                "name": "XAttr3",
+                                "arguments": null
+                            }
+                        ]
+                    }
+                ],
+                "readonly": false,
+                "extAttrs": []
+            }
+        ],
+        "inheritance": null,
+        "extAttrs": []
     }
 ]
 
diff --git a/test/syntax/json/record.json b/test/syntax/json/record.json
index 3a71444..5240185 100644
--- a/test/syntax/json/record.json
+++ b/test/syntax/json/record.json
@@ -166,5 +166,55 @@
                 ]
             }
         ]
+    },
+    {
+        "type": "interface",
+        "name": "Bar",
+        "partial": false,
+        "members": [
+            {
+                "type": "operation",
+                "getter": false,
+                "setter": false,
+                "creator": false,
+                "deleter": false,
+                "legacycaller": false,
+                "static": false,
+                "stringifier": false,
+                "idlType": {
+                    "sequence": false,
+                    "generic": "record",
+                    "nullable": false,
+                    "union": false,
+                    "idlType": [
+                        {
+                            "sequence": false,
+                            "generic": null,
+                            "nullable": false,
+                            "union": false,
+                            "idlType": "DOMString"
+                        },
+                        {
+                            "sequence": false,
+                            "generic": null,
+                            "nullable": false,
+                            "union": false,
+                            "idlType": "float",
+                            "extAttrs": [
+                                {
+                                    "name": "XAttr",
+                                    "arguments": null
+                                }
+                            ]
+                        }
+                    ]
+                },
+                "name": "bar",
+                "arguments": [],
+                "extAttrs": []
+            }
+        ],
+        "inheritance": null,
+        "extAttrs": []
     }
 ]
diff --git a/test/syntax/json/sequence.json b/test/syntax/json/sequence.json
index 619a08a..8815a33 100644
--- a/test/syntax/json/sequence.json
+++ b/test/syntax/json/sequence.json
@@ -103,5 +103,61 @@
         ],
         "inheritance": null,
         "extAttrs": []
-    }    
+    },
+    
+    {
+        "type": "interface",
+        "name": "I",
+        "partial": false,
+        "members": [
+            {
+                "type": "operation",
+                "getter": false,
+                "setter": false,
+                "creator": false,
+                "deleter": false,
+                "legacycaller": false,
+                "static": false,
+                "stringifier": false,
+                "idlType": {
+                    "sequence": false,
+                    "generic": null,
+                    "nullable": false,
+                    "union": false,
+                    "idlType": "void"
+                },
+                "name": "f1",
+                "arguments": [
+                    {
+                        "optional": false,
+                        "variadic": false,
+                        "extAttrs": [],
+                        "idlType": {
+                            "sequence": true,
+                            "generic": "sequence",
+                            "nullable": false,
+                            "union": false,
+                            "idlType": {
+                                "sequence": false,
+                                "generic": null,
+                                "nullable": false,
+                                "union": false,
+                                "idlType": "long",
+                                "extAttrs": [
+                                    {
+                                        "name": "XAttr",
+                                        "arguments": null
+                                    }
+                                ]
+                            }
+                        },
+                        "name": "arg"
+                    }
+                ],
+                "extAttrs": []
+            }
+        ],
+        "inheritance": null,
+        "extAttrs": []
+    }
 ]
\ No newline at end of file
diff --git a/test/syntax/json/setlike.json b/test/syntax/json/setlike.json
index e17175d..62e2d39 100644
--- a/test/syntax/json/setlike.json
+++ b/test/syntax/json/setlike.json
@@ -40,6 +40,33 @@
         ],
         "inheritance": null,
         "extAttrs": []
+    },
+    {
+        "type": "interface",
+        "name": "SetLikeExt",
+        "partial": false,
+        "members": [
+            {
+                "type": "setlike",
+                "idlType": {
+                    "sequence": false,
+                    "generic": null,
+                    "nullable": false,
+                    "union": false,
+                    "idlType": "long",
+                    "extAttrs": [
+                        {
+                            "name": "XAttr",
+                            "arguments": null
+                        }
+                    ]
+                },
+                "readonly": false,
+                "extAttrs": []
+            }
+        ],
+        "inheritance": null,
+        "extAttrs": []
     }
 ]