-
Notifications
You must be signed in to change notification settings - Fork 47
/
webidl2.js
2 lines (2 loc) · 41.2 KB
/
webidl2.js
1
2
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.WebIDL2=t():e.WebIDL2=t()}(globalThis,(()=>(()=>{"use strict";var e={d:(t,n)=>{for(var s in n)e.o(n,s)&&!e.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:n[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};function n(e,t,n,s,r,{level:i="error",autofix:o,ruleName:a}={}){function c(n){return n>0?e.slice(t,t+n):e.slice(Math.max(t+n,0),t)}function u(n,{precedes:s}={}){const r=n.map((e=>e.trivia+e.value)).join(""),i=e[t];return"eof"===i.type?r:s?r+i.trivia:r.slice(i.trivia.length)}const l="eof"!==e[t].type?e[t].line:e.length>1?e[t-1].line:1,p=function(e){const t=e.split("\n");return t[t.length-1]}(u(c(-5),{precedes:!0})),d=c(5),h=u(d),m=p+h.split("\n")[0]+"\n"+(" ".repeat(p.length)+"^"),f="Syntax"===r?"since":"inside",y=`${r} error at line ${l}${e.name?` in ${e.name}`:""}${n&&n.name?`, ${f} \`${n.partial?"partial ":""}${function(e){const t=[e];for(;e&&e.parent;){const{parent:n}=e;t.unshift(n),e=n}return t.map((e=>function(e,t){let n=e;return t&&(n+=` ${t}`),n}(e.type,e.name))).join(" -> ")}(n)}\``:""}:\n${m}`;return{message:`${y} ${s}`,bareMessage:s,context:y,line:l,sourceName:e.name,level:i,ruleName:a,autofix:o,input:h,tokens:d}}function s(e,t,s,r){return n(e,t,s,r,"Syntax")}function r(e,t,s,r,i={}){return i.ruleName=s,n(t.source,e.index,t,r,"Validation",i)}e.r(t),e.d(t,{WebIDLParseError:()=>WebIDLParseError,parse:()=>q,validate:()=>_,write:()=>F});class Base{constructor({source:e,tokens:t}){Object.defineProperties(this,{source:{value:e},tokens:{value:t,writable:!0},parent:{value:null,writable:!0},this:{value:this}})}toJSON(){const e={type:void 0,name:void 0,inheritance:void 0};let t=this;for(;t!==Object.prototype;){const n=Object.getOwnPropertyDescriptors(t);for(const[t,s]of Object.entries(n))(s.enumerable||s.get)&&(e[t]=this[t]);t=Object.getPrototypeOf(t)}return e}}function i(e,t,{useNullableInner:n}={}){if(!e.union){const s=t.unique.get(e.idlType);if(!s)return;if("typedef"===s.type){const{typedefIncludesDictionary:n}=t.cache;if(n.has(s))return n.get(s);t.cache.typedefIncludesDictionary.set(s,void 0);const r=i(s.idlType,t);if(t.cache.typedefIncludesDictionary.set(s,r),r)return{reference:e,dictionary:r.dictionary}}if("dictionary"===s.type&&(n||!e.nullable))return{reference:e,dictionary:s}}for(const n of e.subtype){const e=i(n,t);if(e)return n.union?e:{reference:n,dictionary:e.dictionary}}}function o(e,t){if(t.cache.dictionaryIncludesRequiredField.has(e))return t.cache.dictionaryIncludesRequiredField.get(e);t.cache.dictionaryIncludesRequiredField.set(e,void 0);let n=e.members.some((e=>e.required));if(!n&&e.inheritance){const s=t.unique.get(e.inheritance);s?o(s,t)&&(n=!0):n=!0}return t.cache.dictionaryIncludesRequiredField.set(e,n),n}class ArrayBase extends Array{constructor({source:e,tokens:t}){super(),Object.defineProperties(this,{source:{value:e},tokens:{value:t},parent:{value:null,writable:!0}})}}class WrappedToken extends Base{static parser(e,t){return()=>{const n=e.consumeKind(t);if(n)return new WrappedToken({source:e.source,tokens:{value:n}})}}get value(){return m(this.tokens.value.value)}write(e){return e.ts.wrap([e.token(this.tokens.value),e.token(this.tokens.separator)])}}class Eof extends WrappedToken{static parse(e){const t=e.consumeKind("eof");if(t)return new Eof({source:e.source,tokens:{value:t}})}get type(){return"eof"}}function a(e,t){return f(e,{parser:WrappedToken.parser(e,t),listName:t+" list"})}const c=["identifier","decimal","integer","string"],u=new Map([...["NoInterfaceObject","LenientSetter","LenientThis","TreatNonObjectAsNull","Unforgeable"].map((e=>[e,`Legacy${e}`])),["NamedConstructor","LegacyFactoryFunction"],["OverrideBuiltins","LegacyOverrideBuiltIns"],["TreatNullAs","LegacyNullToEmptyString"]]);function l(e){for(const t of c){const n=a(e,t);if(n.length)return n}e.error("Expected identifiers, strings, decimals, or integers but none found")}class ExtendedAttributeParameters extends Base{static parse(e){const t={assign:e.consume("=")},n=E(new ExtendedAttributeParameters({source:e.source,tokens:t}));if(n.list=[],t.assign){if(t.asterisk=e.consume("*"),t.asterisk)return n.this;t.secondaryName=e.consumeKind(...c)}return t.open=e.consume("("),t.open?(n.list=n.rhsIsList?l(e):g(e),t.close=e.consume(")")||e.error("Unexpected token in extended attribute argument list")):t.assign&&!t.secondaryName&&e.error("No right hand side to extended attribute assignment"),n.this}get rhsIsList(){return this.tokens.assign&&!this.tokens.asterisk&&!this.tokens.secondaryName}get rhsType(){return this.rhsIsList?this.list[0].tokens.value.type+"-list":this.tokens.asterisk?"*":this.tokens.secondaryName?this.tokens.secondaryName.type:null}write(e){const{rhsType:t}=this;return e.ts.wrap([e.token(this.tokens.assign),e.token(this.tokens.asterisk),e.reference_token(this.tokens.secondaryName,this.parent),e.token(this.tokens.open),...this.list.map((n=>"identifier-list"===t?e.identifier(n,this.parent):n.write(e))),e.token(this.tokens.close)])}}class SimpleExtendedAttribute extends Base{static parse(e){const t=e.consumeKind("identifier");if(t)return new SimpleExtendedAttribute({source:e.source,tokens:{name:t},params:ExtendedAttributeParameters.parse(e)})}constructor({source:e,tokens:t,params:n}){super({source:e,tokens:t}),n.parent=this,Object.defineProperty(this,"params",{value:n})}get type(){return"extended-attribute"}get name(){return this.tokens.name.value}get rhs(){const{rhsType:e,tokens:t,list:n}=this.params;if(!e)return null;return{type:e,value:this.params.rhsIsList?n:this.params.tokens.secondaryName?m(t.secondaryName.value):null}}get arguments(){const{rhsIsList:e,list:t}=this.params;return!t||e?[]:t}*validate(e){const{name:t}=this;if("LegacyNoInterfaceObject"===t){const e="`[LegacyNoInterfaceObject]` extended attribute is an undesirable feature that may be removed from Web IDL in the future. Refer to the [relevant upstream PR](https://github.com/whatwg/webidl/pull/609) for more information.";yield r(this.tokens.name,this,"no-nointerfaceobject",e,{level:"warning"})}else if(u.has(t)){const e=`\`[${t}]\` extended attribute is a legacy feature that is now renamed to \`[${u.get(t)}]\`. Refer to the [relevant upstream PR](https://github.com/whatwg/webidl/pull/870) for more information.`;yield r(this.tokens.name,this,"renamed-legacy",e,{level:"warning",autofix:(n=this,()=>{const{name:e}=n;n.tokens.name.value=u.get(e),"TreatNullAs"===e&&(n.params.tokens={})})})}var n;for(const t of this.arguments)yield*t.validate(e)}write(e){return e.ts.wrap([e.ts.trivia(this.tokens.name.trivia),e.ts.extendedAttribute(e.ts.wrap([e.ts.extendedAttributeReference(this.name),this.params.write(e)])),e.token(this.tokens.separator)])}}class ExtendedAttributes extends ArrayBase{static parse(e){const t={};t.open=e.consume("[");const n=new ExtendedAttributes({source:e.source,tokens:t});return t.open?(n.push(...f(e,{parser:SimpleExtendedAttribute.parse,listName:"extended attribute"})),t.close=e.consume("]")||e.error("Expected a closing token for the extended attribute list"),n.length||(e.unconsume(t.close.index),e.error("An extended attribute list must not be empty")),e.probe("[")&&e.error("Illegal double extended attribute lists, consider merging them"),n):n}*validate(e){for(const t of this)yield*t.validate(e)}write(e){return this.length?e.ts.wrap([e.token(this.tokens.open),...this.map((t=>t.write(e))),e.token(this.tokens.close)]):""}}function p(e,t){const n=e.consume("?");n&&(t.tokens.nullable=n),e.probe("?")&&e.error("Can't nullable more than once")}function d(e,t){let n=function(e,t){const n=e.consume("FrozenArray","ObservableArray","Promise","sequence","record");if(!n)return;const s=E(new Type({source:e.source,tokens:{base:n}}));switch(s.tokens.open=e.consume("<")||e.error(`No opening bracket after ${n.value}`),n.value){case"Promise":{e.probe("[")&&e.error("Promise type cannot have extended attribute");const n=x(e,t)||e.error("Missing Promise subtype");s.subtype.push(n);break}case"sequence":case"FrozenArray":case"ObservableArray":{const r=v(e,t)||e.error(`Missing ${n.value} subtype`);s.subtype.push(r);break}case"record":{e.probe("[")&&e.error("Record key cannot have extended attribute");const n=e.consume(...C)||e.error(`Record key must be one of: ${C.join(", ")}`),r=new Type({source:e.source,tokens:{base:n}});r.tokens.separator=e.consume(",")||e.error("Missing comma after record key type"),r.type=t;const i=v(e,t)||e.error("Error parsing generic type record");s.subtype.push(r,i);break}}return s.idlType||e.error(`Error parsing generic type ${n.value}`),s.tokens.close=e.consume(">")||e.error(`Missing closing bracket after ${n.value}`),s.this}(e,t)||b(e);if(!n){const t=e.consumeKind("identifier")||e.consume(...C,...O);if(!t)return;n=new Type({source:e.source,tokens:{base:t}}),e.probe("<")&&e.error(`Unsupported generic type ${t.value}`)}return"Promise"===n.generic&&e.probe("?")&&e.error("Promise type cannot be nullable"),n.type=t||null,p(e,n),n.nullable&&"any"===n.idlType&&e.error("Type `any` cannot be made nullable"),n}class Type extends Base{static parse(e,t){return d(e,t)||function(e,t){const n={};if(n.open=e.consume("("),!n.open)return;const s=E(new Type({source:e.source,tokens:n}));for(s.type=t||null;;){const t=v(e)||e.error("No type after open parenthesis or 'or' in union type");"any"===t.idlType&&e.error("Type `any` cannot be included in a union type"),"Promise"===t.generic&&e.error("Type `Promise` cannot be included in a union type"),s.subtype.push(t);const n=e.consume("or");if(!n)break;t.tokens.separator=n}return s.idlType.length<2&&e.error("At least two types are expected in a union type but found less"),n.close=e.consume(")")||e.error("Unterminated union type"),p(e,s),s.this}(e,t)}constructor({source:e,tokens:t}){super({source:e,tokens:t}),Object.defineProperty(this,"subtype",{value:[],writable:!0}),this.extAttrs=new ExtendedAttributes({source:e,tokens:{}})}get generic(){return this.subtype.length&&this.tokens.base?this.tokens.base.value:""}get nullable(){return Boolean(this.tokens.nullable)}get union(){return Boolean(this.subtype.length)&&!this.tokens.base}get idlType(){if(this.subtype.length)return this.subtype;return m([this.tokens.prefix,this.tokens.base,this.tokens.postfix].filter((e=>e)).map((e=>e.value)).join(" "))}*validate(e){if(yield*this.extAttrs.validate(e),"void"===this.idlType){const e="`void` is now replaced by `undefined`. Refer to the [relevant GitHub issue](https://github.com/whatwg/webidl/issues/60) for more information.";yield r(this.tokens.base,this,"replace-void",e,{autofix:(t=this,()=>{t.tokens.base.value="undefined"})})}var t;const n=!this.union&&e.unique.get(this.idlType),s=this.union?this:n&&"typedef"===n.type?n.idlType:void 0;if(s&&this.nullable){const{reference:t}=i(s,e)||{};if(t){const e=(this.union?t:this).tokens.base,n="Nullable union cannot include a dictionary type.";yield r(e,this,"no-nullable-union-dict",n)}}else for(const t of this.subtype)yield*t.validate(e)}write(e){return e.ts.wrap([this.extAttrs.write(e),(()=>{if(this.union||this.generic)return e.ts.wrap([e.token(this.tokens.base,e.ts.generic),e.token(this.tokens.open),...this.subtype.map((t=>t.write(e))),e.token(this.tokens.close)]);const t=this.tokens.prefix||this.tokens.base,n=this.tokens.prefix?[this.tokens.prefix.value,e.ts.trivia(this.tokens.base.trivia)]:[],s=e.reference(e.ts.wrap([...n,this.tokens.base.value,e.token(this.tokens.postfix)]),{unescaped:this.idlType,context:this});return e.ts.wrap([e.ts.trivia(t.trivia),s])})(),e.token(this.tokens.nullable),e.token(this.tokens.separator)])}}class Default extends Base{static parse(e){const t=e.consume("=");if(!t)return null;const n=y(e)||e.consumeKind("string")||e.consume("null","[","{")||e.error("No value for default"),s=[n];if("["===n.value){const t=e.consume("]")||e.error("Default sequence value must be empty");s.push(t)}else if("{"===n.value){const t=e.consume("}")||e.error("Default dictionary value must be empty");s.push(t)}return new Default({source:e.source,tokens:{assign:t},expression:s})}constructor({source:e,tokens:t,expression:n}){super({source:e,tokens:t}),n.parent=this,Object.defineProperty(this,"expression",{value:n})}get type(){return k(this.expression[0]).type}get value(){return k(this.expression[0]).value}get negative(){return k(this.expression[0]).negative}write(e){return e.ts.wrap([e.token(this.tokens.assign),...this.expression.map((t=>e.token(t)))])}}class Argument extends Base{static parse(e){const t=e.position,n={},s=E(new Argument({source:e.source,tokens:n}));return s.extAttrs=ExtendedAttributes.parse(e),n.optional=e.consume("optional"),s.idlType=v(e,"argument-type"),s.idlType?(n.optional||(n.variadic=e.consume("...")),n.name=e.consumeKind("identifier")||e.consume(...$),n.name?(s.default=n.optional?Default.parse(e):null,s.this):e.unconsume(t)):e.unconsume(t)}get type(){return"argument"}get optional(){return!!this.tokens.optional}get variadic(){return!!this.tokens.variadic}get name(){return m(this.tokens.name.value)}*validate(e){yield*this.extAttrs.validate(e),yield*this.idlType.validate(e);const t=i(this.idlType,e,{useNullableInner:!0});if(t)if(this.idlType.nullable){const e="Dictionary arguments cannot be nullable.";yield r(this.tokens.name,this,"no-nullable-dict-arg",e)}else if(this.optional){if(!this.default){const e="Optional dictionary arguments must have a default value of `{}`.";yield r(this.tokens.name,this,"dict-arg-default",e,{autofix:h(this)})}}else if(this.parent&&!o(t.dictionary,e)&&function(e){const t=e.parent.arguments||e.parent.list,n=t.indexOf(e);return!t.slice(n+1).some((e=>!e.optional))}(this)){const e="Dictionary argument must be optional if it has no required fields";yield r(this.tokens.name,this,"dict-arg-optional",e,{autofix:(n=this,()=>{const e=I(n.idlType);n.tokens.optional={...e,type:"optional",value:"optional"},e.trivia=" ",h(n)()})})}var n}write(e){return e.ts.wrap([this.extAttrs.write(e),e.token(this.tokens.optional),e.ts.type(this.idlType.write(e)),e.token(this.tokens.variadic),e.name_token(this.tokens.name,{data:this}),this.default?this.default.write(e):"",e.token(this.tokens.separator)])}}function h(e){return()=>{e.default=Default.parse(new Tokeniser(" = {}"))}}class Operation extends Base{static parse(e,{special:t,regular:n}={}){const s={special:t},r=E(new Operation({source:e.source,tokens:s}));return t&&"stringifier"===t.value&&(s.termination=e.consume(";"),s.termination)?(r.arguments=[],r):(t||n||(s.special=e.consume("getter","setter","deleter")),r.idlType=x(e)||e.error("Missing return type"),s.name=e.consumeKind("identifier")||e.consume("includes"),s.open=e.consume("(")||e.error("Invalid operation"),r.arguments=g(e),s.close=e.consume(")")||e.error("Unterminated operation"),s.termination=e.consume(";")||e.error("Unterminated operation, expected `;`"),r.this)}get type(){return"operation"}get name(){const{name:e}=this.tokens;return e?m(e.value):""}get special(){return this.tokens.special?this.tokens.special.value:""}*validate(e){if(yield*this.extAttrs.validate(e),!this.name&&["","static"].includes(this.special)){const e="Regular or static operations must have both a return type and an identifier.";yield r(this.tokens.open,this,"incomplete-op",e)}this.idlType&&(yield*this.idlType.validate(e));for(const t of this.arguments)yield*t.validate(e)}write(e){const{parent:t}=this,n=this.idlType?[e.ts.type(this.idlType.write(e)),e.name_token(this.tokens.name,{data:this,parent:t}),e.token(this.tokens.open),e.ts.wrap(this.arguments.map((t=>t.write(e)))),e.token(this.tokens.close)]:[];return e.ts.definition(e.ts.wrap([this.extAttrs.write(e),this.tokens.name?e.token(this.tokens.special):e.token(this.tokens.special,e.ts.nameless,{data:this,parent:t}),...n,e.token(this.tokens.termination)]),{data:this,parent:t})}}class Attribute extends Base{static parse(e,{special:t,noInherit:n=!1,readonly:s=!1}={}){const r=e.position,i={special:t},o=E(new Attribute({source:e.source,tokens:i}));if(t||n||(i.special=e.consume("inherit")),"inherit"===o.special&&e.probe("readonly")&&e.error("Inherited attributes cannot be read-only"),i.readonly=e.consume("readonly"),s&&!i.readonly&&e.probe("attribute")&&e.error("Attributes must be readonly in this context"),i.base=e.consume("attribute"),i.base)return o.idlType=v(e,"attribute-type")||e.error("Attribute lacks a type"),i.name=e.consumeKind("identifier")||e.consume("async","required")||e.error("Attribute lacks a name"),i.termination=e.consume(";")||e.error("Unterminated attribute, expected `;`"),o.this;e.unconsume(r)}get type(){return"attribute"}get special(){return this.tokens.special?this.tokens.special.value:""}get readonly(){return!!this.tokens.readonly}get name(){return m(this.tokens.name.value)}*validate(e){switch(yield*this.extAttrs.validate(e),yield*this.idlType.validate(e),this.idlType.generic){case"sequence":case"record":{const e=`Attributes cannot accept ${this.idlType.generic} types.`;yield r(this.tokens.name,this,"attr-invalid-type",e);break}default:{const{reference:t}=i(this.idlType,e)||{};if(t){const e=(this.idlType.union?t:this.idlType).tokens.base,n="Attributes cannot accept dictionary types.";yield r(e,this,"attr-invalid-type",n)}}}}write(e){const{parent:t}=this;return e.ts.definition(e.ts.wrap([this.extAttrs.write(e),e.token(this.tokens.special),e.token(this.tokens.readonly),e.token(this.tokens.base),e.ts.type(this.idlType.write(e)),e.name_token(this.tokens.name,{data:this,parent:t}),e.token(this.tokens.termination)]),{data:this,parent:t})}}function m(e){return e.startsWith("_")?e.slice(1):e}function f(e,{parser:t,allowDangler:n,listName:s="list"}){const r=t(e);if(!r)return[];r.tokens.separator=e.consume(",");const i=[r];for(;r.tokens.separator;){const r=t(e);if(!r){n||e.error(`Trailing comma in ${s}`);break}if(r.tokens.separator=e.consume(","),i.push(r),!r.tokens.separator)break}return i}function y(e){return e.consumeKind("decimal","integer")||e.consume("true","false","Infinity","-Infinity","NaN")}function k({type:e,value:t}){switch(e){case"decimal":case"integer":return{type:"number",value:t};case"string":return{type:"string",value:t.slice(1,-1)}}switch(t){case"true":case"false":return{type:"boolean",value:"true"===t};case"Infinity":case"-Infinity":return{type:"Infinity",negative:t.startsWith("-")};case"[":return{type:"sequence",value:[]};case"{":return{type:"dictionary"};default:return{type:t}}}function b(e){const{source:t}=e,n=function(){const n=e.consume("unsigned"),s=e.consume("short","long");if(s){const r=e.consume("long");return new Type({source:t,tokens:{prefix:n,base:s,postfix:r}})}n&&e.error("Failed to parse integer type")}()||function(){const n=e.consume("unrestricted"),s=e.consume("float","double");if(s)return new Type({source:t,tokens:{prefix:n,base:s}});n&&e.error("Failed to parse float type")}();if(n)return n;const s=e.consume("bigint","boolean","byte","octet","undefined");return s?new Type({source:t,tokens:{base:s}}):void 0}function g(e){return f(e,{parser:Argument.parse,listName:"arguments list"})}function v(e,t){const n=ExtendedAttributes.parse(e),s=Type.parse(e,t);return s&&(E(s).extAttrs=n),s}function x(e,t){const n=Type.parse(e,t||"return-type");if(n)return n;const s=e.consume("void");if(s){const t=new Type({source:e.source,tokens:{base:s}});return t.type="return-type",t}}function w(e){const t=e.consume("stringifier");if(!t)return;return Attribute.parse(e,{special:t})||Operation.parse(e,{special:t})||e.error("Unterminated stringifier")}function A(e){const t=e.split("\n");if(t.length){const e=t[t.length-1].match(/^\s+/);if(e)return e[0]}return""}function T(e){return()=>{if(e.extAttrs.length){const t=new Tokeniser("Exposed=Window,"),n=SimpleExtendedAttribute.parse(t);n.tokens.separator=t.consume(",");const s=e.extAttrs[0];/^\s/.test(s.tokens.name.trivia)||(s.tokens.name.trivia=` ${s.tokens.name.trivia}`),e.extAttrs.unshift(n)}else{E(e).extAttrs=ExtendedAttributes.parse(new Tokeniser("[Exposed=Window]"));const t=e.tokens.base.trivia;e.extAttrs.tokens.open.trivia=t,e.tokens.base.trivia=`\n${A(t)}`}}}function I(e){if(e.extAttrs.length)return e.extAttrs.tokens.open;if("operation"===e.type&&!e.special)return I(e.idlType);return Object.values(e.tokens).sort(((e,t)=>e.index-t.index))[0]}function E(e,t){if(t||(t=e),!e)return e;return new Proxy(e,{get(e,t){const n=e[t];return Array.isArray(n)&&"source"!==t?E(n,e):n},set(e,n,s){if(e[n]=s,!s)return!0;if(Array.isArray(s))for(const e of s)void 0!==e.parent&&(e.parent=t);else void 0!==s.parent&&(s.parent=t);return!0}})}const N={decimal:/-?(?=[0-9]*\.|[0-9]+[eE])(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][-+]?[0-9]+)?|[0-9]+[Ee][-+]?[0-9]+)/y,integer:/-?(0([Xx][0-9A-Fa-f]+|[0-7]*)|[1-9][0-9]*)/y,identifier:/[_-]?[A-Za-z][0-9A-Z_a-z-]*/y,string:/"[^"]*"/y,whitespace:/[\t\n\r ]+/y,comment:/\/\/.*|\/\*[\s\S]*?\*\//y,other:/[^\t\n\r 0-9A-Za-z]/y},O=["ArrayBuffer","DataView","Int8Array","Int16Array","Int32Array","Uint8Array","Uint16Array","Uint32Array","Uint8ClampedArray","BigInt64Array","BigUint64Array","Float32Array","Float64Array","any","object","symbol"],C=["ByteString","DOMString","USVString"],$=["async","attribute","callback","const","constructor","deleter","dictionary","enum","getter","includes","inherit","interface","iterable","maplike","namespace","partial","required","setlike","setter","static","stringifier","typedef","unrestricted"],D=["-Infinity","FrozenArray","Infinity","NaN","ObservableArray","Promise","bigint","boolean","byte","double","false","float","long","mixin","null","octet","optional","or","readonly","record","sequence","short","true","undefined","unsigned","void"].concat($,C,O),M=["(",")",",","...",":",";","<","=",">","?","*","[","]","{","}"],P=["_constructor","toString","_toString"];class Tokeniser{constructor(e){this.source=function(e){const t=[];let n=0,r="",i=1,o=0;for(;n<e.length;){const c=e.charAt(n);let u=-1;if(/[\t\n\r ]/.test(c)?u=a("whitespace",{noFlushTrivia:!0}):"/"===c&&(u=a("comment",{noFlushTrivia:!0})),-1!==u){const e=t.pop().value;i+=(e.match(/\n/g)||[]).length,r+=e,o-=1}else if(/[-0-9.A-Z_a-z]/.test(c)){if(u=a("decimal"),-1===u&&(u=a("integer")),-1===u){u=a("identifier");const e=t.length-1,n=t[e];if(-1!==u){if(P.includes(n.value)){const r=`${m(n.value)} is a reserved identifier and must not be used.`;throw new WebIDLParseError(s(t,e,null,r))}D.includes(n.value)&&(n.type="inline")}}}else'"'===c&&(u=a("string"));for(const s of M)if(e.startsWith(s,n)){t.push({type:"inline",value:s,trivia:r,line:i,index:o}),r="",n+=s.length,u=n;break}if(-1===u&&(u=a("other")),-1===u)throw new Error("Token stream not progressing");n=u,o+=1}return t.push({type:"eof",value:"",trivia:r,line:i,index:o}),t;function a(s,{noFlushTrivia:a}={}){const c=N[s];c.lastIndex=n;const u=c.exec(e);return u?(t.push({type:s,value:u[0],trivia:r,line:i,index:o}),a||(r=""),c.lastIndex):-1}}(e),this.position=0}error(e){throw new WebIDLParseError(s(this.source,this.position,this.current,e))}probeKind(e){return this.source.length>this.position&&this.source[this.position].type===e}probe(e){return this.probeKind("inline")&&this.source[this.position].value===e}consumeKind(...e){for(const t of e){if(!this.probeKind(t))continue;const e=this.source[this.position];return this.position++,e}}consume(...e){if(!this.probeKind("inline"))return;const t=this.source[this.position];for(const n of e)if(t.value===n)return this.position++,t}consumeIdentifier(e){if(this.probeKind("identifier")&&this.source[this.position].value===e)return this.consumeKind("identifier")}unconsume(e){this.position=e}}class WebIDLParseError extends Error{constructor({message:e,bareMessage:t,context:n,line:s,sourceName:r,input:i,tokens:o}){super(e),this.name="WebIDLParseError",this.bareMessage=t,this.context=n,this.line=s,this.sourceName=r,this.input=i,this.tokens=o}}class EnumValue extends WrappedToken{static parse(e){const t=e.consumeKind("string");if(t)return new EnumValue({source:e.source,tokens:{value:t}})}get type(){return"enum-value"}get value(){return super.value.slice(1,-1)}write(e){const{parent:t}=this;return e.ts.wrap([e.ts.trivia(this.tokens.value.trivia),e.ts.definition(e.ts.wrap(['"',e.ts.name(this.value,{data:this,parent:t}),'"']),{data:this,parent:t}),e.token(this.tokens.separator)])}}class Enum extends Base{static parse(e){const t={};if(t.base=e.consume("enum"),!t.base)return;t.name=e.consumeKind("identifier")||e.error("No name for enum");const n=E(new Enum({source:e.source,tokens:t}));return e.current=n.this,t.open=e.consume("{")||e.error("Bodyless enum"),n.values=f(e,{parser:EnumValue.parse,allowDangler:!0,listName:"enumeration"}),e.probeKind("string")&&e.error("No comma between enum values"),t.close=e.consume("}")||e.error("Unexpected value in enum"),n.values.length||e.error("No value in enum"),t.termination=e.consume(";")||e.error("No semicolon after enum"),n.this}get type(){return"enum"}get name(){return m(this.tokens.name.value)}write(e){return e.ts.definition(e.ts.wrap([this.extAttrs.write(e),e.token(this.tokens.base),e.name_token(this.tokens.name,{data:this}),e.token(this.tokens.open),e.ts.wrap(this.values.map((t=>t.write(e)))),e.token(this.tokens.close),e.token(this.tokens.termination)]),{data:this})}}class Includes extends Base{static parse(e){const t=e.consumeKind("identifier");if(!t)return;const n={target:t};if(n.includes=e.consume("includes"),n.includes)return n.mixin=e.consumeKind("identifier")||e.error("Incomplete includes statement"),n.termination=e.consume(";")||e.error("No terminating ; for includes statement"),new Includes({source:e.source,tokens:n});e.unconsume(t.index)}get type(){return"includes"}get target(){return m(this.tokens.target.value)}get includes(){return m(this.tokens.mixin.value)}write(e){return e.ts.definition(e.ts.wrap([this.extAttrs.write(e),e.reference_token(this.tokens.target,this),e.token(this.tokens.includes),e.reference_token(this.tokens.mixin,this),e.token(this.tokens.termination)]),{data:this})}}class Typedef extends Base{static parse(e){const t={},n=E(new Typedef({source:e.source,tokens:t}));if(t.base=e.consume("typedef"),t.base)return n.idlType=v(e,"typedef-type")||e.error("Typedef lacks a type"),t.name=e.consumeKind("identifier")||e.error("Typedef lacks a name"),e.current=n.this,t.termination=e.consume(";")||e.error("Unterminated typedef, expected `;`"),n.this}get type(){return"typedef"}get name(){return m(this.tokens.name.value)}*validate(e){yield*this.idlType.validate(e)}write(e){return e.ts.definition(e.ts.wrap([this.extAttrs.write(e),e.token(this.tokens.base),e.ts.type(this.idlType.write(e)),e.name_token(this.tokens.name,{data:this}),e.token(this.tokens.termination)]),{data:this})}}class CallbackFunction extends Base{static parse(e,t){const n={base:t},s=E(new CallbackFunction({source:e.source,tokens:n}));return n.name=e.consumeKind("identifier")||e.error("Callback lacks a name"),e.current=s.this,n.assign=e.consume("=")||e.error("Callback lacks an assignment"),s.idlType=x(e)||e.error("Callback lacks a return type"),n.open=e.consume("(")||e.error("Callback lacks parentheses for arguments"),s.arguments=g(e),n.close=e.consume(")")||e.error("Unterminated callback"),n.termination=e.consume(";")||e.error("Unterminated callback, expected `;`"),s.this}get type(){return"callback"}get name(){return m(this.tokens.name.value)}*validate(e){yield*this.extAttrs.validate(e),yield*this.idlType.validate(e)}write(e){return e.ts.definition(e.ts.wrap([this.extAttrs.write(e),e.token(this.tokens.base),e.name_token(this.tokens.name,{data:this}),e.token(this.tokens.assign),e.ts.type(this.idlType.write(e)),e.token(this.tokens.open),...this.arguments.map((t=>t.write(e))),e.token(this.tokens.close),e.token(this.tokens.termination)]),{data:this})}}class Container extends Base{static parse(e,t,{inheritable:n,allowedMembers:s}){const{tokens:r,type:i}=t;for(r.name=e.consumeKind("identifier")||e.error(`Missing name in ${i}`),e.current=t,t=E(t),n&&Object.assign(r,function(e){const t=e.consume(":");return t?{colon:t,inheritance:e.consumeKind("identifier")||e.error("Inheritance lacks a type")}:{}}(e)),r.open=e.consume("{")||e.error(`Bodyless ${i}`),t.members=[];;){if(r.close=e.consume("}"),r.close)return r.termination=e.consume(";")||e.error(`Missing semicolon after ${i}`),t.this;const n=ExtendedAttributes.parse(e);let o;for(const[t,...n]of s)if(o=E(t(e,...n)),o)break;o||e.error("Unknown member"),o.extAttrs=n,t.members.push(o.this)}}get partial(){return!!this.tokens.partial}get name(){return m(this.tokens.name.value)}get inheritance(){return this.tokens.inheritance?m(this.tokens.inheritance.value):null}*validate(e){for(const t of this.members)t.validate&&(yield*t.validate(e))}write(e){return e.ts.definition(e.ts.wrap([this.extAttrs.write(e),e.token(this.tokens.callback),e.token(this.tokens.partial),e.token(this.tokens.base),e.token(this.tokens.mixin),e.name_token(this.tokens.name,{data:this}),(()=>this.tokens.inheritance?e.ts.wrap([e.token(this.tokens.colon),e.ts.trivia(this.tokens.inheritance.trivia),e.ts.inheritance(e.reference(this.tokens.inheritance.value,{context:this}))]):"")(),e.token(this.tokens.open),e.ts.wrap(this.members.map((t=>t.write(e)))),e.token(this.tokens.close),e.token(this.tokens.termination)]),{data:this})}}class Constant extends Base{static parse(e){const t={};if(t.base=e.consume("const"),!t.base)return;let n=b(e);if(!n){const t=e.consumeKind("identifier")||e.error("Const lacks a type");n=new Type({source:e.source,tokens:{base:t}})}e.probe("?")&&e.error("Unexpected nullable constant type"),n.type="const-type",t.name=e.consumeKind("identifier")||e.error("Const lacks a name"),t.assign=e.consume("=")||e.error("Const lacks value assignment"),t.value=y(e)||e.error("Const lacks a value"),t.termination=e.consume(";")||e.error("Unterminated const, expected `;`");const s=new Constant({source:e.source,tokens:t});return E(s).idlType=n,s}get type(){return"const"}get name(){return m(this.tokens.name.value)}get value(){return k(this.tokens.value)}write(e){const{parent:t}=this;return e.ts.definition(e.ts.wrap([this.extAttrs.write(e),e.token(this.tokens.base),e.ts.type(this.idlType.write(e)),e.name_token(this.tokens.name,{data:this,parent:t}),e.token(this.tokens.assign),e.token(this.tokens.value),e.token(this.tokens.termination)]),{data:this,parent:t})}}class IterableLike extends Base{static parse(e){const t=e.position,n=E(new IterableLike({source:e.source,tokens:{}})),{tokens:s}=n;if(s.readonly=e.consume("readonly"),s.readonly||(s.async=e.consume("async")),s.base=s.readonly?e.consume("maplike","setlike"):s.async?e.consume("iterable"):e.consume("iterable","maplike","setlike"),!s.base)return void e.unconsume(t);const{type:r}=n,i="maplike"===r,o=i||"iterable"===r,a=n.async&&"iterable"===r;s.open=e.consume("<")||e.error(`Missing less-than sign \`<\` in ${r} declaration`);const c=v(e)||e.error(`Missing a type argument in ${r} declaration`);return n.idlType=[c],n.arguments=[],o&&(c.tokens.separator=e.consume(","),c.tokens.separator?n.idlType.push(v(e)):i&&e.error(`Missing second type argument in ${r} declaration`)),s.close=e.consume(">")||e.error(`Missing greater-than sign \`>\` in ${r} declaration`),e.probe("(")&&(a?(s.argsOpen=e.consume("("),n.arguments.push(...g(e)),s.argsClose=e.consume(")")||e.error("Unterminated async iterable argument list")):e.error("Arguments are only allowed for `async iterable`")),s.termination=e.consume(";")||e.error(`Missing semicolon after ${r} declaration`),n.this}get type(){return this.tokens.base.value}get readonly(){return!!this.tokens.readonly}get async(){return!!this.tokens.async}*validate(e){for(const t of this.idlType)yield*t.validate(e);for(const t of this.arguments)yield*t.validate(e)}write(e){return e.ts.definition(e.ts.wrap([this.extAttrs.write(e),e.token(this.tokens.readonly),e.token(this.tokens.async),e.token(this.tokens.base,e.ts.generic),e.token(this.tokens.open),e.ts.wrap(this.idlType.map((t=>t.write(e)))),e.token(this.tokens.close),e.token(this.tokens.argsOpen),e.ts.wrap(this.arguments.map((t=>t.write(e)))),e.token(this.tokens.argsClose),e.token(this.tokens.termination)]),{data:this,parent:this.parent})}}class Constructor extends Base{static parse(e){const t=e.consume("constructor");if(!t)return;const n={base:t};n.open=e.consume("(")||e.error("No argument list in constructor");const s=g(e);n.close=e.consume(")")||e.error("Unterminated constructor"),n.termination=e.consume(";")||e.error("No semicolon after constructor");const r=new Constructor({source:e.source,tokens:n});return E(r).arguments=s,r}get type(){return"constructor"}*validate(e){for(const t of this.arguments)yield*t.validate(e)}write(e){const{parent:t}=this;return e.ts.definition(e.ts.wrap([this.extAttrs.write(e),e.token(this.tokens.base,e.ts.nameless,{data:this,parent:t}),e.token(this.tokens.open),e.ts.wrap(this.arguments.map((t=>t.write(e)))),e.token(this.tokens.close),e.token(this.tokens.termination)]),{data:this,parent:t})}}function j(e){const t=e.consume("static");if(!t)return;return Attribute.parse(e,{special:t})||Operation.parse(e,{special:t})||e.error("No body in static member")}class Interface extends Container{static parse(e,t,{partial:n=null}={}){const s={partial:n,base:t};return Container.parse(e,new Interface({source:e.source,tokens:s}),{inheritable:!n,allowedMembers:[[Constant.parse],[Constructor.parse],[j],[w],[IterableLike.parse],[Attribute.parse],[Operation.parse]]})}get type(){return"interface"}*validate(e){if(yield*this.extAttrs.validate(e),!this.partial&&this.extAttrs.every((e=>"Exposed"!==e.name))){const e="Interfaces must have `[Exposed]` extended attribute. To fix, add, for example, `[Exposed=Window]`. Please also consider carefully if your interface should also be exposed in a Worker scope. Refer to the [WebIDL spec section on Exposed](https://heycam.github.io/webidl/#Exposed) for more information.";yield r(this.tokens.name,this,"require-exposed",e,{autofix:T(this)})}const t=this.extAttrs.filter((e=>"Constructor"===e.name));for(const e of t){const t="Constructors should now be represented as a `constructor()` operation on the interface instead of `[Constructor]` extended attribute. Refer to the [WebIDL spec section on constructor operations](https://heycam.github.io/webidl/#idl-constructors) for more information.";yield r(e.tokens.name,this,"constructor-member",t,{autofix:W(this,e)})}if(this.extAttrs.some((e=>"Global"===e.name))){const e=this.extAttrs.filter((e=>"LegacyFactoryFunction"===e.name));for(const t of e){const e="Interfaces marked as `[Global]` cannot have factory functions.";yield r(t.tokens.name,this,"no-constructible-global",e)}const t=this.members.filter((e=>"constructor"===e.type));for(const e of t){const t="Interfaces marked as `[Global]` cannot have constructors.";yield r(e.tokens.base,this,"no-constructible-global",t)}}yield*super.validate(e),this.partial||(yield*function*(e,t){const n=function(e){const t=a(e);return{statics:new Set(t.filter((e=>"static"===e.special)).map((e=>e.name))),nonstatics:new Set(t.filter((e=>"static"!==e.special)).map((e=>e.name)))}}(t),s=e.partials.get(t.name)||[],i=e.mixinMap.get(t.name)||[];for(const e of[...s,...i]){const s=a(e),r=s.filter((e=>"static"===e.special)),i=s.filter((e=>"static"!==e.special));yield*o(r,n.statics,e,t),yield*o(i,n.nonstatics,e,t),r.forEach((e=>n.statics.add(e.name))),i.forEach((e=>n.nonstatics.add(e.name)))}function*o(e,t,n,s){for(const i of e){const{name:e}=i;if(e&&t.has(e)){const t=`The ${"static"===i.special?"static ":""}operation "${e}" has already been defined for the base interface "${s.name}" either in itself or in a mixin`;yield r(i.tokens.name,n,"no-cross-overload",t)}}}function a(e){return e.members.filter((({type:e})=>"operation"===e))}}(e,this))}}function W(e,t){return e=E(e),()=>{const n=A(e.extAttrs.tokens.open.trivia),s=e.members.length?A(I(e.members[0]).trivia):function(e){const t=A(e),n=t.includes("\t")?"\t":" ";return t+n}(n),r=Constructor.parse(new Tokeniser(`\n${s}constructor();`));r.extAttrs=new ExtendedAttributes({source:e.source,tokens:{}}),E(r).arguments=t.arguments;const i=function(e,t){const n=e.slice().reverse().findIndex(t);return-1===n?n:e.length-n-1}(e.members,(e=>"constructor"===e.type));e.members.splice(i+1,0,r);const{close:o}=e.tokens;o.trivia.includes("\n")||(o.trivia+=`\n${n}`);const{extAttrs:a}=e,c=a.indexOf(t),u=a.splice(c,1);a.length?a.length===c?a[c-1].tokens.separator=void 0:a[c].tokens.name.trivia.trim()||(a[c].tokens.name.trivia=u[0].tokens.name.trivia):a.tokens.open=a.tokens.close=void 0}}class Mixin extends Container{static parse(e,t,{partial:n}={}){const s={partial:n,base:t};if(s.mixin=e.consume("mixin"),s.mixin)return Container.parse(e,new Mixin({source:e.source,tokens:s}),{allowedMembers:[[Constant.parse],[w],[Attribute.parse,{noInherit:!0}],[Operation.parse,{regular:!0}]]})}get type(){return"interface mixin"}}class Field extends Base{static parse(e){const t={},n=E(new Field({source:e.source,tokens:t}));return n.extAttrs=ExtendedAttributes.parse(e),t.required=e.consume("required"),n.idlType=v(e,"dictionary-type")||e.error("Dictionary member lacks a type"),t.name=e.consumeKind("identifier")||e.error("Dictionary member lacks a name"),n.default=Default.parse(e),t.required&&n.default&&e.error("Required member must not have a default"),t.termination=e.consume(";")||e.error("Unterminated dictionary member, expected `;`"),n.this}get type(){return"field"}get name(){return m(this.tokens.name.value)}get required(){return!!this.tokens.required}*validate(e){yield*this.idlType.validate(e)}write(e){const{parent:t}=this;return e.ts.definition(e.ts.wrap([this.extAttrs.write(e),e.token(this.tokens.required),e.ts.type(this.idlType.write(e)),e.name_token(this.tokens.name,{data:this,parent:t}),this.default?this.default.write(e):"",e.token(this.tokens.termination)]),{data:this,parent:t})}}class Dictionary extends Container{static parse(e,{partial:t}={}){const n={partial:t};if(n.base=e.consume("dictionary"),n.base)return Container.parse(e,new Dictionary({source:e.source,tokens:n}),{inheritable:!t,allowedMembers:[[Field.parse]]})}get type(){return"dictionary"}}class Namespace extends Container{static parse(e,{partial:t}={}){const n={partial:t};if(n.base=e.consume("namespace"),n.base)return Container.parse(e,new Namespace({source:e.source,tokens:n}),{allowedMembers:[[Attribute.parse,{noInherit:!0,readonly:!0}],[Constant.parse],[Operation.parse,{regular:!0}]]})}get type(){return"namespace"}*validate(e){if(!this.partial&&this.extAttrs.every((e=>"Exposed"!==e.name))){const e="Namespaces must have [Exposed] extended attribute. To fix, add, for example, [Exposed=Window]. Please also consider carefully if your namespace should also be exposed in a Worker scope. Refer to the [WebIDL spec section on Exposed](https://heycam.github.io/webidl/#Exposed) for more information.";yield r(this.tokens.name,this,"require-exposed",e,{autofix:T(this)})}yield*super.validate(e)}}class CallbackInterface extends Container{static parse(e,t,{partial:n=null}={}){const s={callback:t};if(s.base=e.consume("interface"),s.base)return Container.parse(e,new CallbackInterface({source:e.source,tokens:s}),{inheritable:!n,allowedMembers:[[Constant.parse],[Operation.parse,{regular:!0}]]})}get type(){return"callback interface"}}function B(e,t){const n=e.source;function s(t){e.error(t)}function r(...t){return e.consume(...t)}function i(t){const n=r("interface");if(!n)return;return Mixin.parse(e,n,t)||Interface.parse(e,n,t)||s("Interface has no proper body")}function o(){if(t.productions)for(const n of t.productions){const t=n(e);if(t)return t}return function(){const t=r("callback");if(t)return e.probe("interface")?CallbackInterface.parse(e,t):CallbackFunction.parse(e,t)}()||i()||function(){const t=r("partial");if(t)return Dictionary.parse(e,{partial:t})||i({partial:t})||Namespace.parse(e,{partial:t})||s("Partial doesn't apply to anything")}()||Dictionary.parse(e)||Enum.parse(e)||Typedef.parse(e)||Includes.parse(e)||Namespace.parse(e)}const a=function(){if(!n.length)return[];const r=[];for(;;){const t=ExtendedAttributes.parse(e),n=o();if(!n){t.length&&s("Stray extended attributes");break}E(n).extAttrs=t,r.push(n)}const i=Eof.parse(e);return t.concrete&&r.push(i),r}();return e.position<n.length&&s("Unrecognised tokens"),a}function q(e,t={}){const n=new Tokeniser(e);return void 0!==t.sourceName&&(n.source.name=t.sourceName),B(n,t)}function K(e){return e}const L={wrap:e=>e.join(""),trivia:K,name:K,reference:K,type:K,generic:K,nameless:K,inheritance:K,definition:K,extendedAttribute:K,extendedAttributeReference:K};class Writer{constructor(e){this.ts=Object.assign({},L,e)}reference(e,{unescaped:t,context:n}){return t||(t=e.startsWith("_")?e.slice(1):e),this.ts.reference(e,t,n)}token(e,t=K,...n){if(!e)return"";const s=t(e.value,...n);return this.ts.wrap([this.ts.trivia(e.trivia),s])}reference_token(e,t){return this.token(e,this.reference.bind(this),{context:t})}name_token(e,t){return this.token(e,this.ts.name,t)}identifier(e,t){return this.ts.wrap([this.reference_token(e.tokens.value,t),this.token(e.tokens.separator)])}}function F(e,{templates:t=L}={}){t=Object.assign({},L,t);const n=new Writer(t);return t.wrap(e.map((e=>e.write(n))))}function S(e,t){const n=new Map,s=e.filter((e=>"includes"===e.type));for(const e of s){const s=t.get(e.includes);if(!s)continue;const r=n.get(e.target);r?r.push(s):n.set(e.target,[s])}return n}function*U(e){const t=function(e){const t=new Map,n=new Set,s=new Map;for(const r of e)if(r.partial){const e=s.get(r.name);e?e.push(r):s.set(r.name,[r])}else r.name&&(t.has(r.name)?n.add(r):t.set(r.name,r));return{all:e,unique:t,partials:s,duplicates:n,mixinMap:S(e,t),cache:{typedefIncludesDictionary:new WeakMap,dictionaryIncludesRequiredField:new WeakMap}}}(e);for(const e of t.all)e.validate&&(yield*e.validate(t));yield*function*({unique:e,duplicates:t}){for(const n of t){const{name:t}=n,s=`The name "${t}" of type "${e.get(t).type}" was already seen`;yield r(n.tokens.name,n,"no-duplicate",s)}}(t)}function _(e){return[...U((t=e,t.flat?t.flat():[].concat(...t)))];var t}return t})()));
//# sourceMappingURL=webidl2.js.map