webpack 5.111.0 → 5.111.1
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/lib/APIPlugin.js +3 -4
- package/lib/CompatibilityPlugin.js +3 -4
- package/lib/Compilation.js +16 -35
- package/lib/Compiler.js +4 -5
- package/lib/ConstPlugin.js +16 -132
- package/lib/DependencyTemplate.js +2 -1
- package/lib/DotenvPlugin.js +24 -28
- package/lib/ErrorHelpers.js +113 -0
- package/lib/ExportsInfo.js +20 -16
- package/lib/ExternalModule.js +6 -8
- package/lib/FlagDependencyExportsPlugin.js +8 -13
- package/lib/FlagDependencyUsagePlugin.js +9 -13
- package/lib/Generator.js +24 -2
- package/lib/HotModuleReplacementPlugin.js +2 -0
- package/lib/IgnorePlugin.js +1 -1
- package/lib/LoaderOptionsPlugin.js +1 -1
- package/lib/Module.js +3 -3
- package/lib/ModuleGraph.js +6 -9
- package/lib/MultiCompiler.js +6 -16
- package/lib/NormalModule.js +96 -44
- package/lib/RuntimeTemplate.js +33 -43
- package/lib/SourceMapDevToolPlugin.js +53 -103
- package/lib/TemplatedPathPlugin.js +16 -59
- package/lib/asset/AssetBytesGenerator.js +7 -1
- package/lib/asset/AssetGenerator.js +25 -16
- package/lib/asset/AssetSourceGenerator.js +7 -1
- package/lib/buildChunkGraph.js +11 -15
- package/lib/cache/MemoryCachePlugin.js +4 -4
- package/lib/cache/MemoryWithGcCachePlugin.js +7 -8
- package/lib/cache/PackFileCacheStrategy.js +3 -18
- package/lib/cache/getLazyHashedEtag.js +3 -5
- package/lib/config/browserslistTargetHandler.js +2 -8
- package/lib/config/defaults.js +52 -78
- package/lib/config/getClaimedAssetTypes.js +10 -11
- package/lib/config/target.js +3 -4
- package/lib/{ContextExclusionPlugin.js → context/ContextExclusionPlugin.js} +1 -1
- package/lib/{ContextModule.js → context/ContextModule.js} +37 -34
- package/lib/{ContextModuleFactory.js → context/ContextModuleFactory.js} +19 -21
- package/lib/{ContextReplacementPlugin.js → context/ContextReplacementPlugin.js} +4 -4
- package/lib/css/CssGenerator.js +19 -11
- package/lib/css/CssParser.js +18 -20
- package/lib/css/cssMinify.js +32 -29
- package/lib/css/data.js +797 -288
- package/lib/css/syntax.js +2250 -934
- package/lib/debug/ProfilingPlugin.js +3 -4
- package/lib/dependencies/CommonJsExportRequireDependency.js +10 -11
- package/lib/dependencies/CommonJsImportsParserPlugin.js +4 -5
- package/lib/dependencies/CommonJsSelfReferenceDependency.js +2 -4
- package/lib/dependencies/ContextDependency.js +1 -1
- package/lib/dependencies/ContextDependencyHelpers.js +3 -9
- package/lib/dependencies/ContextElementDependency.js +1 -1
- package/lib/dependencies/CssIcssExportDependency.js +6 -8
- package/lib/dependencies/CssIcssImportDependency.js +3 -6
- package/lib/dependencies/CssUrlDependency.js +3 -5
- package/lib/dependencies/HarmonyCompatibilityDependency.js +11 -20
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +3 -4
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +2 -4
- package/lib/dependencies/HarmonyExportExpressionDependency.js +3 -4
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +3 -4
- package/lib/dependencies/HarmonyExportInitFragment.js +26 -19
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +7 -28
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +103 -16
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +3 -4
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +16 -2
- package/lib/dependencies/HtmlEntryDependency.js +74 -102
- package/lib/dependencies/HtmlInlineScriptDependency.js +3 -4
- package/lib/dependencies/HtmlInlineStyleDependency.js +3 -4
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
- package/lib/dependencies/ImportMetaGlobHelpers.js +1 -1
- package/lib/dependencies/ImportMetaPlugin.js +8 -10
- package/lib/dependencies/ImportParserPlugin.js +1 -1
- package/lib/dependencies/LoaderPlugin.js +26 -1
- package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
- package/lib/dependencies/URLContextDependency.js +1 -1
- package/lib/dependencies/URLDependency.js +6 -5
- package/lib/dependencies/WorkerAndWorkletPlugin.js +15 -21
- package/lib/dependencies/WorkerDependency.js +6 -5
- package/lib/dependencies/WorkletDependency.js +6 -9
- package/lib/errors/HookWebpackError.js +3 -2
- package/lib/hmr/LazyCompilationPlugin.js +3 -5
- package/lib/html/HtmlGenerator.js +61 -82
- package/lib/html/HtmlModulesPlugin.js +88 -139
- package/lib/html/HtmlParser.js +97 -141
- package/lib/html/data.js +21 -0
- package/lib/html/htmlMinify.js +10 -11
- package/lib/html/syntax.js +883 -993
- package/lib/index.js +46 -3
- package/lib/javascript/ChunkFormatHelpers.js +4 -3
- package/lib/javascript/JavascriptGenerator.js +8 -1
- package/lib/javascript/JavascriptModulesPlugin.js +21 -48
- package/lib/javascript/JavascriptParser.js +721 -178
- package/lib/javascript/parser.js +6 -0
- package/lib/javascript/syntax.js +420 -92
- package/lib/json/JsonGenerator.js +7 -1
- package/lib/library/ModuleLibraryPlugin.js +64 -136
- package/lib/loaders/LoaderRunner.js +137 -9
- package/lib/node/NodeWatchFileSystem.js +3 -9
- package/lib/optimize/AggressiveMergingPlugin.js +3 -5
- package/lib/optimize/ConcatenatedModule.js +81 -100
- package/lib/optimize/FlagIncludedChunksPlugin.js +3 -11
- package/lib/optimize/InnerGraphPlugin.js +7 -13
- package/lib/optimize/LimitChunkCountPlugin.js +5 -8
- package/lib/optimize/MangleExportsPlugin.js +3 -4
- package/lib/optimize/ModuleConcatenationPlugin.js +3 -4
- package/lib/optimize/SideEffectsFlagPlugin.js +7 -19
- package/lib/optimize/SplitChunksPlugin.js +2 -4
- package/lib/performance/BroadContextsPlugin.js +1 -1
- package/lib/performance/CacheEffectivenessPlugin.js +3 -4
- package/lib/performance/SizeLimitsPlugin.js +2 -4
- package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +6 -8
- package/lib/prefetch/ResourceHintPlugin.js +17 -21
- package/lib/prefetch/StartupAssetHintRuntimeModule.js +7 -10
- package/lib/runtime/AsyncModuleRuntimeModule.js +3 -5
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -4
- package/lib/runtime/GlobalRuntimeModule.js +2 -4
- package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +55 -85
- package/lib/schemes/DataUriPlugin.js +3 -6
- package/lib/schemes/VirtualUrlPlugin.js +1 -1
- package/lib/serialization/BinaryMiddleware.js +9 -9
- package/lib/serialization/FileMiddleware.js +16 -16
- package/lib/serialization/ObjectMiddleware.js +30 -33
- package/lib/stats/DefaultStatsFactoryPlugin.js +3 -4
- package/lib/typescript/TypeScriptPlugin.js +2 -3
- package/lib/url/URLParserPlugin.js +6 -8
- package/lib/util/LocConverter.js +4 -7
- package/lib/util/SourceProcessor.js +15 -22
- package/lib/util/chainedImports.js +3 -4
- package/lib/util/concatenate.js +4 -4
- package/lib/util/createHooksRegistry.js +1 -2
- package/lib/util/dataURL.js +2 -3
- package/lib/util/deterministicGrouping.js +8 -13
- package/lib/util/findGraphRoots.js +6 -13
- package/lib/util/globUtils.js +1 -1
- package/lib/util/hash/wasm-hash.js +3 -4
- package/lib/util/internalSerializables.js +1 -1
- package/lib/util/semver.js +5 -3
- package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -1
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +5 -1
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +3 -4
- package/lib/wasm-sync/WebAssemblyGenerator.js +6 -1
- package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +5 -1
- package/lib/wasm-sync/WebAssemblyUtils.js +2 -4
- package/package.json +30 -23
- package/types.d.ts +299 -280
|
@@ -17,12 +17,19 @@ const {
|
|
|
17
17
|
parseCommentOptionsInRange
|
|
18
18
|
} = require("../util/magicComment");
|
|
19
19
|
const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
|
20
|
+
const { nonASCIIwhitespace } = require("./parser");
|
|
20
21
|
const {
|
|
22
|
+
BLOCK_DECLARATIONS,
|
|
23
|
+
HOISTED_DECLARATIONS,
|
|
21
24
|
LEGACY_ASSERT_ATTRIBUTES,
|
|
25
|
+
MAX_MASKED_INDEX,
|
|
26
|
+
MODULE_DECLARATIONS,
|
|
22
27
|
WebpackParser,
|
|
23
28
|
buildLineStarts,
|
|
29
|
+
declaresIntoBlock,
|
|
24
30
|
hasOctalEscape,
|
|
25
31
|
isIdentifierChar,
|
|
32
|
+
overflowFrom,
|
|
26
33
|
positionAt
|
|
27
34
|
} = require("./syntax");
|
|
28
35
|
|
|
@@ -137,6 +144,9 @@ const {
|
|
|
137
144
|
/** @typedef {(ident: string) => void} OnIdentString */
|
|
138
145
|
/** @typedef {(ident: string, identifier: Identifier) => void} OnIdent */
|
|
139
146
|
/** @typedef {StatementPathItem[]} StatementPath */
|
|
147
|
+
/** @typedef {(Statement | ModuleDeclaration)[]} HoistedDeclarations the declarations one scope hoists, in source order */
|
|
148
|
+
/** @typedef {(ModuleDeclaration | Statement | undefined)[]} ModuleDeclarations the program's import and re-export declarations in source order, each followed by the statement written before it */
|
|
149
|
+
/** @typedef {number | number[]} BlockDeclarations which statements of one list declare into its block scope: a mask of their indices, or the indices themselves once one is too large to mask */
|
|
140
150
|
|
|
141
151
|
/** @typedef {Set<DestructuringAssignmentProperty>} DestructuringAssignmentProperties */
|
|
142
152
|
|
|
@@ -145,6 +155,32 @@ const {
|
|
|
145
155
|
|
|
146
156
|
/** @type {string[]} */
|
|
147
157
|
const EMPTY_ARRAY = [];
|
|
158
|
+
/** @type {HoistedDeclarations} */
|
|
159
|
+
const EMPTY_HOISTED_DECLARATIONS = [];
|
|
160
|
+
// what the module pass reports; `export default` is the block pass's
|
|
161
|
+
const MODULE_STATEMENT_TYPES = new Set([
|
|
162
|
+
"ImportDeclaration",
|
|
163
|
+
"ExportNamedDeclaration",
|
|
164
|
+
"ExportAllDeclaration"
|
|
165
|
+
]);
|
|
166
|
+
// what the parser records per scope, and so what the hoisting pass reaches
|
|
167
|
+
const RECORDED_STATEMENT_TYPES = new Set([
|
|
168
|
+
"VariableDeclaration",
|
|
169
|
+
"FunctionDeclaration",
|
|
170
|
+
"ClassDeclaration"
|
|
171
|
+
]);
|
|
172
|
+
/** @type {ModuleDeclarations} */
|
|
173
|
+
const EMPTY_MODULE_DECLARATIONS = [];
|
|
174
|
+
// what the parser records per statement list, and so what the block pass
|
|
175
|
+
// reaches. An expression statement is recorded only when it assigns to an
|
|
176
|
+
// object pattern, so a tap on that type is not served from the list.
|
|
177
|
+
const BLOCK_DECLARATION_TYPES = new Set([
|
|
178
|
+
"VariableDeclaration",
|
|
179
|
+
"ClassDeclaration",
|
|
180
|
+
"ExportNamedDeclaration",
|
|
181
|
+
"ExportDefaultDeclaration"
|
|
182
|
+
]);
|
|
183
|
+
|
|
148
184
|
/** @type {MembersOptionals} */
|
|
149
185
|
const EMPTY_MEMBERS_OPTIONALS = [];
|
|
150
186
|
|
|
@@ -354,6 +390,7 @@ class VariableInfo {
|
|
|
354
390
|
|
|
355
391
|
/** @typedef {string[]} CalleeMembers */
|
|
356
392
|
/** @typedef {string[]} Members */
|
|
393
|
+
/** @typedef {UpdateExpression | ForInStatement | ForOfStatement | AssignmentExpression} WriteStatement a construct that writes to the reference it carries */
|
|
357
394
|
/** @typedef {boolean[]} MembersOptionals */
|
|
358
395
|
/** @typedef {Range[]} MemberRanges */
|
|
359
396
|
|
|
@@ -922,6 +959,183 @@ const evaluateAstCaches = new WeakMap();
|
|
|
922
959
|
// The inner map is strong while the compilation lives, so cap it
|
|
923
960
|
const EVALUATE_AST_CACHE_LIMIT = 4096;
|
|
924
961
|
|
|
962
|
+
/**
|
|
963
|
+
* Add one declaration, starting the list at the first — most scopes declare
|
|
964
|
+
* nothing, and the shared empty list spares them an array.
|
|
965
|
+
* @param {HoistedDeclarations} hoisted the list so far
|
|
966
|
+
* @param {Statement | ModuleDeclaration} declaration what to add
|
|
967
|
+
* @returns {HoistedDeclarations} the list holding it
|
|
968
|
+
*/
|
|
969
|
+
const addHoistedDeclaration = (hoisted, declaration) => {
|
|
970
|
+
if (hoisted === EMPTY_HOISTED_DECLARATIONS) return [declaration];
|
|
971
|
+
hoisted.push(declaration);
|
|
972
|
+
return hoisted;
|
|
973
|
+
};
|
|
974
|
+
|
|
975
|
+
/**
|
|
976
|
+
* Collect the declarations that hoist to one scope, for an AST that did not
|
|
977
|
+
* come from webpack's parser and so carries no record of its own.
|
|
978
|
+
* @param {(Statement | ModuleDeclaration)[]} statements the scope's statements
|
|
979
|
+
* @param {HoistedDeclarations} hoisted the list so far
|
|
980
|
+
* @returns {HoistedDeclarations} the list holding what they declare
|
|
981
|
+
*/
|
|
982
|
+
const collectHoistedDeclarations = (statements, hoisted) => {
|
|
983
|
+
for (let index = 0, len = statements.length; index < len; index++) {
|
|
984
|
+
hoisted = collectHoistedDeclaration(statements[index], hoisted);
|
|
985
|
+
}
|
|
986
|
+
return hoisted;
|
|
987
|
+
};
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* Collect from one statement, descending exactly as far as a `var` reaches:
|
|
991
|
+
* through blocks and loop bodies, never into another function.
|
|
992
|
+
* @param {Statement | ModuleDeclaration} statement the statement
|
|
993
|
+
* @param {HoistedDeclarations} hoisted the list so far
|
|
994
|
+
* @returns {HoistedDeclarations} the list holding what it declares
|
|
995
|
+
*/
|
|
996
|
+
const collectHoistedDeclaration = (statement, hoisted) => {
|
|
997
|
+
switch (statement.type) {
|
|
998
|
+
case "VariableDeclaration":
|
|
999
|
+
if (statement.kind === "var") {
|
|
1000
|
+
hoisted = addHoistedDeclaration(hoisted, statement);
|
|
1001
|
+
}
|
|
1002
|
+
break;
|
|
1003
|
+
case "FunctionDeclaration":
|
|
1004
|
+
case "ClassDeclaration":
|
|
1005
|
+
hoisted = addHoistedDeclaration(hoisted, statement);
|
|
1006
|
+
break;
|
|
1007
|
+
case "BlockStatement":
|
|
1008
|
+
hoisted = collectHoistedDeclarations(statement.body, hoisted);
|
|
1009
|
+
break;
|
|
1010
|
+
case "IfStatement":
|
|
1011
|
+
hoisted = collectHoistedDeclaration(statement.consequent, hoisted);
|
|
1012
|
+
if (statement.alternate) {
|
|
1013
|
+
hoisted = collectHoistedDeclaration(statement.alternate, hoisted);
|
|
1014
|
+
}
|
|
1015
|
+
break;
|
|
1016
|
+
case "ForStatement":
|
|
1017
|
+
if (statement.init && statement.init.type === "VariableDeclaration") {
|
|
1018
|
+
hoisted = collectHoistedDeclaration(statement.init, hoisted);
|
|
1019
|
+
}
|
|
1020
|
+
hoisted = collectHoistedDeclaration(statement.body, hoisted);
|
|
1021
|
+
break;
|
|
1022
|
+
case "ForInStatement":
|
|
1023
|
+
case "ForOfStatement":
|
|
1024
|
+
if (statement.left.type === "VariableDeclaration") {
|
|
1025
|
+
hoisted = collectHoistedDeclaration(statement.left, hoisted);
|
|
1026
|
+
}
|
|
1027
|
+
hoisted = collectHoistedDeclaration(statement.body, hoisted);
|
|
1028
|
+
break;
|
|
1029
|
+
case "WhileStatement":
|
|
1030
|
+
case "DoWhileStatement":
|
|
1031
|
+
case "LabeledStatement":
|
|
1032
|
+
case "WithStatement":
|
|
1033
|
+
hoisted = collectHoistedDeclaration(statement.body, hoisted);
|
|
1034
|
+
break;
|
|
1035
|
+
case "TryStatement":
|
|
1036
|
+
hoisted = collectHoistedDeclaration(statement.block, hoisted);
|
|
1037
|
+
if (statement.handler) {
|
|
1038
|
+
hoisted = collectHoistedDeclaration(statement.handler.body, hoisted);
|
|
1039
|
+
}
|
|
1040
|
+
if (statement.finalizer) {
|
|
1041
|
+
hoisted = collectHoistedDeclaration(statement.finalizer, hoisted);
|
|
1042
|
+
}
|
|
1043
|
+
break;
|
|
1044
|
+
case "SwitchStatement": {
|
|
1045
|
+
const cases = statement.cases;
|
|
1046
|
+
for (let index = 0, len = cases.length; index < len; index++) {
|
|
1047
|
+
hoisted = collectHoistedDeclarations(cases[index].consequent, hoisted);
|
|
1048
|
+
}
|
|
1049
|
+
break;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
return hoisted;
|
|
1053
|
+
};
|
|
1054
|
+
|
|
1055
|
+
/**
|
|
1056
|
+
* What the program imports and re-exports: the parser's own record, or a scan
|
|
1057
|
+
* of the top-level statements for an AST some other parser built.
|
|
1058
|
+
* @param {Program} ast the program
|
|
1059
|
+
* @param {boolean} trusted whether the parser's own record may be read
|
|
1060
|
+
* @returns {ModuleDeclarations} the declarations, in source order
|
|
1061
|
+
*/
|
|
1062
|
+
const moduleDeclarationsOf = (ast, trusted) => {
|
|
1063
|
+
if (trusted) {
|
|
1064
|
+
const recorded = /** @type {EXPECTED_ANY} */ (ast)[MODULE_DECLARATIONS];
|
|
1065
|
+
if (recorded !== undefined) return recorded;
|
|
1066
|
+
}
|
|
1067
|
+
/** @type {ModuleDeclarations} */
|
|
1068
|
+
let declarations = EMPTY_MODULE_DECLARATIONS;
|
|
1069
|
+
const body = ast.body;
|
|
1070
|
+
for (let index = 0, len = body.length; index < len; index++) {
|
|
1071
|
+
const statement = body[index];
|
|
1072
|
+
if (MODULE_STATEMENT_TYPES.has(statement.type)) {
|
|
1073
|
+
if (declarations === EMPTY_MODULE_DECLARATIONS) declarations = [];
|
|
1074
|
+
declarations.push(statement, index === 0 ? undefined : body[index - 1]);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
return declarations;
|
|
1078
|
+
};
|
|
1079
|
+
|
|
1080
|
+
/**
|
|
1081
|
+
* What hoists to the scope the node opens: the parser's own record, or a walk
|
|
1082
|
+
* of the body for an AST some other parser built.
|
|
1083
|
+
* @param {Program | BlockStatement} node the node owning the scope
|
|
1084
|
+
* @param {boolean} trusted whether the parser's own record may be read
|
|
1085
|
+
* @returns {HoistedDeclarations} the declarations, in source order
|
|
1086
|
+
*/
|
|
1087
|
+
const hoistedDeclarationsOf = (node, trusted) => {
|
|
1088
|
+
if (trusted) {
|
|
1089
|
+
const recorded = /** @type {EXPECTED_ANY} */ (node)[HOISTED_DECLARATIONS];
|
|
1090
|
+
if (recorded !== undefined) return recorded;
|
|
1091
|
+
}
|
|
1092
|
+
return collectHoistedDeclarations(node.body, EMPTY_HOISTED_DECLARATIONS);
|
|
1093
|
+
};
|
|
1094
|
+
|
|
1095
|
+
/**
|
|
1096
|
+
* Which statements of a list declare into its block scope, scanned for an AST
|
|
1097
|
+
* some other parser built. The parser's own record is read instead when there
|
|
1098
|
+
* is one.
|
|
1099
|
+
* @param {(Statement | ModuleDeclaration)[]} statements the list
|
|
1100
|
+
* @returns {BlockDeclarations} their indices, in source order
|
|
1101
|
+
*/
|
|
1102
|
+
const collectBlockDeclarations = (statements) => {
|
|
1103
|
+
let mask = 0;
|
|
1104
|
+
/** @type {number[] | undefined} */
|
|
1105
|
+
let overflow;
|
|
1106
|
+
for (let index = 0, len = statements.length; index < len; index++) {
|
|
1107
|
+
if (!declaresIntoBlock(statements[index])) continue;
|
|
1108
|
+
if (overflow !== undefined) overflow.push(index);
|
|
1109
|
+
else if (index <= MAX_MASKED_INDEX) mask |= 1 << index;
|
|
1110
|
+
else overflow = overflowFrom(mask, index);
|
|
1111
|
+
}
|
|
1112
|
+
return overflow === undefined ? mask : overflow;
|
|
1113
|
+
};
|
|
1114
|
+
|
|
1115
|
+
/**
|
|
1116
|
+
* Whether the source between two offsets is whitespace only.
|
|
1117
|
+
* @param {string} source the module source
|
|
1118
|
+
* @param {number} start where to start
|
|
1119
|
+
* @param {number} end where to stop
|
|
1120
|
+
* @returns {boolean} whether nothing but whitespace lies between them
|
|
1121
|
+
*/
|
|
1122
|
+
const onlyWhitespaceBetween = (source, start, end) => {
|
|
1123
|
+
for (let index = start; index < end; index++) {
|
|
1124
|
+
const code = source.charCodeAt(index);
|
|
1125
|
+
// the classification `skipSpace` uses: anything else is a token, and a
|
|
1126
|
+
// token means the run of comments before the statement has ended
|
|
1127
|
+
if (
|
|
1128
|
+
code !== 32 &&
|
|
1129
|
+
code !== 160 &&
|
|
1130
|
+
!(code > 8 && code < 14) &&
|
|
1131
|
+
!(code >= 5760 && nonASCIIwhitespace.test(source[index]))
|
|
1132
|
+
) {
|
|
1133
|
+
return false;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
return true;
|
|
1137
|
+
};
|
|
1138
|
+
|
|
925
1139
|
const CLASS_NAME = "JavascriptParser";
|
|
926
1140
|
|
|
927
1141
|
// Reserved words in strict mode, so unusable as binding names there (12.7.2).
|
|
@@ -984,17 +1198,33 @@ class JavascriptParser extends Parser {
|
|
|
984
1198
|
isPure: new HookMap(
|
|
985
1199
|
() => new SyncBailHook(["expression", "commentsStartPosition"])
|
|
986
1200
|
),
|
|
987
|
-
/**
|
|
1201
|
+
/**
|
|
1202
|
+
* Every statement the hoisting pass reads, which a tap on this turns
|
|
1203
|
+
* back into a walk of them all. Tap `preStatementByType` instead.
|
|
1204
|
+
* @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>}
|
|
1205
|
+
* @deprecated TODO webpack 6: remove, with the statement walk it turns on
|
|
1206
|
+
*/
|
|
988
1207
|
preStatement: new SyncBailHook(["statement"]),
|
|
989
1208
|
/**
|
|
1209
|
+
* Each declaration the parser records: a variable, function or class
|
|
1210
|
+
* one. Any other type turns the pass back into a walk of every
|
|
1211
|
+
* statement, and goes away with that walk in webpack 6.
|
|
990
1212
|
* @type {HookMap<SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>>}
|
|
991
1213
|
* @since 5.109.0
|
|
992
1214
|
*/
|
|
993
1215
|
preStatementByType: new HookMap(() => new SyncBailHook(["statement"])),
|
|
994
1216
|
|
|
995
|
-
/**
|
|
1217
|
+
/**
|
|
1218
|
+
* Every statement the block pass reads, which a tap on this turns back
|
|
1219
|
+
* into a walk of them all. Tap `blockPreStatementByType` instead.
|
|
1220
|
+
* @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>}
|
|
1221
|
+
* @deprecated TODO webpack 6: remove, with the statement walk it turns on
|
|
1222
|
+
*/
|
|
996
1223
|
blockPreStatement: new SyncBailHook(["declaration"]),
|
|
997
1224
|
/**
|
|
1225
|
+
* Each statement the parser records for the block pass: a variable, class
|
|
1226
|
+
* or export declaration. Any other type turns the pass back into a walk
|
|
1227
|
+
* of every statement, and goes away with that walk in webpack 6.
|
|
998
1228
|
* @type {HookMap<SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>>}
|
|
999
1229
|
* @since 5.109.0
|
|
1000
1230
|
*/
|
|
@@ -1092,6 +1322,12 @@ class JavascriptParser extends Parser {
|
|
|
1092
1322
|
rename: new HookMap(() => new SyncBailHook(["initExpression"])),
|
|
1093
1323
|
/** @type {HookMap<SyncBailHook<[AssignmentExpression], boolean | void>>} */
|
|
1094
1324
|
assign: new HookMap(() => new SyncBailHook(["expression"])),
|
|
1325
|
+
/** @type {HookMap<SyncBailHook<[WriteStatement], boolean | void>>} */
|
|
1326
|
+
write: new HookMap(() => new SyncBailHook(["node"])),
|
|
1327
|
+
/** @type {HookMap<SyncBailHook<[WriteStatement, Members], boolean | void>>} */
|
|
1328
|
+
writeMemberChain: new HookMap(
|
|
1329
|
+
() => new SyncBailHook(["node", "members"])
|
|
1330
|
+
),
|
|
1095
1331
|
/** @type {HookMap<SyncBailHook<[AssignmentExpression, Members], boolean | void>>} */
|
|
1096
1332
|
assignMemberChain: new HookMap(
|
|
1097
1333
|
() => new SyncBailHook(["expression", "members"])
|
|
@@ -1201,6 +1437,37 @@ class JavascriptParser extends Parser {
|
|
|
1201
1437
|
this.statementPath = undefined;
|
|
1202
1438
|
/** @type {Statement | ModuleDeclaration | Expression | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | undefined} */
|
|
1203
1439
|
this.prevStatement = undefined;
|
|
1440
|
+
/** @type {boolean} */
|
|
1441
|
+
this._hasParserRecord = false;
|
|
1442
|
+
// BACKWARD-COMPAT START
|
|
1443
|
+
|
|
1444
|
+
// WHY: the hoisting pass reaches declarations alone, so a tap that
|
|
1445
|
+
// expects every statement would quietly stop seeing most of them. Such a
|
|
1446
|
+
// tap turns the pass back into the walk it used to be, which no build
|
|
1447
|
+
// webpack's own plugins drive ever asks for.
|
|
1448
|
+
/** @type {boolean} */
|
|
1449
|
+
this._needsFullPreWalk = false;
|
|
1450
|
+
this.hooks.preStatementByType.intercept({
|
|
1451
|
+
factory: (type, hook) => {
|
|
1452
|
+
if (!RECORDED_STATEMENT_TYPES.has(type)) {
|
|
1453
|
+
this._needsFullPreWalk = true;
|
|
1454
|
+
}
|
|
1455
|
+
return hook;
|
|
1456
|
+
}
|
|
1457
|
+
});
|
|
1458
|
+
|
|
1459
|
+
// The same for the block pass, over the types the parser records for it.
|
|
1460
|
+
/** @type {boolean} */
|
|
1461
|
+
this._needsFullBlockPreWalk = false;
|
|
1462
|
+
this.hooks.blockPreStatementByType.intercept({
|
|
1463
|
+
factory: (type, hook) => {
|
|
1464
|
+
if (!BLOCK_DECLARATION_TYPES.has(type)) {
|
|
1465
|
+
this._needsFullBlockPreWalk = true;
|
|
1466
|
+
}
|
|
1467
|
+
return hook;
|
|
1468
|
+
}
|
|
1469
|
+
});
|
|
1470
|
+
// BACKWARD-COMPAT END
|
|
1204
1471
|
/** @type {WeakMap<Expression, DestructuringAssignmentProperties> | undefined} */
|
|
1205
1472
|
this.destructuringAssignmentProperties = undefined;
|
|
1206
1473
|
/** @type {TagData | undefined} */
|
|
@@ -2378,12 +2645,19 @@ class JavascriptParser extends Parser {
|
|
|
2378
2645
|
}
|
|
2379
2646
|
|
|
2380
2647
|
/**
|
|
2381
|
-
*
|
|
2382
|
-
*
|
|
2648
|
+
* Report what the program imports and re-exports, before anything reads a
|
|
2649
|
+
* name. The list is what the parser recorded, in source order.
|
|
2650
|
+
* @param {ModuleDeclarations} declarations the program's module declarations
|
|
2383
2651
|
*/
|
|
2384
|
-
|
|
2385
|
-
for (let index = 0, len =
|
|
2386
|
-
const statement =
|
|
2652
|
+
_modulePreWalkDeclarations(declarations) {
|
|
2653
|
+
for (let index = 0, len = declarations.length; index < len; index += 2) {
|
|
2654
|
+
const statement =
|
|
2655
|
+
/** @type {ModuleDeclaration} */
|
|
2656
|
+
(declarations[index]);
|
|
2657
|
+
// what precedes it decides whether removing it joins two statements
|
|
2658
|
+
this.prevStatement =
|
|
2659
|
+
/** @type {Statement | undefined} */
|
|
2660
|
+
(declarations[index + 1]);
|
|
2387
2661
|
/** @type {StatementPath} */
|
|
2388
2662
|
(this.statementPath).push(statement);
|
|
2389
2663
|
switch (statement.type) {
|
|
@@ -2404,19 +2678,212 @@ class JavascriptParser extends Parser {
|
|
|
2404
2678
|
}
|
|
2405
2679
|
|
|
2406
2680
|
/**
|
|
2407
|
-
*
|
|
2681
|
+
* Declare what the scope the node opens hoists, before anything reads a
|
|
2682
|
+
* name in it.
|
|
2683
|
+
* @param {Program | BlockStatement} node the node owning the scope
|
|
2684
|
+
*/
|
|
2685
|
+
_preWalkScope(node) {
|
|
2686
|
+
// BACKWARD-COMPAT START
|
|
2687
|
+
if (this._needsFullPreWalk || this.hooks.preStatement.taps.length !== 0) {
|
|
2688
|
+
if (node.type === "Program") this.preWalkStatements(node.body);
|
|
2689
|
+
else this.preWalkStatement(node);
|
|
2690
|
+
return;
|
|
2691
|
+
}
|
|
2692
|
+
// BACKWARD-COMPAT END
|
|
2693
|
+
this._preWalkHoistedDeclarations(
|
|
2694
|
+
hoistedDeclarationsOf(node, this._hasParserRecord)
|
|
2695
|
+
);
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
/**
|
|
2699
|
+
* Declare what hoists to the scope being entered, from what the parser
|
|
2700
|
+
* recorded while reading it. `prevStatement` is not available here.
|
|
2701
|
+
* @param {HoistedDeclarations} hoisted what the scope declares
|
|
2702
|
+
*/
|
|
2703
|
+
_preWalkHoistedDeclarations(hoisted) {
|
|
2704
|
+
for (let index = 0, len = hoisted.length; index < len; index++) {
|
|
2705
|
+
// WHY: the statements between two declarations are not read here, so
|
|
2706
|
+
// the one before this declaration is unknown rather than the previous
|
|
2707
|
+
// declaration. A tap needing it taps `preStatement`, which walks.
|
|
2708
|
+
this.prevStatement = undefined;
|
|
2709
|
+
this.preWalkStatement(hoisted[index]);
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2712
|
+
|
|
2713
|
+
// BACKWARD-COMPAT START
|
|
2714
|
+
/**
|
|
2715
|
+
* Walk every statement of a scope to declare what hoists to it. Only a tap
|
|
2716
|
+
* on the deprecated `preStatement` hook asks for this.
|
|
2408
2717
|
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
|
2718
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2409
2719
|
*/
|
|
2410
2720
|
preWalkStatements(statements) {
|
|
2721
|
+
for (let index = 0, len = statements.length; index < len; index++) {
|
|
2722
|
+
this.preWalkStatement(statements[index]);
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2726
|
+
/**
|
|
2727
|
+
* Pre walk block statement.
|
|
2728
|
+
* @param {BlockStatement} statement block statement
|
|
2729
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2730
|
+
*/
|
|
2731
|
+
preWalkBlockStatement(statement) {
|
|
2732
|
+
this.preWalkStatements(statement.body);
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2735
|
+
/**
|
|
2736
|
+
* Pre walk if statement.
|
|
2737
|
+
* @param {IfStatement} statement if statement
|
|
2738
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2739
|
+
*/
|
|
2740
|
+
preWalkIfStatement(statement) {
|
|
2741
|
+
this.preWalkStatement(statement.consequent);
|
|
2742
|
+
if (statement.alternate) {
|
|
2743
|
+
this.preWalkStatement(statement.alternate);
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
|
|
2747
|
+
/**
|
|
2748
|
+
* Pre walk labeled statement.
|
|
2749
|
+
* @param {LabeledStatement} statement labeled statement
|
|
2750
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2751
|
+
*/
|
|
2752
|
+
preWalkLabeledStatement(statement) {
|
|
2753
|
+
this.preWalkStatement(statement.body);
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2756
|
+
/**
|
|
2757
|
+
* Pre walk with statement.
|
|
2758
|
+
* @param {WithStatement} statement with statement
|
|
2759
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2760
|
+
*/
|
|
2761
|
+
preWalkWithStatement(statement) {
|
|
2762
|
+
this.preWalkStatement(statement.body);
|
|
2763
|
+
}
|
|
2764
|
+
|
|
2765
|
+
/**
|
|
2766
|
+
* Pre walk switch statement.
|
|
2767
|
+
* @param {SwitchStatement} statement switch statement
|
|
2768
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2769
|
+
*/
|
|
2770
|
+
preWalkSwitchStatement(statement) {
|
|
2771
|
+
this.preWalkSwitchCases(statement.cases);
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2774
|
+
/**
|
|
2775
|
+
* Pre walk switch cases.
|
|
2776
|
+
* @param {SwitchCase[]} switchCases switch cases
|
|
2777
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2778
|
+
*/
|
|
2779
|
+
preWalkSwitchCases(switchCases) {
|
|
2780
|
+
for (let index = 0, len = switchCases.length; index < len; index++) {
|
|
2781
|
+
this.preWalkStatements(switchCases[index].consequent);
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
|
|
2785
|
+
/**
|
|
2786
|
+
* Pre walk try statement.
|
|
2787
|
+
* @param {TryStatement} statement try statement
|
|
2788
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2789
|
+
*/
|
|
2790
|
+
preWalkTryStatement(statement) {
|
|
2791
|
+
this.preWalkStatement(statement.block);
|
|
2792
|
+
if (statement.handler) this.preWalkCatchClause(statement.handler);
|
|
2793
|
+
if (statement.finalizer) this.preWalkStatement(statement.finalizer);
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2796
|
+
/**
|
|
2797
|
+
* Pre walk catch clause.
|
|
2798
|
+
* @param {CatchClause} catchClause catch clause
|
|
2799
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2800
|
+
*/
|
|
2801
|
+
preWalkCatchClause(catchClause) {
|
|
2802
|
+
this.preWalkStatement(catchClause.body);
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2805
|
+
/**
|
|
2806
|
+
* Pre walk while statement.
|
|
2807
|
+
* @param {WhileStatement} statement while statement
|
|
2808
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2809
|
+
*/
|
|
2810
|
+
preWalkWhileStatement(statement) {
|
|
2811
|
+
this.preWalkStatement(statement.body);
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2814
|
+
/**
|
|
2815
|
+
* Pre walk do while statement.
|
|
2816
|
+
* @param {DoWhileStatement} statement do while statement
|
|
2817
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2818
|
+
*/
|
|
2819
|
+
preWalkDoWhileStatement(statement) {
|
|
2820
|
+
this.preWalkStatement(statement.body);
|
|
2821
|
+
}
|
|
2822
|
+
|
|
2823
|
+
/**
|
|
2824
|
+
* Pre walk for statement.
|
|
2825
|
+
* @param {ForStatement} statement for statement
|
|
2826
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2827
|
+
*/
|
|
2828
|
+
preWalkForStatement(statement) {
|
|
2829
|
+
if (statement.init && statement.init.type === "VariableDeclaration") {
|
|
2830
|
+
this.preWalkStatement(statement.init);
|
|
2831
|
+
}
|
|
2832
|
+
this.preWalkStatement(statement.body);
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2835
|
+
/**
|
|
2836
|
+
* Pre walk for in statement.
|
|
2837
|
+
* @param {ForInStatement} statement for in statement
|
|
2838
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2839
|
+
*/
|
|
2840
|
+
preWalkForInStatement(statement) {
|
|
2841
|
+
if (statement.left.type === "VariableDeclaration") {
|
|
2842
|
+
this.preWalkStatement(statement.left);
|
|
2843
|
+
}
|
|
2844
|
+
this.preWalkStatement(statement.body);
|
|
2845
|
+
}
|
|
2846
|
+
|
|
2847
|
+
/**
|
|
2848
|
+
* Pre walk for of statement. `for await` is reported by the walk, not here.
|
|
2849
|
+
* @param {ForOfStatement} statement for of statement
|
|
2850
|
+
* @deprecated TODO webpack 6: remove, with the `preStatement` hook
|
|
2851
|
+
*/
|
|
2852
|
+
preWalkForOfStatement(statement) {
|
|
2853
|
+
if (statement.left.type === "VariableDeclaration") {
|
|
2854
|
+
this.preWalkStatement(statement.left);
|
|
2855
|
+
}
|
|
2856
|
+
this.preWalkStatement(statement.body);
|
|
2857
|
+
}
|
|
2858
|
+
|
|
2859
|
+
/**
|
|
2860
|
+
* Scan every top-level statement for the program's module declarations.
|
|
2861
|
+
* The parser records them now, so nothing inside webpack scans for them.
|
|
2862
|
+
* @deprecated TODO webpack 6: remove
|
|
2863
|
+
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
|
2864
|
+
*/
|
|
2865
|
+
modulePreWalkStatements(statements) {
|
|
2866
|
+
/** @type {ModuleDeclarations} */
|
|
2867
|
+
const declarations = [];
|
|
2411
2868
|
for (let index = 0, len = statements.length; index < len; index++) {
|
|
2412
2869
|
const statement = statements[index];
|
|
2413
|
-
|
|
2870
|
+
if (MODULE_STATEMENT_TYPES.has(statement.type)) {
|
|
2871
|
+
declarations.push(
|
|
2872
|
+
statement,
|
|
2873
|
+
index === 0 ? undefined : statements[index - 1]
|
|
2874
|
+
);
|
|
2875
|
+
}
|
|
2414
2876
|
}
|
|
2877
|
+
this._modulePreWalkDeclarations(declarations);
|
|
2415
2878
|
}
|
|
2879
|
+
// BACKWARD-COMPAT END
|
|
2416
2880
|
|
|
2881
|
+
// BACKWARD-COMPAT START
|
|
2417
2882
|
/**
|
|
2418
|
-
*
|
|
2883
|
+
* Walk every statement of a list to declare what it binds. Only a tap on the
|
|
2884
|
+
* deprecated `blockPreStatement` hook asks for this.
|
|
2419
2885
|
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
|
2886
|
+
* @deprecated TODO webpack 6: remove, with the `blockPreStatement` hook
|
|
2420
2887
|
*/
|
|
2421
2888
|
blockPreWalkStatements(statements) {
|
|
2422
2889
|
for (let index = 0, len = statements.length; index < len; index++) {
|
|
@@ -2424,6 +2891,68 @@ class JavascriptParser extends Parser {
|
|
|
2424
2891
|
this.blockPreWalkStatement(statement);
|
|
2425
2892
|
}
|
|
2426
2893
|
}
|
|
2894
|
+
// BACKWARD-COMPAT END
|
|
2895
|
+
|
|
2896
|
+
/**
|
|
2897
|
+
* Declare what the statement list binds into its own block scope, before any
|
|
2898
|
+
* of it is walked. The list is what the parser recorded while reading it.
|
|
2899
|
+
* @param {Program | BlockStatement | StaticBlock | SwitchCase} node the node owning the list
|
|
2900
|
+
* @param {(Statement | ModuleDeclaration)[]} statements the list it holds
|
|
2901
|
+
*/
|
|
2902
|
+
_blockPreWalkScope(node, statements) {
|
|
2903
|
+
// BACKWARD-COMPAT START
|
|
2904
|
+
if (
|
|
2905
|
+
this._needsFullBlockPreWalk ||
|
|
2906
|
+
this.hooks.blockPreStatement.taps.length !== 0
|
|
2907
|
+
) {
|
|
2908
|
+
this.blockPreWalkStatements(statements);
|
|
2909
|
+
return;
|
|
2910
|
+
}
|
|
2911
|
+
// BACKWARD-COMPAT END
|
|
2912
|
+
/** @type {BlockDeclarations | undefined} */
|
|
2913
|
+
let recorded;
|
|
2914
|
+
if (this._hasParserRecord) {
|
|
2915
|
+
recorded = /** @type {EXPECTED_ANY} */ (node)[BLOCK_DECLARATIONS];
|
|
2916
|
+
// 72.8% of the lists a build reads declare nothing, and saying so is
|
|
2917
|
+
// the whole pass for them
|
|
2918
|
+
if (recorded === 0) return;
|
|
2919
|
+
}
|
|
2920
|
+
if (recorded === undefined) {
|
|
2921
|
+
recorded = collectBlockDeclarations(statements);
|
|
2922
|
+
if (recorded === 0) return;
|
|
2923
|
+
}
|
|
2924
|
+
this._blockPreWalkDeclarations(statements, recorded);
|
|
2925
|
+
}
|
|
2926
|
+
|
|
2927
|
+
/**
|
|
2928
|
+
* Declare what the recorded statements of the list bind, in source order.
|
|
2929
|
+
* @param {(Statement | ModuleDeclaration)[]} statements the whole list
|
|
2930
|
+
* @param {BlockDeclarations} declarations which of them declare
|
|
2931
|
+
*/
|
|
2932
|
+
_blockPreWalkDeclarations(statements, declarations) {
|
|
2933
|
+
if (typeof declarations === "number") {
|
|
2934
|
+
for (let bits = declarations; bits !== 0; bits &= bits - 1) {
|
|
2935
|
+
this._blockPreWalkAt(statements, 31 - Math.clz32(bits & -bits));
|
|
2936
|
+
}
|
|
2937
|
+
return;
|
|
2938
|
+
}
|
|
2939
|
+
for (let index = 0, len = declarations.length; index < len; index++) {
|
|
2940
|
+
this._blockPreWalkAt(statements, declarations[index]);
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
|
|
2944
|
+
/**
|
|
2945
|
+
* Declare what one statement of the list binds, with the statement written
|
|
2946
|
+
* before it, so a tap reading `prevStatement` sees what the walk would show.
|
|
2947
|
+
* @param {(Statement | ModuleDeclaration)[]} statements the whole list
|
|
2948
|
+
* @param {number} index which statement declares
|
|
2949
|
+
*/
|
|
2950
|
+
_blockPreWalkAt(statements, index) {
|
|
2951
|
+
// the first statement of the list has nothing before it, and leaves
|
|
2952
|
+
// whatever the caller set standing, as walking the whole list did
|
|
2953
|
+
if (index !== 0) this.prevStatement = statements[index - 1];
|
|
2954
|
+
this.blockPreWalkStatement(statements[index]);
|
|
2955
|
+
}
|
|
2427
2956
|
|
|
2428
2957
|
/**
|
|
2429
2958
|
* Walking iterates the statements and expressions and processes them
|
|
@@ -2473,21 +3002,22 @@ class JavascriptParser extends Parser {
|
|
|
2473
3002
|
(this.statementPath).pop();
|
|
2474
3003
|
return;
|
|
2475
3004
|
}
|
|
2476
|
-
//
|
|
2477
|
-
//
|
|
3005
|
+
// a class declaration reaches here for the typed hook alone: defining it
|
|
3006
|
+
// is the block pass's. The rest are only walked into by the deprecated
|
|
3007
|
+
// statement walk, which a tap expecting every statement turns back on.
|
|
2478
3008
|
switch (statement.type) {
|
|
2479
3009
|
case "VariableDeclaration":
|
|
2480
3010
|
this.preWalkVariableDeclaration(statement);
|
|
2481
3011
|
break;
|
|
3012
|
+
case "FunctionDeclaration":
|
|
3013
|
+
this.preWalkFunctionDeclaration(statement);
|
|
3014
|
+
break;
|
|
2482
3015
|
case "IfStatement":
|
|
2483
3016
|
this.preWalkIfStatement(statement);
|
|
2484
3017
|
break;
|
|
2485
3018
|
case "BlockStatement":
|
|
2486
3019
|
this.preWalkBlockStatement(statement);
|
|
2487
3020
|
break;
|
|
2488
|
-
case "FunctionDeclaration":
|
|
2489
|
-
this.preWalkFunctionDeclaration(statement);
|
|
2490
|
-
break;
|
|
2491
3021
|
case "ForStatement":
|
|
2492
3022
|
this.preWalkForStatement(statement);
|
|
2493
3023
|
break;
|
|
@@ -2660,13 +3190,6 @@ class JavascriptParser extends Parser {
|
|
|
2660
3190
|
}
|
|
2661
3191
|
|
|
2662
3192
|
// Real Statements
|
|
2663
|
-
/**
|
|
2664
|
-
* Pre walk block statement.
|
|
2665
|
-
* @param {BlockStatement} statement block statement
|
|
2666
|
-
*/
|
|
2667
|
-
preWalkBlockStatement(statement) {
|
|
2668
|
-
this.preWalkStatements(statement.body);
|
|
2669
|
-
}
|
|
2670
3193
|
|
|
2671
3194
|
/**
|
|
2672
3195
|
* Walk block statement.
|
|
@@ -2676,7 +3199,7 @@ class JavascriptParser extends Parser {
|
|
|
2676
3199
|
const oldScope = this._enterBlockScope();
|
|
2677
3200
|
const body = statement.body;
|
|
2678
3201
|
const prev = this.prevStatement;
|
|
2679
|
-
this.
|
|
3202
|
+
this._blockPreWalkScope(statement, body);
|
|
2680
3203
|
this.prevStatement = prev;
|
|
2681
3204
|
this.walkStatements(body);
|
|
2682
3205
|
|
|
@@ -2691,17 +3214,6 @@ class JavascriptParser extends Parser {
|
|
|
2691
3214
|
this.walkExpression(statement.expression);
|
|
2692
3215
|
}
|
|
2693
3216
|
|
|
2694
|
-
/**
|
|
2695
|
-
* Pre walk if statement.
|
|
2696
|
-
* @param {IfStatement} statement if statement
|
|
2697
|
-
*/
|
|
2698
|
-
preWalkIfStatement(statement) {
|
|
2699
|
-
this.preWalkStatement(statement.consequent);
|
|
2700
|
-
if (statement.alternate) {
|
|
2701
|
-
this.preWalkStatement(statement.alternate);
|
|
2702
|
-
}
|
|
2703
|
-
}
|
|
2704
|
-
|
|
2705
3217
|
/**
|
|
2706
3218
|
* Walks a conditional branch with its guard frame (if any) pushed onto the
|
|
2707
3219
|
* parser-state guard stack for the duration of the branch body.
|
|
@@ -2768,14 +3280,6 @@ class JavascriptParser extends Parser {
|
|
|
2768
3280
|
}
|
|
2769
3281
|
}
|
|
2770
3282
|
|
|
2771
|
-
/**
|
|
2772
|
-
* Pre walk labeled statement.
|
|
2773
|
-
* @param {LabeledStatement} statement with statement
|
|
2774
|
-
*/
|
|
2775
|
-
preWalkLabeledStatement(statement) {
|
|
2776
|
-
this.preWalkStatement(statement.body);
|
|
2777
|
-
}
|
|
2778
|
-
|
|
2779
3283
|
/**
|
|
2780
3284
|
* Walk labeled statement.
|
|
2781
3285
|
* @param {LabeledStatement} statement with statement
|
|
@@ -2792,14 +3296,6 @@ class JavascriptParser extends Parser {
|
|
|
2792
3296
|
this._exitBlockScope(oldScope, false);
|
|
2793
3297
|
}
|
|
2794
3298
|
|
|
2795
|
-
/**
|
|
2796
|
-
* Pre walk with statement.
|
|
2797
|
-
* @param {WithStatement} statement with statement
|
|
2798
|
-
*/
|
|
2799
|
-
preWalkWithStatement(statement) {
|
|
2800
|
-
this.preWalkStatement(statement.body);
|
|
2801
|
-
}
|
|
2802
|
-
|
|
2803
3299
|
/**
|
|
2804
3300
|
* Walk with statement.
|
|
2805
3301
|
* @param {WithStatement} statement with statement
|
|
@@ -2818,14 +3314,6 @@ class JavascriptParser extends Parser {
|
|
|
2818
3314
|
this._exitBlockScope(oldScope, false);
|
|
2819
3315
|
}
|
|
2820
3316
|
|
|
2821
|
-
/**
|
|
2822
|
-
* Pre walk switch statement.
|
|
2823
|
-
* @param {SwitchStatement} statement switch statement
|
|
2824
|
-
*/
|
|
2825
|
-
preWalkSwitchStatement(statement) {
|
|
2826
|
-
this.preWalkSwitchCases(statement.cases);
|
|
2827
|
-
}
|
|
2828
|
-
|
|
2829
3317
|
/**
|
|
2830
3318
|
* Walk switch statement.
|
|
2831
3319
|
* @param {SwitchStatement} statement switch statement
|
|
@@ -2867,16 +3355,6 @@ class JavascriptParser extends Parser {
|
|
|
2867
3355
|
this.walkTerminatingStatement(statement);
|
|
2868
3356
|
}
|
|
2869
3357
|
|
|
2870
|
-
/**
|
|
2871
|
-
* Pre walk try statement.
|
|
2872
|
-
* @param {TryStatement} statement try statement
|
|
2873
|
-
*/
|
|
2874
|
-
preWalkTryStatement(statement) {
|
|
2875
|
-
this.preWalkStatement(statement.block);
|
|
2876
|
-
if (statement.handler) this.preWalkCatchClause(statement.handler);
|
|
2877
|
-
if (statement.finalizer) this.preWalkStatement(statement.finalizer);
|
|
2878
|
-
}
|
|
2879
|
-
|
|
2880
3358
|
/**
|
|
2881
3359
|
* Walk try statement.
|
|
2882
3360
|
* @param {TryStatement} statement try statement
|
|
@@ -2915,14 +3393,6 @@ class JavascriptParser extends Parser {
|
|
|
2915
3393
|
}
|
|
2916
3394
|
}
|
|
2917
3395
|
|
|
2918
|
-
/**
|
|
2919
|
-
* Pre walk while statement.
|
|
2920
|
-
* @param {WhileStatement} statement while statement
|
|
2921
|
-
*/
|
|
2922
|
-
preWalkWhileStatement(statement) {
|
|
2923
|
-
this.preWalkStatement(statement.body);
|
|
2924
|
-
}
|
|
2925
|
-
|
|
2926
3396
|
/**
|
|
2927
3397
|
* Walk while statement.
|
|
2928
3398
|
* @param {WhileStatement} statement while statement
|
|
@@ -2935,14 +3405,6 @@ class JavascriptParser extends Parser {
|
|
|
2935
3405
|
this._exitBlockScope(oldScope, false);
|
|
2936
3406
|
}
|
|
2937
3407
|
|
|
2938
|
-
/**
|
|
2939
|
-
* Pre walk do while statement.
|
|
2940
|
-
* @param {DoWhileStatement} statement do while statement
|
|
2941
|
-
*/
|
|
2942
|
-
preWalkDoWhileStatement(statement) {
|
|
2943
|
-
this.preWalkStatement(statement.body);
|
|
2944
|
-
}
|
|
2945
|
-
|
|
2946
3408
|
/**
|
|
2947
3409
|
* Walk do while statement.
|
|
2948
3410
|
* @param {DoWhileStatement} statement do while statement
|
|
@@ -2955,17 +3417,6 @@ class JavascriptParser extends Parser {
|
|
|
2955
3417
|
this._exitBlockScope(oldScope, false);
|
|
2956
3418
|
}
|
|
2957
3419
|
|
|
2958
|
-
/**
|
|
2959
|
-
* Pre walk for statement.
|
|
2960
|
-
* @param {ForStatement} statement for statement
|
|
2961
|
-
*/
|
|
2962
|
-
preWalkForStatement(statement) {
|
|
2963
|
-
if (statement.init && statement.init.type === "VariableDeclaration") {
|
|
2964
|
-
this.preWalkStatement(statement.init);
|
|
2965
|
-
}
|
|
2966
|
-
this.preWalkStatement(statement.body);
|
|
2967
|
-
}
|
|
2968
|
-
|
|
2969
3420
|
/**
|
|
2970
3421
|
* Walk for statement.
|
|
2971
3422
|
* @param {ForStatement} statement for statement
|
|
@@ -2993,7 +3444,7 @@ class JavascriptParser extends Parser {
|
|
|
2993
3444
|
if (body.type === "BlockStatement") {
|
|
2994
3445
|
// no need to add additional scope
|
|
2995
3446
|
const prev = this.prevStatement;
|
|
2996
|
-
this.
|
|
3447
|
+
this._blockPreWalkScope(body, body.body);
|
|
2997
3448
|
this.prevStatement = prev;
|
|
2998
3449
|
this.walkStatements(body.body);
|
|
2999
3450
|
} else {
|
|
@@ -3003,17 +3454,6 @@ class JavascriptParser extends Parser {
|
|
|
3003
3454
|
this._exitBlockScope(oldScope, false);
|
|
3004
3455
|
}
|
|
3005
3456
|
|
|
3006
|
-
/**
|
|
3007
|
-
* Pre walk for in statement.
|
|
3008
|
-
* @param {ForInStatement} statement for statement
|
|
3009
|
-
*/
|
|
3010
|
-
preWalkForInStatement(statement) {
|
|
3011
|
-
if (statement.left.type === "VariableDeclaration") {
|
|
3012
|
-
this.preWalkVariableDeclaration(statement.left);
|
|
3013
|
-
}
|
|
3014
|
-
this.preWalkStatement(statement.body);
|
|
3015
|
-
}
|
|
3016
|
-
|
|
3017
3457
|
/**
|
|
3018
3458
|
* Walk for in statement.
|
|
3019
3459
|
* @param {ForInStatement} statement for statement
|
|
@@ -3023,7 +3463,7 @@ class JavascriptParser extends Parser {
|
|
|
3023
3463
|
if (statement.left.type === "VariableDeclaration") {
|
|
3024
3464
|
this.blockPreWalkVariableDeclaration(statement.left);
|
|
3025
3465
|
this.walkVariableDeclaration(statement.left);
|
|
3026
|
-
} else {
|
|
3466
|
+
} else if (!this._walkWriteTarget(statement.left, statement)) {
|
|
3027
3467
|
this.walkPattern(statement.left);
|
|
3028
3468
|
}
|
|
3029
3469
|
|
|
@@ -3034,7 +3474,7 @@ class JavascriptParser extends Parser {
|
|
|
3034
3474
|
if (body.type === "BlockStatement") {
|
|
3035
3475
|
// no need to add additional scope
|
|
3036
3476
|
const prev = this.prevStatement;
|
|
3037
|
-
this.
|
|
3477
|
+
this._blockPreWalkScope(body, body.body);
|
|
3038
3478
|
this.prevStatement = prev;
|
|
3039
3479
|
this.walkStatements(body.body);
|
|
3040
3480
|
} else {
|
|
@@ -3044,30 +3484,19 @@ class JavascriptParser extends Parser {
|
|
|
3044
3484
|
this._exitBlockScope(oldScope, false);
|
|
3045
3485
|
}
|
|
3046
3486
|
|
|
3047
|
-
/**
|
|
3048
|
-
* Pre walk for of statement.
|
|
3049
|
-
* @param {ForOfStatement} statement statement
|
|
3050
|
-
*/
|
|
3051
|
-
preWalkForOfStatement(statement) {
|
|
3052
|
-
if (statement.await && this.scope.topLevelScope === true) {
|
|
3053
|
-
this.hooks.topLevelAwait.call(statement);
|
|
3054
|
-
}
|
|
3055
|
-
if (statement.left.type === "VariableDeclaration") {
|
|
3056
|
-
this.preWalkVariableDeclaration(statement.left);
|
|
3057
|
-
}
|
|
3058
|
-
this.preWalkStatement(statement.body);
|
|
3059
|
-
}
|
|
3060
|
-
|
|
3061
3487
|
/**
|
|
3062
3488
|
* Walk for of statement.
|
|
3063
3489
|
* @param {ForOfStatement} statement for statement
|
|
3064
3490
|
*/
|
|
3065
3491
|
walkForOfStatement(statement) {
|
|
3492
|
+
if (statement.await && this.scope.topLevelScope === true) {
|
|
3493
|
+
this.hooks.topLevelAwait.call(statement);
|
|
3494
|
+
}
|
|
3066
3495
|
const oldScope = this._enterBlockScope();
|
|
3067
3496
|
if (statement.left.type === "VariableDeclaration") {
|
|
3068
3497
|
this.blockPreWalkVariableDeclaration(statement.left);
|
|
3069
3498
|
this.walkVariableDeclaration(statement.left);
|
|
3070
|
-
} else {
|
|
3499
|
+
} else if (!this._walkWriteTarget(statement.left, statement)) {
|
|
3071
3500
|
this.walkPattern(statement.left);
|
|
3072
3501
|
}
|
|
3073
3502
|
|
|
@@ -3078,7 +3507,7 @@ class JavascriptParser extends Parser {
|
|
|
3078
3507
|
if (body.type === "BlockStatement") {
|
|
3079
3508
|
// no need to add additional scope
|
|
3080
3509
|
const prev = this.prevStatement;
|
|
3081
|
-
this.
|
|
3510
|
+
this._blockPreWalkScope(body, body.body);
|
|
3082
3511
|
this.prevStatement = prev;
|
|
3083
3512
|
this.walkStatements(body.body);
|
|
3084
3513
|
} else {
|
|
@@ -3120,7 +3549,7 @@ class JavascriptParser extends Parser {
|
|
|
3120
3549
|
|
|
3121
3550
|
const prev = this.prevStatement;
|
|
3122
3551
|
|
|
3123
|
-
this.
|
|
3552
|
+
this._preWalkScope(statement.body);
|
|
3124
3553
|
this.prevStatement = prev;
|
|
3125
3554
|
this.walkStatement(statement.body);
|
|
3126
3555
|
|
|
@@ -3698,17 +4127,6 @@ class JavascriptParser extends Parser {
|
|
|
3698
4127
|
this.walkClass(statement);
|
|
3699
4128
|
}
|
|
3700
4129
|
|
|
3701
|
-
/**
|
|
3702
|
-
* Pre walk switch cases.
|
|
3703
|
-
* @param {SwitchCase[]} switchCases switch statement
|
|
3704
|
-
*/
|
|
3705
|
-
preWalkSwitchCases(switchCases) {
|
|
3706
|
-
for (let index = 0, len = switchCases.length; index < len; index++) {
|
|
3707
|
-
const switchCase = switchCases[index];
|
|
3708
|
-
this.preWalkStatements(switchCase.consequent);
|
|
3709
|
-
}
|
|
3710
|
-
}
|
|
3711
|
-
|
|
3712
4130
|
/**
|
|
3713
4131
|
* Processes the provided switch case.
|
|
3714
4132
|
* @param {SwitchCase[]} switchCases switch statement
|
|
@@ -3724,7 +4142,7 @@ class JavascriptParser extends Parser {
|
|
|
3724
4142
|
|
|
3725
4143
|
if (switchCase.consequent.length > 0) {
|
|
3726
4144
|
const prev = this.prevStatement;
|
|
3727
|
-
this.
|
|
4145
|
+
this._blockPreWalkScope(switchCase, switchCase.consequent);
|
|
3728
4146
|
this.prevStatement = prev;
|
|
3729
4147
|
}
|
|
3730
4148
|
}
|
|
@@ -3745,14 +4163,6 @@ class JavascriptParser extends Parser {
|
|
|
3745
4163
|
this._exitBlockScope(oldScope, false);
|
|
3746
4164
|
}
|
|
3747
4165
|
|
|
3748
|
-
/**
|
|
3749
|
-
* Pre walk catch clause.
|
|
3750
|
-
* @param {CatchClause} catchClause catch clause
|
|
3751
|
-
*/
|
|
3752
|
-
preWalkCatchClause(catchClause) {
|
|
3753
|
-
this.preWalkStatement(catchClause.body);
|
|
3754
|
-
}
|
|
3755
|
-
|
|
3756
4166
|
/**
|
|
3757
4167
|
* Processes the provided catch clause.
|
|
3758
4168
|
* @param {CatchClause} catchClause catch clause
|
|
@@ -4081,7 +4491,7 @@ class JavascriptParser extends Parser {
|
|
|
4081
4491
|
|
|
4082
4492
|
const prev = this.prevStatement;
|
|
4083
4493
|
|
|
4084
|
-
this.
|
|
4494
|
+
this._preWalkScope(expression.body);
|
|
4085
4495
|
this.prevStatement = prev;
|
|
4086
4496
|
this.walkStatement(expression.body);
|
|
4087
4497
|
|
|
@@ -4106,7 +4516,7 @@ class JavascriptParser extends Parser {
|
|
|
4106
4516
|
if (expression.body.type === "BlockStatement") {
|
|
4107
4517
|
this.detectMode(expression.body.body);
|
|
4108
4518
|
const prev = this.prevStatement;
|
|
4109
|
-
this.
|
|
4519
|
+
this._preWalkScope(expression.body);
|
|
4110
4520
|
this.prevStatement = prev;
|
|
4111
4521
|
this.walkStatement(expression.body);
|
|
4112
4522
|
} else {
|
|
@@ -4167,9 +4577,98 @@ class JavascriptParser extends Parser {
|
|
|
4167
4577
|
) {
|
|
4168
4578
|
this._checkStrictModeAssignTarget(expression.argument.name, expression);
|
|
4169
4579
|
}
|
|
4580
|
+
if (this._walkWriteTarget(expression.argument, expression)) return;
|
|
4170
4581
|
this.walkExpression(expression.argument);
|
|
4171
4582
|
}
|
|
4172
4583
|
|
|
4584
|
+
/**
|
|
4585
|
+
* Offers a write that is not an assignment's left side — an update's target
|
|
4586
|
+
* or a loop's binding — to the taps that care, `assign` carrying only an
|
|
4587
|
+
* AssignmentExpression.
|
|
4588
|
+
* @param {Expression | Pattern} target the written reference
|
|
4589
|
+
* @param {WriteStatement} node the construct performing the write
|
|
4590
|
+
* @returns {boolean} true when a tap rendered the write itself
|
|
4591
|
+
*/
|
|
4592
|
+
_walkWriteTarget(target, node) {
|
|
4593
|
+
if (target.type === "Identifier") {
|
|
4594
|
+
return Boolean(
|
|
4595
|
+
this._callHooksForName1(this.hooks.write, target.name, node)
|
|
4596
|
+
);
|
|
4597
|
+
}
|
|
4598
|
+
if (target.type.endsWith("Pattern")) {
|
|
4599
|
+
this.enterPattern(/** @type {Pattern} */ (target), (name) => {
|
|
4600
|
+
this._callHooksForName1(this.hooks.write, name, node);
|
|
4601
|
+
});
|
|
4602
|
+
this._walkPatternWriteMembers(target, node);
|
|
4603
|
+
return false;
|
|
4604
|
+
}
|
|
4605
|
+
return Boolean(
|
|
4606
|
+
target.type === "MemberExpression" &&
|
|
4607
|
+
this._callWriteMemberChain(target, node)
|
|
4608
|
+
);
|
|
4609
|
+
}
|
|
4610
|
+
|
|
4611
|
+
/**
|
|
4612
|
+
* Offers the member expressions a destructuring target writes to the
|
|
4613
|
+
* `writeMemberChain` taps, which `enterPattern` passes over because they
|
|
4614
|
+
* bind no name.
|
|
4615
|
+
* @param {Pattern | Expression | null} pattern the destructuring target
|
|
4616
|
+
* @param {WriteStatement} node the construct performing the write
|
|
4617
|
+
* @returns {void}
|
|
4618
|
+
*/
|
|
4619
|
+
_walkPatternWriteMembers(pattern, node) {
|
|
4620
|
+
if (!pattern) return;
|
|
4621
|
+
switch (pattern.type) {
|
|
4622
|
+
case "MemberExpression":
|
|
4623
|
+
this._callWriteMemberChain(pattern, node);
|
|
4624
|
+
break;
|
|
4625
|
+
case "ObjectPattern":
|
|
4626
|
+
for (const property of pattern.properties) {
|
|
4627
|
+
this._walkPatternWriteMembers(
|
|
4628
|
+
property.type === "RestElement"
|
|
4629
|
+
? property.argument
|
|
4630
|
+
: /** @type {Pattern} */ (property.value),
|
|
4631
|
+
node
|
|
4632
|
+
);
|
|
4633
|
+
}
|
|
4634
|
+
break;
|
|
4635
|
+
case "ArrayPattern":
|
|
4636
|
+
for (const element of pattern.elements) {
|
|
4637
|
+
this._walkPatternWriteMembers(element, node);
|
|
4638
|
+
}
|
|
4639
|
+
break;
|
|
4640
|
+
case "AssignmentPattern":
|
|
4641
|
+
this._walkPatternWriteMembers(pattern.left, node);
|
|
4642
|
+
break;
|
|
4643
|
+
case "RestElement":
|
|
4644
|
+
this._walkPatternWriteMembers(pattern.argument, node);
|
|
4645
|
+
break;
|
|
4646
|
+
}
|
|
4647
|
+
}
|
|
4648
|
+
|
|
4649
|
+
/**
|
|
4650
|
+
* Offers a written member expression to the `writeMemberChain` taps.
|
|
4651
|
+
* @param {MemberExpression} target the written member expression
|
|
4652
|
+
* @param {WriteStatement} node the construct performing the write
|
|
4653
|
+
* @returns {boolean} true when a tap rendered the write itself
|
|
4654
|
+
*/
|
|
4655
|
+
_callWriteMemberChain(target, node) {
|
|
4656
|
+
return Boolean(
|
|
4657
|
+
this._resolveMemberExpression(target, ALLOWED_MEMBER_TYPES_EXPRESSION) ===
|
|
4658
|
+
1 &&
|
|
4659
|
+
this._hasHooksForInfo(
|
|
4660
|
+
this.hooks.writeMemberChain,
|
|
4661
|
+
/** @type {string | VariableInfo} */ (this._memberRootInfo)
|
|
4662
|
+
) &&
|
|
4663
|
+
this.callHooksForInfo(
|
|
4664
|
+
this.hooks.writeMemberChain,
|
|
4665
|
+
/** @type {string | VariableInfo} */ (this._memberRootInfo),
|
|
4666
|
+
node,
|
|
4667
|
+
this._members
|
|
4668
|
+
)
|
|
4669
|
+
);
|
|
4670
|
+
}
|
|
4671
|
+
|
|
4173
4672
|
/**
|
|
4174
4673
|
* Reports `arguments.callee` / `arguments.caller` — both throw a TypeError
|
|
4175
4674
|
* once the module runs in strict-mode ESM output.
|
|
@@ -4418,6 +4917,7 @@ class JavascriptParser extends Parser {
|
|
|
4418
4917
|
this.defineVariable(name);
|
|
4419
4918
|
}
|
|
4420
4919
|
});
|
|
4920
|
+
this._walkPatternWriteMembers(expression.left, expression);
|
|
4421
4921
|
this.walkPattern(expression.left);
|
|
4422
4922
|
} else if (expression.left.type === "MemberExpression") {
|
|
4423
4923
|
if (
|
|
@@ -4641,7 +5141,7 @@ class JavascriptParser extends Parser {
|
|
|
4641
5141
|
if (functionExpression.body.type === "BlockStatement") {
|
|
4642
5142
|
this.detectMode(functionExpression.body.body);
|
|
4643
5143
|
const prev = this.prevStatement;
|
|
4644
|
-
this.
|
|
5144
|
+
this._preWalkScope(functionExpression.body);
|
|
4645
5145
|
this.prevStatement = prev;
|
|
4646
5146
|
this.walkStatement(functionExpression.body);
|
|
4647
5147
|
} else {
|
|
@@ -4931,11 +5431,9 @@ class JavascriptParser extends Parser {
|
|
|
4931
5431
|
onUnhandled
|
|
4932
5432
|
) {
|
|
4933
5433
|
if (expression.object.type === "MemberExpression") {
|
|
4934
|
-
//
|
|
4935
|
-
//
|
|
4936
|
-
//
|
|
4937
|
-
// extractMemberExpressionChain) since the AST node may be a
|
|
4938
|
-
// TemplateLiteral, which has neither .name nor .value.
|
|
5434
|
+
// A nested MemberExpression keeps its info by calling walkMemberExpression
|
|
5435
|
+
// directly. The property comes from `members` rather than the node, which
|
|
5436
|
+
// may be a TemplateLiteral and carry neither `.name` nor `.value`.
|
|
4939
5437
|
const property = members[members.length - 1];
|
|
4940
5438
|
name = name.slice(0, -property.length - 1);
|
|
4941
5439
|
members.pop();
|
|
@@ -5716,6 +6214,13 @@ class JavascriptParser extends Parser {
|
|
|
5716
6214
|
const oldStrictInModuleOutput = this._strictInModuleOutput;
|
|
5717
6215
|
const oldSource = this._source;
|
|
5718
6216
|
const oldLineStarts = this._lineStarts;
|
|
6217
|
+
const oldHasParserRecord = this._hasParserRecord;
|
|
6218
|
+
// WHY: the parser's record of each scope is only the truth for a tree it
|
|
6219
|
+
// just built. A loader's AST, and whatever `module.parser.javascript.parse`
|
|
6220
|
+
// returns, may have been edited after it was read — or built by something
|
|
6221
|
+
// else entirely — so both are collected from instead of trusted.
|
|
6222
|
+
this._hasParserRecord =
|
|
6223
|
+
typeof source !== "object" && typeof this.options.parse !== "function";
|
|
5719
6224
|
// a preparsed AST carries no text, but the build passes the module
|
|
5720
6225
|
// source in the state — offsets still map for it
|
|
5721
6226
|
this._source =
|
|
@@ -5763,11 +6268,13 @@ class JavascriptParser extends Parser {
|
|
|
5763
6268
|
if (this._strictInModuleOutput && this.scope.isStrict) {
|
|
5764
6269
|
this._strictInModuleOutput = false;
|
|
5765
6270
|
}
|
|
5766
|
-
this.
|
|
6271
|
+
this._modulePreWalkDeclarations(
|
|
6272
|
+
moduleDeclarationsOf(ast, this._hasParserRecord)
|
|
6273
|
+
);
|
|
5767
6274
|
this.prevStatement = undefined;
|
|
5768
|
-
this.
|
|
6275
|
+
this._preWalkScope(ast);
|
|
5769
6276
|
this.prevStatement = undefined;
|
|
5770
|
-
this.
|
|
6277
|
+
this._blockPreWalkScope(ast, ast.body);
|
|
5771
6278
|
this.prevStatement = undefined;
|
|
5772
6279
|
this.walkStatements(ast.body);
|
|
5773
6280
|
this.destructuringAssignmentProperties = undefined;
|
|
@@ -5784,6 +6291,7 @@ class JavascriptParser extends Parser {
|
|
|
5784
6291
|
// release — these retain the whole source string and its line table
|
|
5785
6292
|
this._source = oldSource;
|
|
5786
6293
|
this._lineStarts = oldLineStarts;
|
|
6294
|
+
this._hasParserRecord = oldHasParserRecord;
|
|
5787
6295
|
return state;
|
|
5788
6296
|
}
|
|
5789
6297
|
|
|
@@ -5902,10 +6410,9 @@ class JavascriptParser extends Parser {
|
|
|
5902
6410
|
});
|
|
5903
6411
|
}
|
|
5904
6412
|
case "TemplateLiteral":
|
|
5905
|
-
// Thread `commentsStartPos` through the interpolations so a
|
|
5906
|
-
//
|
|
5907
|
-
// the
|
|
5908
|
-
// the inner expression's purity is evaluated.
|
|
6413
|
+
// Thread `commentsStartPos` through the interpolations, so a
|
|
6414
|
+
// `/*#__PURE__*/` inside `${ … }`, or before the first one, is within
|
|
6415
|
+
// the range scanned when the inner expression's purity is judged.
|
|
5909
6416
|
return expr.expressions.every((e) => {
|
|
5910
6417
|
const pureFlag = this.isPure(e, commentsStartPos);
|
|
5911
6418
|
commentsStartPos = /** @type {Range} */ (e.range)[1];
|
|
@@ -5959,17 +6466,13 @@ class JavascriptParser extends Parser {
|
|
|
5959
6466
|
return this.isPure(expr.expression, commentsStartPos);
|
|
5960
6467
|
|
|
5961
6468
|
case "UnaryExpression":
|
|
5962
|
-
//
|
|
5963
|
-
//
|
|
5964
|
-
//
|
|
5965
|
-
//
|
|
5966
|
-
//
|
|
5967
|
-
//
|
|
5968
|
-
//
|
|
5969
|
-
// any user code (objects → true, etc.).
|
|
5970
|
-
// Other operators (`+`, `-`, `~`, `delete`) fall through to
|
|
5971
|
-
// the generic evaluator which can still recognize literal
|
|
5972
|
-
// cases (e.g. `-1`, `+5`).
|
|
6469
|
+
// WHY: these three produce their result without invoking user code on
|
|
6470
|
+
// the operand. `typeof` returns a type tag and never throws, even for an
|
|
6471
|
+
// undeclared identifier, and coerces nothing; `void` evaluates the
|
|
6472
|
+
// operand and discards it, so it is pure exactly when the operand is; and
|
|
6473
|
+
// `!` coerces through ToBoolean, which is defined to call no user code.
|
|
6474
|
+
// `+`, `-`, `~` and `delete` fall through to the generic evaluator, which
|
|
6475
|
+
// still recognizes literal cases such as `-1` and `+5`.
|
|
5973
6476
|
if (
|
|
5974
6477
|
expr.operator === "typeof" ||
|
|
5975
6478
|
expr.operator === "void" ||
|
|
@@ -5983,12 +6486,12 @@ class JavascriptParser extends Parser {
|
|
|
5983
6486
|
return true;
|
|
5984
6487
|
|
|
5985
6488
|
case "BinaryExpression":
|
|
5986
|
-
//
|
|
5987
|
-
//
|
|
5988
|
-
//
|
|
5989
|
-
// `
|
|
5990
|
-
//
|
|
5991
|
-
//
|
|
6489
|
+
// WHY: strict (in)equality compares without coercion and never invokes user
|
|
6490
|
+
// code on its operands, so the result is pure where both sides are. Every
|
|
6491
|
+
// other binary operator may invoke `valueOf`, `toString`,
|
|
6492
|
+
// `[Symbol.hasInstance]` or a Proxy trap, and falls through to the generic
|
|
6493
|
+
// evaluator, which still recognizes the cases where both sides evaluate
|
|
6494
|
+
// to known primitive literals.
|
|
5992
6495
|
if (expr.operator === "===" || expr.operator === "!==") {
|
|
5993
6496
|
return (
|
|
5994
6497
|
this.isPure(expr.left, commentsStartPos) &&
|
|
@@ -6145,6 +6648,46 @@ class JavascriptParser extends Parser {
|
|
|
6145
6648
|
);
|
|
6146
6649
|
}
|
|
6147
6650
|
|
|
6651
|
+
/**
|
|
6652
|
+
* Where the comments written for `statement` begin: the run of comments
|
|
6653
|
+
* before it that whitespace alone separates from it and from each other.
|
|
6654
|
+
* @param {StatementPathItem} statement the statement they belong to
|
|
6655
|
+
* @returns {number} the offset the run starts at, or the statement's own
|
|
6656
|
+
*/
|
|
6657
|
+
getAttachedCommentsStart(statement) {
|
|
6658
|
+
let position = /** @type {Range} */ (statement.range)[0];
|
|
6659
|
+
// what precedes `export function f() {}` is written for the export, and
|
|
6660
|
+
// the export keyword is the token the run would otherwise stop at
|
|
6661
|
+
const path = this.statementPath;
|
|
6662
|
+
if (path !== undefined && path.length > 1) {
|
|
6663
|
+
const outer = path[path.length - 2];
|
|
6664
|
+
if (
|
|
6665
|
+
(outer.type === "ExportNamedDeclaration" ||
|
|
6666
|
+
outer.type === "ExportDefaultDeclaration") &&
|
|
6667
|
+
outer.declaration === statement
|
|
6668
|
+
) {
|
|
6669
|
+
position = /** @type {Range} */ (outer.range)[0];
|
|
6670
|
+
}
|
|
6671
|
+
}
|
|
6672
|
+
const comments = this.comments;
|
|
6673
|
+
if (comments === undefined) return position;
|
|
6674
|
+
const source = this._source;
|
|
6675
|
+
for (let index = comments.length - 1; index >= 0; index--) {
|
|
6676
|
+
const range = /** @type {Range} */ (comments[index].range);
|
|
6677
|
+
if (range[1] > position) continue;
|
|
6678
|
+
// with no source to read, nothing can be ruled out, so the run is
|
|
6679
|
+
// taken to reach as far as the comments themselves do
|
|
6680
|
+
if (
|
|
6681
|
+
source !== undefined &&
|
|
6682
|
+
!onlyWhitespaceBetween(source, range[1], position)
|
|
6683
|
+
) {
|
|
6684
|
+
break;
|
|
6685
|
+
}
|
|
6686
|
+
position = range[0];
|
|
6687
|
+
}
|
|
6688
|
+
return position;
|
|
6689
|
+
}
|
|
6690
|
+
|
|
6148
6691
|
/**
|
|
6149
6692
|
* Reports whether `identifier` may occur as a word in the source text of
|
|
6150
6693
|
* `range`. A conservative pre-filter for expensive AST scans: `false` means
|