Repository: w3c/webidl2.js
Pull request #199 (2018-06-10 12:41:21)

Add trivia for const member type
Includes some refactoring.


Patch:
diff --git a/lib/webidl2.js b/lib/webidl2.js
index bd013ff..0499b97 100644
--- a/lib/webidl2.js
+++ b/lib/webidl2.js
@@ -325,14 +325,29 @@
     }
 
     function const_value() {
-      if (consume("true")) return { type: "boolean", value: true };
-      if (consume("false")) return { type: "boolean", value: false };
-      if (consume("null")) return { type: "null" };
-      if (consume("Infinity")) return { type: "Infinity", negative: false };
-      if (consume("-Infinity")) return { type: "Infinity", negative: true };
-      if (consume("NaN")) return { type: "NaN" };
-      const ret = consume(FLOAT, INT);
-      if (ret) return { type: "number", value: ret.value };
+      const token = consume("true", "false", "null", "Infinity", "-Infinity", "NaN", FLOAT, INT);
+      if (!token) {
+        return;
+      }
+      const { trivia } = token;
+      let data;
+      switch (token.type) {
+        case "true":
+        case "false":
+          data = { type: "boolean", value: token.type === "true" };
+          break;
+        case "Infinity":
+        case "-Infinity":
+          data = { type: "Infinity", negative: token.type.startsWith("-") };
+          break;
+        case FLOAT:
+        case INT:
+          data = { type: "number", value: token.value };
+          break;
+        default:
+          data = { type: token.type };
+      }
+      return { data, trivia };
     }
 
     function type_suffix(obj) {
@@ -542,40 +557,57 @@
     }
 
     function default_() {
-      if (consume("=")) {
-        const def = const_value();
-        if (def) {
-          return def;
-        } else if (consume("[")) {
-          if (!consume("]")) error("Default sequence value must be empty");
-          return { type: "sequence", value: [] };
-        } else {
-          const str = consume(STR) || error("No value for default");
-          str.value = str.value.slice(1, -1);
-          // No trivia exposure yet
-          str.trivia = undefined;
-          return str;
-        }
+      const assign = consume("=");
+      if (!assign) {
+        return;
+      }
+
+      const trivia = { assign: assign.trivia };
+      const def = const_value();
+      if (def) {
+        trivia.value = def.trivia;
+        return Object.assign(def.data, { trivia });
       }
+
+      const open = consume("[");
+      if (open) {
+        const close = consume("]");
+        if (!close) error("Default sequence value must be empty");
+        trivia.open = open.trivia;
+        trivia.close = close.trivia;
+        return { type: "sequence", value: [], trivia };
+      }
+
+      const str = consume(STR) || error("No value for default");
+      str.value = str.value.slice(1, -1);
+      trivia.value = str.trivia;
+      str.trivia = trivia;
+      return str;
     }
 
     function const_() {
-      if (!consume("const")) return;
+      const base = consume("const");
+      if (!base) return;
+      const trivia = { base: base.trivia };
       const ret = { type: "const" };
       let typ = primitive_type();
       if (!typ) {
         typ = consume(ID) || error("No type for const");
-        typ = { idlType: type.value }
+        typ = { idlType: typ.value, baseName: typ.value, trivia: { base: typ.trivia } };
       }
       ret.idlType = Object.assign({ type: "const-type" }, EMPTY_IDLTYPE, typ);
       type_suffix(ret.idlType);
       const name = consume(ID) || error("No name for const");
       ret.name = name.value;
-      consume("=") || error("No value assignment for const");
-      const cnt = const_value();
-      if (cnt) ret.value = cnt;
-      else error("No value for const");
-      consume(";") || error("Unterminated const");
+      trivia.name = name.trivia;
+      const assign = consume("=") || error("No value assignment for const");
+      trivia.assign = assign.trivia;
+      const cnt = const_value() || error("No value for const");
+      ret.value = cnt.data;
+      trivia.value = cnt.trivia;
+      const termination = consume(";") || error("Unterminated const");
+      trivia.termination = termination.trivia;
+      ret.trivia = trivia;
       return ret;
     }
 
diff --git a/lib/writer.js b/lib/writer.js
index 215eacb..3a7462b 100644
--- a/lib/writer.js
+++ b/lib/writer.js
@@ -24,16 +24,22 @@
       else if (tp === "Infinity") return (it.negative ? "-" : "") + "Infinity";
       else if (tp === "NaN") return "NaN";
       else if (tp === "number") return it.value;
-      else if (tp === "sequence") return "[]";
       else return `"${it.value}"`;
     };
