lexer.js
1 let source, pos, end; 2 let openTokenDepth, 3 templateDepth, 4 lastTokenPos, 5 lastSlashWasDivision, 6 templateStack, 7 templateStackDepth, 8 openTokenPosStack, 9 openClassPosStack, 10 nextBraceIsClass, 11 starExportMap, 12 lastStarExportSpecifier, 13 _exports, 14 reexports; 15 16 function resetState () { 17 openTokenDepth = 0; 18 templateDepth = -1; 19 lastTokenPos = -1; 20 lastSlashWasDivision = false; 21 templateStack = new Array(1024); 22 templateStackDepth = 0; 23 openTokenPosStack = new Array(1024); 24 openClassPosStack = new Array(1024); 25 nextBraceIsClass = false; 26 starExportMap = Object.create(null); 27 lastStarExportSpecifier = null; 28 29 _exports = new Set(); 30 reexports = new Set(); 31 } 32 33 // RequireType 34 const Import = 0; 35 const ExportAssign = 1; 36 const ExportStar = 2; 37 38 const strictReserved = new Set(['implements', 'interface', 'let', 'package', 'private', 'protected', 'public', 'static', 'yield', 'enum']); 39 40 function parseCJS (source, name = '@') { 41 resetState(); 42 try { 43 parseSource(source); 44 } 45 catch (e) { 46 e.message += `\n at ${name}:${source.slice(0, pos).split('\n').length}:${pos - source.lastIndexOf('\n', pos - 1)}`; 47 e.loc = pos; 48 throw e; 49 } 50 const result = { exports: [..._exports], reexports: [...reexports] }; 51 resetState(); 52 return result; 53 } 54 55 function addExport (name) { 56 if (!strictReserved.has(name)) 57 _exports.add(name); 58 } 59 60 function parseSource (cjsSource) { 61 source = cjsSource; 62 pos = -1; 63 end = source.length - 1; 64 let ch = 0; 65 66 // Handle #! 67 if (source.charCodeAt(0) === 35/*#*/ && source.charCodeAt(1) === 33/*!*/) { 68 if (source.length === 2) 69 return true; 70 pos += 2; 71 while (pos++ < end) { 72 ch = source.charCodeAt(pos); 73 if (ch === 10/*\n*/ || ch === 13/*\r*/) 74 break; 75 } 76 } 77 78 while (pos++ < end) { 79 ch = source.charCodeAt(pos); 80 81 if (ch === 32 || ch < 14 && ch > 8) 82 continue; 83 84 if (openTokenDepth === 0) { 85 switch (ch) { 86 case 105/*i*/: 87 if (source.startsWith('mport', pos + 1) && keywordStart(pos)) 88 throwIfImportStatement(); 89 lastTokenPos = pos; 90 continue; 91 case 114/*r*/: 92 const startPos = pos; 93 if (tryParseRequire(Import) && keywordStart(startPos)) 94 tryBacktrackAddStarExportBinding(startPos - 1); 95 lastTokenPos = pos; 96 continue; 97 case 95/*_*/: 98 if (source.startsWith('_export', pos + 1) && (keywordStart(pos) || source.charCodeAt(pos - 1) === 46/*.*/)) { 99 pos += 8; 100 if (source.startsWith('Star', pos)) 101 pos += 4; 102 if (source.charCodeAt(pos) === 40/*(*/) { 103 openTokenPosStack[openTokenDepth++] = lastTokenPos; 104 if (source.charCodeAt(++pos) === 114/*r*/) 105 tryParseRequire(ExportStar); 106 } 107 } 108 lastTokenPos = pos; 109 continue; 110 } 111 } 112 113 switch (ch) { 114 case 101/*e*/: 115 if (source.startsWith('xport', pos + 1) && keywordStart(pos)) { 116 if (source.charCodeAt(pos + 6) === 115/*s*/) 117 tryParseExportsDotAssign(false); 118 else if (openTokenDepth === 0) 119 throwIfExportStatement(); 120 } 121 break; 122 case 99/*c*/: 123 if (keywordStart(pos) && source.startsWith('lass', pos + 1) && isBrOrWs(source.charCodeAt(pos + 5))) 124 nextBraceIsClass = true; 125 break; 126 case 109/*m*/: 127 if (source.startsWith('odule', pos + 1) && keywordStart(pos)) 128 tryParseModuleExportsDotAssign(); 129 break; 130 case 79/*O*/: 131 if (source.startsWith('bject', pos + 1) && keywordStart(pos)) 132 tryParseObjectDefineOrKeys(openTokenDepth === 0); 133 break; 134 case 40/*(*/: 135 openTokenPosStack[openTokenDepth++] = lastTokenPos; 136 break; 137 case 41/*)*/: 138 if (openTokenDepth === 0) 139 throw new Error('Unexpected closing bracket.'); 140 openTokenDepth--; 141 break; 142 case 123/*{*/: 143 openClassPosStack[openTokenDepth] = nextBraceIsClass; 144 nextBraceIsClass = false; 145 openTokenPosStack[openTokenDepth++] = lastTokenPos; 146 break; 147 case 125/*}*/: 148 if (openTokenDepth === 0) 149 throw new Error('Unexpected closing brace.'); 150 if (openTokenDepth-- === templateDepth) { 151 templateDepth = templateStack[--templateStackDepth]; 152 templateString(); 153 } 154 else { 155 if (templateDepth !== -1 && openTokenDepth < templateDepth) 156 throw new Error('Unexpected closing brace.'); 157 } 158 break; 159 case 60/*>*/: 160 // TODO: <!-- XML comment support 161 break; 162 case 39/*'*/: 163 singleQuoteString(); 164 break; 165 case 34/*"*/: 166 doubleQuoteString(); 167 break; 168 case 47/*/*/: { 169 const next_ch = source.charCodeAt(pos + 1); 170 if (next_ch === 47/*/*/) { 171 lineComment(); 172 // dont update lastToken 173 continue; 174 } 175 else if (next_ch === 42/***/) { 176 blockComment(); 177 // dont update lastToken 178 continue; 179 } 180 else { 181 // Division / regex ambiguity handling based on checking backtrack analysis of: 182 // - what token came previously (lastToken) 183 // - if a closing brace or paren, what token came before the corresponding 184 // opening brace or paren (lastOpenTokenIndex) 185 const lastToken = source.charCodeAt(lastTokenPos); 186 if (isExpressionPunctuator(lastToken) && 187 !(lastToken === 46/*.*/ && (source.charCodeAt(lastTokenPos - 1) >= 48/*0*/ && source.charCodeAt(lastTokenPos - 1) <= 57/*9*/)) && 188 !(lastToken === 43/*+*/ && source.charCodeAt(lastTokenPos - 1) === 43/*+*/) && !(lastToken === 45/*-*/ && source.charCodeAt(lastTokenPos - 1) === 45/*-*/) || 189 lastToken === 41/*)*/ && isParenKeyword(openTokenPosStack[openTokenDepth]) || 190 lastToken === 125/*}*/ && (isExpressionTerminator(openTokenPosStack[openTokenDepth]) || openClassPosStack[openTokenDepth]) || 191 lastToken === 47/*/*/ && lastSlashWasDivision || 192 isExpressionKeyword(lastTokenPos) || 193 !lastToken) { 194 regularExpression(); 195 lastSlashWasDivision = false; 196 } 197 else { 198 lastSlashWasDivision = true; 199 } 200 } 201 break; 202 } 203 case 96/*`*/: 204 templateString(); 205 break; 206 } 207 lastTokenPos = pos; 208 } 209 210 if (templateDepth !== -1) 211 throw new Error('Unterminated template.'); 212 213 if (openTokenDepth) 214 throw new Error('Unterminated braces.'); 215 } 216 217 function tryBacktrackAddStarExportBinding (bPos) { 218 while (source.charCodeAt(bPos) === 32/* */ && bPos >= 0) 219 bPos--; 220 if (source.charCodeAt(bPos) === 61/*=*/) { 221 bPos--; 222 while (source.charCodeAt(bPos) === 32/* */ && bPos >= 0) 223 bPos--; 224 let codePoint; 225 const id_end = bPos; 226 let identifierStart = false; 227 while ((codePoint = codePointAtLast(bPos)) && bPos >= 0) { 228 if (codePoint === 92/*\*/) 229 return; 230 if (!isIdentifierChar(codePoint, true)) 231 break; 232 identifierStart = isIdentifierStart(codePoint, true); 233 bPos -= codePointLen(codePoint); 234 } 235 if (identifierStart && source.charCodeAt(bPos) === 32/* */) { 236 const starExportId = source.slice(bPos + 1, id_end + 1); 237 while (source.charCodeAt(bPos) === 32/* */ && bPos >= 0) 238 bPos--; 239 switch (source.charCodeAt(bPos)) { 240 case 114/*r*/: 241 if (!source.startsWith('va', bPos - 2)) 242 return; 243 break; 244 case 116/*t*/: 245 if (!source.startsWith('le', bPos - 2) && !source.startsWith('cons', bPos - 4)) 246 return; 247 break; 248 default: return; 249 } 250 starExportMap[starExportId] = lastStarExportSpecifier; 251 } 252 } 253 } 254 255 function tryParseObjectDefineOrKeys (keys) { 256 pos += 6; 257 let revertPos = pos - 1; 258 let ch = commentWhitespace(); 259 if (ch === 46/*.*/) { 260 pos++; 261 ch = commentWhitespace(); 262 if (ch === 100/*d*/ && source.startsWith('efineProperty', pos + 1)) { 263 while (true) { 264 pos += 14; 265 revertPos = pos - 1; 266 ch = commentWhitespace(); 267 if (ch !== 40/*(*/) break; 268 pos++; 269 ch = commentWhitespace(); 270 if (!readExportsOrModuleDotExports(ch)) break; 271 ch = commentWhitespace(); 272 if (ch !== 44/*,*/) break; 273 pos++; 274 ch = commentWhitespace(); 275 if (ch !== 39/*'*/ && ch !== 34/*"*/) break; 276 let quot = ch; 277 const exportPos = ++pos; 278 if (!identifier() || source.charCodeAt(pos) !== quot) break; 279 const expt = source.slice(exportPos, pos); 280 pos++; 281 ch = commentWhitespace(); 282 if (ch !== 44/*,*/) break; 283 pos++; 284 ch = commentWhitespace(); 285 if (ch !== 123/*{*/) break; 286 pos++; 287 ch = commentWhitespace(); 288 if (ch === 101/*e*/) { 289 if (!source.startsWith('numerable', pos + 1)) break; 290 pos += 10; 291 ch = commentWhitespace(); 292 if (ch !== 58/*:*/) break; 293 pos++; 294 ch = commentWhitespace(); 295 if (ch !== 116/*t*/ || !source.startsWith('rue', pos + 1)) break; 296 pos += 4; 297 ch = commentWhitespace(); 298 if (ch !== 44) break; 299 pos++; 300 ch = commentWhitespace(); 301 } 302 if (ch === 118/*v*/) { 303 if (!source.startsWith('alue', pos + 1)) break; 304 pos += 5; 305 ch = commentWhitespace(); 306 if (ch !== 58/*:*/) break; 307 pos++; 308 addExport(expt); 309 break; 310 } 311 else if (ch === 103/*g*/) { 312 if (!source.startsWith('et', pos + 1)) break; 313 pos += 3; 314 ch = commentWhitespace(); 315 if (ch === 58/*:*/) { 316 pos++; 317 ch = commentWhitespace(); 318 if (ch !== 102/*f*/) break; 319 if (!source.startsWith('unction', pos + 1)) break; 320 pos += 8; 321 let lastPos = pos; 322 ch = commentWhitespace(); 323 if (ch !== 40 && (lastPos === pos || !identifier())) break; 324 ch = commentWhitespace(); 325 } 326 if (ch !== 40/*(*/) break; 327 pos++; 328 ch = commentWhitespace(); 329 if (ch !== 41/*)*/) break; 330 pos++; 331 ch = commentWhitespace(); 332 if (ch !== 123/*{*/) break; 333 pos++; 334 ch = commentWhitespace(); 335 if (ch !== 114/*r*/) break; 336 if (!source.startsWith('eturn', pos + 1)) break; 337 pos += 6; 338 ch = commentWhitespace(); 339 if (!identifier()) break; 340 ch = commentWhitespace(); 341 if (ch === 46/*.*/) { 342 pos++; 343 commentWhitespace(); 344 if (!identifier()) break; 345 ch = commentWhitespace(); 346 } 347 else if (ch === 91/*[*/) { 348 pos++; 349 ch = commentWhitespace(); 350 if (ch === 39/*'*/) singleQuoteString(); 351 else if (ch === 34/*"*/) doubleQuoteString(); 352 else break; 353 pos++; 354 ch = commentWhitespace(); 355 if (ch !== 93/*]*/) break; 356 pos++; 357 ch = commentWhitespace(); 358 } 359 if (ch === 59/*;*/) { 360 pos++; 361 ch = commentWhitespace(); 362 } 363 if (ch !== 125/*}*/) break; 364 pos++; 365 ch = commentWhitespace(); 366 if (ch !== 125/*}*/) break; 367 pos++; 368 ch = commentWhitespace(); 369 if (ch !== 41/*)*/) break; 370 addExport(expt); 371 return; 372 } 373 break; 374 } 375 } 376 else if (keys && ch === 107/*k*/ && source.startsWith('eys', pos + 1)) { 377 while (true) { 378 pos += 4; 379 revertPos = pos - 1; 380 ch = commentWhitespace(); 381 if (ch !== 40/*(*/) break; 382 pos++; 383 ch = commentWhitespace(); 384 const id_start = pos; 385 if (!identifier()) break; 386 const id = source.slice(id_start, pos); 387 ch = commentWhitespace(); 388 if (ch !== 41/*)*/) break; 389 390 revertPos = pos++; 391 ch = commentWhitespace(); 392 if (ch !== 46/*.*/) break; 393 pos++; 394 ch = commentWhitespace(); 395 if (ch !== 102/*f*/ || !source.startsWith('orEach', pos + 1)) break; 396 pos += 7; 397 ch = commentWhitespace(); 398 revertPos = pos - 1; 399 if (ch !== 40/*(*/) break; 400 pos++; 401 ch = commentWhitespace(); 402 if (ch !== 102/*f*/ || !source.startsWith('unction', pos + 1)) break; 403 pos += 8; 404 ch = commentWhitespace(); 405 if (ch !== 40/*(*/) break; 406 pos++; 407 ch = commentWhitespace(); 408 const it_id_start = pos; 409 if (!identifier()) break; 410 const it_id = source.slice(it_id_start, pos); 411 ch = commentWhitespace(); 412 if (ch !== 41/*)*/) break; 413 pos++; 414 ch = commentWhitespace(); 415 if (ch !== 123/*{*/) break; 416 pos++; 417 ch = commentWhitespace(); 418 if (ch !== 105/*i*/ || source.charCodeAt(pos + 1) !== 102/*f*/) break; 419 pos += 2; 420 ch = commentWhitespace(); 421 if (ch !== 40/*(*/) break; 422 pos++; 423 ch = commentWhitespace(); 424 if (!source.startsWith(it_id, pos)) break; 425 pos += it_id.length; 426 ch = commentWhitespace(); 427 // `if (` IDENTIFIER$2 `===` ( `'default'` | `"default"` ) `||` IDENTIFIER$2 `===` ( '__esModule' | `"__esModule"` ) `) return` `;`? | 428 if (ch === 61/*=*/) { 429 if (!source.startsWith('==', pos + 1)) break; 430 pos += 3; 431 ch = commentWhitespace(); 432 if (ch !== 34/*"*/ && ch !== 39/*'*/) break; 433 let quot = ch; 434 if (!source.startsWith('default', pos + 1)) break; 435 pos += 8; 436 ch = commentWhitespace(); 437 if (ch !== quot) break; 438 pos += 1; 439 ch = commentWhitespace(); 440 if (ch !== 124/*|*/ || source.charCodeAt(pos + 1) !== 124/*|*/) break; 441 pos += 2; 442 ch = commentWhitespace(); 443 if (source.slice(pos, pos + it_id.length) !== it_id) break; 444 pos += it_id.length; 445 ch = commentWhitespace(); 446 if (ch !== 61/*=*/ || source.slice(pos + 1, pos + 3) !== '==') break; 447 pos += 3; 448 ch = commentWhitespace(); 449 if (ch !== 34/*"*/ && ch !== 39/*'*/) break; 450 quot = ch; 451 if (!source.startsWith('__esModule', pos + 1)) break; 452 pos += 11; 453 ch = commentWhitespace(); 454 if (ch !== quot) break; 455 pos += 1; 456 ch = commentWhitespace(); 457 if (ch !== 41/*)*/) break; 458 pos += 1; 459 ch = commentWhitespace(); 460 if (ch !== 114/*r*/ || !source.startsWith('eturn', pos + 1)) break; 461 pos += 6; 462 ch = commentWhitespace(); 463 if (ch === 59/*;*/) 464 pos++; 465 ch = commentWhitespace(); 466 } 467 // `if (` IDENTIFIER$2 `!==` ( `'default'` | `"default"` ) `)` 468 else if (ch === 33/*!*/) { 469 if (!source.startsWith('==', pos + 1)) break; 470 pos += 3; 471 ch = commentWhitespace(); 472 if (ch !== 34/*"*/ && ch !== 39/*'*/) break; 473 const quot = ch; 474 if (!source.startsWith('default', pos + 1)) break; 475 pos += 8; 476 ch = commentWhitespace(); 477 if (ch !== quot) break; 478 pos += 1; 479 ch = commentWhitespace(); 480 if (ch !== 41/*)*/) break; 481 pos += 1; 482 ch = commentWhitespace(); 483 } 484 else break; 485 486 // `if (` IDENTIFIER$2 `in` EXPORTS_IDENTIFIER `&&` EXPORTS_IDENTIFIER `[` IDENTIFIER$2 `] ===` IDENTIFIER$1 `[` IDENTIFIER$2 `]) return` `;`? 487 if (ch === 105/*i*/ && source.charCodeAt(pos + 1) === 102/*f*/) { 488 pos += 2; 489 ch = commentWhitespace(); 490 if (ch !== 40/*(*/) break; 491 pos++; 492 ch = commentWhitespace(); 493 if (!source.startsWith(it_id, pos)) break; 494 pos += it_id.length; 495 ch = commentWhitespace(); 496 if (ch !== 105/*i*/ || !source.startsWith('n ', pos + 1)) break; 497 pos += 3; 498 ch = commentWhitespace(); 499 if (!readExportsOrModuleDotExports(ch)) break; 500 ch = commentWhitespace(); 501 if (ch !== 38/*&*/ || source.charCodeAt(pos + 1) !== 38/*&*/) break; 502 pos += 2; 503 ch = commentWhitespace(); 504 if (!readExportsOrModuleDotExports(ch)) break; 505 ch = commentWhitespace(); 506 if (ch !== 91/*[*/) break; 507 pos++; 508 ch = commentWhitespace(); 509 if (!source.startsWith(it_id, pos)) break; 510 pos += it_id.length; 511 ch = commentWhitespace(); 512 if (ch !== 93/*]*/) break; 513 pos++; 514 ch = commentWhitespace(); 515 if (ch !== 61/*=*/ || !source.startsWith('==', pos + 1)) break; 516 pos += 3; 517 ch = commentWhitespace(); 518 if (!source.startsWith(id, pos)) break; 519 pos += id.length; 520 ch = commentWhitespace(); 521 if (ch !== 91/*[*/) break; 522 pos++; 523 ch = commentWhitespace(); 524 if (!source.startsWith(it_id, pos)) break; 525 pos += it_id.length; 526 ch = commentWhitespace(); 527 if (ch !== 93/*]*/) break; 528 pos++; 529 ch = commentWhitespace(); 530 if (ch !== 41/*)*/) break; 531 pos++; 532 ch = commentWhitespace(); 533 if (ch !== 114/*r*/ || !source.startsWith('eturn', pos + 1)) break; 534 pos += 6; 535 ch = commentWhitespace(); 536 if (ch === 59/*;*/) 537 pos++; 538 ch = commentWhitespace(); 539 } 540 541 // EXPORTS_IDENTIFIER `[` IDENTIFIER$2 `] =` IDENTIFIER$1 `[` IDENTIFIER$2 `]` 542 if (readExportsOrModuleDotExports(ch)) { 543 ch = commentWhitespace(); 544 if (ch !== 91/*[*/) break; 545 pos++; 546 ch = commentWhitespace(); 547 if (source.slice(pos, pos + it_id.length) !== it_id) break; 548 pos += it_id.length; 549 ch = commentWhitespace(); 550 if (ch !== 93/*]*/) break; 551 pos++; 552 ch = commentWhitespace(); 553 if (ch !== 61/*=*/) break; 554 pos++; 555 ch = commentWhitespace(); 556 if (source.slice(pos, pos + id.length) !== id) break; 557 pos += id.length; 558 ch = commentWhitespace(); 559 if (ch !== 91/*[*/) break; 560 pos++; 561 ch = commentWhitespace(); 562 if (source.slice(pos, pos + it_id.length) !== it_id) break; 563 pos += it_id.length; 564 ch = commentWhitespace(); 565 if (ch !== 93/*]*/) break; 566 pos++; 567 ch = commentWhitespace(); 568 if (ch === 59/*;*/) { 569 pos++; 570 ch = commentWhitespace(); 571 } 572 } 573 // `Object.defineProperty(` EXPORTS_IDENTIFIER `, ` IDENTIFIER$2 `, { enumerable: true, get: function () { return ` IDENTIFIER$1 `[` IDENTIFIER$2 `]; } })` 574 else if (ch === 79/*O*/) { 575 if (source.slice(pos + 1, pos + 6) !== 'bject') break; 576 pos += 6; 577 ch = commentWhitespace(); 578 if (ch !== 46/*.*/) break; 579 pos++; 580 ch = commentWhitespace(); 581 if (ch !== 100/*d*/ || !source.startsWith('efineProperty', pos + 1)) break; 582 pos += 14; 583 ch = commentWhitespace(); 584 if (ch !== 40/*(*/) break; 585 pos++; 586 ch = commentWhitespace(); 587 if (!readExportsOrModuleDotExports(ch)) break; 588 ch = commentWhitespace(); 589 if (ch !== 44/*,*/) break; 590 pos++; 591 ch = commentWhitespace(); 592 if (!source.startsWith(it_id, pos)) break; 593 pos += it_id.length; 594 ch = commentWhitespace(); 595 if (ch !== 44/*,*/) break; 596 pos++; 597 ch = commentWhitespace(); 598 if (ch !== 123/*{*/) break; 599 pos++; 600 ch = commentWhitespace(); 601 if (ch !== 101/*e*/ || !source.startsWith('numerable', pos + 1)) break; 602 pos += 10; 603 ch = commentWhitespace(); 604 if (ch !== 58/*:*/) break; 605 pos++; 606 ch = commentWhitespace(); 607 if (ch !== 116/*t*/ && !source.startsWith('rue', pos + 1)) break; 608 pos += 4; 609 ch = commentWhitespace(); 610 if (ch !== 44/*,*/) break; 611 pos++; 612 ch = commentWhitespace(); 613 if (ch !== 103/*g*/ || !source.startsWith('et', pos + 1)) break; 614 pos += 3; 615 ch = commentWhitespace(); 616 if (ch !== 58/*:*/) break; 617 pos++; 618 ch = commentWhitespace(); 619 if (ch !== 102/*f*/ || !source.startsWith('unction', pos + 1)) break; 620 pos += 8; 621 ch = commentWhitespace(); 622 if (ch !== 40/*(*/) break; 623 pos++; 624 ch = commentWhitespace(); 625 if (ch !== 41/*)*/) break; 626 pos++; 627 ch = commentWhitespace(); 628 if (ch !== 123/*{*/) break; 629 pos++; 630 ch = commentWhitespace(); 631 if (ch !== 114/*r*/ || !source.startsWith('eturn', pos + 1)) break; 632 pos += 6; 633 ch = commentWhitespace(); 634 if (!source.startsWith(id, pos)) break; 635 pos += id.length; 636 ch = commentWhitespace(); 637 if (ch !== 91/*[*/) break; 638 pos++; 639 ch = commentWhitespace(); 640 if (!source.startsWith(it_id, pos)) break; 641 pos += it_id.length; 642 ch = commentWhitespace(); 643 if (ch !== 93/*]*/) break; 644 pos++; 645 ch = commentWhitespace(); 646 if (ch === 59/*;*/) { 647 pos++; 648 ch = commentWhitespace(); 649 } 650 if (ch !== 125/*}*/) break; 651 pos++; 652 ch = commentWhitespace(); 653 if (ch !== 125/*}*/) break; 654 pos++; 655 ch = commentWhitespace(); 656 if (ch !== 41/*)*/) break; 657 pos++; 658 ch = commentWhitespace(); 659 if (ch === 59/*;*/) { 660 pos++; 661 ch = commentWhitespace(); 662 } 663 } 664 else break; 665 666 if (ch !== 125/*}*/) break; 667 pos++; 668 ch = commentWhitespace(); 669 if (ch !== 41/*)*/) break; 670 671 const starExportSpecifier = starExportMap[id]; 672 if (starExportSpecifier) { 673 reexports.add(starExportSpecifier); 674 pos = revertPos; 675 return; 676 } 677 return; 678 } 679 } 680 } 681 pos = revertPos; 682 } 683 684 function readExportsOrModuleDotExports (ch) { 685 const revertPos = pos; 686 if (ch === 109/*m*/ && source.startsWith('odule', pos + 1)) { 687 pos += 6; 688 ch = commentWhitespace(); 689 if (ch !== 46/*.*/) { 690 pos = revertPos; 691 return false; 692 } 693 pos++; 694 ch = commentWhitespace(); 695 } 696 if (ch === 101/*e*/ && source.startsWith('xports', pos + 1)) { 697 pos += 7; 698 return true; 699 } 700 else { 701 pos = revertPos; 702 return false; 703 } 704 } 705 706 function tryParseModuleExportsDotAssign () { 707 pos += 6; 708 const revertPos = pos - 1; 709 let ch = commentWhitespace(); 710 if (ch === 46/*.*/) { 711 pos++; 712 ch = commentWhitespace(); 713 if (ch === 101/*e*/ && source.startsWith('xports', pos + 1)) { 714 tryParseExportsDotAssign(true); 715 return; 716 } 717 } 718 pos = revertPos; 719 } 720 721 function tryParseExportsDotAssign (assign) { 722 pos += 7; 723 const revertPos = pos - 1; 724 let ch = commentWhitespace(); 725 switch (ch) { 726 // exports.asdf 727 case 46/*.*/: { 728 pos++; 729 ch = commentWhitespace(); 730 const startPos = pos; 731 if (identifier()) { 732 const endPos = pos; 733 ch = commentWhitespace(); 734 if (ch === 61/*=*/) { 735 addExport(source.slice(startPos, endPos)); 736 return; 737 } 738 } 739 break; 740 } 741 // exports['asdf'] 742 case 91/*[*/: { 743 pos++; 744 ch = commentWhitespace(); 745 if (ch === 39/*'*/ || ch === 34/*"*/) { 746 pos++; 747 const startPos = pos; 748 if (identifier() && source.charCodeAt(pos) === ch) { 749 const endPos = pos++; 750 ch = commentWhitespace(); 751 if (ch !== 93/*]*/) 752 break; 753 pos++; 754 ch = commentWhitespace(); 755 if (ch !== 61/*=*/) 756 break; 757 addExport(source.slice(startPos, endPos)); 758 } 759 } 760 break; 761 } 762 // module.exports = 763 case 61/*=*/: { 764 if (assign) { 765 if (reexports.size) 766 reexports = new Set(); 767 pos++; 768 ch = commentWhitespace(); 769 // { ... } 770 if (ch === 123/*{*/) { 771 tryParseLiteralExports(); 772 return; 773 } 774 775 // require('...') 776 if (ch === 114/*r*/) 777 tryParseRequire(ExportAssign); 778 } 779 } 780 } 781 pos = revertPos; 782 } 783 784 function tryParseRequire (requireType) { 785 // require('...') 786 const revertPos = pos; 787 if (source.startsWith('equire', pos + 1)) { 788 pos += 7; 789 let ch = commentWhitespace(); 790 if (ch === 40/*(*/) { 791 pos++; 792 ch = commentWhitespace(); 793 const reexportStart = pos + 1; 794 if (ch === 39/*'*/) { 795 singleQuoteString(); 796 const reexportEnd = pos++; 797 ch = commentWhitespace(); 798 if (ch === 41/*)*/) { 799 switch (requireType) { 800 case ExportAssign: 801 reexports.add(source.slice(reexportStart, reexportEnd)); 802 return true; 803 case ExportStar: 804 reexports.add(source.slice(reexportStart, reexportEnd)); 805 return true; 806 default: 807 lastStarExportSpecifier = source.slice(reexportStart, reexportEnd); 808 return true; 809 } 810 } 811 } 812 else if (ch === 34/*"*/) { 813 doubleQuoteString(); 814 const reexportEnd = pos++; 815 ch = commentWhitespace(); 816 if (ch === 41/*)*/) { 817 switch (requireType) { 818 case ExportAssign: 819 reexports.add(source.slice(reexportStart, reexportEnd)); 820 return true; 821 case ExportStar: 822 reexports.add(source.slice(reexportStart, reexportEnd)); 823 return true; 824 default: 825 lastStarExportSpecifier = source.slice(reexportStart, reexportEnd); 826 return true; 827 } 828 } 829 } 830 } 831 pos = revertPos; 832 } 833 return false; 834 } 835 836 function tryParseLiteralExports () { 837 const revertPos = pos - 1; 838 while (pos++ < end) { 839 let ch = commentWhitespace(); 840 const startPos = pos; 841 if (identifier()) { 842 const endPos = pos; 843 ch = commentWhitespace(); 844 if (ch === 58/*:*/) { 845 pos++; 846 ch = commentWhitespace(); 847 // nothing more complex than identifier expressions for now 848 if (!identifier()) { 849 pos = revertPos; 850 return; 851 } 852 ch = source.charCodeAt(pos); 853 } 854 addExport(source.slice(startPos, endPos)); 855 } 856 else if (ch === 46/*.*/ && source.startsWith('..', pos + 1)) { 857 pos += 3; 858 if (source.charCodeAt(pos) === 114/*r*/ && tryParseRequire(ExportAssign)) { 859 pos++; 860 } 861 else if (!identifier()) { 862 pos = revertPos; 863 return; 864 } 865 ch = commentWhitespace(); 866 } 867 else if (ch === 39/*'*/ || ch === 34/*"*/) { 868 const startPos = ++pos; 869 if (identifier() && source.charCodeAt(pos) === ch) { 870 const endPos = pos++; 871 ch = commentWhitespace(); 872 if (ch === 58/*:*/) { 873 pos++; 874 ch = commentWhitespace(); 875 // nothing more complex than identifier expressions for now 876 if (!identifier()) { 877 pos = revertPos; 878 return; 879 } 880 ch = source.charCodeAt(pos); 881 addExport(source.slice(startPos, endPos)); 882 } 883 } 884 } 885 else { 886 pos = revertPos; 887 return; 888 } 889 890 if (ch === 125/*}*/) 891 return; 892 893 if (ch !== 44/*,*/) { 894 pos = revertPos; 895 return; 896 } 897 } 898 } 899 900 // --- Extracted from AcornJS --- 901 //(https://github.com/acornjs/acorn/blob/master/acorn/src/identifier.js#L23 902 // 903 // MIT License 904 905 // Copyright (C) 2012-2018 by various contributors (see AUTHORS) 906 907 // Permission is hereby granted, free of charge, to any person obtaining a copy 908 // of this software and associated documentation files (the "Software"), to deal 909 // in the Software without restriction, including without limitation the rights 910 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 911 // copies of the Software, and to permit persons to whom the Software is 912 // furnished to do so, subject to the following conditions: 913 914 // The above copyright notice and this permission notice shall be included in 915 // all copies or substantial portions of the Software. 916 917 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 918 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 919 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 920 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 921 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 922 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 923 // THE SOFTWARE. 924 925 // ## Character categories 926 927 // Big ugly regular expressions that match characters in the 928 // whitespace, identifier, and identifier-start categories. These 929 // are only applied when a character is found to actually have a 930 // code point above 128. 931 // Generated by `bin/generate-identifier-regex.js`. 932 let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08c7\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc" 933 let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf\u1ac0\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f" 934 935 const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]") 936 const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]") 937 938 nonASCIIidentifierStartChars = nonASCIIidentifierChars = null 939 940 // These are a run-length and offset encoded representation of the 941 // >0xffff code points that are a valid part of identifiers. The 942 // offset starts at 0x10000, and each pair of numbers represents an 943 // offset to the next range, and then a size of the range. They were 944 // generated by bin/generate-identifier-regex.js 945 946 // eslint-disable-next-line comma-spacing 947 const astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,349,41,7,1,79,28,11,0,9,21,107,20,28,22,13,52,76,44,33,24,27,35,30,0,3,0,9,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,230,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,190,0,80,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,74,6,0,67,12,65,1,2,0,29,6135,9,1237,43,8,8952,286,50,2,18,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,2357,44,11,6,17,0,370,43,1301,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42717,35,4148,12,221,3,5761,15,7472,3104,541,1507,4938] 948 949 // eslint-disable-next-line comma-spacing 950 const astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,370,1,154,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,2,11,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1014,0,2,54,8,3,82,0,12,1,19628,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,262,6,10,9,419,13,1495,6,110,6,6,9,4759,9,787719,239] 951 952 // This has a complexity linear to the value of the code. The 953 // assumption is that looking up astral identifier characters is 954 // rare. 955 function isInAstralSet(code, set) { 956 let pos = 0x10000 957 for (let i = 0; i < set.length; i += 2) { 958 pos += set[i] 959 if (pos > code) return false 960 pos += set[i + 1] 961 if (pos >= code) return true 962 } 963 } 964 965 // Test whether a given character code starts an identifier. 966 967 function isIdentifierStart(code, astral) { 968 if (code < 65) return code === 36 969 if (code < 91) return true 970 if (code < 97) return code === 95 971 if (code < 123) return true 972 if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) 973 if (astral === false) return false 974 return isInAstralSet(code, astralIdentifierStartCodes) 975 } 976 977 // Test whether a given character is part of an identifier. 978 979 function isIdentifierChar(code, astral) { 980 if (code < 48) return code === 36 981 if (code < 58) return true 982 if (code < 65) return false 983 if (code < 91) return true 984 if (code < 97) return code === 95 985 if (code < 123) return true 986 if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) 987 if (astral === false) return false 988 return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) 989 } 990 991 function identifier () { 992 let ch = source.codePointAt(pos); 993 if (!isIdentifierStart(ch, true) || ch === '\\') 994 return false; 995 pos += codePointLen(ch); 996 while (ch = source.codePointAt(pos)) { 997 if (isIdentifierChar(ch, true)) { 998 pos += codePointLen(ch); 999 } 1000 else if (ch === '\\') { 1001 // no identifier escapes support for now 1002 return false; 1003 } 1004 else { 1005 break; 1006 } 1007 } 1008 return true; 1009 } 1010 1011 function codePointLen (ch) { 1012 if (ch < 0x10000) return 1; 1013 return 2; 1014 } 1015 1016 function codePointAtLast (bPos) { 1017 // Gives the UTF char for backtracking surrogates 1018 const ch = source.charCodeAt(bPos); 1019 if ((ch & 0xFC00) === 0xDC00) 1020 return (((source.charCodeAt(bPos - 1) & 0x3FF) << 10) | (ch & 0x3FF)) + 0x10000; 1021 return ch; 1022 } 1023 1024 function throwIfImportStatement () { 1025 const startPos = pos; 1026 pos += 6; 1027 const ch = commentWhitespace(); 1028 switch (ch) { 1029 // dynamic import 1030 case 40/*(*/: 1031 openTokenPosStack[openTokenDepth++] = startPos; 1032 return; 1033 // import.meta 1034 case 46/*.*/: 1035 throw new Error('Unexpected import.meta in CJS module.'); 1036 return; 1037 1038 default: 1039 // no space after "import" -> not an import keyword 1040 if (pos === startPos + 6) 1041 break; 1042 case 34/*"*/: 1043 case 39/*'*/: 1044 case 123/*{*/: 1045 case 42/***/: 1046 // import statement only permitted at base-level 1047 if (openTokenDepth !== 0) { 1048 pos--; 1049 return; 1050 } 1051 // import statements are a syntax error in CommonJS 1052 throw new Error('Unexpected import statement in CJS module.'); 1053 } 1054 } 1055 1056 function throwIfExportStatement () { 1057 pos += 6; 1058 const curPos = pos; 1059 const ch = commentWhitespace(); 1060 if (pos === curPos && !isPunctuator(ch)) 1061 return; 1062 throw new Error('Unexpected export statement in CJS module.'); 1063 } 1064 1065 function commentWhitespace () { 1066 let ch; 1067 do { 1068 ch = source.charCodeAt(pos); 1069 if (ch === 47/*/*/) { 1070 const next_ch = source.charCodeAt(pos + 1); 1071 if (next_ch === 47/*/*/) 1072 lineComment(); 1073 else if (next_ch === 42/***/) 1074 blockComment(); 1075 else 1076 return ch; 1077 } 1078 else if (!isBrOrWs(ch)) { 1079 return ch; 1080 } 1081 } while (pos++ < end); 1082 return ch; 1083 } 1084 1085 function templateString () { 1086 while (pos++ < end) { 1087 const ch = source.charCodeAt(pos); 1088 if (ch === 36/*$*/ && source.charCodeAt(pos + 1) === 123/*{*/) { 1089 pos++; 1090 templateStack[templateStackDepth++] = templateDepth; 1091 templateDepth = ++openTokenDepth; 1092 return; 1093 } 1094 if (ch === 96/*`*/) 1095 return; 1096 if (ch === 92/*\*/) 1097 pos++; 1098 } 1099 syntaxError(); 1100 } 1101 1102 function blockComment () { 1103 pos++; 1104 while (pos++ < end) { 1105 const ch = source.charCodeAt(pos); 1106 if (ch === 42/***/ && source.charCodeAt(pos + 1) === 47/*/*/) { 1107 pos++; 1108 return; 1109 } 1110 } 1111 } 1112 1113 function lineComment () { 1114 while (pos++ < end) { 1115 const ch = source.charCodeAt(pos); 1116 if (ch === 10/*\n*/ || ch === 13/*\r*/) 1117 return; 1118 } 1119 } 1120 1121 function singleQuoteString () { 1122 while (pos++ < end) { 1123 let ch = source.charCodeAt(pos); 1124 if (ch === 39/*'*/) 1125 return; 1126 if (ch === 92/*\*/) { 1127 ch = source.charCodeAt(++pos); 1128 if (ch === 13/*\r*/ && source.charCodeAt(pos + 1) === 10/*\n*/) 1129 pos++; 1130 } 1131 else if (isBr(ch)) 1132 break; 1133 } 1134 throw new Error('Unterminated string.'); 1135 } 1136 1137 function doubleQuoteString () { 1138 while (pos++ < end) { 1139 let ch = source.charCodeAt(pos); 1140 if (ch === 34/*"*/) 1141 return; 1142 if (ch === 92/*\*/) { 1143 ch = source.charCodeAt(++pos); 1144 if (ch === 13/*\r*/ && source.charCodeAt(pos + 1) === 10/*\n*/) 1145 pos++; 1146 } 1147 else if (isBr(ch)) 1148 break; 1149 } 1150 throw new Error('Unterminated string.'); 1151 } 1152 1153 function regexCharacterClass () { 1154 while (pos++ < end) { 1155 let ch = source.charCodeAt(pos); 1156 if (ch === 93/*]*/) 1157 return ch; 1158 if (ch === 92/*\*/) 1159 pos++; 1160 else if (ch === 10/*\n*/ || ch === 13/*\r*/) 1161 break; 1162 } 1163 throw new Error('Syntax error reading regular expression class.'); 1164 } 1165 1166 function regularExpression () { 1167 while (pos++ < end) { 1168 let ch = source.charCodeAt(pos); 1169 if (ch === 47/*/*/) 1170 return; 1171 if (ch === 91/*[*/) 1172 ch = regexCharacterClass(); 1173 else if (ch === 92/*\*/) 1174 pos++; 1175 else if (ch === 10/*\n*/ || ch === 13/*\r*/) 1176 break; 1177 } 1178 throw new Error('Syntax error reading regular expression.'); 1179 } 1180 1181 // Note: non-asii BR and whitespace checks omitted for perf / footprint 1182 // if there is a significant user need this can be reconsidered 1183 function isBr (c) { 1184 return c === 13/*\r*/ || c === 10/*\n*/; 1185 } 1186 1187 function isBrOrWs (c) { 1188 return c > 8 && c < 14 || c === 32 || c === 160; 1189 } 1190 1191 function isBrOrWsOrPunctuatorNotDot (c) { 1192 return c > 8 && c < 14 || c === 32 || c === 160 || isPunctuator(c) && c !== 46/*.*/; 1193 } 1194 1195 function keywordStart (pos) { 1196 return pos === 0 || isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos - 1)); 1197 } 1198 1199 function readPrecedingKeyword (pos, match) { 1200 if (pos < match.length - 1) 1201 return false; 1202 return source.startsWith(match, pos - match.length + 1) && (pos === 0 || isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos - match.length))); 1203 } 1204 1205 function readPrecedingKeyword1 (pos, ch) { 1206 return source.charCodeAt(pos) === ch && (pos === 0 || isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos - 1))); 1207 } 1208 1209 // Detects one of case, debugger, delete, do, else, in, instanceof, new, 1210 // return, throw, typeof, void, yield, await 1211 function isExpressionKeyword (pos) { 1212 switch (source.charCodeAt(pos)) { 1213 case 100/*d*/: 1214 switch (source.charCodeAt(pos - 1)) { 1215 case 105/*i*/: 1216 // void 1217 return readPrecedingKeyword(pos - 2, 'vo'); 1218 case 108/*l*/: 1219 // yield 1220 return readPrecedingKeyword(pos - 2, 'yie'); 1221 default: 1222 return false; 1223 } 1224 case 101/*e*/: 1225 switch (source.charCodeAt(pos - 1)) { 1226 case 115/*s*/: 1227 switch (source.charCodeAt(pos - 2)) { 1228 case 108/*l*/: 1229 // else 1230 return readPrecedingKeyword1(pos - 3, 101/*e*/); 1231 case 97/*a*/: 1232 // case 1233 return readPrecedingKeyword1(pos - 3, 99/*c*/); 1234 default: 1235 return false; 1236 } 1237 case 116/*t*/: 1238 // delete 1239 return readPrecedingKeyword(pos - 2, 'dele'); 1240 default: 1241 return false; 1242 } 1243 case 102/*f*/: 1244 if (source.charCodeAt(pos - 1) !== 111/*o*/ || source.charCodeAt(pos - 2) !== 101/*e*/) 1245 return false; 1246 switch (source.charCodeAt(pos - 3)) { 1247 case 99/*c*/: 1248 // instanceof 1249 return readPrecedingKeyword(pos - 4, 'instan'); 1250 case 112/*p*/: 1251 // typeof 1252 return readPrecedingKeyword(pos - 4, 'ty'); 1253 default: 1254 return false; 1255 } 1256 case 110/*n*/: 1257 // in, return 1258 return readPrecedingKeyword1(pos - 1, 105/*i*/) || readPrecedingKeyword(pos - 1, 'retur'); 1259 case 111/*o*/: 1260 // do 1261 return readPrecedingKeyword1(pos - 1, 100/*d*/); 1262 case 114/*r*/: 1263 // debugger 1264 return readPrecedingKeyword(pos - 1, 'debugge'); 1265 case 116/*t*/: 1266 // await 1267 return readPrecedingKeyword(pos - 1, 'awai'); 1268 case 119/*w*/: 1269 switch (source.charCodeAt(pos - 1)) { 1270 case 101/*e*/: 1271 // new 1272 return readPrecedingKeyword1(pos - 2, 110/*n*/); 1273 case 111/*o*/: 1274 // throw 1275 return readPrecedingKeyword(pos - 2, 'thr'); 1276 default: 1277 return false; 1278 } 1279 } 1280 return false; 1281 } 1282 1283 function isParenKeyword (curPos) { 1284 return source.charCodeAt(curPos) === 101/*e*/ && source.startsWith('whil', curPos - 4) || 1285 source.charCodeAt(curPos) === 114/*r*/ && source.startsWith('fo', curPos - 2) || 1286 source.charCodeAt(curPos - 1) === 105/*i*/ && source.charCodeAt(curPos) === 102/*f*/; 1287 } 1288 1289 function isPunctuator (ch) { 1290 // 23 possible punctuator endings: !%&()*+,-./:;<=>?[]^{}|~ 1291 return ch === 33/*!*/ || ch === 37/*%*/ || ch === 38/*&*/ || 1292 ch > 39 && ch < 48 || ch > 57 && ch < 64 || 1293 ch === 91/*[*/ || ch === 93/*]*/ || ch === 94/*^*/ || 1294 ch > 122 && ch < 127; 1295 } 1296 1297 function isExpressionPunctuator (ch) { 1298 // 20 possible expression endings: !%&(*+,-.:;<=>?[^{|~ 1299 return ch === 33/*!*/ || ch === 37/*%*/ || ch === 38/*&*/ || 1300 ch > 39 && ch < 47 && ch !== 41 || ch > 57 && ch < 64 || 1301 ch === 91/*[*/ || ch === 94/*^*/ || ch > 122 && ch < 127 && ch !== 125/*}*/; 1302 } 1303 1304 function isExpressionTerminator (curPos) { 1305 // detects: 1306 // => ; ) finally catch else 1307 // as all of these followed by a { will indicate a statement brace 1308 switch (source.charCodeAt(curPos)) { 1309 case 62/*>*/: 1310 return source.charCodeAt(curPos - 1) === 61/*=*/; 1311 case 59/*;*/: 1312 case 41/*)*/: 1313 return true; 1314 case 104/*h*/: 1315 return source.startsWith('catc', curPos - 4); 1316 case 121/*y*/: 1317 return source.startsWith('finall', curPos - 6); 1318 case 101/*e*/: 1319 return source.startsWith('els', curPos - 3); 1320 } 1321 return false; 1322 } 1323 1324 const initPromise = Promise.resolve(); 1325 1326 module.exports.init = () => initPromise; 1327 module.exports.parse = parseCJS;