@depup/webpack 5.109.0-depup.0 → 5.109.2-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/bin/webpack.js +12 -0
- package/changes.json +4 -4
- package/lib/ChunkGraph.js +17 -15
- package/lib/CleanPlugin.js +11 -9
- package/lib/CompatibilityPlugin.js +31 -0
- package/lib/Compilation.js +21 -5
- package/lib/Compiler.js +16 -4
- package/lib/DefinePlugin.js +47 -20
- package/lib/ExportsInfo.js +22 -5
- package/lib/ExternalModule.js +10 -7
- package/lib/FileSystemInfo.js +126 -26
- package/lib/FlagDependencyUsagePlugin.js +33 -12
- package/lib/InitFragment.js +20 -32
- package/lib/ModuleFilenameHelpers.js +13 -2
- package/lib/NormalModule.js +80 -71
- package/lib/NormalModuleFactory.js +8 -2
- package/lib/RuntimePlugin.js +40 -113
- package/lib/Template.js +23 -3
- package/lib/cache/PackFileCacheStrategy.js +259 -5
- package/lib/config/defaults.js +21 -2
- package/lib/container/HoistContainerReferencesPlugin.js +47 -55
- package/lib/container/ModuleFederationPlugin.js +15 -9
- package/lib/css/CssGenerator.js +8 -2
- package/lib/css/CssLoadingRuntimeModule.js +25 -12
- package/lib/css/CssModulesPlugin.js +29 -18
- package/lib/css/CssParser.js +135 -50
- package/lib/css/syntax.js +862 -765
- package/lib/dependencies/CommonJsExportRequireDependency.js +19 -0
- package/lib/dependencies/CommonJsFullRequireDependency.js +33 -4
- package/lib/dependencies/CommonJsImportsParserPlugin.js +2 -0
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +2 -1
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +17 -9
- package/lib/dependencies/HarmonyImportDependency.js +1 -1
- package/lib/dependencies/HarmonyImportGuard.js +2 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -7
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +15 -9
- package/lib/hmr/lazyCompilationBackend.js +19 -4
- package/lib/html/HtmlGenerator.js +23 -3
- package/lib/html/HtmlModulesPlugin.js +30 -12
- package/lib/html/syntax.js +2485 -2399
- package/lib/ids/IdHelpers.js +24 -10
- package/lib/javascript/JavascriptModulesPlugin.js +83 -49
- package/lib/javascript/JavascriptParser.js +49 -13
- package/lib/javascript/syntax.js +700 -43
- package/lib/node/ReadFileCompileAsyncWasmPlugin.js +10 -2
- package/lib/node/ReadFileCompileWasmPlugin.js +10 -2
- package/lib/optimize/AggressiveMergingPlugin.js +19 -15
- package/lib/optimize/ConcatenatedModule.js +19 -15
- package/lib/optimize/ModuleConcatenationPlugin.js +73 -24
- package/lib/optimize/RealContentHashPlugin.js +10 -7
- package/lib/optimize/SplitChunksPlugin.js +146 -44
- package/lib/prefetch/ResourceHintPlugin.js +96 -72
- package/lib/serialization/BinaryMiddleware.js +270 -938
- package/lib/serialization/FileMiddleware.js +299 -60
- package/lib/stats/DefaultStatsFactoryPlugin.js +204 -198
- package/lib/stats/DefaultStatsPrinterPlugin.js +24 -166
- package/lib/stats/StatsFactory.js +31 -9
- package/lib/util/identifier.js +21 -1
- package/package.json +10 -10
- package/schemas/WebpackOptions.json +110 -55
- package/types.d.ts +832 -247
package/lib/javascript/syntax.js
CHANGED
|
@@ -36,6 +36,45 @@ const keywordTypes =
|
|
|
36
36
|
(/** @type {unknown} */ (require("acorn"))).keywordTypes
|
|
37
37
|
);
|
|
38
38
|
|
|
39
|
+
// acorn exports these Unicode/character helpers at runtime but leaves them out
|
|
40
|
+
// of its public types; the ported cold-path readers below reuse them so their
|
|
41
|
+
// classification stays byte-identical to acorn's tokenizer.
|
|
42
|
+
const {
|
|
43
|
+
isIdentifierChar,
|
|
44
|
+
isIdentifierStart,
|
|
45
|
+
isNewLine,
|
|
46
|
+
lineBreak,
|
|
47
|
+
nonASCIIwhitespace
|
|
48
|
+
} =
|
|
49
|
+
/** @type {{ isIdentifierStart: (code: number, astral?: boolean) => boolean, isIdentifierChar: (code: number, astral?: boolean) => boolean, isNewLine: (code: number) => boolean, lineBreak: RegExp, nonASCIIwhitespace: RegExp }} */
|
|
50
|
+
(/** @type {unknown} */ (require("acorn")));
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {number} code code point
|
|
54
|
+
* @returns {string} the string for a single code point
|
|
55
|
+
*/
|
|
56
|
+
const codePointToString = (code) => String.fromCodePoint(code);
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* acorn's `stringToNumber`: legacy octal parses in base 8, everything else via
|
|
60
|
+
* `parseFloat` after dropping `_` separators.
|
|
61
|
+
* @param {string} str numeric literal text (may contain `_` separators)
|
|
62
|
+
* @param {boolean} isLegacyOctal whether it is a legacy octal literal
|
|
63
|
+
* @returns {number} numeric value
|
|
64
|
+
*/
|
|
65
|
+
const stringToNumber = (str, isLegacyOctal) =>
|
|
66
|
+
isLegacyOctal
|
|
67
|
+
? Number.parseInt(str, 8)
|
|
68
|
+
: Number.parseFloat(str.replace(/_/g, ""));
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* acorn's `stringToBigInt`, minus the pre-BigInt fallback (every supported
|
|
72
|
+
* Node has `BigInt`).
|
|
73
|
+
* @param {string} str numeric literal text (may contain `_` separators)
|
|
74
|
+
* @returns {bigint} bigint value
|
|
75
|
+
*/
|
|
76
|
+
const stringToBigInt = (str) => BigInt(str.replace(/_/g, ""));
|
|
77
|
+
|
|
39
78
|
/** @typedef {import("acorn").Options} Options */
|
|
40
79
|
/** @typedef {import("acorn").Position} Position */
|
|
41
80
|
/** @typedef {import("acorn").Node} Node */
|
|
@@ -867,6 +906,18 @@ class Scope {
|
|
|
867
906
|
* readNumber: (startsWithDot: boolean) => void,
|
|
868
907
|
* readRadixNumber: (radix: number) => void,
|
|
869
908
|
* readTmplToken: () => void,
|
|
909
|
+
* invalidStringToken: (position: number, message: string) => void,
|
|
910
|
+
* _readInt: (radix: number, len?: number, maybeLegacyOctal?: boolean) => number | null,
|
|
911
|
+
* _readCodePoint: () => number,
|
|
912
|
+
* _readHexChar: (len: number) => number,
|
|
913
|
+
* _readEscapedChar: (inTemplate: boolean) => string,
|
|
914
|
+
* _readStringCold: (quote: number) => void,
|
|
915
|
+
* _readTmplTokenCold: () => void,
|
|
916
|
+
* _readNumberCold: (startsWithDot: boolean) => void,
|
|
917
|
+
* _readRadixNumber: (radix: number) => void,
|
|
918
|
+
* _readWord1Cold: () => string,
|
|
919
|
+
* _skipSpaceCold: () => void,
|
|
920
|
+
* _getUnknownOrPrivate: (code: number) => void,
|
|
870
921
|
* finishToken: (type: TokenType, value?: unknown) => void,
|
|
871
922
|
* context: TokContextShim[],
|
|
872
923
|
* pos: number,
|
|
@@ -1030,6 +1081,26 @@ const WORD_CACHE_MAX_LEN = 12;
|
|
|
1030
1081
|
/** @type {Map<number, string>} */
|
|
1031
1082
|
const OP_CACHE = new Map();
|
|
1032
1083
|
|
|
1084
|
+
// The regexp flag whitelist depends only on the ecmaVersion, so build one
|
|
1085
|
+
// string per version instead of a fresh one in every parser constructor.
|
|
1086
|
+
/** @type {Map<number, string>} */
|
|
1087
|
+
const VALID_REGEXP_FLAGS = new Map();
|
|
1088
|
+
|
|
1089
|
+
/**
|
|
1090
|
+
* @param {number} ecmaVersion normalized acorn ecmaVersion
|
|
1091
|
+
* @returns {string} the regexp flags allowed at `ecmaVersion`
|
|
1092
|
+
*/
|
|
1093
|
+
const getValidRegexpFlags = (ecmaVersion) => {
|
|
1094
|
+
let flags = VALID_REGEXP_FLAGS.get(ecmaVersion);
|
|
1095
|
+
if (flags === undefined) {
|
|
1096
|
+
flags = `gim${ecmaVersion >= 6 ? "uy" : ""}${
|
|
1097
|
+
ecmaVersion >= 9 ? "s" : ""
|
|
1098
|
+
}${ecmaVersion >= 13 ? "d" : ""}${ecmaVersion >= 15 ? "v" : ""}`;
|
|
1099
|
+
VALID_REGEXP_FLAGS.set(ecmaVersion, flags);
|
|
1100
|
+
}
|
|
1101
|
+
return flags;
|
|
1102
|
+
};
|
|
1103
|
+
|
|
1033
1104
|
// Sticky mirrors of acorn's `skipWhiteSpace` / string-literal / `lineBreak`
|
|
1034
1105
|
// regexes for the owned `strictDirective` (they scan at an offset, no slice).
|
|
1035
1106
|
const STRICT_SKIP_WS = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
|
|
@@ -1211,9 +1282,7 @@ class WebpackParser extends BaseParser {
|
|
|
1211
1282
|
this._propHashStack = [];
|
|
1212
1283
|
this._propHashDepth = 0;
|
|
1213
1284
|
// `readRegexp`'s flag whitelist depends only on the ecmaVersion
|
|
1214
|
-
this._validRegexpFlags =
|
|
1215
|
-
this._ecmaVersion >= 9 ? "s" : ""
|
|
1216
|
-
}${this._ecmaVersion >= 13 ? "d" : ""}${this._ecmaVersion >= 15 ? "v" : ""}`;
|
|
1285
|
+
this._validRegexpFlags = getValidRegexpFlags(this._ecmaVersion);
|
|
1217
1286
|
// the owned parseStatement inlines these methods, so a parser plugin
|
|
1218
1287
|
// overriding any of them turns the statement fast path off
|
|
1219
1288
|
const proto = WebpackParser.prototype;
|
|
@@ -1267,6 +1336,7 @@ class WebpackParser extends BaseParser {
|
|
|
1267
1336
|
* this folds whitespace and comment skipping and the ASCII token dispatch
|
|
1268
1337
|
* into one function so nothing re-enters acorn's per-step option checks.
|
|
1269
1338
|
* Template/`preserveSpace` contexts and non-lazy mode use acorn's tokenizer.
|
|
1339
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
1270
1340
|
* @returns {void}
|
|
1271
1341
|
* @this {ParserInternals}
|
|
1272
1342
|
*/
|
|
@@ -1300,9 +1370,9 @@ class WebpackParser extends BaseParser {
|
|
|
1300
1370
|
cls = CHAR_CLASS[code];
|
|
1301
1371
|
if (cls < CLS_SPACE) {
|
|
1302
1372
|
if (cls === CLS_UNICODE) {
|
|
1303
|
-
// unicode whitespace / line terminators:
|
|
1373
|
+
// unicode whitespace / line terminators: the cold reader consumes them
|
|
1304
1374
|
this.pos = pos;
|
|
1305
|
-
|
|
1375
|
+
this._skipSpaceCold();
|
|
1306
1376
|
pos = this.pos;
|
|
1307
1377
|
if (newline === 0) newline = 2;
|
|
1308
1378
|
code = pos < len ? input.charCodeAt(pos) : 0;
|
|
@@ -1375,6 +1445,7 @@ class WebpackParser extends BaseParser {
|
|
|
1375
1445
|
* `endLoc` write on every token and reaches `updateContext` through an extra
|
|
1376
1446
|
* method call. Skip the probe and inline acorn's `updateContext` body — this
|
|
1377
1447
|
* runs once per token. Other modes use acorn's.
|
|
1448
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
1378
1449
|
* @param {TokenType} type token type
|
|
1379
1450
|
* @param {unknown=} value token value
|
|
1380
1451
|
* @returns {void}
|
|
@@ -1442,6 +1513,7 @@ class WebpackParser extends BaseParser {
|
|
|
1442
1513
|
* Owned `braceIsBlock`, acorn's verbatim except the line-terminator probe:
|
|
1443
1514
|
* acorn slices the inter-token gap and runs a regexp; `_gapHasNewline`
|
|
1444
1515
|
* answers from the tokenizer's newline flag (scanning only when unknown).
|
|
1516
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokencontext.js
|
|
1445
1517
|
* @param {TokenType} prevType type of the previous token
|
|
1446
1518
|
* @returns {boolean} whether a `{` opens a block in this context
|
|
1447
1519
|
* @this {ParserInternals}
|
|
@@ -1515,6 +1587,7 @@ class WebpackParser extends BaseParser {
|
|
|
1515
1587
|
* `lastTokStartLoc` and probes `options.onToken` on every token, both dead in
|
|
1516
1588
|
* lazy mode (locations off, no token stream), leaving only the two offset
|
|
1517
1589
|
* writes and the keyword-escape guard. Other modes use acorn's.
|
|
1590
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
1518
1591
|
* @param {boolean=} ignoreEscapeSequenceInKeyword whether an escape in a keyword is allowed here
|
|
1519
1592
|
* @returns {void}
|
|
1520
1593
|
* @this {ParserInternals}
|
|
@@ -1540,6 +1613,7 @@ class WebpackParser extends BaseParser {
|
|
|
1540
1613
|
* every operator token, allocating a fresh 2-4 char string per `=>`, `===`,
|
|
1541
1614
|
* `&&` etc. Serve those from `OP_CACHE` instead; single-char operators keep
|
|
1542
1615
|
* the direct slice, which V8 serves from its single-character table.
|
|
1616
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
1543
1617
|
* @param {TokenType} type token type
|
|
1544
1618
|
* @param {number} size operator length
|
|
1545
1619
|
* @returns {void}
|
|
@@ -1571,7 +1645,9 @@ class WebpackParser extends BaseParser {
|
|
|
1571
1645
|
* `readToken_*` methods that each end in `finishOp`'s source slice. Resolve
|
|
1572
1646
|
* every operator by direct char peeks to a static string instead (yuku's
|
|
1573
1647
|
* `scanPunctuation`) — no method chain, no slice, no `OP_CACHE` probe. The
|
|
1574
|
-
* HTML-comment forms (`<!--`, `-->`)
|
|
1648
|
+
* HTML-comment forms (`<!--`, `-->`) inline acorn's line-comment handling;
|
|
1649
|
+
* `#` and unknown chars use the owned cold reader.
|
|
1650
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
1575
1651
|
* @param {number} code current char code
|
|
1576
1652
|
* @returns {void}
|
|
1577
1653
|
* @this {ParserInternals}
|
|
@@ -1697,8 +1773,17 @@ class WebpackParser extends BaseParser {
|
|
|
1697
1773
|
// '-': --, -= or -; `-->` may open an HTML line comment
|
|
1698
1774
|
const next = input.charCodeAt(pos + 1);
|
|
1699
1775
|
if (next === 45) {
|
|
1700
|
-
|
|
1701
|
-
|
|
1776
|
+
// `-->` opens an HTML line comment only at the start of a line
|
|
1777
|
+
// (acorn readToken_plus_min): https://github.com/acornjs/acorn/blob/8.15.0/acorn/src/tokenize.js#L599-L618
|
|
1778
|
+
if (
|
|
1779
|
+
input.charCodeAt(pos + 2) === 62 &&
|
|
1780
|
+
!this.inModule &&
|
|
1781
|
+
(this.lastTokEnd === 0 ||
|
|
1782
|
+
lineBreak.test(input.slice(this.lastTokEnd, pos)))
|
|
1783
|
+
) {
|
|
1784
|
+
this.skipLineComment(3);
|
|
1785
|
+
this.skipSpace();
|
|
1786
|
+
return this.nextToken();
|
|
1702
1787
|
}
|
|
1703
1788
|
this.pos = pos + 2;
|
|
1704
1789
|
return this.finishToken(tokTypes.incDec, "--");
|
|
@@ -1727,7 +1812,11 @@ class WebpackParser extends BaseParser {
|
|
|
1727
1812
|
input.charCodeAt(pos + 2) === 45 &&
|
|
1728
1813
|
input.charCodeAt(pos + 3) === 45
|
|
1729
1814
|
) {
|
|
1730
|
-
|
|
1815
|
+
// `<!--` opens an HTML line comment (acorn readToken_lt_gt):
|
|
1816
|
+
// https://github.com/acornjs/acorn/blob/8.15.0/acorn/src/tokenize.js#L620-L649
|
|
1817
|
+
this.skipLineComment(4);
|
|
1818
|
+
this.skipSpace();
|
|
1819
|
+
return this.nextToken();
|
|
1731
1820
|
}
|
|
1732
1821
|
if (next === 61) {
|
|
1733
1822
|
this.pos = pos + 2;
|
|
@@ -1828,9 +1917,9 @@ class WebpackParser extends BaseParser {
|
|
|
1828
1917
|
case 48: {
|
|
1829
1918
|
// '0': radix literals split off before the decimal reader
|
|
1830
1919
|
const next = input.charCodeAt(pos + 1);
|
|
1831
|
-
if (next === 120 || next === 88) return this.
|
|
1832
|
-
if (next === 111 || next === 79) return this.
|
|
1833
|
-
if (next === 98 || next === 66) return this.
|
|
1920
|
+
if (next === 120 || next === 88) return this._readRadixNumber(16);
|
|
1921
|
+
if (next === 111 || next === 79) return this._readRadixNumber(8);
|
|
1922
|
+
if (next === 98 || next === 66) return this._readRadixNumber(2);
|
|
1834
1923
|
return this.readNumber(false);
|
|
1835
1924
|
}
|
|
1836
1925
|
case 49:
|
|
@@ -1847,18 +1936,19 @@ class WebpackParser extends BaseParser {
|
|
|
1847
1936
|
case 39:
|
|
1848
1937
|
return this.readString(code);
|
|
1849
1938
|
default:
|
|
1850
|
-
return
|
|
1939
|
+
return this._getUnknownOrPrivate(code);
|
|
1851
1940
|
}
|
|
1852
1941
|
}
|
|
1853
1942
|
|
|
1854
1943
|
/**
|
|
1855
1944
|
* ASCII fast path for acorn's `readWord1`, which pays a surrogate-aware
|
|
1856
1945
|
* method call and a range-check helper per character. Escapes, non-ASCII
|
|
1857
|
-
* and astral input restart the
|
|
1946
|
+
* and astral input restart the owned cold reader from the word start.
|
|
1858
1947
|
* Words are deduplicated through `WORD_CACHE` so repeated identifiers —
|
|
1859
1948
|
* which dominate real code — reuse one string instead of slicing a fresh
|
|
1860
1949
|
* one per occurrence; sharing also keeps their cached string hashes warm
|
|
1861
1950
|
* for the keyword/scope Map lookups downstream.
|
|
1951
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
1862
1952
|
* @this {ParserInternals}
|
|
1863
1953
|
* @returns {string} the word
|
|
1864
1954
|
*/
|
|
@@ -1876,13 +1966,13 @@ class WebpackParser extends BaseParser {
|
|
|
1876
1966
|
if (ch < 128) {
|
|
1877
1967
|
if (IDENT_CHAR[ch] === 0) {
|
|
1878
1968
|
// backslash escape: restart cold so escape rules see the word
|
|
1879
|
-
if (ch === 92) return
|
|
1969
|
+
if (ch === 92) return this._readWord1Cold();
|
|
1880
1970
|
break;
|
|
1881
1971
|
}
|
|
1882
1972
|
hash = (Math.imul(hash, 33) + ch) | 0;
|
|
1883
1973
|
pos++;
|
|
1884
1974
|
} else {
|
|
1885
|
-
return
|
|
1975
|
+
return this._readWord1Cold();
|
|
1886
1976
|
}
|
|
1887
1977
|
}
|
|
1888
1978
|
this.containsEsc = false;
|
|
@@ -1908,11 +1998,12 @@ class WebpackParser extends BaseParser {
|
|
|
1908
1998
|
}
|
|
1909
1999
|
|
|
1910
2000
|
/**
|
|
1911
|
-
* String fast path: one scan
|
|
1912
|
-
*
|
|
1913
|
-
*
|
|
1914
|
-
*
|
|
1915
|
-
*
|
|
2001
|
+
* String fast path: one scan finds the closing quote and cooks the common
|
|
2002
|
+
* single-char escapes (`\n \t \\ \" \'` …) and line continuations inline.
|
|
2003
|
+
* Hex/unicode/octal escapes (`\x`, `\u`, `\0`-`\9`) restart the owned cold
|
|
2004
|
+
* reader, which owns their readers and strict-mode errors; old ecmaVersions
|
|
2005
|
+
* (LS/PS terminate strings there) and location tracking use acorn's own.
|
|
2006
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
1916
2007
|
* @this {ParserInternals}
|
|
1917
2008
|
* @param {number} quote quote char code
|
|
1918
2009
|
* @returns {void}
|
|
@@ -1923,33 +2014,94 @@ class WebpackParser extends BaseParser {
|
|
|
1923
2014
|
}
|
|
1924
2015
|
const input = this.input;
|
|
1925
2016
|
const len = input.length;
|
|
1926
|
-
const
|
|
2017
|
+
const quotePos = this.pos;
|
|
2018
|
+
const start = quotePos + 1;
|
|
1927
2019
|
let pos = start;
|
|
2020
|
+
// spans between escapes accumulate here; a plain string never touches
|
|
2021
|
+
// `out` and slices once at the end
|
|
2022
|
+
let out = "";
|
|
2023
|
+
let chunkStart = start;
|
|
1928
2024
|
for (;;) {
|
|
1929
2025
|
if (pos >= len) this.raise(this.start, "Unterminated string constant");
|
|
1930
2026
|
const ch = input.charCodeAt(pos);
|
|
1931
2027
|
if (ch === quote) break;
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
2028
|
+
if (ch === 92) {
|
|
2029
|
+
const esc = input.charCodeAt(pos + 1);
|
|
2030
|
+
// hex/unicode/octal escapes (and a trailing `\`) need the cold
|
|
2031
|
+
// reader's escape handling; restart from the quote (this.pos unmoved)
|
|
2032
|
+
if (
|
|
2033
|
+
pos + 1 >= len ||
|
|
2034
|
+
esc === 120 ||
|
|
2035
|
+
esc === 117 ||
|
|
2036
|
+
(esc >= 48 && esc <= 57)
|
|
2037
|
+
) {
|
|
2038
|
+
this.pos = quotePos;
|
|
2039
|
+
return this._readStringCold(quote);
|
|
2040
|
+
}
|
|
2041
|
+
let rep;
|
|
2042
|
+
let advance = 2;
|
|
2043
|
+
switch (esc) {
|
|
2044
|
+
case 110:
|
|
2045
|
+
rep = "\n";
|
|
2046
|
+
break;
|
|
2047
|
+
case 114:
|
|
2048
|
+
rep = "\r";
|
|
2049
|
+
break;
|
|
2050
|
+
case 116:
|
|
2051
|
+
rep = "\t";
|
|
2052
|
+
break;
|
|
2053
|
+
case 98:
|
|
2054
|
+
rep = "\b";
|
|
2055
|
+
break;
|
|
2056
|
+
case 102:
|
|
2057
|
+
rep = "\f";
|
|
2058
|
+
break;
|
|
2059
|
+
case 118:
|
|
2060
|
+
rep = "\u000B";
|
|
2061
|
+
break;
|
|
2062
|
+
case 13:
|
|
2063
|
+
// `\` + CR(LF): line continuation cooked away
|
|
2064
|
+
rep = "";
|
|
2065
|
+
if (input.charCodeAt(pos + 2) === 10) advance = 3;
|
|
2066
|
+
break;
|
|
2067
|
+
case 10:
|
|
2068
|
+
case 0x2028:
|
|
2069
|
+
case 0x2029:
|
|
2070
|
+
rep = "";
|
|
2071
|
+
break;
|
|
2072
|
+
default:
|
|
2073
|
+
// any other escape is the escaped code unit verbatim (`\\`, `\q`)
|
|
2074
|
+
rep = input[pos + 1];
|
|
2075
|
+
}
|
|
2076
|
+
out += input.slice(chunkStart, pos) + rep;
|
|
2077
|
+
pos += advance;
|
|
2078
|
+
chunkStart = pos;
|
|
2079
|
+
} else if (ch === 10 || ch === 13) {
|
|
2080
|
+
// bare LF/CR is unterminated; LS/PS stay valid at ES2019+
|
|
2081
|
+
this.raise(this.start, "Unterminated string constant");
|
|
2082
|
+
} else {
|
|
2083
|
+
pos++;
|
|
1935
2084
|
}
|
|
1936
|
-
pos++;
|
|
1937
2085
|
}
|
|
1938
2086
|
this.pos = pos + 1;
|
|
1939
|
-
|
|
2087
|
+
if (chunkStart === start) {
|
|
2088
|
+
return this.finishToken(tokTypes.string, input.slice(start, pos));
|
|
2089
|
+
}
|
|
2090
|
+
this.finishToken(tokTypes.string, out + input.slice(chunkStart, pos));
|
|
1940
2091
|
}
|
|
1941
2092
|
|
|
1942
2093
|
/**
|
|
1943
2094
|
* Number fast path: plain integer literals (no leading zero, up to 15
|
|
1944
2095
|
* digits so the float is exact) are accumulated numerically — no slice,
|
|
1945
2096
|
* no parseFloat, no separator handling. Everything else (dots, exponents,
|
|
1946
|
-
* bigints, separators, octal forms) restarts
|
|
2097
|
+
* bigints, separators, octal forms) restarts the owned cold reader.
|
|
2098
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
1947
2099
|
* @this {ParserInternals}
|
|
1948
2100
|
* @param {boolean} startsWithDot whether the number started with a dot
|
|
1949
2101
|
* @returns {void}
|
|
1950
2102
|
*/
|
|
1951
2103
|
readNumber(startsWithDot) {
|
|
1952
|
-
if (startsWithDot) return
|
|
2104
|
+
if (startsWithDot) return this._readNumberCold(startsWithDot);
|
|
1953
2105
|
const input = this.input;
|
|
1954
2106
|
const start = this.pos;
|
|
1955
2107
|
const len = input.length;
|
|
@@ -1962,7 +2114,7 @@ class WebpackParser extends BaseParser {
|
|
|
1962
2114
|
pos = start + 1;
|
|
1963
2115
|
} else if (c1 > 127 || IDENT_CHAR[c1] === 1) {
|
|
1964
2116
|
// 0x/0o/0b, 0e…, 0n, 0_, legacy `0NN`, or `0`+identifier: acorn
|
|
1965
|
-
return
|
|
2117
|
+
return this._readNumberCold(startsWithDot);
|
|
1966
2118
|
} else {
|
|
1967
2119
|
// bare `0` before punctuation/operator/whitespace/EOF
|
|
1968
2120
|
this.pos = start + 1;
|
|
@@ -1993,18 +2145,18 @@ class WebpackParser extends BaseParser {
|
|
|
1993
2145
|
after > 127 ||
|
|
1994
2146
|
IDENT_CHAR[after] === 1
|
|
1995
2147
|
) {
|
|
1996
|
-
return
|
|
2148
|
+
return this._readNumberCold(startsWithDot);
|
|
1997
2149
|
}
|
|
1998
2150
|
// 15 digits always fit exactly into a double
|
|
1999
2151
|
if (pos - start > 15) {
|
|
2000
|
-
return
|
|
2152
|
+
return this._readNumberCold(startsWithDot);
|
|
2001
2153
|
}
|
|
2002
2154
|
this.pos = pos;
|
|
2003
2155
|
return this.finishToken(tokTypes.num, value);
|
|
2004
2156
|
}
|
|
2005
2157
|
// a fraction follows the integer part
|
|
2006
2158
|
} else {
|
|
2007
|
-
return
|
|
2159
|
+
return this._readNumberCold(startsWithDot);
|
|
2008
2160
|
}
|
|
2009
2161
|
// decimal fraction: `pos` is at the '.'
|
|
2010
2162
|
pos++;
|
|
@@ -2024,7 +2176,7 @@ class WebpackParser extends BaseParser {
|
|
|
2024
2176
|
after > 127 ||
|
|
2025
2177
|
IDENT_CHAR[after] === 1
|
|
2026
2178
|
) {
|
|
2027
|
-
return
|
|
2179
|
+
return this._readNumberCold(startsWithDot);
|
|
2028
2180
|
}
|
|
2029
2181
|
this.pos = pos;
|
|
2030
2182
|
this.finishToken(tokTypes.num, Number.parseFloat(input.slice(start, pos)));
|
|
@@ -2035,6 +2187,7 @@ class WebpackParser extends BaseParser {
|
|
|
2035
2187
|
* `this.input.slice(start)` — a fresh sliced string per (sloppy-mode)
|
|
2036
2188
|
* function body. Sticky regexes at the offset scan the same grammar with no
|
|
2037
2189
|
* slice. Same directive-prologue semantics, including the ASI tail checks.
|
|
2190
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/parseutil.js
|
|
2038
2191
|
* @param {number} start offset of the function body's first statement
|
|
2039
2192
|
* @returns {boolean} true when a 'use strict' directive leads the prologue
|
|
2040
2193
|
* @this {ParserInternals & { input: string, options: { ecmaVersion: number } }}
|
|
@@ -2079,9 +2232,10 @@ class WebpackParser extends BaseParser {
|
|
|
2079
2232
|
|
|
2080
2233
|
/**
|
|
2081
2234
|
* Template fast path: when the chunk contains no backslash and no CR, the
|
|
2082
|
-
* cooked value is one slice (LF/LS/PS cook to themselves). Escapes
|
|
2083
|
-
* normalization
|
|
2084
|
-
*
|
|
2235
|
+
* cooked value is one slice (LF/LS/PS cook to themselves). Escapes and CR
|
|
2236
|
+
* normalization restart the owned cold reader (its exact errors); location
|
|
2237
|
+
* tracking uses acorn's own.
|
|
2238
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2085
2239
|
* @this {ParserInternals}
|
|
2086
2240
|
* @returns {void}
|
|
2087
2241
|
*/
|
|
@@ -2109,9 +2263,9 @@ class WebpackParser extends BaseParser {
|
|
|
2109
2263
|
this.pos = pos;
|
|
2110
2264
|
return this.finishToken(tokTypes.template, input.slice(start, pos));
|
|
2111
2265
|
}
|
|
2112
|
-
// backslash and CR need
|
|
2266
|
+
// backslash and CR need the cooked-string building of the cold reader
|
|
2113
2267
|
if (ch === 92 || ch === 13) {
|
|
2114
|
-
return
|
|
2268
|
+
return this._readTmplTokenCold();
|
|
2115
2269
|
}
|
|
2116
2270
|
pos++;
|
|
2117
2271
|
}
|
|
@@ -2119,8 +2273,9 @@ class WebpackParser extends BaseParser {
|
|
|
2119
2273
|
}
|
|
2120
2274
|
|
|
2121
2275
|
/**
|
|
2122
|
-
* Fast path for the common run of plain ASCII whitespace; comments
|
|
2123
|
-
* unicode whitespace
|
|
2276
|
+
* Fast path for the common run of plain ASCII whitespace; comments and
|
|
2277
|
+
* unicode whitespace use the owned cold reader, location tracking acorn's.
|
|
2278
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2124
2279
|
* @this {ParserInternals & { pos: number }}
|
|
2125
2280
|
* @returns {void}
|
|
2126
2281
|
*/
|
|
@@ -2135,9 +2290,9 @@ class WebpackParser extends BaseParser {
|
|
|
2135
2290
|
if (ch === 32 || (ch > 8 && ch < 14)) {
|
|
2136
2291
|
pos++;
|
|
2137
2292
|
} else if (ch === 47 || ch > 127) {
|
|
2138
|
-
// comments or unicode whitespace:
|
|
2293
|
+
// comments or unicode whitespace: hand off to the cold reader
|
|
2139
2294
|
this.pos = pos;
|
|
2140
|
-
return
|
|
2295
|
+
return this._skipSpaceCold();
|
|
2141
2296
|
} else {
|
|
2142
2297
|
break;
|
|
2143
2298
|
}
|
|
@@ -2145,12 +2300,468 @@ class WebpackParser extends BaseParser {
|
|
|
2145
2300
|
this.pos = pos;
|
|
2146
2301
|
}
|
|
2147
2302
|
|
|
2303
|
+
// ----- cold-path readers (ported from acorn's tokenizer, reached only from
|
|
2304
|
+
// the lazy fast paths above; non-lazy mode keeps acorn's own prototype
|
|
2305
|
+
// methods so plugins that patch them still see acorn's tokenizer) -----
|
|
2306
|
+
|
|
2307
|
+
/**
|
|
2308
|
+
* acorn `readInt`: reads `radix`-base digits (optionally exactly `len` of
|
|
2309
|
+
* them), honoring ES2021 `_` separators.
|
|
2310
|
+
* https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2311
|
+
* @this {ParserInternals}
|
|
2312
|
+
* @param {number} radix numeric radix
|
|
2313
|
+
* @param {number=} len fixed digit count (for escapes), else read greedily
|
|
2314
|
+
* @param {boolean=} maybeLegacyOctal whether a leading zero disallows separators
|
|
2315
|
+
* @returns {number | null} the integer value, or null when no digits matched
|
|
2316
|
+
*/
|
|
2317
|
+
_readInt(radix, len, maybeLegacyOctal) {
|
|
2318
|
+
const input = this.input;
|
|
2319
|
+
const allowSeparators = this._ecmaVersion >= 12 && len === undefined;
|
|
2320
|
+
const isLegacyOctal =
|
|
2321
|
+
maybeLegacyOctal === true && input.charCodeAt(this.pos) === 48;
|
|
2322
|
+
const start = this.pos;
|
|
2323
|
+
let total = 0;
|
|
2324
|
+
let lastCode = 0;
|
|
2325
|
+
for (
|
|
2326
|
+
let i = 0, e = len === undefined ? Infinity : len;
|
|
2327
|
+
i < e;
|
|
2328
|
+
++i, ++this.pos
|
|
2329
|
+
) {
|
|
2330
|
+
const code = input.charCodeAt(this.pos);
|
|
2331
|
+
let val;
|
|
2332
|
+
if (allowSeparators && code === 95) {
|
|
2333
|
+
if (isLegacyOctal) {
|
|
2334
|
+
this.raiseRecoverable(
|
|
2335
|
+
this.pos,
|
|
2336
|
+
"Numeric separator is not allowed in legacy octal numeric literals"
|
|
2337
|
+
);
|
|
2338
|
+
}
|
|
2339
|
+
if (lastCode === 95) {
|
|
2340
|
+
this.raiseRecoverable(
|
|
2341
|
+
this.pos,
|
|
2342
|
+
"Numeric separator must be exactly one underscore"
|
|
2343
|
+
);
|
|
2344
|
+
}
|
|
2345
|
+
if (i === 0) {
|
|
2346
|
+
this.raiseRecoverable(
|
|
2347
|
+
this.pos,
|
|
2348
|
+
"Numeric separator is not allowed at the first of digits"
|
|
2349
|
+
);
|
|
2350
|
+
}
|
|
2351
|
+
lastCode = code;
|
|
2352
|
+
continue;
|
|
2353
|
+
}
|
|
2354
|
+
if (code >= 97) val = code - 97 + 10;
|
|
2355
|
+
else if (code >= 65) val = code - 65 + 10;
|
|
2356
|
+
else if (code >= 48 && code <= 57) val = code - 48;
|
|
2357
|
+
else val = Infinity;
|
|
2358
|
+
if (val >= radix) break;
|
|
2359
|
+
lastCode = code;
|
|
2360
|
+
total = total * radix + val;
|
|
2361
|
+
}
|
|
2362
|
+
if (allowSeparators && lastCode === 95) {
|
|
2363
|
+
this.raiseRecoverable(
|
|
2364
|
+
this.pos - 1,
|
|
2365
|
+
"Numeric separator is not allowed at the last of digits"
|
|
2366
|
+
);
|
|
2367
|
+
}
|
|
2368
|
+
if (this.pos === start || (len !== undefined && this.pos - start !== len)) {
|
|
2369
|
+
return null;
|
|
2370
|
+
}
|
|
2371
|
+
return total;
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
/**
|
|
2375
|
+
* acorn `readRadixNumber`: `0x`/`0o`/`0b` integer or bigint literals.
|
|
2376
|
+
* https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2377
|
+
* @this {ParserInternals}
|
|
2378
|
+
* @param {number} radix numeric radix (2/8/16)
|
|
2379
|
+
* @returns {void}
|
|
2380
|
+
*/
|
|
2381
|
+
_readRadixNumber(radix) {
|
|
2382
|
+
const input = this.input;
|
|
2383
|
+
const start = this.pos;
|
|
2384
|
+
this.pos += 2;
|
|
2385
|
+
let val = this._readInt(radix);
|
|
2386
|
+
if (val === null) {
|
|
2387
|
+
this.raise(this.start + 2, `Expected number in radix ${radix}`);
|
|
2388
|
+
}
|
|
2389
|
+
if (this._ecmaVersion >= 11 && input.charCodeAt(this.pos) === 110) {
|
|
2390
|
+
val = /** @type {EXPECTED_ANY} */ (
|
|
2391
|
+
stringToBigInt(input.slice(start, this.pos))
|
|
2392
|
+
);
|
|
2393
|
+
++this.pos;
|
|
2394
|
+
} else if (isIdentifierStart(this.fullCharCodeAtPos())) {
|
|
2395
|
+
this.raise(this.pos, "Identifier directly after number");
|
|
2396
|
+
}
|
|
2397
|
+
return this.finishToken(tokTypes.num, val);
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
/**
|
|
2401
|
+
* acorn `readNumber`: decimal/float/legacy-octal/bigint literals (the fast
|
|
2402
|
+
* path handles only plain integers and simple fractions).
|
|
2403
|
+
* https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2404
|
+
* @this {ParserInternals}
|
|
2405
|
+
* @param {boolean} startsWithDot whether the literal started with `.`
|
|
2406
|
+
* @returns {void}
|
|
2407
|
+
*/
|
|
2408
|
+
_readNumberCold(startsWithDot) {
|
|
2409
|
+
const input = this.input;
|
|
2410
|
+
const start = this.pos;
|
|
2411
|
+
if (!startsWithDot && this._readInt(10, undefined, true) === null) {
|
|
2412
|
+
this.raise(start, "Invalid number");
|
|
2413
|
+
}
|
|
2414
|
+
let octal = this.pos - start >= 2 && input.charCodeAt(start) === 48;
|
|
2415
|
+
if (octal && this.strict) this.raise(start, "Invalid number");
|
|
2416
|
+
let next = input.charCodeAt(this.pos);
|
|
2417
|
+
if (!octal && !startsWithDot && this._ecmaVersion >= 11 && next === 110) {
|
|
2418
|
+
const val = stringToBigInt(input.slice(start, this.pos));
|
|
2419
|
+
++this.pos;
|
|
2420
|
+
if (isIdentifierStart(this.fullCharCodeAtPos())) {
|
|
2421
|
+
this.raise(this.pos, "Identifier directly after number");
|
|
2422
|
+
}
|
|
2423
|
+
return this.finishToken(tokTypes.num, /** @type {EXPECTED_ANY} */ (val));
|
|
2424
|
+
}
|
|
2425
|
+
if (octal && /[89]/.test(input.slice(start, this.pos))) octal = false;
|
|
2426
|
+
if (next === 46 && !octal) {
|
|
2427
|
+
++this.pos;
|
|
2428
|
+
this._readInt(10);
|
|
2429
|
+
next = input.charCodeAt(this.pos);
|
|
2430
|
+
}
|
|
2431
|
+
if ((next === 69 || next === 101) && !octal) {
|
|
2432
|
+
next = input.charCodeAt(++this.pos);
|
|
2433
|
+
if (next === 43 || next === 45) ++this.pos;
|
|
2434
|
+
if (this._readInt(10) === null) this.raise(start, "Invalid number");
|
|
2435
|
+
}
|
|
2436
|
+
if (isIdentifierStart(this.fullCharCodeAtPos())) {
|
|
2437
|
+
this.raise(this.pos, "Identifier directly after number");
|
|
2438
|
+
}
|
|
2439
|
+
const val = stringToNumber(input.slice(start, this.pos), octal);
|
|
2440
|
+
return this.finishToken(tokTypes.num, val);
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
/**
|
|
2444
|
+
* acorn `readCodePoint`: a `\u{...}` or `\uXXXX` escape.
|
|
2445
|
+
* https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2446
|
+
* @this {ParserInternals}
|
|
2447
|
+
* @returns {number} the escaped code point
|
|
2448
|
+
*/
|
|
2449
|
+
_readCodePoint() {
|
|
2450
|
+
const input = this.input;
|
|
2451
|
+
const ch = input.charCodeAt(this.pos);
|
|
2452
|
+
let code;
|
|
2453
|
+
if (ch === 123) {
|
|
2454
|
+
if (this._ecmaVersion < 6) this.unexpected();
|
|
2455
|
+
const codePos = ++this.pos;
|
|
2456
|
+
code = this._readHexChar(input.indexOf("}", this.pos) - this.pos);
|
|
2457
|
+
++this.pos;
|
|
2458
|
+
if (code > 0x10ffff) {
|
|
2459
|
+
this.invalidStringToken(codePos, "Code point out of bounds");
|
|
2460
|
+
}
|
|
2461
|
+
} else {
|
|
2462
|
+
code = this._readHexChar(4);
|
|
2463
|
+
}
|
|
2464
|
+
return code;
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2467
|
+
/**
|
|
2468
|
+
* acorn `readHexChar`: exactly `len` hex digits.
|
|
2469
|
+
* https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2470
|
+
* @this {ParserInternals}
|
|
2471
|
+
* @param {number} len number of hex digits
|
|
2472
|
+
* @returns {number} the parsed code
|
|
2473
|
+
*/
|
|
2474
|
+
_readHexChar(len) {
|
|
2475
|
+
const codePos = this.pos;
|
|
2476
|
+
const n = this._readInt(16, len);
|
|
2477
|
+
if (n === null) {
|
|
2478
|
+
this.invalidStringToken(codePos, "Bad character escape sequence");
|
|
2479
|
+
}
|
|
2480
|
+
return /** @type {number} */ (n);
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
/**
|
|
2484
|
+
* acorn `readString`: the escape-bearing string reader (the fast path cooks
|
|
2485
|
+
* only the common single-char escapes inline).
|
|
2486
|
+
* https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2487
|
+
* @this {ParserInternals}
|
|
2488
|
+
* @param {number} quote quote char code
|
|
2489
|
+
* @returns {void}
|
|
2490
|
+
*/
|
|
2491
|
+
_readStringCold(quote) {
|
|
2492
|
+
const input = this.input;
|
|
2493
|
+
let out = "";
|
|
2494
|
+
let chunkStart = ++this.pos;
|
|
2495
|
+
for (;;) {
|
|
2496
|
+
if (this.pos >= input.length) {
|
|
2497
|
+
this.raise(this.start, "Unterminated string constant");
|
|
2498
|
+
}
|
|
2499
|
+
const ch = input.charCodeAt(this.pos);
|
|
2500
|
+
if (ch === quote) break;
|
|
2501
|
+
if (ch === 92) {
|
|
2502
|
+
out += input.slice(chunkStart, this.pos);
|
|
2503
|
+
out += this._readEscapedChar(false);
|
|
2504
|
+
chunkStart = this.pos;
|
|
2505
|
+
} else if (ch === 0x2028 || ch === 0x2029) {
|
|
2506
|
+
if (this._ecmaVersion < 10) {
|
|
2507
|
+
this.raise(this.start, "Unterminated string constant");
|
|
2508
|
+
}
|
|
2509
|
+
++this.pos;
|
|
2510
|
+
} else {
|
|
2511
|
+
if (isNewLine(ch)) {
|
|
2512
|
+
this.raise(this.start, "Unterminated string constant");
|
|
2513
|
+
}
|
|
2514
|
+
++this.pos;
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
out += input.slice(chunkStart, this.pos++);
|
|
2518
|
+
return this.finishToken(tokTypes.string, out);
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
/**
|
|
2522
|
+
* acorn `readTmplToken`: the escape/CR-normalizing template reader. Invalid
|
|
2523
|
+
* escapes throw acorn's sentinel via `invalidStringToken`, which acorn's own
|
|
2524
|
+
* `tryReadTemplateToken` (not overridden here) catches to re-read raw.
|
|
2525
|
+
* https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2526
|
+
* @this {ParserInternals}
|
|
2527
|
+
* @returns {void}
|
|
2528
|
+
*/
|
|
2529
|
+
_readTmplTokenCold() {
|
|
2530
|
+
const input = this.input;
|
|
2531
|
+
let out = "";
|
|
2532
|
+
let chunkStart = this.pos;
|
|
2533
|
+
for (;;) {
|
|
2534
|
+
if (this.pos >= input.length) {
|
|
2535
|
+
this.raise(this.start, "Unterminated template");
|
|
2536
|
+
}
|
|
2537
|
+
const ch = input.charCodeAt(this.pos);
|
|
2538
|
+
if (ch === 96 || (ch === 36 && input.charCodeAt(this.pos + 1) === 123)) {
|
|
2539
|
+
if (
|
|
2540
|
+
this.pos === this.start &&
|
|
2541
|
+
(this.type === tokTypes.template ||
|
|
2542
|
+
this.type === tokTypes.invalidTemplate)
|
|
2543
|
+
) {
|
|
2544
|
+
if (ch === 36) {
|
|
2545
|
+
this.pos += 2;
|
|
2546
|
+
return this.finishToken(tokTypes.dollarBraceL);
|
|
2547
|
+
}
|
|
2548
|
+
++this.pos;
|
|
2549
|
+
return this.finishToken(tokTypes.backQuote);
|
|
2550
|
+
}
|
|
2551
|
+
out += input.slice(chunkStart, this.pos);
|
|
2552
|
+
return this.finishToken(tokTypes.template, out);
|
|
2553
|
+
}
|
|
2554
|
+
if (ch === 92) {
|
|
2555
|
+
out += input.slice(chunkStart, this.pos);
|
|
2556
|
+
out += this._readEscapedChar(true);
|
|
2557
|
+
chunkStart = this.pos;
|
|
2558
|
+
} else if (isNewLine(ch)) {
|
|
2559
|
+
out += input.slice(chunkStart, this.pos);
|
|
2560
|
+
++this.pos;
|
|
2561
|
+
if (ch === 13 && input.charCodeAt(this.pos) === 10) ++this.pos;
|
|
2562
|
+
out += "\n";
|
|
2563
|
+
chunkStart = this.pos;
|
|
2564
|
+
} else {
|
|
2565
|
+
++this.pos;
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
/**
|
|
2571
|
+
* acorn `readEscapedChar`: cooks one backslash escape in a string/template.
|
|
2572
|
+
* https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2573
|
+
* @this {ParserInternals}
|
|
2574
|
+
* @param {boolean} inTemplate whether the escape is in a template literal
|
|
2575
|
+
* @returns {string} the cooked replacement (may be `""`)
|
|
2576
|
+
*/
|
|
2577
|
+
_readEscapedChar(inTemplate) {
|
|
2578
|
+
const input = this.input;
|
|
2579
|
+
let ch = input.charCodeAt(++this.pos);
|
|
2580
|
+
++this.pos;
|
|
2581
|
+
switch (ch) {
|
|
2582
|
+
case 110:
|
|
2583
|
+
return "\n";
|
|
2584
|
+
case 114:
|
|
2585
|
+
return "\r";
|
|
2586
|
+
case 120:
|
|
2587
|
+
return String.fromCharCode(this._readHexChar(2));
|
|
2588
|
+
case 117:
|
|
2589
|
+
return codePointToString(this._readCodePoint());
|
|
2590
|
+
case 116:
|
|
2591
|
+
return "\t";
|
|
2592
|
+
case 98:
|
|
2593
|
+
return "\b";
|
|
2594
|
+
case 118:
|
|
2595
|
+
return "\u000B";
|
|
2596
|
+
case 102:
|
|
2597
|
+
return "\f";
|
|
2598
|
+
case 13:
|
|
2599
|
+
if (input.charCodeAt(this.pos) === 10) ++this.pos;
|
|
2600
|
+
// falls through
|
|
2601
|
+
case 10:
|
|
2602
|
+
return "";
|
|
2603
|
+
case 56:
|
|
2604
|
+
case 57:
|
|
2605
|
+
if (this.strict) {
|
|
2606
|
+
this.invalidStringToken(this.pos - 1, "Invalid escape sequence");
|
|
2607
|
+
}
|
|
2608
|
+
if (inTemplate) {
|
|
2609
|
+
this.invalidStringToken(
|
|
2610
|
+
this.pos - 1,
|
|
2611
|
+
"Invalid escape sequence in template string"
|
|
2612
|
+
);
|
|
2613
|
+
}
|
|
2614
|
+
// falls through
|
|
2615
|
+
default:
|
|
2616
|
+
if (ch >= 48 && ch <= 55) {
|
|
2617
|
+
let octalStr = /** @type {RegExpMatchArray} */ (
|
|
2618
|
+
input.slice(this.pos - 1, this.pos + 2).match(/^[0-7]+/)
|
|
2619
|
+
)[0];
|
|
2620
|
+
let octal = Number.parseInt(octalStr, 8);
|
|
2621
|
+
if (octal > 255) {
|
|
2622
|
+
octalStr = octalStr.slice(0, -1);
|
|
2623
|
+
octal = Number.parseInt(octalStr, 8);
|
|
2624
|
+
}
|
|
2625
|
+
this.pos += octalStr.length - 1;
|
|
2626
|
+
ch = input.charCodeAt(this.pos);
|
|
2627
|
+
if (
|
|
2628
|
+
(octalStr !== "0" || ch === 56 || ch === 57) &&
|
|
2629
|
+
(this.strict || inTemplate)
|
|
2630
|
+
) {
|
|
2631
|
+
this.invalidStringToken(
|
|
2632
|
+
this.pos - 1 - octalStr.length,
|
|
2633
|
+
inTemplate
|
|
2634
|
+
? "Octal literal in template string"
|
|
2635
|
+
: "Octal literal in strict mode"
|
|
2636
|
+
);
|
|
2637
|
+
}
|
|
2638
|
+
return String.fromCharCode(octal);
|
|
2639
|
+
}
|
|
2640
|
+
if (isNewLine(ch)) return "";
|
|
2641
|
+
return String.fromCharCode(ch);
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2645
|
+
/**
|
|
2646
|
+
* acorn `readWord1`: the escape-/astral-aware identifier reader (the fast
|
|
2647
|
+
* path handles pure-ASCII words).
|
|
2648
|
+
* https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2649
|
+
* @this {ParserInternals}
|
|
2650
|
+
* @returns {string} the (possibly escape-cooked) word
|
|
2651
|
+
*/
|
|
2652
|
+
_readWord1Cold() {
|
|
2653
|
+
const input = this.input;
|
|
2654
|
+
this.containsEsc = false;
|
|
2655
|
+
let word = "";
|
|
2656
|
+
let first = true;
|
|
2657
|
+
let chunkStart = this.pos;
|
|
2658
|
+
const astral = this._ecmaVersion >= 6;
|
|
2659
|
+
while (this.pos < input.length) {
|
|
2660
|
+
const ch = this.fullCharCodeAtPos();
|
|
2661
|
+
if (isIdentifierChar(ch, astral)) {
|
|
2662
|
+
this.pos += ch <= 0xffff ? 1 : 2;
|
|
2663
|
+
} else if (ch === 92) {
|
|
2664
|
+
this.containsEsc = true;
|
|
2665
|
+
word += input.slice(chunkStart, this.pos);
|
|
2666
|
+
const escStart = this.pos;
|
|
2667
|
+
if (input.charCodeAt(++this.pos) !== 117) {
|
|
2668
|
+
this.invalidStringToken(
|
|
2669
|
+
this.pos,
|
|
2670
|
+
"Expecting Unicode escape sequence \\uXXXX"
|
|
2671
|
+
);
|
|
2672
|
+
}
|
|
2673
|
+
++this.pos;
|
|
2674
|
+
const esc = this._readCodePoint();
|
|
2675
|
+
if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) {
|
|
2676
|
+
this.invalidStringToken(escStart, "Invalid Unicode escape");
|
|
2677
|
+
}
|
|
2678
|
+
word += codePointToString(esc);
|
|
2679
|
+
chunkStart = this.pos;
|
|
2680
|
+
} else {
|
|
2681
|
+
break;
|
|
2682
|
+
}
|
|
2683
|
+
first = false;
|
|
2684
|
+
}
|
|
2685
|
+
return word + input.slice(chunkStart, this.pos);
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
/**
|
|
2689
|
+
* acorn `skipSpace` (location-free): unicode whitespace and comments. Only
|
|
2690
|
+
* reached from the lazy fast paths, which keep no line bookkeeping.
|
|
2691
|
+
* https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2692
|
+
* @this {ParserInternals}
|
|
2693
|
+
* @returns {void}
|
|
2694
|
+
*/
|
|
2695
|
+
_skipSpaceCold() {
|
|
2696
|
+
const input = this.input;
|
|
2697
|
+
const len = input.length;
|
|
2698
|
+
loop: while (this.pos < len) {
|
|
2699
|
+
const ch = input.charCodeAt(this.pos);
|
|
2700
|
+
switch (ch) {
|
|
2701
|
+
case 32:
|
|
2702
|
+
case 160:
|
|
2703
|
+
++this.pos;
|
|
2704
|
+
break;
|
|
2705
|
+
case 13:
|
|
2706
|
+
if (input.charCodeAt(this.pos + 1) === 10) ++this.pos;
|
|
2707
|
+
// falls through
|
|
2708
|
+
case 10:
|
|
2709
|
+
case 8232:
|
|
2710
|
+
case 8233:
|
|
2711
|
+
++this.pos;
|
|
2712
|
+
break;
|
|
2713
|
+
case 47:
|
|
2714
|
+
switch (input.charCodeAt(this.pos + 1)) {
|
|
2715
|
+
case 42:
|
|
2716
|
+
this.skipBlockComment();
|
|
2717
|
+
break;
|
|
2718
|
+
case 47:
|
|
2719
|
+
this.skipLineComment(2);
|
|
2720
|
+
break;
|
|
2721
|
+
default:
|
|
2722
|
+
break loop;
|
|
2723
|
+
}
|
|
2724
|
+
break;
|
|
2725
|
+
default:
|
|
2726
|
+
if (
|
|
2727
|
+
(ch > 8 && ch < 14) ||
|
|
2728
|
+
(ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch)))
|
|
2729
|
+
) {
|
|
2730
|
+
++this.pos;
|
|
2731
|
+
} else {
|
|
2732
|
+
break loop;
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
|
|
2738
|
+
/**
|
|
2739
|
+
* acorn `readToken_numberSign` plus `getTokenFromCode`'s default: a private
|
|
2740
|
+
* identifier (`#x`) or an unexpected-character error.
|
|
2741
|
+
* https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2742
|
+
* @this {ParserInternals}
|
|
2743
|
+
* @param {number} code current char code
|
|
2744
|
+
* @returns {void}
|
|
2745
|
+
*/
|
|
2746
|
+
_getUnknownOrPrivate(code) {
|
|
2747
|
+
if (code === 35 && this._ecmaVersion >= 13) {
|
|
2748
|
+
++this.pos;
|
|
2749
|
+
const next = this.fullCharCodeAtPos();
|
|
2750
|
+
if (isIdentifierStart(next, true) || next === 92) {
|
|
2751
|
+
return this.finishToken(tokTypes.privateId, this.readWord1());
|
|
2752
|
+
}
|
|
2753
|
+
this.raise(this.pos, `Unexpected character '${codePointToString(next)}'`);
|
|
2754
|
+
}
|
|
2755
|
+
this.raise(this.pos, `Unexpected character '${codePointToString(code)}'`);
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2148
2758
|
// ----- word classification (Map/Set lookups, replaces acorn's regexps) -----
|
|
2149
2759
|
|
|
2150
2760
|
/**
|
|
2151
2761
|
* Replaces acorn's `readWord`, whose `this.keywords.test(word)` runs an
|
|
2152
2762
|
* anchored alternation regexp for every identifier and keyword token; a
|
|
2153
2763
|
* Map lookup on the same keyword set is cheaper.
|
|
2764
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2154
2765
|
* @this {ParserInternals}
|
|
2155
2766
|
* @returns {void}
|
|
2156
2767
|
*/
|
|
@@ -2176,6 +2787,7 @@ class WebpackParser extends BaseParser {
|
|
|
2176
2787
|
* single `reservedKinds` lookup — one hash probe instead of two, and the
|
|
2177
2788
|
* common plain identifier misses it and returns. Branches and error
|
|
2178
2789
|
* messages match acorn exactly.
|
|
2790
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
2179
2791
|
* @param {Identifier} ref identifier node
|
|
2180
2792
|
* @this {ParserInternals}
|
|
2181
2793
|
*/
|
|
@@ -2243,6 +2855,7 @@ class WebpackParser extends BaseParser {
|
|
|
2243
2855
|
* inter-token gap and runs a regexp on it for every ASI decision (hundreds
|
|
2244
2856
|
* of thousands per file). Scan the gap for a line terminator instead — no
|
|
2245
2857
|
* slice, no regexp.
|
|
2858
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/parseutil.js
|
|
2246
2859
|
* @returns {boolean} whether a semicolon may be inserted here
|
|
2247
2860
|
* @this {ParserInternals}
|
|
2248
2861
|
*/
|
|
@@ -2261,6 +2874,7 @@ class WebpackParser extends BaseParser {
|
|
|
2261
2874
|
* Replaces acorn's `skipLineComment` when comments are collected lazily:
|
|
2262
2875
|
* the same scan, but no text slice and no position objects. Acorn calls
|
|
2263
2876
|
* this for `//`, hashbangs and HTML-style comments (varying `startSkip`).
|
|
2877
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2264
2878
|
* @this {ParserInternals}
|
|
2265
2879
|
* @param {number} startSkip length of the comment opener
|
|
2266
2880
|
* @returns {void}
|
|
@@ -2287,6 +2901,7 @@ class WebpackParser extends BaseParser {
|
|
|
2287
2901
|
/**
|
|
2288
2902
|
* Replaces acorn's `skipBlockComment` when comments are collected lazily.
|
|
2289
2903
|
* Locations are always off in lazy mode, so line breaks need no handling.
|
|
2904
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
2290
2905
|
* @this {ParserInternals}
|
|
2291
2906
|
* @returns {void}
|
|
2292
2907
|
*/
|
|
@@ -2307,6 +2922,7 @@ class WebpackParser extends BaseParser {
|
|
|
2307
2922
|
// ----- lazy range -----
|
|
2308
2923
|
|
|
2309
2924
|
/**
|
|
2925
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/node.js
|
|
2310
2926
|
* @returns {Node} new node
|
|
2311
2927
|
* @this {ParserInternals}
|
|
2312
2928
|
*/
|
|
@@ -2316,6 +2932,7 @@ class WebpackParser extends BaseParser {
|
|
|
2316
2932
|
}
|
|
2317
2933
|
|
|
2318
2934
|
/**
|
|
2935
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/node.js
|
|
2319
2936
|
* @param {number} pos start offset
|
|
2320
2937
|
* @param {Position=} loc start position when acorn tracks locations
|
|
2321
2938
|
* @returns {Node} new node
|
|
@@ -2330,6 +2947,7 @@ class WebpackParser extends BaseParser {
|
|
|
2330
2947
|
* Lazy-mode `finishNode`: acorn's `locations`/`ranges` writes are dead when
|
|
2331
2948
|
* `range` is served lazily and `loc` not at all, so skip them and the `finishNodeAt`
|
|
2332
2949
|
* indirection. Runs once per node.
|
|
2950
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/node.js
|
|
2333
2951
|
* @param {Node} node node to finish
|
|
2334
2952
|
* @param {string} type node type
|
|
2335
2953
|
* @returns {Node} the finished node
|
|
@@ -2345,6 +2963,7 @@ class WebpackParser extends BaseParser {
|
|
|
2345
2963
|
/**
|
|
2346
2964
|
* Mirror of acorn's `copyNode`, which bypasses `startNodeAt` via
|
|
2347
2965
|
* `new Node(...)` and would otherwise produce non-lazy nodes.
|
|
2966
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/node.js
|
|
2348
2967
|
* @param {Node} node node to copy
|
|
2349
2968
|
* @returns {Node} copied node
|
|
2350
2969
|
* @this {ParserInternals}
|
|
@@ -2369,6 +2988,7 @@ class WebpackParser extends BaseParser {
|
|
|
2369
2988
|
* `IdentifierNode` directly, skipping acorn's `parseIdentNode`/`startNode`/
|
|
2370
2989
|
* `finishNode` chain and its keyword branches. Keyword-as-identifier
|
|
2371
2990
|
* (`obj.class`) and non-lazy mode delegate to acorn.
|
|
2991
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
2372
2992
|
* @param {boolean=} liberal whether reserved words are allowed
|
|
2373
2993
|
* @returns {Identifier} identifier node
|
|
2374
2994
|
* @this {ParserInternals}
|
|
@@ -2403,6 +3023,7 @@ class WebpackParser extends BaseParser {
|
|
|
2403
3023
|
* reachable during it), landing on `MemberExpressionNode`/
|
|
2404
3024
|
* `CallExpressionNode`'s single shapes. Pre-optional-chaining ecmaVersions
|
|
2405
3025
|
* and non-lazy mode delegate to acorn.
|
|
3026
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
2406
3027
|
* @param {Expression} baseExpr subscript base
|
|
2407
3028
|
* @param {number} startPos expression start offset
|
|
2408
3029
|
* @param {Position | undefined} startLoc expression start position
|
|
@@ -2554,6 +3175,7 @@ class WebpackParser extends BaseParser {
|
|
|
2554
3175
|
* blocks and plain expression statements) without it; everything rarer, the
|
|
2555
3176
|
* `name`-token ambiguities (`let`/`async`/`using`/`await` heads) and
|
|
2556
3177
|
* plugin-overridden parsers delegate to acorn.
|
|
3178
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2557
3179
|
* @param {string | null} context statement context
|
|
2558
3180
|
* @param {boolean=} topLevel whether parsing top-level statements
|
|
2559
3181
|
* @param {unknown=} exports export tracking object
|
|
@@ -2641,6 +3263,7 @@ class WebpackParser extends BaseParser {
|
|
|
2641
3263
|
* Owned `parseVarStatement`: the passed started node is filled by
|
|
2642
3264
|
* `parseVar` as acorn expects, then the finished statement lands on
|
|
2643
3265
|
* `VariableDeclarationNode`'s single shape. Non-lazy mode delegates.
|
|
3266
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2644
3267
|
* @param {Node} node started statement node from `parseStatement`
|
|
2645
3268
|
* @param {string} kind declaration kind
|
|
2646
3269
|
* @param {boolean=} allowMissingInitializer whether `const x;` is allowed
|
|
@@ -2662,6 +3285,7 @@ class WebpackParser extends BaseParser {
|
|
|
2662
3285
|
/**
|
|
2663
3286
|
* Statement-position `var`/`let`/`const` without a started node: the
|
|
2664
3287
|
* declaration lands directly on `VariableDeclarationNode`'s single shape.
|
|
3288
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2665
3289
|
* @param {number} start statement start offset
|
|
2666
3290
|
* @param {string} kind declaration kind
|
|
2667
3291
|
* @param {boolean=} allowMissingInitializer whether `const x;` is allowed
|
|
@@ -2686,6 +3310,7 @@ class WebpackParser extends BaseParser {
|
|
|
2686
3310
|
* declarator fully-formed on `VariableDeclaratorNode`'s single shape. The
|
|
2687
3311
|
* passed node keeps receiving `declarations`/`kind` because
|
|
2688
3312
|
* `parseForStatement` finishes it itself. Non-lazy mode delegates.
|
|
3313
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2689
3314
|
* @param {Node} node declaration node to fill
|
|
2690
3315
|
* @param {boolean} isFor whether parsing a `for` head
|
|
2691
3316
|
* @param {string} kind declaration kind
|
|
@@ -2716,6 +3341,7 @@ class WebpackParser extends BaseParser {
|
|
|
2716
3341
|
/**
|
|
2717
3342
|
* The declarator loop of the owned `parseVar`, shared with the owned
|
|
2718
3343
|
* `parseStatement`'s node-free statement path.
|
|
3344
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2719
3345
|
* @param {Node[]} declarations output array for the declarators
|
|
2720
3346
|
* @param {boolean} isFor whether parsing a `for` head
|
|
2721
3347
|
* @param {string} kind declaration kind
|
|
@@ -2783,6 +3409,7 @@ class WebpackParser extends BaseParser {
|
|
|
2783
3409
|
* Owned `parseExpressionStatement`: the statement lands on
|
|
2784
3410
|
* `ExpressionStatementNode`'s single shape (the passed started node is
|
|
2785
3411
|
* discarded, matching acorn's observable output). Non-lazy mode delegates.
|
|
3412
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2786
3413
|
* @param {Node} node started statement node from `parseStatement`
|
|
2787
3414
|
* @param {Expression} expr the parsed expression
|
|
2788
3415
|
* @returns {Node} expression statement
|
|
@@ -2797,6 +3424,7 @@ class WebpackParser extends BaseParser {
|
|
|
2797
3424
|
|
|
2798
3425
|
/**
|
|
2799
3426
|
* `parseExpressionStatement` without a started node.
|
|
3427
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2800
3428
|
* @param {number} start statement start offset
|
|
2801
3429
|
* @param {Expression} expr the parsed expression
|
|
2802
3430
|
* @returns {Node} expression statement
|
|
@@ -2814,6 +3442,7 @@ class WebpackParser extends BaseParser {
|
|
|
2814
3442
|
/**
|
|
2815
3443
|
* Owned `parseBlock`, an exact-semantics copy of acorn 8's landing on
|
|
2816
3444
|
* `BlockStatementNode`'s single shape. Non-lazy mode delegates.
|
|
3445
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2817
3446
|
* @param {boolean=} createNewLexicalScope whether the block opens a scope
|
|
2818
3447
|
* @param {Node=} node started statement node, when called from `parseStatement`
|
|
2819
3448
|
* @param {boolean=} exitStrict whether to restore sloppy mode at the end
|
|
@@ -2851,6 +3480,7 @@ class WebpackParser extends BaseParser {
|
|
|
2851
3480
|
/**
|
|
2852
3481
|
* Owned `parseIfStatement` landing on `IfStatementNode`'s single shape.
|
|
2853
3482
|
* Non-lazy mode delegates to acorn.
|
|
3483
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2854
3484
|
* @param {Node} node started statement node from `parseStatement`
|
|
2855
3485
|
* @returns {Node} if statement
|
|
2856
3486
|
* @this {ParserInternals}
|
|
@@ -2862,6 +3492,7 @@ class WebpackParser extends BaseParser {
|
|
|
2862
3492
|
|
|
2863
3493
|
/**
|
|
2864
3494
|
* `parseIfStatement` without a started node.
|
|
3495
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2865
3496
|
* @param {number} start statement start offset
|
|
2866
3497
|
* @returns {Node} if statement
|
|
2867
3498
|
* @this {ParserInternals}
|
|
@@ -2884,6 +3515,7 @@ class WebpackParser extends BaseParser {
|
|
|
2884
3515
|
/**
|
|
2885
3516
|
* Owned `parseReturnStatement` landing on `ReturnStatementNode`'s single
|
|
2886
3517
|
* shape. Non-lazy mode delegates to acorn.
|
|
3518
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2887
3519
|
* @param {Node} node started statement node from `parseStatement`
|
|
2888
3520
|
* @returns {Node} return statement
|
|
2889
3521
|
* @this {ParserInternals}
|
|
@@ -2923,6 +3555,7 @@ class WebpackParser extends BaseParser {
|
|
|
2923
3555
|
|
|
2924
3556
|
/**
|
|
2925
3557
|
* `parseReturnStatement` without a started node.
|
|
3558
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
2926
3559
|
* @param {number} start statement start offset
|
|
2927
3560
|
* @returns {Node} return statement
|
|
2928
3561
|
* @this {ParserInternals}
|
|
@@ -2949,6 +3582,7 @@ class WebpackParser extends BaseParser {
|
|
|
2949
3582
|
/**
|
|
2950
3583
|
* Owned `parseSpread` landing on `RestSpreadNode`'s single shape.
|
|
2951
3584
|
* Non-lazy mode delegates.
|
|
3585
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/lval.js
|
|
2952
3586
|
* @param {DestructuringErrorsShim | null=} refDestructuringErrors destructuring errors to fill
|
|
2953
3587
|
* @returns {Node} spread element
|
|
2954
3588
|
* @this {ParserInternals}
|
|
@@ -2970,6 +3604,7 @@ class WebpackParser extends BaseParser {
|
|
|
2970
3604
|
/**
|
|
2971
3605
|
* Owned `parseMaybeConditional` landing on
|
|
2972
3606
|
* `ConditionalExpressionNode`'s single shape. Non-lazy mode delegates.
|
|
3607
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
2973
3608
|
* @param {boolean | string=} forInit for-init context flag
|
|
2974
3609
|
* @param {DestructuringErrorsShim | null=} refDestructuringErrors destructuring errors to fill
|
|
2975
3610
|
* @returns {Expression} expression node
|
|
@@ -3013,6 +3648,7 @@ class WebpackParser extends BaseParser {
|
|
|
3013
3648
|
* lands on `NewExpressionNode`'s single shape (zero-argument calls share
|
|
3014
3649
|
* one empty array like acorn's `empty`); the rare `new.target` path keeps
|
|
3015
3650
|
* the generic node. Non-lazy mode delegates.
|
|
3651
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3016
3652
|
* @returns {Expression} new expression or meta property
|
|
3017
3653
|
* @this {ParserInternals}
|
|
3018
3654
|
*/
|
|
@@ -3084,6 +3720,7 @@ class WebpackParser extends BaseParser {
|
|
|
3084
3720
|
* Owned `parseTemplateElement` landing on `TemplateElementNode`'s single
|
|
3085
3721
|
* shape; matches acorn's CRLF normalization and invalid-escape handling.
|
|
3086
3722
|
* Non-lazy mode delegates.
|
|
3723
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3087
3724
|
* @param {{ isTagged: boolean }} opts whether the template is tagged
|
|
3088
3725
|
* @returns {Node} template element
|
|
3089
3726
|
* @this {ParserInternals}
|
|
@@ -3134,6 +3771,7 @@ class WebpackParser extends BaseParser {
|
|
|
3134
3771
|
/**
|
|
3135
3772
|
* Owned `parseTemplate` landing on `TemplateLiteralNode`'s single shape.
|
|
3136
3773
|
* Non-lazy mode delegates.
|
|
3774
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3137
3775
|
* @param {{ isTagged?: boolean }=} opts whether the template is tagged
|
|
3138
3776
|
* @returns {Node} template literal
|
|
3139
3777
|
* @this {ParserInternals}
|
|
@@ -3180,6 +3818,7 @@ class WebpackParser extends BaseParser {
|
|
|
3180
3818
|
* Owned `parseMaybeUnary`, an exact-semantics copy of acorn 8's: prefix
|
|
3181
3819
|
* unary/update and postfix update nodes are built fully-formed on
|
|
3182
3820
|
* `UnaryNode`'s shared single shape. Non-lazy mode delegates to acorn.
|
|
3821
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3183
3822
|
* @param {DestructuringErrorsShim | null} refDestructuringErrors destructuring errors to fill
|
|
3184
3823
|
* @param {boolean} sawUnary whether a unary operator was already consumed
|
|
3185
3824
|
* @param {boolean} incDec whether the caller was an update operator
|
|
@@ -3297,6 +3936,7 @@ class WebpackParser extends BaseParser {
|
|
|
3297
3936
|
* operator is captured before `next()` and the `AssignmentExpression` is
|
|
3298
3937
|
* built fully-formed on `AssignmentNode`'s single shape after the
|
|
3299
3938
|
* right-hand parse. Yield and non-lazy mode delegate to acorn.
|
|
3939
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3300
3940
|
* @param {boolean | string=} forInit for-init context flag
|
|
3301
3941
|
* @param {DestructuringErrorsShim | null=} refDestructuringErrors destructuring errors to fill
|
|
3302
3942
|
* @param {((this: unknown, left: Expression, startPos: number, startLoc?: Position) => Expression)=} afterLeftParse hook applied to the parsed left side
|
|
@@ -3393,6 +4033,7 @@ class WebpackParser extends BaseParser {
|
|
|
3393
4033
|
* Owned `parseExprOps`, an exact copy of acorn 8's, so the hot expression
|
|
3394
4034
|
* spine (`parseMaybeAssign` → here → `parseMaybeUnary`) stays monomorphic
|
|
3395
4035
|
* on owned code. Non-lazy mode delegates.
|
|
4036
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3396
4037
|
* @param {boolean | string=} forInit for-init context flag
|
|
3397
4038
|
* @param {DestructuringErrorsShim | null=} refDestructuringErrors destructuring errors to fill
|
|
3398
4039
|
* @returns {Expression} expression node
|
|
@@ -3421,6 +4062,7 @@ class WebpackParser extends BaseParser {
|
|
|
3421
4062
|
* same-precedence continuation turned from tail recursion into a loop —
|
|
3422
4063
|
* `a + b + c + d` runs one frame instead of one per operator. Non-lazy mode
|
|
3423
4064
|
* delegates.
|
|
4065
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3424
4066
|
* @param {Expression} left left operand
|
|
3425
4067
|
* @param {number} leftStartPos expression start offset
|
|
3426
4068
|
* @param {Position | undefined} leftStartLoc expression start position
|
|
@@ -3497,6 +4139,7 @@ class WebpackParser extends BaseParser {
|
|
|
3497
4139
|
* Owned `buildBinary` (acorn calls it only from `parseExprOp`): binary and
|
|
3498
4140
|
* logical nodes are built fully-formed on `BinaryNode`'s single shape.
|
|
3499
4141
|
* Non-lazy mode delegates to acorn.
|
|
4142
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3500
4143
|
* @param {number} startPos expression start offset
|
|
3501
4144
|
* @param {Position | undefined} startLoc expression start position
|
|
3502
4145
|
* @param {Expression} left left operand
|
|
@@ -3544,6 +4187,7 @@ class WebpackParser extends BaseParser {
|
|
|
3544
4187
|
* async-function/async-arrow detection), number/string literals, keyword
|
|
3545
4188
|
* literals (`true`/`false`/`null` — on the same `LiteralNode` shape as the
|
|
3546
4189
|
* rest) and `this`. Everything else, and non-lazy mode, delegates to acorn.
|
|
4190
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3547
4191
|
* @param {DestructuringErrorsShim | null=} refDestructuringErrors destructuring errors to fill
|
|
3548
4192
|
* @param {boolean | string=} forInit for-init context flag
|
|
3549
4193
|
* @param {boolean=} forNew whether parsed as a `new` callee
|
|
@@ -3670,6 +4314,7 @@ class WebpackParser extends BaseParser {
|
|
|
3670
4314
|
* Owned `parseObj`, an exact-semantics copy of acorn 8's landing on
|
|
3671
4315
|
* `ObjectNode`'s single shape (the ES5 trailing-comma gate is dropped —
|
|
3672
4316
|
* the fast path requires ES11+). Non-lazy mode delegates.
|
|
4317
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3673
4318
|
* @param {boolean} isPattern whether parsing a binding pattern
|
|
3674
4319
|
* @param {DestructuringErrorsShim | null=} refDestructuringErrors destructuring errors to fill
|
|
3675
4320
|
* @returns {Node} object expression or pattern
|
|
@@ -3736,6 +4381,7 @@ class WebpackParser extends BaseParser {
|
|
|
3736
4381
|
* `PropertyNode`, which acorn's shared `parsePropertyName`/
|
|
3737
4382
|
* `parsePropertyValue` then fill in place (ES9+ semantics assumed via the
|
|
3738
4383
|
* ES11 fast-path gate). Non-lazy mode delegates.
|
|
4384
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3739
4385
|
* @param {boolean} isPattern whether parsing a binding pattern
|
|
3740
4386
|
* @param {DestructuringErrorsShim | null=} refDestructuringErrors destructuring errors to fill
|
|
3741
4387
|
* @returns {Node} property, spread element or rest element
|
|
@@ -3829,6 +4475,7 @@ class WebpackParser extends BaseParser {
|
|
|
3829
4475
|
/**
|
|
3830
4476
|
* Owned `parseLiteral`: builds the finished `LiteralNode` directly; the
|
|
3831
4477
|
* `bigint` branch matches acorn's. Non-lazy mode delegates to acorn.
|
|
4478
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
3832
4479
|
* @param {unknown} value literal value
|
|
3833
4480
|
* @returns {Node} literal node
|
|
3834
4481
|
* @this {ParserInternals}
|
|
@@ -3854,6 +4501,7 @@ class WebpackParser extends BaseParser {
|
|
|
3854
4501
|
* then builds the value with a second `new RegExp`. This override scans
|
|
3855
4502
|
* like acorn, keeps acorn's flag validation (for its exact messages) and
|
|
3856
4503
|
* lets one `new RegExp` be both the V8-backed validation and the value.
|
|
4504
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/tokenize.js
|
|
3857
4505
|
* @this {ParserInternals & { regexpState: unknown }}
|
|
3858
4506
|
* @returns {void}
|
|
3859
4507
|
*/
|
|
@@ -3926,6 +4574,7 @@ class WebpackParser extends BaseParser {
|
|
|
3926
4574
|
* that validation costs several percent of parse time. Raise from V8's
|
|
3927
4575
|
* verdict instead — invalid patterns still fail the module build, only
|
|
3928
4576
|
* exotic engine-specific message texts may differ.
|
|
4577
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/regexp.js
|
|
3929
4578
|
* @param {{ start: number, source: string, flags: string }} state acorn regexp validation state
|
|
3930
4579
|
* @this {ParserInternals}
|
|
3931
4580
|
*/
|
|
@@ -3941,6 +4590,7 @@ class WebpackParser extends BaseParser {
|
|
|
3941
4590
|
// ----- scope tracking (Set-based, replaces acorn's array + indexOf) -----
|
|
3942
4591
|
|
|
3943
4592
|
/**
|
|
4593
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/scope.js
|
|
3944
4594
|
* @param {number} flags scope flags
|
|
3945
4595
|
* @this {ParserInternals}
|
|
3946
4596
|
*/
|
|
@@ -3950,6 +4600,7 @@ class WebpackParser extends BaseParser {
|
|
|
3950
4600
|
|
|
3951
4601
|
/**
|
|
3952
4602
|
* Set-backed replacement for acorn's `declareName` on Set-backed scopes.
|
|
4603
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/scope.js
|
|
3953
4604
|
* @param {string} name declared name
|
|
3954
4605
|
* @param {number} bindingType acorn BIND_* binding type
|
|
3955
4606
|
* @param {number} pos source offset for redeclaration errors
|
|
@@ -4020,6 +4671,7 @@ class WebpackParser extends BaseParser {
|
|
|
4020
4671
|
|
|
4021
4672
|
/**
|
|
4022
4673
|
* Set-backed replacement for acorn's `checkLocalExport` on Set-backed scopes.
|
|
4674
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/scope.js
|
|
4023
4675
|
* @param {Identifier} id exported identifier
|
|
4024
4676
|
* @this {ParserInternals}
|
|
4025
4677
|
*/
|
|
@@ -4095,6 +4747,7 @@ class WebpackParser extends BaseParser {
|
|
|
4095
4747
|
// ----- import phases (`import defer/source`, `import.defer/source()`) -----
|
|
4096
4748
|
|
|
4097
4749
|
/**
|
|
4750
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
4098
4751
|
* @param {Node & { phase?: ImportPhase }} node import declaration node
|
|
4099
4752
|
* @returns {Node} finished node
|
|
4100
4753
|
* @this {ParserInternals}
|
|
@@ -4110,6 +4763,7 @@ class WebpackParser extends BaseParser {
|
|
|
4110
4763
|
/**
|
|
4111
4764
|
* Owned `parseExport` only to flag module syntax for the auto-fallback guard;
|
|
4112
4765
|
* parsing itself delegates to acorn.
|
|
4766
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
4113
4767
|
* @param {Node} node started export node
|
|
4114
4768
|
* @param {unknown} exports export-name tracking object
|
|
4115
4769
|
* @returns {Node} export declaration
|
|
@@ -4123,6 +4777,7 @@ class WebpackParser extends BaseParser {
|
|
|
4123
4777
|
/**
|
|
4124
4778
|
* Owned `parseAwait` only to flag top-level await (module-only) for the
|
|
4125
4779
|
* auto-fallback guard; await inside a function is not module syntax.
|
|
4780
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
4126
4781
|
* @param {boolean | string=} forInit for-loop init context flag
|
|
4127
4782
|
* @returns {Expression} await expression
|
|
4128
4783
|
* @this {ParserInternals}
|
|
@@ -4135,6 +4790,7 @@ class WebpackParser extends BaseParser {
|
|
|
4135
4790
|
}
|
|
4136
4791
|
|
|
4137
4792
|
/**
|
|
4793
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/statement.js
|
|
4138
4794
|
* @returns {AnyImportSpecifier[]} import specifiers
|
|
4139
4795
|
* @this {ParserInternals}
|
|
4140
4796
|
*/
|
|
@@ -4211,6 +4867,7 @@ class WebpackParser extends BaseParser {
|
|
|
4211
4867
|
}
|
|
4212
4868
|
|
|
4213
4869
|
/**
|
|
4870
|
+
* acorn source: https://github.com/acornjs/acorn/blob/8.17.0/acorn/src/expression.js
|
|
4214
4871
|
* @param {boolean} forNew whether parsed as the operand of `new`
|
|
4215
4872
|
* @returns {Expression} expression node
|
|
4216
4873
|
* @this {ParserInternals}
|