+    function default_(def) {
+      const assign = `${def.trivia.assign}=`;
+      if (def.type === "sequence") {
+        return `${assign}${def.trivia.open}[${def.trivia.close}]`;
+      }
+      return `${assign}${def.trivia.value}${const_value(def)}`;
+    }
     function argument(arg) {
       let ret = extended_attributes(arg.extAttrs);
       if (arg.optional) ret += `${arg.optional.trivia}optional`;
       ret += type(arg.idlType);
       if (arg.variadic) ret += `${arg.variadic.trivia}...`;
       ret += `${arg.trivia.name}${arg.escapedName}`;
-      if (arg.default) ret += ` = ${const_value(arg.default)}`;
+      if (arg.default) ret += default_(arg.default);
       if (arg.separator) ret += `${arg.separator.trivia}${arg.separator.value}`;
       return ret;
     };
@@ -117,13 +123,13 @@
       let ret = extended_attributes(it.extAttrs);
       if (it.required) ret += "required";
       ret += `${type(it.idlType)} ${it.escapedName}`;
-      if (it.default) ret += ` = ${const_value(it.default)}`;
+      if (it.default) ret += default_(it.default);
       ret += ";";
       return ret;
     };
     function const_(it) {
-      const ret = extended_attributes(it.extAttrs);
-      return `${ret}const${type(it.idlType)} ${it.name} = ${const_value(it.value)};`;
+      let ret = extended_attributes(it.extAttrs);
+      return `${ret}${it.trivia.base}const${type(it.idlType)}${it.trivia.name}${it.name}${it.trivia.assign}=${it.trivia.value}${const_value(it.value)}${it.trivia.termination};`;
     };
     function typedef(it) {
       let ret = extended_attributes(it.extAttrs);


Test patch:
diff --git a/test/syntax/json/constants.json b/test/syntax/json/constants.json
index 435fa1a..c3b70b9 100644
--- a/test/syntax/json/constants.json
+++ b/test/syntax/json/constants.json
@@ -26,6 +26,13 @@
                     "type": "boolean",
                     "value": false
                 },
+                "trivia": {
+                    "base": "\n  ",
+                    "name": " ",
+                    "assign": " ",
+                    "value": " ",
+                    "termination": ""
+                },
                 "extAttrs": []
             },
             {
@@ -50,6 +57,13 @@
                     "type": "number",
                     "value": "-1"
                 },
+                "trivia": {
+                    "base": "\n  ",
+                    "name": " ",
+                    "assign": " ",
+                    "value": " ",
+                    "termination": ""
+                },
                 "extAttrs": []
             },
             {
@@ -74,6 +88,13 @@
                     "type": "number",
                     "value": "10"
                 },
+                "trivia": {
+                    "base": "\n  ",
+                    "name": " ",
+                    "assign": " ",
+                    "value": " ",
+                    "termination": ""
+                },
                 "extAttrs": []
             },
             {
@@ -101,6 +122,13 @@
                     "type": "number",
                     "value": "0x0000fc00"
                 },
+                "trivia": {
+                    "base": "\n  ",
+                    "name": " ",
+                    "assign": " ",
+                    "value": " ",
+                    "termination": ""
+                },
                 "extAttrs": []
             },
             {
@@ -125,6 +153,13 @@
                     "type": "number",
                     "value": "6.022e23"
                 },
