1(function webpackUniversalModuleDefinition(root, factory) { 2 if(typeof exports === 'object' && typeof module === 'object') 3 module.exports = factory(); 4 else if(typeof define === 'function' && define.amd) 5 define([], factory); 6 else if(typeof exports === 'object') 7 exports["WebIDL2"] = factory(); 8 else 9 root["WebIDL2"] = factory(); 10})(globalThis, () => { 11return /******/ (() => { // webpackBootstrap 12/******/ "use strict"; 13/******/ var __webpack_modules__ = ([ 14/* 0 */, 15/* 1 */ 16/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 17 18__webpack_require__.r(__webpack_exports__); 19/* harmony export */ __webpack_require__.d(__webpack_exports__, { 20/* harmony export */ "parse": () => (/* binding */ parse) 21/* harmony export */ }); 22/* harmony import */ var _tokeniser_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); 23/* harmony import */ var _productions_enum_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(15); 24/* harmony import */ var _productions_includes_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16); 25/* harmony import */ var _productions_extended_attributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8); 26/* harmony import */ var _productions_typedef_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17); 27/* harmony import */ var _productions_callback_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(18); 28/* harmony import */ var _productions_interface_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(19); 29/* harmony import */ var _productions_mixin_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(25); 30/* harmony import */ var _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(26); 31/* harmony import */ var _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(28); 32/* harmony import */ var _productions_callback_interface_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(29); 33/* harmony import */ var _productions_helpers_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(4); 34/* harmony import */ var _productions_token_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(10); 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49/** 50 * @param {Tokeniser} tokeniser 51 * @param {object} options 52 * @param {boolean} [options.concrete] 53 * @param {Function[]} [options.productions] 54 */ 55function parseByTokens(tokeniser, options) { 56 const source = tokeniser.source; 57 58 function error(str) { 59 tokeniser.error(str); 60 } 61 62 function consume(...candidates) { 63 return tokeniser.consume(...candidates); 64 } 65 66 function callback() { 67 const callback = consume("callback"); 68 if (!callback) return; 69 if (tokeniser.probe("interface")) { 70 return _productions_callback_interface_js__WEBPACK_IMPORTED_MODULE_10__.CallbackInterface.parse(tokeniser, callback); 71 } 72 return _productions_callback_js__WEBPACK_IMPORTED_MODULE_5__.CallbackFunction.parse(tokeniser, callback); 73 } 74 75 function interface_(opts) { 76 const base = consume("interface"); 77 if (!base) return; 78 const ret = 79 _productions_mixin_js__WEBPACK_IMPORTED_MODULE_7__.Mixin.parse(tokeniser, base, opts) || 80 _productions_interface_js__WEBPACK_IMPORTED_MODULE_6__.Interface.parse(tokeniser, base, opts) || 81 error("Interface has no proper body"); 82 return ret; 83 } 84 85 function partial() { 86 const partial = consume("partial"); 87 if (!partial) return; 88 return ( 89 _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__.Dictionary.parse(tokeniser, { partial }) || 90 interface_({ partial }) || 91 _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__.Namespace.parse(tokeniser, { partial }) || 92 error("Partial doesn't apply to anything") 93 ); 94 } 95 96 function definition() { 97 if (options.productions) { 98 for (const production of options.productions) { 99 const result = production(tokeniser); 100 if (result) { 101 return result; 102 } 103 } 104 } 105 106 return ( 107 callback() || 108 interface_() || 109 partial() || 110 _productions_dictionary_js__WEBPACK_IMPORTED_MODULE_8__.Dictionary.parse(tokeniser) || 111 _productions_enum_js__WEBPACK_IMPORTED_MODULE_1__.Enum.parse(tokeniser) || 112 _productions_typedef_js__WEBPACK_IMPORTED_MODULE_4__.Typedef.parse(tokeniser) || 113 _productions_includes_js__WEBPACK_IMPORTED_MODULE_2__.Includes.parse(tokeniser) || 114 _productions_namespace_js__WEBPACK_IMPORTED_MODULE_9__.Namespace.parse(tokeniser) 115 ); 116 } 117 118 function definitions() { 119 if (!source.length) return []; 120 const defs = []; 121 while (true) { 122 const ea = _productions_extended_attributes_js__WEBPACK_IMPORTED_MODULE_3__.ExtendedAttributes.parse(tokeniser); 123 const def = definition(); 124 if (!def) { 125 if (ea.length) error("Stray extended attributes"); 126 break; 127 } 128 (0,_productions_helpers_js__WEBPACK_IMPORTED_MODULE_11__.autoParenter)(def).extAttrs = ea; 129 defs.push(def); 130 } 131 const eof = _productions_token_js__WEBPACK_IMPORTED_MODULE_12__.Eof.parse(tokeniser); 132 if (options.concrete) { 133 defs.push(eof); 134 } 135 return defs; 136 } 137 const res = definitions(); 138 if (tokeniser.position < source.length) error("Unrecognised tokens"); 139 return res; 140} 141 142/** 143 * @param {string} str 144 * @param {object} [options] 145 * @param {*} [options.sourceName] 146 * @param {boolean} [options.concrete] 147 * @param {Function[]} [options.productions] 148 * @return {import("./productions/base.js").Base[]} 149 */ 150function parse(str, options = {}) { 151 const tokeniser = new _tokeniser_js__WEBPACK_IMPORTED_MODULE_0__.Tokeniser(str); 152 if (typeof options.sourceName !== "undefined") { 153 // @ts-ignore (See Tokeniser.source in supplement.d.ts) 154 tokeniser.source.name = options.sourceName; 155 } 156 return parseByTokens(tokeniser, options); 157} 158 159 160/***/ }), 161/* 2 */ 162/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 163 164__webpack_require__.r(__webpack_exports__); 165/* harmony export */ __webpack_require__.d(__webpack_exports__, { 166/* harmony export */ "Tokeniser": () => (/* binding */ Tokeniser), 167/* harmony export */ "WebIDLParseError": () => (/* binding */ WebIDLParseError), 168/* harmony export */ "argumentNameKeywords": () => (/* binding */ argumentNameKeywords), 169/* harmony export */ "stringTypes": () => (/* binding */ stringTypes), 170/* harmony export */ "typeNameKeywords": () => (/* binding */ typeNameKeywords) 171/* harmony export */ }); 172/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); 173/* harmony import */ var _productions_helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); 174 175 176 177// These regular expressions use the sticky flag so they will only match at 178// the current location (ie. the offset of lastIndex). 179const tokenRe = { 180 // This expression uses a lookahead assertion to catch false matches 181 // against integers early. 182 decimal: 183 /-?(?=[0-9]*\.|[0-9]+[eE])(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][-+]?[0-9]+)?|[0-9]+[Ee][-+]?[0-9]+)/y, 184 integer: /-?(0([Xx][0-9A-Fa-f]+|[0-7]*)|[1-9][0-9]*)/y, 185 identifier: /[_-]?[A-Za-z][0-9A-Z_a-z-]*/y, 186 string: /"[^"]*"/y, 187 whitespace: /[\t\n\r ]+/y, 188 comment: /\/\/.*|\/\*[\s\S]*?\*\//y, 189 other: /[^\t\n\r 0-9A-Za-z]/y, 190}; 191 192const typeNameKeywords = [ 193 "ArrayBuffer", 194 "DataView", 195 "Int8Array", 196 "Int16Array", 197 "Int32Array", 198 "Uint8Array", 199 "Uint16Array", 200 "Uint32Array", 201 "Uint8ClampedArray", 202 "BigInt64Array", 203 "BigUint64Array", 204 "Float32Array", 205 "Float64Array", 206 "any", 207 "object", 208 "symbol", 209]; 210 211const stringTypes = ["ByteString", "DOMString", "USVString"]; 212 213const argumentNameKeywords = [ 214 "async", 215 "attribute", 216 "callback", 217 "const", 218 "constructor", 219 "deleter", 220 "dictionary", 221 "enum", 222 "getter", 223 "includes", 224 "inherit", 225 "interface", 226 "iterable", 227 "maplike", 228 "namespace", 229 "partial", 230 "required", 231 "setlike", 232 "setter", 233 "static", 234 "stringifier", 235 "typedef", 236 "unrestricted", 237]; 238 239const nonRegexTerminals = [ 240 "-Infinity", 241 "FrozenArray", 242 "Infinity", 243 "NaN", 244 "ObservableArray", 245 "Promise", 246 "bigint", 247 "boolean", 248 "byte", 249 "double", 250 "false", 251 "float", 252 "long", 253 "mixin", 254 "null", 255 "octet", 256 "optional", 257 "or", 258 "readonly", 259 "record", 260 "sequence", 261 "short", 262 "true", 263 "undefined", 264 "unsigned", 265 "void", 266].concat(argumentNameKeywords, stringTypes, typeNameKeywords); 267 268const punctuations = [ 269 "(", 270 ")", 271 ",", 272 "...", 273 ":", 274 ";", 275 "<", 276 "=", 277 ">", 278 "?", 279 "*", 280 "[", 281 "]", 282 "{", 283 "}", 284]; 285 286const reserved = [ 287 // "constructor" is now a keyword 288 "_constructor", 289 "toString", 290 "_toString", 291]; 292 293/** 294 * @typedef {ArrayItemType<ReturnType<typeof tokenise>>} Token 295 * @param {string} str 296 */ 297function tokenise(str) { 298 const tokens = []; 299 let lastCharIndex = 0; 300 let trivia = ""; 301 let line = 1; 302 let index = 0; 303 while (lastCharIndex < str.length) { 304 const nextChar = str.charAt(lastCharIndex); 305 let result = -1; 306 307 if (/[\t\n\r ]/.test(nextChar)) { 308 result = attemptTokenMatch("whitespace", { noFlushTrivia: true }); 309 } else if (nextChar === "/") { 310 result = attemptTokenMatch("comment", { noFlushTrivia: true }); 311 } 312 313 if (result !== -1) { 314 const currentTrivia = tokens.pop().value; 315 line += (currentTrivia.match(/\n/g) || []).length; 316 trivia += currentTrivia; 317 index -= 1; 318 } else if (/[-0-9.A-Z_a-z]/.test(nextChar)) { 319 result = attemptTokenMatch("decimal"); 320 if (result === -1) { 321 result = attemptTokenMatch("integer"); 322 } 323 if (result === -1) { 324 result = attemptTokenMatch("identifier"); 325 const lastIndex = tokens.length - 1; 326 const token = tokens[lastIndex]; 327 if (result !== -1) { 328 if (reserved.includes(token.value)) { 329 const message = `${(0,_productions_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)( 330 token.value 331 )} is a reserved identifier and must not be used.`; 332 throw new WebIDLParseError( 333 (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.syntaxError)(tokens, lastIndex, null, message) 334 ); 335 } else if (nonRegexTerminals.includes(token.value)) { 336 token.type = "inline"; 337 } 338 } 339 } 340 } else if (nextChar === '"') { 341 result = attemptTokenMatch("string"); 342 } 343 344 for (const punctuation of punctuations) { 345 if (str.startsWith(punctuation, lastCharIndex)) { 346 tokens.push({ 347 type: "inline", 348 value: punctuation, 349 trivia, 350 line, 351 index, 352 }); 353 trivia = ""; 354 lastCharIndex += punctuation.length; 355 result = lastCharIndex; 356 break; 357 } 358 } 359 360 // other as the last try 361 if (result === -1) { 362 result = attemptTokenMatch("other"); 363 } 364 if (result === -1) { 365 throw new Error("Token stream not progressing"); 366 } 367 lastCharIndex = result; 368 index += 1; 369 } 370 371 // remaining trivia as eof 372 tokens.push({ 373 type: "eof", 374 value: "", 375 trivia, 376 line, 377 index, 378 }); 379 380 return tokens; 381 382 /** 383 * @param {keyof typeof tokenRe} type 384 * @param {object} options 385 * @param {boolean} [options.noFlushTrivia] 386 */ 387 function attemptTokenMatch(type, { noFlushTrivia } = {}) { 388 const re = tokenRe[type]; 389 re.lastIndex = lastCharIndex; 390 const result = re.exec(str); 391 if (result) { 392 tokens.push({ type, value: result[0], trivia, line, index }); 393 if (!noFlushTrivia) { 394 trivia = ""; 395 } 396 return re.lastIndex; 397 } 398 return -1; 399 } 400} 401 402class Tokeniser { 403 /** 404 * @param {string} idl 405 */ 406 constructor(idl) { 407 this.source = tokenise(idl); 408 this.position = 0; 409 } 410 411 /** 412 * @param {string} message 413 * @return {never} 414 */ 415 error(message) { 416 throw new WebIDLParseError( 417 (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.syntaxError)(this.source, this.position, this.current, message) 418 ); 419 } 420 421 /** 422 * @param {string} type 423 */ 424 probeKind(type) { 425 return ( 426 this.source.length > this.position && 427 this.source[this.position].type === type 428 ); 429 } 430 431 /** 432 * @param {string} value 433 */ 434 probe(value) { 435 return ( 436 this.probeKind("inline") && this.source[this.position].value === value 437 ); 438 } 439 440 /** 441 * @param {...string} candidates 442 */ 443 consumeKind(...candidates) { 444 for (const type of candidates) { 445 if (!this.probeKind(type)) continue; 446 const token = this.source[this.position]; 447 this.position++; 448 return token; 449 } 450 } 451 452 /** 453 * @param {...string} candidates 454 */ 455 consume(...candidates) { 456 if (!this.probeKind("inline")) return; 457 const token = this.source[this.position]; 458 for (const value of candidates) { 459 if (token.value !== value) continue; 460 this.position++; 461 return token; 462 } 463 } 464 465 /** 466 * @param {string} value 467 */ 468 consumeIdentifier(value) { 469 if (!this.probeKind("identifier")) { 470 return; 471 } 472 if (this.source[this.position].value !== value) { 473 return; 474 } 475 return this.consumeKind("identifier"); 476 } 477 478 /** 479 * @param {number} position 480 */ 481 unconsume(position) { 482 this.position = position; 483 } 484} 485 486class WebIDLParseError extends Error { 487 /** 488 * @param {object} options 489 * @param {string} options.message 490 * @param {string} options.bareMessage 491 * @param {string} options.context 492 * @param {number} options.line 493 * @param {*} options.sourceName 494 * @param {string} options.input 495 * @param {*[]} options.tokens 496 */ 497 constructor({ 498 message, 499 bareMessage, 500 context, 501 line, 502 sourceName, 503 input, 504 tokens, 505 }) { 506 super(message); 507 508 this.name = "WebIDLParseError"; // not to be mangled 509 this.bareMessage = bareMessage; 510 this.context = context; 511 this.line = line; 512 this.sourceName = sourceName; 513 this.input = input; 514 this.tokens = tokens; 515 } 516} 517 518 519/***/ }), 520/* 3 */ 521/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 522 523__webpack_require__.r(__webpack_exports__); 524/* harmony export */ __webpack_require__.d(__webpack_exports__, { 525/* harmony export */ "syntaxError": () => (/* binding */ syntaxError), 526/* harmony export */ "validationError": () => (/* binding */ validationError) 527/* harmony export */ }); 528/** 529 * @param {string} text 530 */ 531function lastLine(text) { 532 const splitted = text.split("\n"); 533 return splitted[splitted.length - 1]; 534} 535 536function appendIfExist(base, target) { 537 let result = base; 538 if (target) { 539 result += ` ${target}`; 540 } 541 return result; 542} 543 544function contextAsText(node) { 545 const hierarchy = [node]; 546 while (node && node.parent) { 547 const { parent } = node; 548 hierarchy.unshift(parent); 549 node = parent; 550 } 551 return hierarchy.map((n) => appendIfExist(n.type, n.name)).join(" -> "); 552} 553 554/** 555 * @typedef {object} WebIDL2ErrorOptions 556 * @property {"error" | "warning"} [level] 557 * @property {Function} [autofix] 558 * @property {string} [ruleName] 559 * 560 * @typedef {ReturnType<typeof error>} WebIDLErrorData 561 * 562 * @param {string} message error message 563 * @param {*} position 564 * @param {*} current 565 * @param {*} message 566 * @param {"Syntax" | "Validation"} kind error type 567 * @param {WebIDL2ErrorOptions=} options 568 */ 569function error( 570 source, 571 position, 572 current, 573 message, 574 kind, 575 { level = "error", autofix, ruleName } = {} 576) { 577 /** 578 * @param {number} count 579 */ 580 function sliceTokens(count) { 581 return count > 0 582 ? source.slice(position, position + count) 583 : source.slice(Math.max(position + count, 0), position); 584 } 585 586 /** 587 * @param {import("./tokeniser.js").Token[]} inputs 588 * @param {object} [options] 589 * @param {boolean} [options.precedes] 590 * @returns 591 */ 592 function tokensToText(inputs, { precedes } = {}) { 593 const text = inputs.map((t) => t.trivia + t.value).join(""); 594 const nextToken = source[position]; 595 if (nextToken.type === "eof") { 596 return text; 597 } 598 if (precedes) { 599 return text + nextToken.trivia; 600 } 601 return text.slice(nextToken.trivia.length); 602 } 603 604 const maxTokens = 5; // arbitrary but works well enough 605 const line = 606 source[position].type !== "eof" 607 ? source[position].line 608 : source.length > 1 609 ? source[position - 1].line 610 : 1; 611 612 const precedingLastLine = lastLine( 613 tokensToText(sliceTokens(-maxTokens), { precedes: true }) 614 ); 615 616 const subsequentTokens = sliceTokens(maxTokens); 617 const subsequentText = tokensToText(subsequentTokens); 618 const subsequentFirstLine = subsequentText.split("\n")[0]; 619 620 const spaced = " ".repeat(precedingLastLine.length) + "^"; 621 const sourceContext = precedingLastLine + subsequentFirstLine + "\n" + spaced; 622 623 const contextType = kind === "Syntax" ? "since" : "inside"; 624 const inSourceName = source.name ? ` in ${source.name}` : ""; 625 const grammaticalContext = 626 current && current.name 627 ? `, ${contextType} \`${current.partial ? "partial " : ""}${contextAsText( 628 current 629 )}\`` 630 : ""; 631 const context = `${kind} error at line ${line}${inSourceName}${grammaticalContext}:\n${sourceContext}`; 632 return { 633 message: `${context} ${message}`, 634 bareMessage: message, 635 context, 636 line, 637 sourceName: source.name, 638 level, 639 ruleName, 640 autofix, 641 input: subsequentText, 642 tokens: subsequentTokens, 643 }; 644} 645 646/** 647 * @param {string} message error message 648 */ 649function syntaxError(source, position, current, message) { 650 return error(source, position, current, message, "Syntax"); 651} 652 653/** 654 * @param {string} message error message 655 * @param {WebIDL2ErrorOptions} [options] 656 */ 657function validationError( 658 token, 659 current, 660 ruleName, 661 message, 662 options = {} 663) { 664 options.ruleName = ruleName; 665 return error( 666 current.source, 667 token.index, 668 current, 669 message, 670 "Validation", 671 options 672 ); 673} 674 675 676/***/ }), 677/* 4 */ 678/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 679 680__webpack_require__.r(__webpack_exports__); 681/* harmony export */ __webpack_require__.d(__webpack_exports__, { 682/* harmony export */ "argument_list": () => (/* binding */ argument_list), 683/* harmony export */ "autoParenter": () => (/* binding */ autoParenter), 684/* harmony export */ "autofixAddExposedWindow": () => (/* binding */ autofixAddExposedWindow), 685/* harmony export */ "const_data": () => (/* binding */ const_data), 686/* harmony export */ "const_value": () => (/* binding */ const_value), 687/* harmony export */ "findLastIndex": () => (/* binding */ findLastIndex), 688/* harmony export */ "getFirstToken": () => (/* binding */ getFirstToken), 689/* harmony export */ "getLastIndentation": () => (/* binding */ getLastIndentation), 690/* harmony export */ "getMemberIndentation": () => (/* binding */ getMemberIndentation), 691/* harmony export */ "list": () => (/* binding */ list), 692/* harmony export */ "primitive_type": () => (/* binding */ primitive_type), 693/* harmony export */ "return_type": () => (/* binding */ return_type), 694/* harmony export */ "stringifier": () => (/* binding */ stringifier), 695/* harmony export */ "type_with_extended_attributes": () => (/* binding */ type_with_extended_attributes), 696/* harmony export */ "unescape": () => (/* binding */ unescape) 697/* harmony export */ }); 698/* harmony import */ var _type_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5); 699/* harmony import */ var _argument_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); 700/* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8); 701/* harmony import */ var _operation_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(13); 702/* harmony import */ var _attribute_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(14); 703/* harmony import */ var _tokeniser_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2); 704 705 706 707 708 709 710 711/** 712 * @param {string} identifier 713 */ 714function unescape(identifier) { 715 return identifier.startsWith("_") ? identifier.slice(1) : identifier; 716} 717 718/** 719 * Parses comma-separated list 720 * @param {import("../tokeniser.js").Tokeniser} tokeniser 721 * @param {object} args 722 * @param {Function} args.parser parser function for each item 723 * @param {boolean} [args.allowDangler] whether to allow dangling comma 724 * @param {string} [args.listName] the name to be shown on error messages 725 */ 726function list(tokeniser, { parser, allowDangler, listName = "list" }) { 727 const first = parser(tokeniser); 728 if (!first) { 729 return []; 730 } 731 first.tokens.separator = tokeniser.consume(","); 732 const items = [first]; 733 while (first.tokens.separator) { 734 const item = parser(tokeniser); 735 if (!item) { 736 if (!allowDangler) { 737 tokeniser.error(`Trailing comma in ${listName}`); 738 } 739 break; 740 } 741 item.tokens.separator = tokeniser.consume(","); 742 items.push(item); 743 if (!item.tokens.separator) break; 744 } 745 return items; 746} 747 748/** 749 * @param {import("../tokeniser.js").Tokeniser} tokeniser 750 */ 751function const_value(tokeniser) { 752 return ( 753 tokeniser.consumeKind("decimal", "integer") || 754 tokeniser.consume("true", "false", "Infinity", "-Infinity", "NaN") 755 ); 756} 757 758/** 759 * @param {object} token 760 * @param {string} token.type 761 * @param {string} token.value 762 */ 763function const_data({ type, value }) { 764 switch (type) { 765 case "decimal": 766 case "integer": 767 return { type: "number", value }; 768 case "string": 769 return { type: "string", value: value.slice(1, -1) }; 770 } 771 772 switch (value) { 773 case "true": 774 case "false": 775 return { type: "boolean", value: value === "true" }; 776 case "Infinity": 777 case "-Infinity": 778 return { type: "Infinity", negative: value.startsWith("-") }; 779 case "[": 780 return { type: "sequence", value: [] }; 781 case "{": 782 return { type: "dictionary" }; 783 default: 784 return { type: value }; 785 } 786} 787 788/** 789 * @param {import("../tokeniser.js").Tokeniser} tokeniser 790 */ 791function primitive_type(tokeniser) { 792 function integer_type() { 793 const prefix = tokeniser.consume("unsigned"); 794 const base = tokeniser.consume("short", "long"); 795 if (base) { 796 const postfix = tokeniser.consume("long"); 797 return new _type_js__WEBPACK_IMPORTED_MODULE_0__.Type({ source, tokens: { prefix, base, postfix } }); 798 } 799 if (prefix) tokeniser.error("Failed to parse integer type"); 800 } 801 802 function decimal_type() { 803 const prefix = tokeniser.consume("unrestricted"); 804 const base = tokeniser.consume("float", "double"); 805 if (base) { 806 return new _type_js__WEBPACK_IMPORTED_MODULE_0__.Type({ source, tokens: { prefix, base } }); 807 } 808 if (prefix) tokeniser.error("Failed to parse float type"); 809 } 810 811 const { source } = tokeniser; 812 const num_type = integer_type() || decimal_type(); 813 if (num_type) return num_type; 814 const base = tokeniser.consume( 815 "bigint", 816 "boolean", 817 "byte", 818 "octet", 819 "undefined" 820 ); 821 if (base) { 822 return new _type_js__WEBPACK_IMPORTED_MODULE_0__.Type({ source, tokens: { base } }); 823 } 824} 825 826/** 827 * @param {import("../tokeniser.js").Tokeniser} tokeniser 828 */ 829function argument_list(tokeniser) { 830 return list(tokeniser, { 831 parser: _argument_js__WEBPACK_IMPORTED_MODULE_1__.Argument.parse, 832 listName: "arguments list", 833 }); 834} 835 836/** 837 * @param {import("../tokeniser.js").Tokeniser} tokeniser 838 * @param {string=} typeName (TODO: See Type.type for more details) 839 */ 840function type_with_extended_attributes(tokeniser, typeName) { 841 const extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.ExtendedAttributes.parse(tokeniser); 842 const ret = _type_js__WEBPACK_IMPORTED_MODULE_0__.Type.parse(tokeniser, typeName); 843 if (ret) autoParenter(ret).extAttrs = extAttrs; 844 return ret; 845} 846 847/** 848 * @param {import("../tokeniser.js").Tokeniser} tokeniser 849 * @param {string=} typeName (TODO: See Type.type for more details) 850 */ 851function return_type(tokeniser, typeName) { 852 const typ = _type_js__WEBPACK_IMPORTED_MODULE_0__.Type.parse(tokeniser, typeName || "return-type"); 853 if (typ) { 854 return typ; 855 } 856 const voidToken = tokeniser.consume("void"); 857 if (voidToken) { 858 const ret = new _type_js__WEBPACK_IMPORTED_MODULE_0__.Type({ 859 source: tokeniser.source, 860 tokens: { base: voidToken }, 861 }); 862 ret.type = "return-type"; 863 return ret; 864 } 865} 866 867/** 868 * @param {import("../tokeniser.js").Tokeniser} tokeniser 869 */ 870function stringifier(tokeniser) { 871 const special = tokeniser.consume("stringifier"); 872 if (!special) return; 873 const member = 874 _attribute_js__WEBPACK_IMPORTED_MODULE_4__.Attribute.parse(tokeniser, { special }) || 875 _operation_js__WEBPACK_IMPORTED_MODULE_3__.Operation.parse(tokeniser, { special }) || 876 tokeniser.error("Unterminated stringifier"); 877 return member; 878} 879 880/** 881 * @param {string} str 882 */ 883function getLastIndentation(str) { 884 const lines = str.split("\n"); 885 // the first line visually binds to the preceding token 886 if (lines.length) { 887 const match = lines[lines.length - 1].match(/^\s+/); 888 if (match) { 889 return match[0]; 890 } 891 } 892 return ""; 893} 894 895/** 896 * @param {string} parentTrivia 897 */ 898function getMemberIndentation(parentTrivia) { 899 const indentation = getLastIndentation(parentTrivia); 900 const indentCh = indentation.includes("\t") ? "\t" : " "; 901 return indentation + indentCh; 902} 903 904/** 905 * @param {import("./interface.js").Interface} def 906 */ 907function autofixAddExposedWindow(def) { 908 return () => { 909 if (def.extAttrs.length) { 910 const tokeniser = new _tokeniser_js__WEBPACK_IMPORTED_MODULE_5__.Tokeniser("Exposed=Window,"); 911 const exposed = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.SimpleExtendedAttribute.parse(tokeniser); 912 exposed.tokens.separator = tokeniser.consume(","); 913 const existing = def.extAttrs[0]; 914 if (!/^\s/.test(existing.tokens.name.trivia)) { 915 existing.tokens.name.trivia = ` ${existing.tokens.name.trivia}`; 916 } 917 def.extAttrs.unshift(exposed); 918 } else { 919 autoParenter(def).extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.ExtendedAttributes.parse( 920 new _tokeniser_js__WEBPACK_IMPORTED_MODULE_5__.Tokeniser("[Exposed=Window]") 921 ); 922 const trivia = def.tokens.base.trivia; 923 def.extAttrs.tokens.open.trivia = trivia; 924 def.tokens.base.trivia = `\n${getLastIndentation(trivia)}`; 925 } 926 }; 927} 928 929/** 930 * Get the first syntax token for the given IDL object. 931 * @param {*} data 932 */ 933function getFirstToken(data) { 934 if (data.extAttrs.length) { 935 return data.extAttrs.tokens.open; 936 } 937 if (data.type === "operation" && !data.special) { 938 return getFirstToken(data.idlType); 939 } 940 const tokens = Object.values(data.tokens).sort((x, y) => x.index - y.index); 941 return tokens[0]; 942} 943 944/** 945 * @template T 946 * @param {T[]} array 947 * @param {(item: T) => boolean} predicate 948 */ 949function findLastIndex(array, predicate) { 950 const index = array.slice().reverse().findIndex(predicate); 951 if (index === -1) { 952 return index; 953 } 954 return array.length - index - 1; 955} 956 957/** 958 * Returns a proxy that auto-assign `parent` field. 959 * @template {Record<string | symbol, any>} T 960 * @param {T} data 961 * @param {*} [parent] The object that will be assigned to `parent`. 962 * If absent, it will be `data` by default. 963 * @return {T} 964 */ 965function autoParenter(data, parent) { 966 if (!parent) { 967 // Defaults to `data` unless specified otherwise. 968 parent = data; 969 } 970 if (!data) { 971 // This allows `autoParenter(undefined)` which again allows 972 // `autoParenter(parse())` where the function may return nothing. 973 return data; 974 } 975 const proxy = new Proxy(data, { 976 get(target, p) { 977 const value = target[p]; 978 if (Array.isArray(value) && p !== "source") { 979 // Wraps the array so that any added items will also automatically 980 // get their `parent` values. 981 return autoParenter(value, target); 982 } 983 return value; 984 }, 985 set(target, p, value) { 986 // @ts-ignore https://github.com/microsoft/TypeScript/issues/47357 987 target[p] = value; 988 if (!value) { 989 return true; 990 } else if (Array.isArray(value)) { 991 // Assigning an array will add `parent` to its items. 992 for (const item of value) { 993 if (typeof item.parent !== "undefined") { 994 item.parent = parent; 995 } 996 } 997 } else if (typeof value.parent !== "undefined") { 998 value.parent = parent; 999 } 1000 return true; 1001 }, 1002 }); 1003 return proxy; 1004} 1005 1006 1007/***/ }), 1008/* 5 */ 1009/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 1010 1011__webpack_require__.r(__webpack_exports__); 1012/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1013/* harmony export */ "Type": () => (/* binding */ Type) 1014/* harmony export */ }); 1015/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 1016/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); 1017/* harmony import */ var _tokeniser_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2); 1018/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3); 1019/* harmony import */ var _validators_helpers_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7); 1020/* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8); 1021 1022 1023 1024 1025 1026 1027 1028/** 1029 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1030 * @param {string} typeName 1031 */ 1032function generic_type(tokeniser, typeName) { 1033 const base = tokeniser.consume( 1034 "FrozenArray", 1035 "ObservableArray", 1036 "Promise", 1037 "sequence", 1038 "record" 1039 ); 1040 if (!base) { 1041 return; 1042 } 1043 const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)( 1044 new Type({ source: tokeniser.source, tokens: { base } }) 1045 ); 1046 ret.tokens.open = 1047 tokeniser.consume("<") || 1048 tokeniser.error(`No opening bracket after ${base.value}`); 1049 switch (base.value) { 1050 case "Promise": { 1051 if (tokeniser.probe("[")) 1052 tokeniser.error("Promise type cannot have extended attribute"); 1053 const subtype = 1054 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.return_type)(tokeniser, typeName) || 1055 tokeniser.error("Missing Promise subtype"); 1056 ret.subtype.push(subtype); 1057 break; 1058 } 1059 case "sequence": 1060 case "FrozenArray": 1061 case "ObservableArray": { 1062 const subtype = 1063 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser, typeName) || 1064 tokeniser.error(`Missing ${base.value} subtype`); 1065 ret.subtype.push(subtype); 1066 break; 1067 } 1068 case "record": { 1069 if (tokeniser.probe("[")) 1070 tokeniser.error("Record key cannot have extended attribute"); 1071 const keyType = 1072 tokeniser.consume(..._tokeniser_js__WEBPACK_IMPORTED_MODULE_2__.stringTypes) || 1073 tokeniser.error(`Record key must be one of: ${_tokeniser_js__WEBPACK_IMPORTED_MODULE_2__.stringTypes.join(", ")}`); 1074 const keyIdlType = new Type({ 1075 source: tokeniser.source, 1076 tokens: { base: keyType }, 1077 }); 1078 keyIdlType.tokens.separator = 1079 tokeniser.consume(",") || 1080 tokeniser.error("Missing comma after record key type"); 1081 keyIdlType.type = typeName; 1082 const valueType = 1083 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser, typeName) || 1084 tokeniser.error("Error parsing generic type record"); 1085 ret.subtype.push(keyIdlType, valueType); 1086 break; 1087 } 1088 } 1089 if (!ret.idlType) tokeniser.error(`Error parsing generic type ${base.value}`); 1090 ret.tokens.close = 1091 tokeniser.consume(">") || 1092 tokeniser.error(`Missing closing bracket after ${base.value}`); 1093 return ret.this; 1094} 1095 1096/** 1097 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1098 */ 1099function type_suffix(tokeniser, obj) { 1100 const nullable = tokeniser.consume("?"); 1101 if (nullable) { 1102 obj.tokens.nullable = nullable; 1103 } 1104 if (tokeniser.probe("?")) tokeniser.error("Can't nullable more than once"); 1105} 1106 1107/** 1108 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1109 * @param {string} typeName 1110 */ 1111function single_type(tokeniser, typeName) { 1112 let ret = generic_type(tokeniser, typeName) || (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.primitive_type)(tokeniser); 1113 if (!ret) { 1114 const base = 1115 tokeniser.consumeKind("identifier") || 1116 tokeniser.consume(..._tokeniser_js__WEBPACK_IMPORTED_MODULE_2__.stringTypes, ..._tokeniser_js__WEBPACK_IMPORTED_MODULE_2__.typeNameKeywords); 1117 if (!base) { 1118 return; 1119 } 1120 ret = new Type({ source: tokeniser.source, tokens: { base } }); 1121 if (tokeniser.probe("<")) 1122 tokeniser.error(`Unsupported generic type ${base.value}`); 1123 } 1124 if (ret.generic === "Promise" && tokeniser.probe("?")) { 1125 tokeniser.error("Promise type cannot be nullable"); 1126 } 1127 ret.type = typeName || null; 1128 type_suffix(tokeniser, ret); 1129 if (ret.nullable && ret.idlType === "any") 1130 tokeniser.error("Type `any` cannot be made nullable"); 1131 return ret; 1132} 1133 1134/** 1135 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1136 * @param {string} type 1137 */ 1138function union_type(tokeniser, type) { 1139 const tokens = {}; 1140 tokens.open = tokeniser.consume("("); 1141 if (!tokens.open) return; 1142 const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(new Type({ source: tokeniser.source, tokens })); 1143 ret.type = type || null; 1144 while (true) { 1145 const typ = 1146 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser) || 1147 tokeniser.error("No type after open parenthesis or 'or' in union type"); 1148 if (typ.idlType === "any") 1149 tokeniser.error("Type `any` cannot be included in a union type"); 1150 if (typ.generic === "Promise") 1151 tokeniser.error("Type `Promise` cannot be included in a union type"); 1152 ret.subtype.push(typ); 1153 const or = tokeniser.consume("or"); 1154 if (or) { 1155 typ.tokens.separator = or; 1156 } else break; 1157 } 1158 if (ret.idlType.length < 2) { 1159 tokeniser.error( 1160 "At least two types are expected in a union type but found less" 1161 ); 1162 } 1163 tokens.close = 1164 tokeniser.consume(")") || tokeniser.error("Unterminated union type"); 1165 type_suffix(tokeniser, ret); 1166 return ret.this; 1167} 1168 1169class Type extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 1170 /** 1171 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1172 * @param {string} typeName 1173 */ 1174 static parse(tokeniser, typeName) { 1175 return single_type(tokeniser, typeName) || union_type(tokeniser, typeName); 1176 } 1177 1178 constructor({ source, tokens }) { 1179 super({ source, tokens }); 1180 Object.defineProperty(this, "subtype", { value: [], writable: true }); 1181 this.extAttrs = new _extended_attributes_js__WEBPACK_IMPORTED_MODULE_5__.ExtendedAttributes({ source, tokens: {} }); 1182 } 1183 1184 get generic() { 1185 if (this.subtype.length && this.tokens.base) { 1186 return this.tokens.base.value; 1187 } 1188 return ""; 1189 } 1190 get nullable() { 1191 return Boolean(this.tokens.nullable); 1192 } 1193 get union() { 1194 return Boolean(this.subtype.length) && !this.tokens.base; 1195 } 1196 get idlType() { 1197 if (this.subtype.length) { 1198 return this.subtype; 1199 } 1200 // Adding prefixes/postfixes for "unrestricted float", etc. 1201 const name = [this.tokens.prefix, this.tokens.base, this.tokens.postfix] 1202 .filter((t) => t) 1203 .map((t) => t.value) 1204 .join(" "); 1205 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(name); 1206 } 1207 1208 *validate(defs) { 1209 yield* this.extAttrs.validate(defs); 1210 1211 if (this.idlType === "void") { 1212 const message = `\`void\` is now replaced by \`undefined\`. Refer to the \ 1213[relevant GitHub issue](https://github.com/whatwg/webidl/issues/60) \ 1214for more information.`; 1215 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_3__.validationError)(this.tokens.base, this, "replace-void", message, { 1216 autofix: replaceVoid(this), 1217 }); 1218 } 1219 1220 /* 1221 * If a union is nullable, its subunions cannot include a dictionary 1222 * If not, subunions may include dictionaries if each union is not nullable 1223 */ 1224 const typedef = !this.union && defs.unique.get(this.idlType); 1225 const target = this.union 1226 ? this 1227 : typedef && typedef.type === "typedef" 1228 ? typedef.idlType 1229 : undefined; 1230 if (target && this.nullable) { 1231 // do not allow any dictionary 1232 const { reference } = (0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_4__.idlTypeIncludesDictionary)(target, defs) || {}; 1233 if (reference) { 1234 const targetToken = (this.union ? reference : this).tokens.base; 1235 const message = "Nullable union cannot include a dictionary type."; 1236 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_3__.validationError)( 1237 targetToken, 1238 this, 1239 "no-nullable-union-dict", 1240 message 1241 ); 1242 } 1243 } else { 1244 // allow some dictionary 1245 for (const subtype of this.subtype) { 1246 yield* subtype.validate(defs); 1247 } 1248 } 1249 } 1250 1251 /** @param {import("../writer.js").Writer} w */ 1252 write(w) { 1253 const type_body = () => { 1254 if (this.union || this.generic) { 1255 return w.ts.wrap([ 1256 w.token(this.tokens.base, w.ts.generic), 1257 w.token(this.tokens.open), 1258 ...this.subtype.map((t) => t.write(w)), 1259 w.token(this.tokens.close), 1260 ]); 1261 } 1262 const firstToken = this.tokens.prefix || this.tokens.base; 1263 const prefix = this.tokens.prefix 1264 ? [this.tokens.prefix.value, w.ts.trivia(this.tokens.base.trivia)] 1265 : []; 1266 const ref = w.reference( 1267 w.ts.wrap([ 1268 ...prefix, 1269 this.tokens.base.value, 1270 w.token(this.tokens.postfix), 1271 ]), 1272 { 1273 unescaped: /** @type {string} (because it's not union) */ ( 1274 this.idlType 1275 ), 1276 context: this, 1277 } 1278 ); 1279 return w.ts.wrap([w.ts.trivia(firstToken.trivia), ref]); 1280 }; 1281 return w.ts.wrap([ 1282 this.extAttrs.write(w), 1283 type_body(), 1284 w.token(this.tokens.nullable), 1285 w.token(this.tokens.separator), 1286 ]); 1287 } 1288} 1289 1290/** 1291 * @param {Type} type 1292 */ 1293function replaceVoid(type) { 1294 return () => { 1295 type.tokens.base.value = "undefined"; 1296 }; 1297} 1298 1299 1300/***/ }), 1301/* 6 */ 1302/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 1303 1304__webpack_require__.r(__webpack_exports__); 1305/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1306/* harmony export */ "Base": () => (/* binding */ Base) 1307/* harmony export */ }); 1308class Base { 1309 /** 1310 * @param {object} initializer 1311 * @param {Base["source"]} initializer.source 1312 * @param {Base["tokens"]} initializer.tokens 1313 */ 1314 constructor({ source, tokens }) { 1315 Object.defineProperties(this, { 1316 source: { value: source }, 1317 tokens: { value: tokens, writable: true }, 1318 parent: { value: null, writable: true }, 1319 this: { value: this }, // useful when escaping from proxy 1320 }); 1321 } 1322 1323 toJSON() { 1324 const json = { type: undefined, name: undefined, inheritance: undefined }; 1325 let proto = this; 1326 while (proto !== Object.prototype) { 1327 const descMap = Object.getOwnPropertyDescriptors(proto); 1328 for (const [key, value] of Object.entries(descMap)) { 1329 if (value.enumerable || value.get) { 1330 // @ts-ignore - allow indexing here 1331 json[key] = this[key]; 1332 } 1333 } 1334 proto = Object.getPrototypeOf(proto); 1335 } 1336 return json; 1337 } 1338} 1339 1340 1341/***/ }), 1342/* 7 */ 1343/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 1344 1345__webpack_require__.r(__webpack_exports__); 1346/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1347/* harmony export */ "dictionaryIncludesRequiredField": () => (/* binding */ dictionaryIncludesRequiredField), 1348/* harmony export */ "idlTypeIncludesDictionary": () => (/* binding */ idlTypeIncludesDictionary) 1349/* harmony export */ }); 1350/** 1351 * @typedef {import("../productions/dictionary.js").Dictionary} Dictionary 1352 * 1353 * @param {*} idlType 1354 * @param {import("../validator.js").Definitions} defs 1355 * @param {object} [options] 1356 * @param {boolean} [options.useNullableInner] use when the input idlType is nullable and you want to use its inner type 1357 * @return {{ reference: *, dictionary: Dictionary }} the type reference that ultimately includes dictionary. 1358 */ 1359function idlTypeIncludesDictionary( 1360 idlType, 1361 defs, 1362 { useNullableInner } = {} 1363) { 1364 if (!idlType.union) { 1365 const def = defs.unique.get(idlType.idlType); 1366 if (!def) { 1367 return; 1368 } 1369 if (def.type === "typedef") { 1370 const { typedefIncludesDictionary } = defs.cache; 1371 if (typedefIncludesDictionary.has(def)) { 1372 // Note that this also halts when it met indeterminate state 1373 // to prevent infinite recursion 1374 return typedefIncludesDictionary.get(def); 1375 } 1376 defs.cache.typedefIncludesDictionary.set(def, undefined); // indeterminate state 1377 const result = idlTypeIncludesDictionary(def.idlType, defs); 1378 defs.cache.typedefIncludesDictionary.set(def, result); 1379 if (result) { 1380 return { 1381 reference: idlType, 1382 dictionary: result.dictionary, 1383 }; 1384 } 1385 } 1386 if (def.type === "dictionary" && (useNullableInner || !idlType.nullable)) { 1387 return { 1388 reference: idlType, 1389 dictionary: def, 1390 }; 1391 } 1392 } 1393 for (const subtype of idlType.subtype) { 1394 const result = idlTypeIncludesDictionary(subtype, defs); 1395 if (result) { 1396 if (subtype.union) { 1397 return result; 1398 } 1399 return { 1400 reference: subtype, 1401 dictionary: result.dictionary, 1402 }; 1403 } 1404 } 1405} 1406 1407/** 1408 * @param {*} dict dictionary type 1409 * @param {import("../validator.js").Definitions} defs 1410 * @return {boolean} 1411 */ 1412function dictionaryIncludesRequiredField(dict, defs) { 1413 if (defs.cache.dictionaryIncludesRequiredField.has(dict)) { 1414 return defs.cache.dictionaryIncludesRequiredField.get(dict); 1415 } 1416 // Set cached result to indeterminate to short-circuit circular definitions. 1417 // The final result will be updated to true or false. 1418 defs.cache.dictionaryIncludesRequiredField.set(dict, undefined); 1419 let result = dict.members.some((field) => field.required); 1420 if (!result && dict.inheritance) { 1421 const superdict = defs.unique.get(dict.inheritance); 1422 if (!superdict) { 1423 // Assume required members in the supertype if it is unknown. 1424 result = true; 1425 } else if (dictionaryIncludesRequiredField(superdict, defs)) { 1426 result = true; 1427 } 1428 } 1429 defs.cache.dictionaryIncludesRequiredField.set(dict, result); 1430 return result; 1431} 1432 1433 1434/***/ }), 1435/* 8 */ 1436/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 1437 1438__webpack_require__.r(__webpack_exports__); 1439/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1440/* harmony export */ "ExtendedAttributeParameters": () => (/* binding */ ExtendedAttributeParameters), 1441/* harmony export */ "ExtendedAttributes": () => (/* binding */ ExtendedAttributes), 1442/* harmony export */ "SimpleExtendedAttribute": () => (/* binding */ SimpleExtendedAttribute) 1443/* harmony export */ }); 1444/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 1445/* harmony import */ var _array_base_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9); 1446/* harmony import */ var _token_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(10); 1447/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4); 1448/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3); 1449 1450 1451 1452 1453 1454 1455/** 1456 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1457 * @param {string} tokenName 1458 */ 1459function tokens(tokeniser, tokenName) { 1460 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.list)(tokeniser, { 1461 parser: _token_js__WEBPACK_IMPORTED_MODULE_2__.WrappedToken.parser(tokeniser, tokenName), 1462 listName: tokenName + " list", 1463 }); 1464} 1465 1466const extAttrValueSyntax = ["identifier", "decimal", "integer", "string"]; 1467 1468const shouldBeLegacyPrefixed = [ 1469 "NoInterfaceObject", 1470 "LenientSetter", 1471 "LenientThis", 1472 "TreatNonObjectAsNull", 1473 "Unforgeable", 1474]; 1475 1476const renamedLegacies = new Map([ 1477 .../** @type {[string, string][]} */ ( 1478 shouldBeLegacyPrefixed.map((name) => [name, `Legacy${name}`]) 1479 ), 1480 ["NamedConstructor", "LegacyFactoryFunction"], 1481 ["OverrideBuiltins", "LegacyOverrideBuiltIns"], 1482 ["TreatNullAs", "LegacyNullToEmptyString"], 1483]); 1484 1485/** 1486 * This will allow a set of extended attribute values to be parsed. 1487 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1488 */ 1489function extAttrListItems(tokeniser) { 1490 for (const syntax of extAttrValueSyntax) { 1491 const toks = tokens(tokeniser, syntax); 1492 if (toks.length) { 1493 return toks; 1494 } 1495 } 1496 tokeniser.error( 1497 `Expected identifiers, strings, decimals, or integers but none found` 1498 ); 1499} 1500 1501class ExtendedAttributeParameters extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 1502 /** 1503 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1504 */ 1505 static parse(tokeniser) { 1506 const tokens = { assign: tokeniser.consume("=") }; 1507 const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.autoParenter)( 1508 new ExtendedAttributeParameters({ source: tokeniser.source, tokens }) 1509 ); 1510 ret.list = []; 1511 if (tokens.assign) { 1512 tokens.asterisk = tokeniser.consume("*"); 1513 if (tokens.asterisk) { 1514 return ret.this; 1515 } 1516 tokens.secondaryName = tokeniser.consumeKind(...extAttrValueSyntax); 1517 } 1518 tokens.open = tokeniser.consume("("); 1519 if (tokens.open) { 1520 ret.list = ret.rhsIsList 1521 ? // [Exposed=(Window,Worker)] 1522 extAttrListItems(tokeniser) 1523 : // [LegacyFactoryFunction=Audio(DOMString src)] or [Constructor(DOMString str)] 1524 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.argument_list)(tokeniser); 1525 tokens.close = 1526 tokeniser.consume(")") || 1527 tokeniser.error("Unexpected token in extended attribute argument list"); 1528 } else if (tokens.assign && !tokens.secondaryName) { 1529 tokeniser.error("No right hand side to extended attribute assignment"); 1530 } 1531 return ret.this; 1532 } 1533 1534 get rhsIsList() { 1535 return ( 1536 this.tokens.assign && !this.tokens.asterisk && !this.tokens.secondaryName 1537 ); 1538 } 1539 1540 get rhsType() { 1541 if (this.rhsIsList) { 1542 return this.list[0].tokens.value.type + "-list"; 1543 } 1544 if (this.tokens.asterisk) { 1545 return "*"; 1546 } 1547 if (this.tokens.secondaryName) { 1548 return this.tokens.secondaryName.type; 1549 } 1550 return null; 1551 } 1552 1553 /** @param {import("../writer.js").Writer} w */ 1554 write(w) { 1555 const { rhsType } = this; 1556 return w.ts.wrap([ 1557 w.token(this.tokens.assign), 1558 w.token(this.tokens.asterisk), 1559 w.reference_token(this.tokens.secondaryName, this.parent), 1560 w.token(this.tokens.open), 1561 ...this.list.map((p) => { 1562 return rhsType === "identifier-list" 1563 ? w.identifier(p, this.parent) 1564 : p.write(w); 1565 }), 1566 w.token(this.tokens.close), 1567 ]); 1568 } 1569} 1570 1571class SimpleExtendedAttribute extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 1572 /** 1573 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1574 */ 1575 static parse(tokeniser) { 1576 const name = tokeniser.consumeKind("identifier"); 1577 if (name) { 1578 return new SimpleExtendedAttribute({ 1579 source: tokeniser.source, 1580 tokens: { name }, 1581 params: ExtendedAttributeParameters.parse(tokeniser), 1582 }); 1583 } 1584 } 1585 1586 constructor({ source, tokens, params }) { 1587 super({ source, tokens }); 1588 params.parent = this; 1589 Object.defineProperty(this, "params", { value: params }); 1590 } 1591 1592 get type() { 1593 return "extended-attribute"; 1594 } 1595 get name() { 1596 return this.tokens.name.value; 1597 } 1598 get rhs() { 1599 const { rhsType: type, tokens, list } = this.params; 1600 if (!type) { 1601 return null; 1602 } 1603 const value = this.params.rhsIsList 1604 ? list 1605 : this.params.tokens.secondaryName 1606 ? (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.unescape)(tokens.secondaryName.value) 1607 : null; 1608 return { type, value }; 1609 } 1610 get arguments() { 1611 const { rhsIsList, list } = this.params; 1612 if (!list || rhsIsList) { 1613 return []; 1614 } 1615 return list; 1616 } 1617 1618 *validate(defs) { 1619 const { name } = this; 1620 if (name === "LegacyNoInterfaceObject") { 1621 const message = `\`[LegacyNoInterfaceObject]\` extended attribute is an \ 1622undesirable feature that may be removed from Web IDL in the future. Refer to the \ 1623[relevant upstream PR](https://github.com/whatwg/webidl/pull/609) for more \ 1624information.`; 1625 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_4__.validationError)( 1626 this.tokens.name, 1627 this, 1628 "no-nointerfaceobject", 1629 message, 1630 { level: "warning" } 1631 ); 1632 } else if (renamedLegacies.has(name)) { 1633 const message = `\`[${name}]\` extended attribute is a legacy feature \ 1634that is now renamed to \`[${renamedLegacies.get(name)}]\`. Refer to the \ 1635[relevant upstream PR](https://github.com/whatwg/webidl/pull/870) for more \ 1636information.`; 1637 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_4__.validationError)(this.tokens.name, this, "renamed-legacy", message, { 1638 level: "warning", 1639 autofix: renameLegacyExtendedAttribute(this), 1640 }); 1641 } 1642 for (const arg of this.arguments) { 1643 yield* arg.validate(defs); 1644 } 1645 } 1646 1647 /** @param {import("../writer.js").Writer} w */ 1648 write(w) { 1649 return w.ts.wrap([ 1650 w.ts.trivia(this.tokens.name.trivia), 1651 w.ts.extendedAttribute( 1652 w.ts.wrap([ 1653 w.ts.extendedAttributeReference(this.name), 1654 this.params.write(w), 1655 ]) 1656 ), 1657 w.token(this.tokens.separator), 1658 ]); 1659 } 1660} 1661 1662/** 1663 * @param {SimpleExtendedAttribute} extAttr 1664 */ 1665function renameLegacyExtendedAttribute(extAttr) { 1666 return () => { 1667 const { name } = extAttr; 1668 extAttr.tokens.name.value = renamedLegacies.get(name); 1669 if (name === "TreatNullAs") { 1670 extAttr.params.tokens = {}; 1671 } 1672 }; 1673} 1674 1675// Note: we parse something simpler than the official syntax. It's all that ever 1676// seems to be used 1677class ExtendedAttributes extends _array_base_js__WEBPACK_IMPORTED_MODULE_1__.ArrayBase { 1678 /** 1679 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1680 */ 1681 static parse(tokeniser) { 1682 const tokens = {}; 1683 tokens.open = tokeniser.consume("["); 1684 const ret = new ExtendedAttributes({ source: tokeniser.source, tokens }); 1685 if (!tokens.open) return ret; 1686 ret.push( 1687 ...(0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.list)(tokeniser, { 1688 parser: SimpleExtendedAttribute.parse, 1689 listName: "extended attribute", 1690 }) 1691 ); 1692 tokens.close = 1693 tokeniser.consume("]") || 1694 tokeniser.error( 1695 "Expected a closing token for the extended attribute list" 1696 ); 1697 if (!ret.length) { 1698 tokeniser.unconsume(tokens.close.index); 1699 tokeniser.error("An extended attribute list must not be empty"); 1700 } 1701 if (tokeniser.probe("[")) { 1702 tokeniser.error( 1703 "Illegal double extended attribute lists, consider merging them" 1704 ); 1705 } 1706 return ret; 1707 } 1708 1709 *validate(defs) { 1710 for (const extAttr of this) { 1711 yield* extAttr.validate(defs); 1712 } 1713 } 1714 1715 /** @param {import("../writer.js").Writer} w */ 1716 write(w) { 1717 if (!this.length) return ""; 1718 return w.ts.wrap([ 1719 w.token(this.tokens.open), 1720 ...this.map((ea) => ea.write(w)), 1721 w.token(this.tokens.close), 1722 ]); 1723 } 1724} 1725 1726 1727/***/ }), 1728/* 9 */ 1729/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 1730 1731__webpack_require__.r(__webpack_exports__); 1732/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1733/* harmony export */ "ArrayBase": () => (/* binding */ ArrayBase) 1734/* harmony export */ }); 1735class ArrayBase extends Array { 1736 constructor({ source, tokens }) { 1737 super(); 1738 Object.defineProperties(this, { 1739 source: { value: source }, 1740 tokens: { value: tokens }, 1741 parent: { value: null, writable: true }, 1742 }); 1743 } 1744} 1745 1746 1747/***/ }), 1748/* 10 */ 1749/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 1750 1751__webpack_require__.r(__webpack_exports__); 1752/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1753/* harmony export */ "Eof": () => (/* binding */ Eof), 1754/* harmony export */ "WrappedToken": () => (/* binding */ WrappedToken) 1755/* harmony export */ }); 1756/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 1757/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); 1758 1759 1760 1761class WrappedToken extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 1762 /** 1763 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1764 * @param {string} type 1765 */ 1766 static parser(tokeniser, type) { 1767 return () => { 1768 const value = tokeniser.consumeKind(type); 1769 if (value) { 1770 return new WrappedToken({ 1771 source: tokeniser.source, 1772 tokens: { value }, 1773 }); 1774 } 1775 }; 1776 } 1777 1778 get value() { 1779 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.value.value); 1780 } 1781 1782 /** @param {import("../writer.js").Writer} w */ 1783 write(w) { 1784 return w.ts.wrap([ 1785 w.token(this.tokens.value), 1786 w.token(this.tokens.separator), 1787 ]); 1788 } 1789} 1790 1791class Eof extends WrappedToken { 1792 /** 1793 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1794 */ 1795 static parse(tokeniser) { 1796 const value = tokeniser.consumeKind("eof"); 1797 if (value) { 1798 return new Eof({ source: tokeniser.source, tokens: { value } }); 1799 } 1800 } 1801 1802 get type() { 1803 return "eof"; 1804 } 1805} 1806 1807 1808/***/ }), 1809/* 11 */ 1810/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 1811 1812__webpack_require__.r(__webpack_exports__); 1813/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1814/* harmony export */ "Argument": () => (/* binding */ Argument) 1815/* harmony export */ }); 1816/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 1817/* harmony import */ var _default_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(12); 1818/* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8); 1819/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4); 1820/* harmony import */ var _tokeniser_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2); 1821/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(3); 1822/* harmony import */ var _validators_helpers_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7); 1823 1824 1825 1826 1827 1828 1829 1830 1831class Argument extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 1832 /** 1833 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1834 */ 1835 static parse(tokeniser) { 1836 const start_position = tokeniser.position; 1837 /** @type {Base["tokens"]} */ 1838 const tokens = {}; 1839 const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.autoParenter)( 1840 new Argument({ source: tokeniser.source, tokens }) 1841 ); 1842 ret.extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.ExtendedAttributes.parse(tokeniser); 1843 tokens.optional = tokeniser.consume("optional"); 1844 ret.idlType = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.type_with_extended_attributes)(tokeniser, "argument-type"); 1845 if (!ret.idlType) { 1846 return tokeniser.unconsume(start_position); 1847 } 1848 if (!tokens.optional) { 1849 tokens.variadic = tokeniser.consume("..."); 1850 } 1851 tokens.name = 1852 tokeniser.consumeKind("identifier") || 1853 tokeniser.consume(..._tokeniser_js__WEBPACK_IMPORTED_MODULE_4__.argumentNameKeywords); 1854 if (!tokens.name) { 1855 return tokeniser.unconsume(start_position); 1856 } 1857 ret.default = tokens.optional ? _default_js__WEBPACK_IMPORTED_MODULE_1__.Default.parse(tokeniser) : null; 1858 return ret.this; 1859 } 1860 1861 get type() { 1862 return "argument"; 1863 } 1864 get optional() { 1865 return !!this.tokens.optional; 1866 } 1867 get variadic() { 1868 return !!this.tokens.variadic; 1869 } 1870 get name() { 1871 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.unescape)(this.tokens.name.value); 1872 } 1873 1874 /** 1875 * @param {import("../validator.js").Definitions} defs 1876 */ 1877 *validate(defs) { 1878 yield* this.extAttrs.validate(defs); 1879 yield* this.idlType.validate(defs); 1880 const result = (0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_6__.idlTypeIncludesDictionary)(this.idlType, defs, { 1881 useNullableInner: true, 1882 }); 1883 if (result) { 1884 if (this.idlType.nullable) { 1885 const message = `Dictionary arguments cannot be nullable.`; 1886 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_5__.validationError)( 1887 this.tokens.name, 1888 this, 1889 "no-nullable-dict-arg", 1890 message 1891 ); 1892 } else if (!this.optional) { 1893 if ( 1894 this.parent && 1895 !(0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_6__.dictionaryIncludesRequiredField)(result.dictionary, defs) && 1896 isLastRequiredArgument(this) 1897 ) { 1898 const message = `Dictionary argument must be optional if it has no required fields`; 1899 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_5__.validationError)( 1900 this.tokens.name, 1901 this, 1902 "dict-arg-optional", 1903 message, 1904 { 1905 autofix: autofixDictionaryArgumentOptionality(this), 1906 } 1907 ); 1908 } 1909 } else if (!this.default) { 1910 const message = `Optional dictionary arguments must have a default value of \`{}\`.`; 1911 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_5__.validationError)( 1912 this.tokens.name, 1913 this, 1914 "dict-arg-default", 1915 message, 1916 { 1917 autofix: autofixOptionalDictionaryDefaultValue(this), 1918 } 1919 ); 1920 } 1921 } 1922 } 1923 1924 /** @param {import("../writer.js").Writer} w */ 1925 write(w) { 1926 return w.ts.wrap([ 1927 this.extAttrs.write(w), 1928 w.token(this.tokens.optional), 1929 w.ts.type(this.idlType.write(w)), 1930 w.token(this.tokens.variadic), 1931 w.name_token(this.tokens.name, { data: this }), 1932 this.default ? this.default.write(w) : "", 1933 w.token(this.tokens.separator), 1934 ]); 1935 } 1936} 1937 1938/** 1939 * @param {Argument} arg 1940 */ 1941function isLastRequiredArgument(arg) { 1942 const list = arg.parent.arguments || arg.parent.list; 1943 const index = list.indexOf(arg); 1944 const requiredExists = list.slice(index + 1).some((a) => !a.optional); 1945 return !requiredExists; 1946} 1947 1948/** 1949 * @param {Argument} arg 1950 */ 1951function autofixDictionaryArgumentOptionality(arg) { 1952 return () => { 1953 const firstToken = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.getFirstToken)(arg.idlType); 1954 arg.tokens.optional = { 1955 ...firstToken, 1956 type: "optional", 1957 value: "optional", 1958 }; 1959 firstToken.trivia = " "; 1960 autofixOptionalDictionaryDefaultValue(arg)(); 1961 }; 1962} 1963 1964/** 1965 * @param {Argument} arg 1966 */ 1967function autofixOptionalDictionaryDefaultValue(arg) { 1968 return () => { 1969 arg.default = _default_js__WEBPACK_IMPORTED_MODULE_1__.Default.parse(new _tokeniser_js__WEBPACK_IMPORTED_MODULE_4__.Tokeniser(" = {}")); 1970 }; 1971} 1972 1973 1974/***/ }), 1975/* 12 */ 1976/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 1977 1978__webpack_require__.r(__webpack_exports__); 1979/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1980/* harmony export */ "Default": () => (/* binding */ Default) 1981/* harmony export */ }); 1982/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 1983/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); 1984 1985 1986 1987class Default extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 1988 /** 1989 * @param {import("../tokeniser.js").Tokeniser} tokeniser 1990 */ 1991 static parse(tokeniser) { 1992 const assign = tokeniser.consume("="); 1993 if (!assign) { 1994 return null; 1995 } 1996 const def = 1997 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.const_value)(tokeniser) || 1998 tokeniser.consumeKind("string") || 1999 tokeniser.consume("null", "[", "{") || 2000 tokeniser.error("No value for default"); 2001 const expression = [def]; 2002 if (def.value === "[") { 2003 const close = 2004 tokeniser.consume("]") || 2005 tokeniser.error("Default sequence value must be empty"); 2006 expression.push(close); 2007 } else if (def.value === "{") { 2008 const close = 2009 tokeniser.consume("}") || 2010 tokeniser.error("Default dictionary value must be empty"); 2011 expression.push(close); 2012 } 2013 return new Default({ 2014 source: tokeniser.source, 2015 tokens: { assign }, 2016 expression, 2017 }); 2018 } 2019 2020 constructor({ source, tokens, expression }) { 2021 super({ source, tokens }); 2022 expression.parent = this; 2023 Object.defineProperty(this, "expression", { value: expression }); 2024 } 2025 2026 get type() { 2027 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.const_data)(this.expression[0]).type; 2028 } 2029 get value() { 2030 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.const_data)(this.expression[0]).value; 2031 } 2032 get negative() { 2033 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.const_data)(this.expression[0]).negative; 2034 } 2035 2036 /** @param {import("../writer.js").Writer} w */ 2037 write(w) { 2038 return w.ts.wrap([ 2039 w.token(this.tokens.assign), 2040 ...this.expression.map((t) => w.token(t)), 2041 ]); 2042 } 2043} 2044 2045 2046/***/ }), 2047/* 13 */ 2048/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 2049 2050__webpack_require__.r(__webpack_exports__); 2051/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2052/* harmony export */ "Operation": () => (/* binding */ Operation) 2053/* harmony export */ }); 2054/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 2055/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); 2056/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3); 2057 2058 2059 2060 2061class Operation extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 2062 /** 2063 * @typedef {import("../tokeniser.js").Token} Token 2064 * 2065 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2066 * @param {object} [options] 2067 * @param {Token} [options.special] 2068 * @param {Token} [options.regular] 2069 */ 2070 static parse(tokeniser, { special, regular } = {}) { 2071 const tokens = { special }; 2072 const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)( 2073 new Operation({ source: tokeniser.source, tokens }) 2074 ); 2075 if (special && special.value === "stringifier") { 2076 tokens.termination = tokeniser.consume(";"); 2077 if (tokens.termination) { 2078 ret.arguments = []; 2079 return ret; 2080 } 2081 } 2082 if (!special && !regular) { 2083 tokens.special = tokeniser.consume("getter", "setter", "deleter"); 2084 } 2085 ret.idlType = 2086 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.return_type)(tokeniser) || tokeniser.error("Missing return type"); 2087 tokens.name = 2088 tokeniser.consumeKind("identifier") || tokeniser.consume("includes"); 2089 tokens.open = 2090 tokeniser.consume("(") || tokeniser.error("Invalid operation"); 2091 ret.arguments = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.argument_list)(tokeniser); 2092 tokens.close = 2093 tokeniser.consume(")") || tokeniser.error("Unterminated operation"); 2094 tokens.termination = 2095 tokeniser.consume(";") || 2096 tokeniser.error("Unterminated operation, expected `;`"); 2097 return ret.this; 2098 } 2099 2100 get type() { 2101 return "operation"; 2102 } 2103 get name() { 2104 const { name } = this.tokens; 2105 if (!name) { 2106 return ""; 2107 } 2108 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(name.value); 2109 } 2110 get special() { 2111 if (!this.tokens.special) { 2112 return ""; 2113 } 2114 return this.tokens.special.value; 2115 } 2116 2117 *validate(defs) { 2118 yield* this.extAttrs.validate(defs); 2119 if (!this.name && ["", "static"].includes(this.special)) { 2120 const message = `Regular or static operations must have both a return type and an identifier.`; 2121 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_2__.validationError)(this.tokens.open, this, "incomplete-op", message); 2122 } 2123 if (this.idlType) { 2124 yield* this.idlType.validate(defs); 2125 } 2126 for (const argument of this.arguments) { 2127 yield* argument.validate(defs); 2128 } 2129 } 2130 2131 /** @param {import("../writer.js").Writer} w */ 2132 write(w) { 2133 const { parent } = this; 2134 const body = this.idlType 2135 ? [ 2136 w.ts.type(this.idlType.write(w)), 2137 w.name_token(this.tokens.name, { data: this, parent }), 2138 w.token(this.tokens.open), 2139 w.ts.wrap(this.arguments.map((arg) => arg.write(w))), 2140 w.token(this.tokens.close), 2141 ] 2142 : []; 2143 return w.ts.definition( 2144 w.ts.wrap([ 2145 this.extAttrs.write(w), 2146 this.tokens.name 2147 ? w.token(this.tokens.special) 2148 : w.token(this.tokens.special, w.ts.nameless, { data: this, parent }), 2149 ...body, 2150 w.token(this.tokens.termination), 2151 ]), 2152 { data: this, parent } 2153 ); 2154 } 2155} 2156 2157 2158/***/ }), 2159/* 14 */ 2160/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 2161 2162__webpack_require__.r(__webpack_exports__); 2163/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2164/* harmony export */ "Attribute": () => (/* binding */ Attribute) 2165/* harmony export */ }); 2166/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); 2167/* harmony import */ var _validators_helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7); 2168/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6); 2169/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4); 2170 2171 2172 2173 2174 2175class Attribute extends _base_js__WEBPACK_IMPORTED_MODULE_2__.Base { 2176 /** 2177 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2178 * @param {object} [options] 2179 * @param {import("../tokeniser.js").Token} [options.special] 2180 * @param {boolean} [options.noInherit] 2181 * @param {boolean} [options.readonly] 2182 */ 2183 static parse( 2184 tokeniser, 2185 { special, noInherit = false, readonly = false } = {} 2186 ) { 2187 const start_position = tokeniser.position; 2188 const tokens = { special }; 2189 const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.autoParenter)( 2190 new Attribute({ source: tokeniser.source, tokens }) 2191 ); 2192 if (!special && !noInherit) { 2193 tokens.special = tokeniser.consume("inherit"); 2194 } 2195 if (ret.special === "inherit" && tokeniser.probe("readonly")) { 2196 tokeniser.error("Inherited attributes cannot be read-only"); 2197 } 2198 tokens.readonly = tokeniser.consume("readonly"); 2199 if (readonly && !tokens.readonly && tokeniser.probe("attribute")) { 2200 tokeniser.error("Attributes must be readonly in this context"); 2201 } 2202 tokens.base = tokeniser.consume("attribute"); 2203 if (!tokens.base) { 2204 tokeniser.unconsume(start_position); 2205 return; 2206 } 2207 ret.idlType = 2208 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.type_with_extended_attributes)(tokeniser, "attribute-type") || 2209 tokeniser.error("Attribute lacks a type"); 2210 tokens.name = 2211 tokeniser.consumeKind("identifier") || 2212 tokeniser.consume("async", "required") || 2213 tokeniser.error("Attribute lacks a name"); 2214 tokens.termination = 2215 tokeniser.consume(";") || 2216 tokeniser.error("Unterminated attribute, expected `;`"); 2217 return ret.this; 2218 } 2219 2220 get type() { 2221 return "attribute"; 2222 } 2223 get special() { 2224 if (!this.tokens.special) { 2225 return ""; 2226 } 2227 return this.tokens.special.value; 2228 } 2229 get readonly() { 2230 return !!this.tokens.readonly; 2231 } 2232 get name() { 2233 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_3__.unescape)(this.tokens.name.value); 2234 } 2235 2236 *validate(defs) { 2237 yield* this.extAttrs.validate(defs); 2238 yield* this.idlType.validate(defs); 2239 2240 switch (this.idlType.generic) { 2241 case "sequence": 2242 case "record": { 2243 const message = `Attributes cannot accept ${this.idlType.generic} types.`; 2244 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)( 2245 this.tokens.name, 2246 this, 2247 "attr-invalid-type", 2248 message 2249 ); 2250 break; 2251 } 2252 default: { 2253 const { reference } = 2254 (0,_validators_helpers_js__WEBPACK_IMPORTED_MODULE_1__.idlTypeIncludesDictionary)(this.idlType, defs) || {}; 2255 if (reference) { 2256 const targetToken = (this.idlType.union ? reference : this.idlType) 2257 .tokens.base; 2258 const message = "Attributes cannot accept dictionary types."; 2259 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)( 2260 targetToken, 2261 this, 2262 "attr-invalid-type", 2263 message 2264 ); 2265 } 2266 } 2267 } 2268 } 2269 2270 /** @param {import("../writer.js").Writer} w */ 2271 write(w) { 2272 const { parent } = this; 2273 return w.ts.definition( 2274 w.ts.wrap([ 2275 this.extAttrs.write(w), 2276 w.token(this.tokens.special), 2277 w.token(this.tokens.readonly), 2278 w.token(this.tokens.base), 2279 w.ts.type(this.idlType.write(w)), 2280 w.name_token(this.tokens.name, { data: this, parent }), 2281 w.token(this.tokens.termination), 2282 ]), 2283 { data: this, parent } 2284 ); 2285 } 2286} 2287 2288 2289/***/ }), 2290/* 15 */ 2291/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 2292 2293__webpack_require__.r(__webpack_exports__); 2294/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2295/* harmony export */ "Enum": () => (/* binding */ Enum), 2296/* harmony export */ "EnumValue": () => (/* binding */ EnumValue) 2297/* harmony export */ }); 2298/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); 2299/* harmony import */ var _token_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10); 2300/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6); 2301 2302 2303 2304 2305class EnumValue extends _token_js__WEBPACK_IMPORTED_MODULE_1__.WrappedToken { 2306 /** 2307 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2308 */ 2309 static parse(tokeniser) { 2310 const value = tokeniser.consumeKind("string"); 2311 if (value) { 2312 return new EnumValue({ source: tokeniser.source, tokens: { value } }); 2313 } 2314 } 2315 2316 get type() { 2317 return "enum-value"; 2318 } 2319 get value() { 2320 return super.value.slice(1, -1); 2321 } 2322 2323 /** @param {import("../writer.js").Writer} w */ 2324 write(w) { 2325 const { parent } = this; 2326 return w.ts.wrap([ 2327 w.ts.trivia(this.tokens.value.trivia), 2328 w.ts.definition( 2329 w.ts.wrap(['"', w.ts.name(this.value, { data: this, parent }), '"']), 2330 { data: this, parent } 2331 ), 2332 w.token(this.tokens.separator), 2333 ]); 2334 } 2335} 2336 2337class Enum extends _base_js__WEBPACK_IMPORTED_MODULE_2__.Base { 2338 /** 2339 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2340 */ 2341 static parse(tokeniser) { 2342 /** @type {Base["tokens"]} */ 2343 const tokens = {}; 2344 tokens.base = tokeniser.consume("enum"); 2345 if (!tokens.base) { 2346 return; 2347 } 2348 tokens.name = 2349 tokeniser.consumeKind("identifier") || 2350 tokeniser.error("No name for enum"); 2351 const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.autoParenter)(new Enum({ source: tokeniser.source, tokens })); 2352 tokeniser.current = ret.this; 2353 tokens.open = tokeniser.consume("{") || tokeniser.error("Bodyless enum"); 2354 ret.values = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.list)(tokeniser, { 2355 parser: EnumValue.parse, 2356 allowDangler: true, 2357 listName: "enumeration", 2358 }); 2359 if (tokeniser.probeKind("string")) { 2360 tokeniser.error("No comma between enum values"); 2361 } 2362 tokens.close = 2363 tokeniser.consume("}") || tokeniser.error("Unexpected value in enum"); 2364 if (!ret.values.length) { 2365 tokeniser.error("No value in enum"); 2366 } 2367 tokens.termination = 2368 tokeniser.consume(";") || tokeniser.error("No semicolon after enum"); 2369 return ret.this; 2370 } 2371 2372 get type() { 2373 return "enum"; 2374 } 2375 get name() { 2376 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.unescape)(this.tokens.name.value); 2377 } 2378 2379 /** @param {import("../writer.js").Writer} w */ 2380 write(w) { 2381 return w.ts.definition( 2382 w.ts.wrap([ 2383 this.extAttrs.write(w), 2384 w.token(this.tokens.base), 2385 w.name_token(this.tokens.name, { data: this }), 2386 w.token(this.tokens.open), 2387 w.ts.wrap(this.values.map((v) => v.write(w))), 2388 w.token(this.tokens.close), 2389 w.token(this.tokens.termination), 2390 ]), 2391 { data: this } 2392 ); 2393 } 2394} 2395 2396 2397/***/ }), 2398/* 16 */ 2399/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 2400 2401__webpack_require__.r(__webpack_exports__); 2402/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2403/* harmony export */ "Includes": () => (/* binding */ Includes) 2404/* harmony export */ }); 2405/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 2406/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); 2407 2408 2409 2410class Includes extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 2411 /** 2412 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2413 */ 2414 static parse(tokeniser) { 2415 const target = tokeniser.consumeKind("identifier"); 2416 if (!target) { 2417 return; 2418 } 2419 const tokens = { target }; 2420 tokens.includes = tokeniser.consume("includes"); 2421 if (!tokens.includes) { 2422 tokeniser.unconsume(target.index); 2423 return; 2424 } 2425 tokens.mixin = 2426 tokeniser.consumeKind("identifier") || 2427 tokeniser.error("Incomplete includes statement"); 2428 tokens.termination = 2429 tokeniser.consume(";") || 2430 tokeniser.error("No terminating ; for includes statement"); 2431 return new Includes({ source: tokeniser.source, tokens }); 2432 } 2433 2434 get type() { 2435 return "includes"; 2436 } 2437 get target() { 2438 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.target.value); 2439 } 2440 get includes() { 2441 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.mixin.value); 2442 } 2443 2444 /** @param {import("../writer.js").Writer} w */ 2445 write(w) { 2446 return w.ts.definition( 2447 w.ts.wrap([ 2448 this.extAttrs.write(w), 2449 w.reference_token(this.tokens.target, this), 2450 w.token(this.tokens.includes), 2451 w.reference_token(this.tokens.mixin, this), 2452 w.token(this.tokens.termination), 2453 ]), 2454 { data: this } 2455 ); 2456 } 2457} 2458 2459 2460/***/ }), 2461/* 17 */ 2462/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 2463 2464__webpack_require__.r(__webpack_exports__); 2465/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2466/* harmony export */ "Typedef": () => (/* binding */ Typedef) 2467/* harmony export */ }); 2468/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 2469/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); 2470 2471 2472 2473class Typedef extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 2474 /** 2475 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2476 */ 2477 static parse(tokeniser) { 2478 /** @type {Base["tokens"]} */ 2479 const tokens = {}; 2480 const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(new Typedef({ source: tokeniser.source, tokens })); 2481 tokens.base = tokeniser.consume("typedef"); 2482 if (!tokens.base) { 2483 return; 2484 } 2485 ret.idlType = 2486 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser, "typedef-type") || 2487 tokeniser.error("Typedef lacks a type"); 2488 tokens.name = 2489 tokeniser.consumeKind("identifier") || 2490 tokeniser.error("Typedef lacks a name"); 2491 tokeniser.current = ret.this; 2492 tokens.termination = 2493 tokeniser.consume(";") || 2494 tokeniser.error("Unterminated typedef, expected `;`"); 2495 return ret.this; 2496 } 2497 2498 get type() { 2499 return "typedef"; 2500 } 2501 get name() { 2502 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.name.value); 2503 } 2504 2505 *validate(defs) { 2506 yield* this.idlType.validate(defs); 2507 } 2508 2509 /** @param {import("../writer.js").Writer} w */ 2510 write(w) { 2511 return w.ts.definition( 2512 w.ts.wrap([ 2513 this.extAttrs.write(w), 2514 w.token(this.tokens.base), 2515 w.ts.type(this.idlType.write(w)), 2516 w.name_token(this.tokens.name, { data: this }), 2517 w.token(this.tokens.termination), 2518 ]), 2519 { data: this } 2520 ); 2521 } 2522} 2523 2524 2525/***/ }), 2526/* 18 */ 2527/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 2528 2529__webpack_require__.r(__webpack_exports__); 2530/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2531/* harmony export */ "CallbackFunction": () => (/* binding */ CallbackFunction) 2532/* harmony export */ }); 2533/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 2534/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); 2535 2536 2537 2538class CallbackFunction extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 2539 /** 2540 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2541 */ 2542 static parse(tokeniser, base) { 2543 const tokens = { base }; 2544 const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)( 2545 new CallbackFunction({ source: tokeniser.source, tokens }) 2546 ); 2547 tokens.name = 2548 tokeniser.consumeKind("identifier") || 2549 tokeniser.error("Callback lacks a name"); 2550 tokeniser.current = ret.this; 2551 tokens.assign = 2552 tokeniser.consume("=") || tokeniser.error("Callback lacks an assignment"); 2553 ret.idlType = 2554 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.return_type)(tokeniser) || tokeniser.error("Callback lacks a return type"); 2555 tokens.open = 2556 tokeniser.consume("(") || 2557 tokeniser.error("Callback lacks parentheses for arguments"); 2558 ret.arguments = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.argument_list)(tokeniser); 2559 tokens.close = 2560 tokeniser.consume(")") || tokeniser.error("Unterminated callback"); 2561 tokens.termination = 2562 tokeniser.consume(";") || 2563 tokeniser.error("Unterminated callback, expected `;`"); 2564 return ret.this; 2565 } 2566 2567 get type() { 2568 return "callback"; 2569 } 2570 get name() { 2571 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.name.value); 2572 } 2573 2574 *validate(defs) { 2575 yield* this.extAttrs.validate(defs); 2576 yield* this.idlType.validate(defs); 2577 } 2578 2579 /** @param {import("../writer.js").Writer} w */ 2580 write(w) { 2581 return w.ts.definition( 2582 w.ts.wrap([ 2583 this.extAttrs.write(w), 2584 w.token(this.tokens.base), 2585 w.name_token(this.tokens.name, { data: this }), 2586 w.token(this.tokens.assign), 2587 w.ts.type(this.idlType.write(w)), 2588 w.token(this.tokens.open), 2589 ...this.arguments.map((arg) => arg.write(w)), 2590 w.token(this.tokens.close), 2591 w.token(this.tokens.termination), 2592 ]), 2593 { data: this } 2594 ); 2595 } 2596} 2597 2598 2599/***/ }), 2600/* 19 */ 2601/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 2602 2603__webpack_require__.r(__webpack_exports__); 2604/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2605/* harmony export */ "Interface": () => (/* binding */ Interface) 2606/* harmony export */ }); 2607/* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20); 2608/* harmony import */ var _attribute_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14); 2609/* harmony import */ var _operation_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13); 2610/* harmony import */ var _constant_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(21); 2611/* harmony import */ var _iterable_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(22); 2612/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(4); 2613/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(3); 2614/* harmony import */ var _validators_interface_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(23); 2615/* harmony import */ var _constructor_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(24); 2616/* harmony import */ var _tokeniser_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2); 2617/* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(8); 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630/** 2631 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2632 */ 2633function static_member(tokeniser) { 2634 const special = tokeniser.consume("static"); 2635 if (!special) return; 2636 const member = 2637 _attribute_js__WEBPACK_IMPORTED_MODULE_1__.Attribute.parse(tokeniser, { special }) || 2638 _operation_js__WEBPACK_IMPORTED_MODULE_2__.Operation.parse(tokeniser, { special }) || 2639 tokeniser.error("No body in static member"); 2640 return member; 2641} 2642 2643class Interface extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { 2644 /** 2645 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2646 */ 2647 static parse(tokeniser, base, { partial = null } = {}) { 2648 const tokens = { partial, base }; 2649 return _container_js__WEBPACK_IMPORTED_MODULE_0__.Container.parse( 2650 tokeniser, 2651 new Interface({ source: tokeniser.source, tokens }), 2652 { 2653 inheritable: !partial, 2654 allowedMembers: [ 2655 [_constant_js__WEBPACK_IMPORTED_MODULE_3__.Constant.parse], 2656 [_constructor_js__WEBPACK_IMPORTED_MODULE_8__.Constructor.parse], 2657 [static_member], 2658 [_helpers_js__WEBPACK_IMPORTED_MODULE_5__.stringifier], 2659 [_iterable_js__WEBPACK_IMPORTED_MODULE_4__.IterableLike.parse], 2660 [_attribute_js__WEBPACK_IMPORTED_MODULE_1__.Attribute.parse], 2661 [_operation_js__WEBPACK_IMPORTED_MODULE_2__.Operation.parse], 2662 ], 2663 } 2664 ); 2665 } 2666 2667 get type() { 2668 return "interface"; 2669 } 2670 2671 *validate(defs) { 2672 yield* this.extAttrs.validate(defs); 2673 if ( 2674 !this.partial && 2675 this.extAttrs.every((extAttr) => extAttr.name !== "Exposed") 2676 ) { 2677 const message = `Interfaces must have \`[Exposed]\` extended attribute. \ 2678To fix, add, for example, \`[Exposed=Window]\`. Please also consider carefully \ 2679if your interface should also be exposed in a Worker scope. Refer to the \ 2680[WebIDL spec section on Exposed](https://heycam.github.io/webidl/#Exposed) \ 2681for more information.`; 2682 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_6__.validationError)( 2683 this.tokens.name, 2684 this, 2685 "require-exposed", 2686 message, 2687 { 2688 autofix: (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.autofixAddExposedWindow)(this), 2689 } 2690 ); 2691 } 2692 const oldConstructors = this.extAttrs.filter( 2693 (extAttr) => extAttr.name === "Constructor" 2694 ); 2695 for (const constructor of oldConstructors) { 2696 const message = `Constructors should now be represented as a \`constructor()\` operation on the interface \ 2697instead of \`[Constructor]\` extended attribute. Refer to the \ 2698[WebIDL spec section on constructor operations](https://heycam.github.io/webidl/#idl-constructors) \ 2699for more information.`; 2700 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_6__.validationError)( 2701 constructor.tokens.name, 2702 this, 2703 "constructor-member", 2704 message, 2705 { 2706 autofix: autofixConstructor(this, constructor), 2707 } 2708 ); 2709 } 2710 2711 const isGlobal = this.extAttrs.some((extAttr) => extAttr.name === "Global"); 2712 if (isGlobal) { 2713 const factoryFunctions = this.extAttrs.filter( 2714 (extAttr) => extAttr.name === "LegacyFactoryFunction" 2715 ); 2716 for (const named of factoryFunctions) { 2717 const message = `Interfaces marked as \`[Global]\` cannot have factory functions.`; 2718 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_6__.validationError)( 2719 named.tokens.name, 2720 this, 2721 "no-constructible-global", 2722 message 2723 ); 2724 } 2725 2726 const constructors = this.members.filter( 2727 (member) => member.type === "constructor" 2728 ); 2729 for (const named of constructors) { 2730 const message = `Interfaces marked as \`[Global]\` cannot have constructors.`; 2731 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_6__.validationError)( 2732 named.tokens.base, 2733 this, 2734 "no-constructible-global", 2735 message 2736 ); 2737 } 2738 } 2739 2740 yield* super.validate(defs); 2741 if (!this.partial) { 2742 yield* (0,_validators_interface_js__WEBPACK_IMPORTED_MODULE_7__.checkInterfaceMemberDuplication)(defs, this); 2743 } 2744 } 2745} 2746 2747function autofixConstructor(interfaceDef, constructorExtAttr) { 2748 interfaceDef = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.autoParenter)(interfaceDef); 2749 return () => { 2750 const indentation = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getLastIndentation)( 2751 interfaceDef.extAttrs.tokens.open.trivia 2752 ); 2753 const memberIndent = interfaceDef.members.length 2754 ? (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getLastIndentation)((0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getFirstToken)(interfaceDef.members[0]).trivia) 2755 : (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.getMemberIndentation)(indentation); 2756 const constructorOp = _constructor_js__WEBPACK_IMPORTED_MODULE_8__.Constructor.parse( 2757 new _tokeniser_js__WEBPACK_IMPORTED_MODULE_9__.Tokeniser(`\n${memberIndent}constructor();`) 2758 ); 2759 constructorOp.extAttrs = new _extended_attributes_js__WEBPACK_IMPORTED_MODULE_10__.ExtendedAttributes({ 2760 source: interfaceDef.source, 2761 tokens: {}, 2762 }); 2763 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.autoParenter)(constructorOp).arguments = constructorExtAttr.arguments; 2764 2765 const existingIndex = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_5__.findLastIndex)( 2766 interfaceDef.members, 2767 (m) => m.type === "constructor" 2768 ); 2769 interfaceDef.members.splice(existingIndex + 1, 0, constructorOp); 2770 2771 const { close } = interfaceDef.tokens; 2772 if (!close.trivia.includes("\n")) { 2773 close.trivia += `\n${indentation}`; 2774 } 2775 2776 const { extAttrs } = interfaceDef; 2777 const index = extAttrs.indexOf(constructorExtAttr); 2778 const removed = extAttrs.splice(index, 1); 2779 if (!extAttrs.length) { 2780 extAttrs.tokens.open = extAttrs.tokens.close = undefined; 2781 } else if (extAttrs.length === index) { 2782 extAttrs[index - 1].tokens.separator = undefined; 2783 } else if (!extAttrs[index].tokens.name.trivia.trim()) { 2784 extAttrs[index].tokens.name.trivia = removed[0].tokens.name.trivia; 2785 } 2786 }; 2787} 2788 2789 2790/***/ }), 2791/* 20 */ 2792/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 2793 2794__webpack_require__.r(__webpack_exports__); 2795/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2796/* harmony export */ "Container": () => (/* binding */ Container) 2797/* harmony export */ }); 2798/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 2799/* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8); 2800/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); 2801 2802 2803 2804 2805/** 2806 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2807 */ 2808function inheritance(tokeniser) { 2809 const colon = tokeniser.consume(":"); 2810 if (!colon) { 2811 return {}; 2812 } 2813 const inheritance = 2814 tokeniser.consumeKind("identifier") || 2815 tokeniser.error("Inheritance lacks a type"); 2816 return { colon, inheritance }; 2817} 2818 2819class Container extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 2820 /** 2821 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2822 * @param {*} instance TODO: This should be {T extends Container}, but see https://github.com/microsoft/TypeScript/issues/4628 2823 * @param {*} args 2824 */ 2825 static parse(tokeniser, instance, { inheritable, allowedMembers }) { 2826 const { tokens, type } = instance; 2827 tokens.name = 2828 tokeniser.consumeKind("identifier") || 2829 tokeniser.error(`Missing name in ${type}`); 2830 tokeniser.current = instance; 2831 instance = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.autoParenter)(instance); 2832 if (inheritable) { 2833 Object.assign(tokens, inheritance(tokeniser)); 2834 } 2835 tokens.open = tokeniser.consume("{") || tokeniser.error(`Bodyless ${type}`); 2836 instance.members = []; 2837 while (true) { 2838 tokens.close = tokeniser.consume("}"); 2839 if (tokens.close) { 2840 tokens.termination = 2841 tokeniser.consume(";") || 2842 tokeniser.error(`Missing semicolon after ${type}`); 2843 return instance.this; 2844 } 2845 const ea = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_1__.ExtendedAttributes.parse(tokeniser); 2846 let mem; 2847 for (const [parser, ...args] of allowedMembers) { 2848 mem = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.autoParenter)(parser(tokeniser, ...args)); 2849 if (mem) { 2850 break; 2851 } 2852 } 2853 if (!mem) { 2854 tokeniser.error("Unknown member"); 2855 } 2856 mem.extAttrs = ea; 2857 instance.members.push(mem.this); 2858 } 2859 } 2860 2861 get partial() { 2862 return !!this.tokens.partial; 2863 } 2864 get name() { 2865 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.unescape)(this.tokens.name.value); 2866 } 2867 get inheritance() { 2868 if (!this.tokens.inheritance) { 2869 return null; 2870 } 2871 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.unescape)(this.tokens.inheritance.value); 2872 } 2873 2874 *validate(defs) { 2875 for (const member of this.members) { 2876 if (member.validate) { 2877 yield* member.validate(defs); 2878 } 2879 } 2880 } 2881 2882 /** @param {import("../writer.js").Writer} w */ 2883 write(w) { 2884 const inheritance = () => { 2885 if (!this.tokens.inheritance) { 2886 return ""; 2887 } 2888 return w.ts.wrap([ 2889 w.token(this.tokens.colon), 2890 w.ts.trivia(this.tokens.inheritance.trivia), 2891 w.ts.inheritance( 2892 w.reference(this.tokens.inheritance.value, { context: this }) 2893 ), 2894 ]); 2895 }; 2896 2897 return w.ts.definition( 2898 w.ts.wrap([ 2899 this.extAttrs.write(w), 2900 w.token(this.tokens.callback), 2901 w.token(this.tokens.partial), 2902 w.token(this.tokens.base), 2903 w.token(this.tokens.mixin), 2904 w.name_token(this.tokens.name, { data: this }), 2905 inheritance(), 2906 w.token(this.tokens.open), 2907 w.ts.wrap(this.members.map((m) => m.write(w))), 2908 w.token(this.tokens.close), 2909 w.token(this.tokens.termination), 2910 ]), 2911 { data: this } 2912 ); 2913 } 2914} 2915 2916 2917/***/ }), 2918/* 21 */ 2919/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 2920 2921__webpack_require__.r(__webpack_exports__); 2922/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2923/* harmony export */ "Constant": () => (/* binding */ Constant) 2924/* harmony export */ }); 2925/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 2926/* harmony import */ var _type_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5); 2927/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); 2928 2929 2930 2931 2932class Constant extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 2933 /** 2934 * @param {import("../tokeniser.js").Tokeniser} tokeniser 2935 */ 2936 static parse(tokeniser) { 2937 /** @type {Base["tokens"]} */ 2938 const tokens = {}; 2939 tokens.base = tokeniser.consume("const"); 2940 if (!tokens.base) { 2941 return; 2942 } 2943 let idlType = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.primitive_type)(tokeniser); 2944 if (!idlType) { 2945 const base = 2946 tokeniser.consumeKind("identifier") || 2947 tokeniser.error("Const lacks a type"); 2948 idlType = new _type_js__WEBPACK_IMPORTED_MODULE_1__.Type({ source: tokeniser.source, tokens: { base } }); 2949 } 2950 if (tokeniser.probe("?")) { 2951 tokeniser.error("Unexpected nullable constant type"); 2952 } 2953 idlType.type = "const-type"; 2954 tokens.name = 2955 tokeniser.consumeKind("identifier") || 2956 tokeniser.error("Const lacks a name"); 2957 tokens.assign = 2958 tokeniser.consume("=") || tokeniser.error("Const lacks value assignment"); 2959 tokens.value = 2960 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.const_value)(tokeniser) || tokeniser.error("Const lacks a value"); 2961 tokens.termination = 2962 tokeniser.consume(";") || 2963 tokeniser.error("Unterminated const, expected `;`"); 2964 const ret = new Constant({ source: tokeniser.source, tokens }); 2965 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.autoParenter)(ret).idlType = idlType; 2966 return ret; 2967 } 2968 2969 get type() { 2970 return "const"; 2971 } 2972 get name() { 2973 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.unescape)(this.tokens.name.value); 2974 } 2975 get value() { 2976 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_2__.const_data)(this.tokens.value); 2977 } 2978 2979 /** @param {import("../writer.js").Writer} w */ 2980 write(w) { 2981 const { parent } = this; 2982 return w.ts.definition( 2983 w.ts.wrap([ 2984 this.extAttrs.write(w), 2985 w.token(this.tokens.base), 2986 w.ts.type(this.idlType.write(w)), 2987 w.name_token(this.tokens.name, { data: this, parent }), 2988 w.token(this.tokens.assign), 2989 w.token(this.tokens.value), 2990 w.token(this.tokens.termination), 2991 ]), 2992 { data: this, parent } 2993 ); 2994 } 2995} 2996 2997 2998/***/ }), 2999/* 22 */ 3000/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3001 3002__webpack_require__.r(__webpack_exports__); 3003/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3004/* harmony export */ "IterableLike": () => (/* binding */ IterableLike) 3005/* harmony export */ }); 3006/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 3007/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); 3008 3009 3010 3011class IterableLike extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 3012 /** 3013 * @param {import("../tokeniser.js").Tokeniser} tokeniser 3014 */ 3015 static parse(tokeniser) { 3016 const start_position = tokeniser.position; 3017 const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)( 3018 new IterableLike({ source: tokeniser.source, tokens: {} }) 3019 ); 3020 const { tokens } = ret; 3021 tokens.readonly = tokeniser.consume("readonly"); 3022 if (!tokens.readonly) { 3023 tokens.async = tokeniser.consume("async"); 3024 } 3025 tokens.base = tokens.readonly 3026 ? tokeniser.consume("maplike", "setlike") 3027 : tokens.async 3028 ? tokeniser.consume("iterable") 3029 : tokeniser.consume("iterable", "maplike", "setlike"); 3030 if (!tokens.base) { 3031 tokeniser.unconsume(start_position); 3032 return; 3033 } 3034 3035 const { type } = ret; 3036 const secondTypeRequired = type === "maplike"; 3037 const secondTypeAllowed = secondTypeRequired || type === "iterable"; 3038 const argumentAllowed = ret.async && type === "iterable"; 3039 3040 tokens.open = 3041 tokeniser.consume("<") || 3042 tokeniser.error(`Missing less-than sign \`<\` in ${type} declaration`); 3043 const first = 3044 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser) || 3045 tokeniser.error(`Missing a type argument in ${type} declaration`); 3046 ret.idlType = [first]; 3047 ret.arguments = []; 3048 3049 if (secondTypeAllowed) { 3050 first.tokens.separator = tokeniser.consume(","); 3051 if (first.tokens.separator) { 3052 ret.idlType.push((0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser)); 3053 } else if (secondTypeRequired) { 3054 tokeniser.error(`Missing second type argument in ${type} declaration`); 3055 } 3056 } 3057 3058 tokens.close = 3059 tokeniser.consume(">") || 3060 tokeniser.error(`Missing greater-than sign \`>\` in ${type} declaration`); 3061 3062 if (tokeniser.probe("(")) { 3063 if (argumentAllowed) { 3064 tokens.argsOpen = tokeniser.consume("("); 3065 ret.arguments.push(...(0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.argument_list)(tokeniser)); 3066 tokens.argsClose = 3067 tokeniser.consume(")") || 3068 tokeniser.error("Unterminated async iterable argument list"); 3069 } else { 3070 tokeniser.error(`Arguments are only allowed for \`async iterable\``); 3071 } 3072 } 3073 3074 tokens.termination = 3075 tokeniser.consume(";") || 3076 tokeniser.error(`Missing semicolon after ${type} declaration`); 3077 3078 return ret.this; 3079 } 3080 3081 get type() { 3082 return this.tokens.base.value; 3083 } 3084 get readonly() { 3085 return !!this.tokens.readonly; 3086 } 3087 get async() { 3088 return !!this.tokens.async; 3089 } 3090 3091 *validate(defs) { 3092 for (const type of this.idlType) { 3093 yield* type.validate(defs); 3094 } 3095 for (const argument of this.arguments) { 3096 yield* argument.validate(defs); 3097 } 3098 } 3099 3100 /** @param {import("../writer.js").Writer} w */ 3101 write(w) { 3102 return w.ts.definition( 3103 w.ts.wrap([ 3104 this.extAttrs.write(w), 3105 w.token(this.tokens.readonly), 3106 w.token(this.tokens.async), 3107 w.token(this.tokens.base, w.ts.generic), 3108 w.token(this.tokens.open), 3109 w.ts.wrap(this.idlType.map((t) => t.write(w))), 3110 w.token(this.tokens.close), 3111 w.token(this.tokens.argsOpen), 3112 w.ts.wrap(this.arguments.map((arg) => arg.write(w))), 3113 w.token(this.tokens.argsClose), 3114 w.token(this.tokens.termination), 3115 ]), 3116 { data: this, parent: this.parent } 3117 ); 3118 } 3119} 3120 3121 3122/***/ }), 3123/* 23 */ 3124/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3125 3126__webpack_require__.r(__webpack_exports__); 3127/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3128/* harmony export */ "checkInterfaceMemberDuplication": () => (/* binding */ checkInterfaceMemberDuplication) 3129/* harmony export */ }); 3130/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); 3131 3132 3133/** 3134 * @param {import("../validator.js").Definitions} defs 3135 * @param {import("../productions/container.js").Container} i 3136 */ 3137function* checkInterfaceMemberDuplication(defs, i) { 3138 const opNames = groupOperationNames(i); 3139 const partials = defs.partials.get(i.name) || []; 3140 const mixins = defs.mixinMap.get(i.name) || []; 3141 for (const ext of [...partials, ...mixins]) { 3142 const additions = getOperations(ext); 3143 const statics = additions.filter((a) => a.special === "static"); 3144 const nonstatics = additions.filter((a) => a.special !== "static"); 3145 yield* checkAdditions(statics, opNames.statics, ext, i); 3146 yield* checkAdditions(nonstatics, opNames.nonstatics, ext, i); 3147 statics.forEach((op) => opNames.statics.add(op.name)); 3148 nonstatics.forEach((op) => opNames.nonstatics.add(op.name)); 3149 } 3150 3151 /** 3152 * @param {import("../productions/operation.js").Operation[]} additions 3153 * @param {Set<string>} existings 3154 * @param {import("../productions/container.js").Container} ext 3155 * @param {import("../productions/container.js").Container} base 3156 */ 3157 function* checkAdditions(additions, existings, ext, base) { 3158 for (const addition of additions) { 3159 const { name } = addition; 3160 if (name && existings.has(name)) { 3161 const isStatic = addition.special === "static" ? "static " : ""; 3162 const message = `The ${isStatic}operation "${name}" has already been defined for the base interface "${base.name}" either in itself or in a mixin`; 3163 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)( 3164 addition.tokens.name, 3165 ext, 3166 "no-cross-overload", 3167 message 3168 ); 3169 } 3170 } 3171 } 3172 3173 /** 3174 * @param {import("../productions/container.js").Container} i 3175 * @returns {import("../productions/operation.js").Operation[]} 3176 */ 3177 function getOperations(i) { 3178 return i.members.filter(({ type }) => type === "operation"); 3179 } 3180 3181 /** 3182 * @param {import("../productions/container.js").Container} i 3183 */ 3184 function groupOperationNames(i) { 3185 const ops = getOperations(i); 3186 return { 3187 statics: new Set( 3188 ops.filter((op) => op.special === "static").map((op) => op.name) 3189 ), 3190 nonstatics: new Set( 3191 ops.filter((op) => op.special !== "static").map((op) => op.name) 3192 ), 3193 }; 3194 } 3195} 3196 3197 3198/***/ }), 3199/* 24 */ 3200/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3201 3202__webpack_require__.r(__webpack_exports__); 3203/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3204/* harmony export */ "Constructor": () => (/* binding */ Constructor) 3205/* harmony export */ }); 3206/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 3207/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); 3208 3209 3210 3211class Constructor extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 3212 /** 3213 * @param {import("../tokeniser.js").Tokeniser} tokeniser 3214 */ 3215 static parse(tokeniser) { 3216 const base = tokeniser.consume("constructor"); 3217 if (!base) { 3218 return; 3219 } 3220 /** @type {Base["tokens"]} */ 3221 const tokens = { base }; 3222 tokens.open = 3223 tokeniser.consume("(") || 3224 tokeniser.error("No argument list in constructor"); 3225 const args = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.argument_list)(tokeniser); 3226 tokens.close = 3227 tokeniser.consume(")") || tokeniser.error("Unterminated constructor"); 3228 tokens.termination = 3229 tokeniser.consume(";") || 3230 tokeniser.error("No semicolon after constructor"); 3231 const ret = new Constructor({ source: tokeniser.source, tokens }); 3232 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(ret).arguments = args; 3233 return ret; 3234 } 3235 3236 get type() { 3237 return "constructor"; 3238 } 3239 3240 *validate(defs) { 3241 for (const argument of this.arguments) { 3242 yield* argument.validate(defs); 3243 } 3244 } 3245 3246 /** @param {import("../writer.js").Writer} w */ 3247 write(w) { 3248 const { parent } = this; 3249 return w.ts.definition( 3250 w.ts.wrap([ 3251 this.extAttrs.write(w), 3252 w.token(this.tokens.base, w.ts.nameless, { data: this, parent }), 3253 w.token(this.tokens.open), 3254 w.ts.wrap(this.arguments.map((arg) => arg.write(w))), 3255 w.token(this.tokens.close), 3256 w.token(this.tokens.termination), 3257 ]), 3258 { data: this, parent } 3259 ); 3260 } 3261} 3262 3263 3264/***/ }), 3265/* 25 */ 3266/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3267 3268__webpack_require__.r(__webpack_exports__); 3269/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3270/* harmony export */ "Mixin": () => (/* binding */ Mixin) 3271/* harmony export */ }); 3272/* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20); 3273/* harmony import */ var _constant_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(21); 3274/* harmony import */ var _attribute_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14); 3275/* harmony import */ var _operation_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(13); 3276/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4); 3277 3278 3279 3280 3281 3282 3283class Mixin extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { 3284 /** 3285 * @typedef {import("../tokeniser.js").Token} Token 3286 * 3287 * @param {import("../tokeniser.js").Tokeniser} tokeniser 3288 * @param {Token} base 3289 * @param {object} [options] 3290 * @param {Token} [options.partial] 3291 */ 3292 static parse(tokeniser, base, { partial } = {}) { 3293 const tokens = { partial, base }; 3294 tokens.mixin = tokeniser.consume("mixin"); 3295 if (!tokens.mixin) { 3296 return; 3297 } 3298 return _container_js__WEBPACK_IMPORTED_MODULE_0__.Container.parse( 3299 tokeniser, 3300 new Mixin({ source: tokeniser.source, tokens }), 3301 { 3302 allowedMembers: [ 3303 [_constant_js__WEBPACK_IMPORTED_MODULE_1__.Constant.parse], 3304 [_helpers_js__WEBPACK_IMPORTED_MODULE_4__.stringifier], 3305 [_attribute_js__WEBPACK_IMPORTED_MODULE_2__.Attribute.parse, { noInherit: true }], 3306 [_operation_js__WEBPACK_IMPORTED_MODULE_3__.Operation.parse, { regular: true }], 3307 ], 3308 } 3309 ); 3310 } 3311 3312 get type() { 3313 return "interface mixin"; 3314 } 3315} 3316 3317 3318/***/ }), 3319/* 26 */ 3320/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3321 3322__webpack_require__.r(__webpack_exports__); 3323/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3324/* harmony export */ "Dictionary": () => (/* binding */ Dictionary) 3325/* harmony export */ }); 3326/* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20); 3327/* harmony import */ var _field_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27); 3328 3329 3330 3331class Dictionary extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { 3332 /** 3333 * @param {import("../tokeniser.js").Tokeniser} tokeniser 3334 * @param {object} [options] 3335 * @param {import("../tokeniser.js").Token} [options.partial] 3336 */ 3337 static parse(tokeniser, { partial } = {}) { 3338 const tokens = { partial }; 3339 tokens.base = tokeniser.consume("dictionary"); 3340 if (!tokens.base) { 3341 return; 3342 } 3343 return _container_js__WEBPACK_IMPORTED_MODULE_0__.Container.parse( 3344 tokeniser, 3345 new Dictionary({ source: tokeniser.source, tokens }), 3346 { 3347 inheritable: !partial, 3348 allowedMembers: [[_field_js__WEBPACK_IMPORTED_MODULE_1__.Field.parse]], 3349 } 3350 ); 3351 } 3352 3353 get type() { 3354 return "dictionary"; 3355 } 3356} 3357 3358 3359/***/ }), 3360/* 27 */ 3361/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3362 3363__webpack_require__.r(__webpack_exports__); 3364/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3365/* harmony export */ "Field": () => (/* binding */ Field) 3366/* harmony export */ }); 3367/* harmony import */ var _base_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); 3368/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); 3369/* harmony import */ var _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8); 3370/* harmony import */ var _default_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(12); 3371 3372 3373 3374 3375 3376class Field extends _base_js__WEBPACK_IMPORTED_MODULE_0__.Base { 3377 /** 3378 * @param {import("../tokeniser.js").Tokeniser} tokeniser 3379 */ 3380 static parse(tokeniser) { 3381 /** @type {Base["tokens"]} */ 3382 const tokens = {}; 3383 const ret = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.autoParenter)(new Field({ source: tokeniser.source, tokens })); 3384 ret.extAttrs = _extended_attributes_js__WEBPACK_IMPORTED_MODULE_2__.ExtendedAttributes.parse(tokeniser); 3385 tokens.required = tokeniser.consume("required"); 3386 ret.idlType = 3387 (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.type_with_extended_attributes)(tokeniser, "dictionary-type") || 3388 tokeniser.error("Dictionary member lacks a type"); 3389 tokens.name = 3390 tokeniser.consumeKind("identifier") || 3391 tokeniser.error("Dictionary member lacks a name"); 3392 ret.default = _default_js__WEBPACK_IMPORTED_MODULE_3__.Default.parse(tokeniser); 3393 if (tokens.required && ret.default) 3394 tokeniser.error("Required member must not have a default"); 3395 tokens.termination = 3396 tokeniser.consume(";") || 3397 tokeniser.error("Unterminated dictionary member, expected `;`"); 3398 return ret.this; 3399 } 3400 3401 get type() { 3402 return "field"; 3403 } 3404 get name() { 3405 return (0,_helpers_js__WEBPACK_IMPORTED_MODULE_1__.unescape)(this.tokens.name.value); 3406 } 3407 get required() { 3408 return !!this.tokens.required; 3409 } 3410 3411 *validate(defs) { 3412 yield* this.idlType.validate(defs); 3413 } 3414 3415 /** @param {import("../writer.js").Writer} w */ 3416 write(w) { 3417 const { parent } = this; 3418 return w.ts.definition( 3419 w.ts.wrap([ 3420 this.extAttrs.write(w), 3421 w.token(this.tokens.required), 3422 w.ts.type(this.idlType.write(w)), 3423 w.name_token(this.tokens.name, { data: this, parent }), 3424 this.default ? this.default.write(w) : "", 3425 w.token(this.tokens.termination), 3426 ]), 3427 { data: this, parent } 3428 ); 3429 } 3430} 3431 3432 3433/***/ }), 3434/* 28 */ 3435/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3436 3437__webpack_require__.r(__webpack_exports__); 3438/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3439/* harmony export */ "Namespace": () => (/* binding */ Namespace) 3440/* harmony export */ }); 3441/* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20); 3442/* harmony import */ var _attribute_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14); 3443/* harmony import */ var _operation_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13); 3444/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3); 3445/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4); 3446/* harmony import */ var _constant_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(21); 3447 3448 3449 3450 3451 3452 3453 3454class Namespace extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { 3455 /** 3456 * @param {import("../tokeniser.js").Tokeniser} tokeniser 3457 * @param {object} [options] 3458 * @param {import("../tokeniser.js").Token} [options.partial] 3459 */ 3460 static parse(tokeniser, { partial } = {}) { 3461 const tokens = { partial }; 3462 tokens.base = tokeniser.consume("namespace"); 3463 if (!tokens.base) { 3464 return; 3465 } 3466 return _container_js__WEBPACK_IMPORTED_MODULE_0__.Container.parse( 3467 tokeniser, 3468 new Namespace({ source: tokeniser.source, tokens }), 3469 { 3470 allowedMembers: [ 3471 [_attribute_js__WEBPACK_IMPORTED_MODULE_1__.Attribute.parse, { noInherit: true, readonly: true }], 3472 [_constant_js__WEBPACK_IMPORTED_MODULE_5__.Constant.parse], 3473 [_operation_js__WEBPACK_IMPORTED_MODULE_2__.Operation.parse, { regular: true }], 3474 ], 3475 } 3476 ); 3477 } 3478 3479 get type() { 3480 return "namespace"; 3481 } 3482 3483 *validate(defs) { 3484 if ( 3485 !this.partial && 3486 this.extAttrs.every((extAttr) => extAttr.name !== "Exposed") 3487 ) { 3488 const message = `Namespaces must have [Exposed] extended attribute. \ 3489To fix, add, for example, [Exposed=Window]. Please also consider carefully \ 3490if your namespace should also be exposed in a Worker scope. Refer to the \ 3491[WebIDL spec section on Exposed](https://heycam.github.io/webidl/#Exposed) \ 3492for more information.`; 3493 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_3__.validationError)( 3494 this.tokens.name, 3495 this, 3496 "require-exposed", 3497 message, 3498 { 3499 autofix: (0,_helpers_js__WEBPACK_IMPORTED_MODULE_4__.autofixAddExposedWindow)(this), 3500 } 3501 ); 3502 } 3503 yield* super.validate(defs); 3504 } 3505} 3506 3507 3508/***/ }), 3509/* 29 */ 3510/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3511 3512__webpack_require__.r(__webpack_exports__); 3513/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3514/* harmony export */ "CallbackInterface": () => (/* binding */ CallbackInterface) 3515/* harmony export */ }); 3516/* harmony import */ var _container_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20); 3517/* harmony import */ var _operation_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(13); 3518/* harmony import */ var _constant_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21); 3519 3520 3521 3522 3523class CallbackInterface extends _container_js__WEBPACK_IMPORTED_MODULE_0__.Container { 3524 /** 3525 * @param {import("../tokeniser.js").Tokeniser} tokeniser 3526 */ 3527 static parse(tokeniser, callback, { partial = null } = {}) { 3528 const tokens = { callback }; 3529 tokens.base = tokeniser.consume("interface"); 3530 if (!tokens.base) { 3531 return; 3532 } 3533 return _container_js__WEBPACK_IMPORTED_MODULE_0__.Container.parse( 3534 tokeniser, 3535 new CallbackInterface({ source: tokeniser.source, tokens }), 3536 { 3537 inheritable: !partial, 3538 allowedMembers: [ 3539 [_constant_js__WEBPACK_IMPORTED_MODULE_2__.Constant.parse], 3540 [_operation_js__WEBPACK_IMPORTED_MODULE_1__.Operation.parse, { regular: true }], 3541 ], 3542 } 3543 ); 3544 } 3545 3546 get type() { 3547 return "callback interface"; 3548 } 3549} 3550 3551 3552/***/ }), 3553/* 30 */ 3554/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3555 3556__webpack_require__.r(__webpack_exports__); 3557/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3558/* harmony export */ "Writer": () => (/* binding */ Writer), 3559/* harmony export */ "write": () => (/* binding */ write) 3560/* harmony export */ }); 3561function noop(arg) { 3562 return arg; 3563} 3564 3565const templates = { 3566 wrap: (items) => items.join(""), 3567 trivia: noop, 3568 name: noop, 3569 reference: noop, 3570 type: noop, 3571 generic: noop, 3572 nameless: noop, 3573 inheritance: noop, 3574 definition: noop, 3575 extendedAttribute: noop, 3576 extendedAttributeReference: noop, 3577}; 3578 3579class Writer { 3580 constructor(ts) { 3581 this.ts = Object.assign({}, templates, ts); 3582 } 3583 3584 /** 3585 * @param {string} raw 3586 * @param {object} options 3587 * @param {string} [options.unescaped] 3588 * @param {import("./productions/base.js").Base} [options.context] 3589 * @returns 3590 */ 3591 reference(raw, { unescaped, context }) { 3592 if (!unescaped) { 3593 unescaped = raw.startsWith("_") ? raw.slice(1) : raw; 3594 } 3595 return this.ts.reference(raw, unescaped, context); 3596 } 3597 3598 /** 3599 * @param {import("./tokeniser.js").Token} t 3600 * @param {Function} wrapper 3601 * @param {...any} args 3602 * @returns 3603 */ 3604 token(t, wrapper = noop, ...args) { 3605 if (!t) { 3606 return ""; 3607 } 3608 const value = wrapper(t.value, ...args); 3609 return this.ts.wrap([this.ts.trivia(t.trivia), value]); 3610 } 3611 3612 reference_token(t, context) { 3613 return this.token(t, this.reference.bind(this), { context }); 3614 } 3615 3616 name_token(t, arg) { 3617 return this.token(t, this.ts.name, arg); 3618 } 3619 3620 identifier(id, context) { 3621 return this.ts.wrap([ 3622 this.reference_token(id.tokens.value, context), 3623 this.token(id.tokens.separator), 3624 ]); 3625 } 3626} 3627 3628function write(ast, { templates: ts = templates } = {}) { 3629 ts = Object.assign({}, templates, ts); 3630 3631 const w = new Writer(ts); 3632 3633 return ts.wrap(ast.map((it) => it.write(w))); 3634} 3635 3636 3637/***/ }), 3638/* 31 */ 3639/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 3640 3641__webpack_require__.r(__webpack_exports__); 3642/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3643/* harmony export */ "validate": () => (/* binding */ validate) 3644/* harmony export */ }); 3645/* harmony import */ var _error_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); 3646 3647 3648function getMixinMap(all, unique) { 3649 const map = new Map(); 3650 const includes = all.filter((def) => def.type === "includes"); 3651 for (const include of includes) { 3652 const mixin = unique.get(include.includes); 3653 if (!mixin) { 3654 continue; 3655 } 3656 const array = map.get(include.target); 3657 if (array) { 3658 array.push(mixin); 3659 } else { 3660 map.set(include.target, [mixin]); 3661 } 3662 } 3663 return map; 3664} 3665 3666/** 3667 * @typedef {ReturnType<typeof groupDefinitions>} Definitions 3668 */ 3669function groupDefinitions(all) { 3670 const unique = new Map(); 3671 const duplicates = new Set(); 3672 const partials = new Map(); 3673 for (const def of all) { 3674 if (def.partial) { 3675 const array = partials.get(def.name); 3676 if (array) { 3677 array.push(def); 3678 } else { 3679 partials.set(def.name, [def]); 3680 } 3681 continue; 3682 } 3683 if (!def.name) { 3684 continue; 3685 } 3686 if (!unique.has(def.name)) { 3687 unique.set(def.name, def); 3688 } else { 3689 duplicates.add(def); 3690 } 3691 } 3692 return { 3693 all, 3694 unique, 3695 partials, 3696 duplicates, 3697 mixinMap: getMixinMap(all, unique), 3698 cache: { 3699 typedefIncludesDictionary: new WeakMap(), 3700 dictionaryIncludesRequiredField: new WeakMap(), 3701 }, 3702 }; 3703} 3704 3705function* checkDuplicatedNames({ unique, duplicates }) { 3706 for (const dup of duplicates) { 3707 const { name } = dup; 3708 const message = `The name "${name}" of type "${ 3709 unique.get(name).type 3710 }" was already seen`; 3711 yield (0,_error_js__WEBPACK_IMPORTED_MODULE_0__.validationError)(dup.tokens.name, dup, "no-duplicate", message); 3712 } 3713} 3714 3715function* validateIterable(ast) { 3716 const defs = groupDefinitions(ast); 3717 for (const def of defs.all) { 3718 if (def.validate) { 3719 yield* def.validate(defs); 3720 } 3721 } 3722 yield* checkDuplicatedNames(defs); 3723} 3724 3725// Remove this once all of our support targets expose `.flat()` by default 3726function flatten(array) { 3727 if (array.flat) { 3728 return array.flat(); 3729 } 3730 return [].concat(...array); 3731} 3732 3733/** 3734 * @param {import("./productions/base.js").Base[]} ast 3735 * @return {import("./error.js").WebIDLErrorData[]} validation errors 3736 */ 3737function validate(ast) { 3738 return [...validateIterable(flatten(ast))]; 3739} 3740 3741 3742/***/ }) 3743/******/ ]); 3744/************************************************************************/ 3745/******/ // The module cache 3746/******/ var __webpack_module_cache__ = {}; 3747/******/ 3748/******/ // The require function 3749/******/ function __webpack_require__(moduleId) { 3750/******/ // Check if module is in cache 3751/******/ var cachedModule = __webpack_module_cache__[moduleId]; 3752/******/ if (cachedModule !== undefined) { 3753/******/ return cachedModule.exports; 3754/******/ } 3755/******/ // Create a new module (and put it into the cache) 3756/******/ var module = __webpack_module_cache__[moduleId] = { 3757/******/ // no module.id needed 3758/******/ // no module.loaded needed 3759/******/ exports: {} 3760/******/ }; 3761/******/ 3762/******/ // Execute the module function 3763/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 3764/******/ 3765/******/ // Return the exports of the module 3766/******/ return module.exports; 3767/******/ } 3768/******/ 3769/************************************************************************/ 3770/******/ /* webpack/runtime/define property getters */ 3771/******/ (() => { 3772/******/ // define getter functions for harmony exports 3773/******/ __webpack_require__.d = (exports, definition) => { 3774/******/ for(var key in definition) { 3775/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 3776/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 3777/******/ } 3778/******/ } 3779/******/ }; 3780/******/ })(); 3781/******/ 3782/******/ /* webpack/runtime/hasOwnProperty shorthand */ 3783/******/ (() => { 3784/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 3785/******/ })(); 3786/******/ 3787/******/ /* webpack/runtime/make namespace object */ 3788/******/ (() => { 3789/******/ // define __esModule on exports 3790/******/ __webpack_require__.r = (exports) => { 3791/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 3792/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 3793/******/ } 3794/******/ Object.defineProperty(exports, '__esModule', { value: true }); 3795/******/ }; 3796/******/ })(); 3797/******/ 3798/************************************************************************/ 3799var __webpack_exports__ = {}; 3800// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. 3801(() => { 3802__webpack_require__.r(__webpack_exports__); 3803/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3804/* harmony export */ "WebIDLParseError": () => (/* reexport safe */ _lib_tokeniser_js__WEBPACK_IMPORTED_MODULE_3__.WebIDLParseError), 3805/* harmony export */ "parse": () => (/* reexport safe */ _lib_webidl2_js__WEBPACK_IMPORTED_MODULE_0__.parse), 3806/* harmony export */ "validate": () => (/* reexport safe */ _lib_validator_js__WEBPACK_IMPORTED_MODULE_2__.validate), 3807/* harmony export */ "write": () => (/* reexport safe */ _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__.write) 3808/* harmony export */ }); 3809/* harmony import */ var _lib_webidl2_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); 3810/* harmony import */ var _lib_writer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30); 3811/* harmony import */ var _lib_validator_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(31); 3812/* harmony import */ var _lib_tokeniser_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2); 3813 3814 3815 3816 3817 3818})(); 3819 3820/******/ return __webpack_exports__; 3821/******/ })() 3822; 3823}); 3824//# sourceMappingURL=webidl2.js.map