+                "trivia": {
+                    "base": "\n  ",
+                    "name": " ",
+                    "assign": " ",
+                    "value": " ",
+                    "termination": ""
+                },
                 "extAttrs": []
             },
             {
@@ -152,6 +187,13 @@
                     "type": "Infinity",
                     "negative": false
                 },
+                "trivia": {
+                    "base": "\n  ",
+                    "name": " ",
+                    "assign": " ",
+                    "value": " ",
+                    "termination": ""
+                },
                 "extAttrs": []
             },
             {
@@ -179,6 +221,13 @@
                     "type": "Infinity",
                     "negative": true
                 },
+                "trivia": {
+                    "base": "\n  ",
+                    "name": " ",
+                    "assign": " ",
+                    "value": " ",
+                    "termination": ""
+                },
                 "extAttrs": []
             },
             {
@@ -202,6 +251,13 @@
                 "value": {
                     "type": "NaN"
                 },
+                "trivia": {
+                    "base": "\n  ",
+                    "name": " ",
+                    "assign": " ",
+                    "value": " ",
+                    "termination": ""
+                },
                 "extAttrs": []
             }
         ],
diff --git a/test/syntax/json/dictionary-inherits.json b/test/syntax/json/dictionary-inherits.json
index 553977a..a0caa4a 100644
--- a/test/syntax/json/dictionary-inherits.json
+++ b/test/syntax/json/dictionary-inherits.json
@@ -29,7 +29,11 @@
                 "extAttrs": [],
                 "default": {
                     "type": "string",
-                    "value": "black"
+                    "value": "black",
+                    "trivia": {
+                        "assign": " ",
+                        "value": " "
+                    }
                 }
             },
             {
@@ -56,7 +60,11 @@
                 },
                 "extAttrs": [],
                 "default": {
-                    "type": "null"
+                    "type": "null",
+                    "trivia": {
+                        "assign": " ",
+                        "value": " "
+                    }
                 }
             },
             {
diff --git a/test/syntax/json/dictionary.json b/test/syntax/json/dictionary.json
index 9a78951..aacf869 100644
--- a/test/syntax/json/dictionary.json
+++ b/test/syntax/json/dictionary.json
@@ -29,7 +29,11 @@
                 "extAttrs": [],
                 "default": {
                     "type": "string",
-                    "value": "black"
+                    "value": "black",
+                    "trivia": {
+                        "assign": " ",
+                        "value": " "
+                    }
                 }
             },
             {
@@ -56,7 +60,11 @@
                 },
                 "extAttrs": [],
                 "default": {
-                    "type": "null"
+                    "type": "null",
+                    "trivia": {
+                        "assign": " ",
+                        "value": " "
+                    }
                 }
             },
             {
@@ -127,7 +135,12 @@
                 "extAttrs": [],
                 "default": {
                     "type": "sequence",
-                    "value": []
+                    "value": [],
+                    "trivia": {
+                        "assign": " ",
+                        "open": " ",
+                        "close": ""
+                    }
                 }
             },
             {
diff --git a/test/syntax/json/nullable.json b/test/syntax/json/nullable.json
index 0e4f0e8..435399a 100644
--- a/test/syntax/json/nullable.json
+++ b/test/syntax/json/nullable.json
@@ -28,6 +28,13 @@
                     "type": "boolean",
                     "value": false
                 },
+                "trivia": {
+                    "base": "\n  ",
+                    "name": " ",
+                    "assign": " ",
+                    "value": " ",
+                    "termination": ""
+                },
                 "extAttrs": []
             }
         ],
diff --git a/test/syntax/json/operation-optional-arg.json b/test/syntax/json/operation-optional-arg.json
index 2e45341..02d3270 100644
--- a/test/syntax/json/operation-optional-arg.json
+++ b/test/syntax/json/operation-optional-arg.json
@@ -134,7 +134,11 @@
                             "variadic": null,
                             "default": {
                                 "type": "number",
-                                "value": "3.5"
+                                "value": "3.5",
+                                "trivia": {
+                                    "assign": " ",
+                                    "value": " "
+                                }
                             },
                             "trivia": {
                                 "name": " "