webpack 5.98.0 → 5.99.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.
Files changed (251) hide show
  1. package/README.md +7 -3
  2. package/lib/AsyncDependenciesBlock.js +3 -1
  3. package/lib/BannerPlugin.js +1 -1
  4. package/lib/Cache.js +9 -7
  5. package/lib/CacheFacade.js +5 -5
  6. package/lib/Chunk.js +2 -2
  7. package/lib/ChunkGraph.js +21 -16
  8. package/lib/ChunkTemplate.js +6 -6
  9. package/lib/CleanPlugin.js +10 -10
  10. package/lib/CodeGenerationResults.js +4 -3
  11. package/lib/CompatibilityPlugin.js +4 -1
  12. package/lib/Compilation.js +326 -152
  13. package/lib/Compiler.js +13 -18
  14. package/lib/ConditionalInitFragment.js +1 -1
  15. package/lib/ConstPlugin.js +5 -3
  16. package/lib/ContextModule.js +4 -2
  17. package/lib/ContextModuleFactory.js +3 -3
  18. package/lib/ContextReplacementPlugin.js +43 -16
  19. package/lib/DefinePlugin.js +25 -24
  20. package/lib/DelegatedModule.js +4 -2
  21. package/lib/DelegatedModuleFactoryPlugin.js +2 -1
  22. package/lib/Dependency.js +19 -13
  23. package/lib/DependencyTemplates.js +4 -3
  24. package/lib/DllModule.js +4 -2
  25. package/lib/DllModuleFactory.js +2 -2
  26. package/lib/DllReferencePlugin.js +2 -1
  27. package/lib/DynamicEntryPlugin.js +1 -1
  28. package/lib/EnvironmentPlugin.js +4 -2
  29. package/lib/ExportsInfo.js +72 -40
  30. package/lib/ExternalModule.js +14 -5
  31. package/lib/ExternalModuleFactoryPlugin.js +24 -12
  32. package/lib/FileSystemInfo.js +129 -94
  33. package/lib/FlagDependencyExportsPlugin.js +6 -4
  34. package/lib/FlagDependencyUsagePlugin.js +1 -1
  35. package/lib/Generator.js +29 -1
  36. package/lib/HookWebpackError.js +2 -2
  37. package/lib/HotModuleReplacementPlugin.js +3 -9
  38. package/lib/IgnoreErrorModuleFactory.js +2 -2
  39. package/lib/IgnorePlugin.js +0 -5
  40. package/lib/InitFragment.js +1 -1
  41. package/lib/LoaderOptionsPlugin.js +8 -5
  42. package/lib/MainTemplate.js +7 -7
  43. package/lib/Module.js +40 -17
  44. package/lib/ModuleBuildError.js +3 -1
  45. package/lib/ModuleDependencyError.js +4 -3
  46. package/lib/ModuleDependencyWarning.js +4 -3
  47. package/lib/ModuleFactory.js +9 -3
  48. package/lib/ModuleFilenameHelpers.js +13 -13
  49. package/lib/ModuleGraph.js +20 -14
  50. package/lib/ModuleGraphConnection.js +7 -13
  51. package/lib/ModuleNotFoundError.js +1 -1
  52. package/lib/ModuleParseError.js +2 -1
  53. package/lib/ModuleSourceTypesConstants.js +11 -0
  54. package/lib/ModuleTemplate.js +5 -5
  55. package/lib/ModuleTypeConstants.js +15 -0
  56. package/lib/MultiCompiler.js +4 -4
  57. package/lib/MultiStats.js +1 -1
  58. package/lib/NormalModule.js +101 -54
  59. package/lib/NormalModuleFactory.js +38 -33
  60. package/lib/NormalModuleReplacementPlugin.js +3 -2
  61. package/lib/NullFactory.js +2 -2
  62. package/lib/Parser.js +4 -3
  63. package/lib/ProgressPlugin.js +1 -2
  64. package/lib/RawModule.js +4 -2
  65. package/lib/RecordIdsPlugin.js +6 -2
  66. package/lib/RequestShortener.js +3 -1
  67. package/lib/ResolverFactory.js +12 -9
  68. package/lib/RuntimeModule.js +4 -2
  69. package/lib/RuntimeTemplate.js +2 -1
  70. package/lib/SelfModuleFactory.js +2 -2
  71. package/lib/SourceMapDevToolPlugin.js +0 -8
  72. package/lib/Template.js +6 -5
  73. package/lib/TemplatedPathPlugin.js +15 -12
  74. package/lib/WebpackOptionsApply.js +1 -1
  75. package/lib/asset/AssetGenerator.js +237 -170
  76. package/lib/asset/AssetModulesPlugin.js +50 -8
  77. package/lib/asset/AssetSourceGenerator.js +18 -0
  78. package/lib/asset/RawDataUrlModule.js +4 -2
  79. package/lib/buildChunkGraph.js +14 -4
  80. package/lib/cache/MemoryWithGcCachePlugin.js +6 -2
  81. package/lib/cache/PackFileCacheStrategy.js +137 -121
  82. package/lib/cache/ResolverCachePlugin.js +15 -7
  83. package/lib/cache/getLazyHashedEtag.js +4 -3
  84. package/lib/cli.js +23 -15
  85. package/lib/config/defaults.js +93 -26
  86. package/lib/config/normalization.js +14 -13
  87. package/lib/config/target.js +8 -8
  88. package/lib/container/ContainerEntryModule.js +4 -2
  89. package/lib/container/ContainerEntryModuleFactory.js +2 -2
  90. package/lib/container/FallbackModule.js +4 -2
  91. package/lib/container/FallbackModuleFactory.js +2 -2
  92. package/lib/container/RemoteModule.js +4 -2
  93. package/lib/container/options.js +5 -5
  94. package/lib/css/CssGenerator.js +71 -9
  95. package/lib/css/CssModulesPlugin.js +30 -5
  96. package/lib/css/CssParser.js +37 -17
  97. package/lib/css/walkCssTokens.js +17 -17
  98. package/lib/debug/ProfilingPlugin.js +98 -38
  99. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +10 -4
  100. package/lib/dependencies/AMDPlugin.js +5 -2
  101. package/lib/dependencies/AMDRequireArrayDependency.js +4 -3
  102. package/lib/dependencies/AMDRequireContextDependency.js +2 -1
  103. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +15 -7
  104. package/lib/dependencies/AMDRuntimeModules.js +3 -1
  105. package/lib/dependencies/CommonJsExportRequireDependency.js +4 -5
  106. package/lib/dependencies/CommonJsExportsParserPlugin.js +3 -3
  107. package/lib/dependencies/CommonJsImportsParserPlugin.js +8 -7
  108. package/lib/dependencies/CommonJsRequireContextDependency.js +2 -1
  109. package/lib/dependencies/ContextDependencyHelpers.js +13 -6
  110. package/lib/dependencies/CssIcssExportDependency.js +15 -12
  111. package/lib/dependencies/CssIcssImportDependency.js +4 -1
  112. package/lib/dependencies/CssLocalIdentifierDependency.js +17 -14
  113. package/lib/dependencies/ExportsInfoDependency.js +6 -1
  114. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +5 -5
  115. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +22 -15
  116. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +23 -8
  117. package/lib/dependencies/HarmonyExportSpecifierDependency.js +2 -2
  118. package/lib/dependencies/HarmonyImportDependency.js +8 -6
  119. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +19 -14
  120. package/lib/dependencies/HarmonyImportSpecifierDependency.js +5 -5
  121. package/lib/dependencies/ImportContextDependency.js +2 -1
  122. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +8 -4
  123. package/lib/dependencies/JsonExportsDependency.js +24 -8
  124. package/lib/dependencies/LoaderPlugin.js +4 -14
  125. package/lib/dependencies/RequireContextDependency.js +2 -1
  126. package/lib/dependencies/RequireContextDependencyParserPlugin.js +6 -3
  127. package/lib/dependencies/RequireEnsureDependenciesBlock.js +3 -2
  128. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +11 -5
  129. package/lib/dependencies/RequireResolveContextDependency.js +1 -1
  130. package/lib/dependencies/WebAssemblyExportImportedDependency.js +1 -1
  131. package/lib/dependencies/WorkerDependency.js +6 -3
  132. package/lib/dependencies/WorkerPlugin.js +100 -41
  133. package/lib/esm/ModuleChunkFormatPlugin.js +5 -0
  134. package/lib/hmr/HotModuleReplacement.runtime.js +1 -0
  135. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +1 -0
  136. package/lib/hmr/LazyCompilationPlugin.js +32 -24
  137. package/lib/hmr/lazyCompilationBackend.js +1 -1
  138. package/lib/ids/DeterministicModuleIdsPlugin.js +1 -1
  139. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  140. package/lib/ids/IdHelpers.js +15 -14
  141. package/lib/ids/SyncModuleIdsPlugin.js +9 -5
  142. package/lib/index.js +5 -5
  143. package/lib/javascript/BasicEvaluatedExpression.js +6 -6
  144. package/lib/javascript/JavascriptGenerator.js +11 -1
  145. package/lib/javascript/JavascriptModulesPlugin.js +51 -31
  146. package/lib/javascript/JavascriptParser.js +272 -188
  147. package/lib/javascript/JavascriptParserHelpers.js +10 -9
  148. package/lib/javascript/StartupHelpers.js +4 -1
  149. package/lib/json/JsonData.js +4 -4
  150. package/lib/json/JsonGenerator.js +54 -22
  151. package/lib/json/JsonModulesPlugin.js +16 -2
  152. package/lib/json/JsonParser.js +8 -4
  153. package/lib/library/AbstractLibraryPlugin.js +7 -3
  154. package/lib/library/AssignLibraryPlugin.js +29 -1
  155. package/lib/library/EnableLibraryPlugin.js +7 -10
  156. package/lib/library/ExportPropertyLibraryPlugin.js +4 -1
  157. package/lib/library/ModuleLibraryPlugin.js +121 -15
  158. package/lib/logging/Logger.js +2 -2
  159. package/lib/logging/createConsoleLogger.js +4 -4
  160. package/lib/node/NodeEnvironmentPlugin.js +6 -2
  161. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +1 -2
  162. package/lib/node/ReadFileCompileWasmPlugin.js +1 -2
  163. package/lib/node/nodeConsole.js +3 -1
  164. package/lib/optimize/AggressiveSplittingPlugin.js +1 -1
  165. package/lib/optimize/ConcatenatedModule.js +19 -12
  166. package/lib/optimize/InnerGraph.js +3 -2
  167. package/lib/optimize/InnerGraphPlugin.js +13 -7
  168. package/lib/optimize/LimitChunkCountPlugin.js +20 -0
  169. package/lib/optimize/ModuleConcatenationPlugin.js +10 -7
  170. package/lib/optimize/RealContentHashPlugin.js +8 -4
  171. package/lib/optimize/SideEffectsFlagPlugin.js +4 -2
  172. package/lib/optimize/SplitChunksPlugin.js +87 -65
  173. package/lib/rules/BasicEffectRulePlugin.js +9 -1
  174. package/lib/rules/BasicMatcherRulePlugin.js +15 -4
  175. package/lib/rules/ObjectMatcherRulePlugin.js +12 -3
  176. package/lib/rules/RuleSetCompiler.js +25 -14
  177. package/lib/rules/UseEffectRulePlugin.js +47 -17
  178. package/lib/runtime/GetChunkFilenameRuntimeModule.js +6 -6
  179. package/lib/schemes/HttpUriPlugin.js +38 -17
  180. package/lib/serialization/BinaryMiddleware.js +52 -19
  181. package/lib/serialization/FileMiddleware.js +78 -48
  182. package/lib/serialization/ObjectMiddleware.js +78 -29
  183. package/lib/serialization/PlainObjectSerializer.js +1 -1
  184. package/lib/serialization/Serializer.js +15 -10
  185. package/lib/serialization/SerializerMiddleware.js +80 -41
  186. package/lib/serialization/SingleItemMiddleware.js +10 -7
  187. package/lib/serialization/types.js +1 -1
  188. package/lib/sharing/ConsumeSharedModule.js +4 -2
  189. package/lib/sharing/ProvideSharedModule.js +4 -2
  190. package/lib/sharing/ProvideSharedModuleFactory.js +5 -3
  191. package/lib/sharing/utils.js +2 -2
  192. package/lib/stats/DefaultStatsFactoryPlugin.js +80 -78
  193. package/lib/stats/DefaultStatsPresetPlugin.js +43 -23
  194. package/lib/stats/DefaultStatsPrinterPlugin.js +85 -43
  195. package/lib/stats/StatsFactory.js +11 -11
  196. package/lib/stats/StatsPrinter.js +7 -7
  197. package/lib/util/ArrayHelpers.js +2 -4
  198. package/lib/util/ArrayQueue.js +1 -1
  199. package/lib/util/AsyncQueue.js +4 -4
  200. package/lib/util/IterableHelpers.js +1 -1
  201. package/lib/util/LazyBucketSortedSet.js +41 -23
  202. package/lib/util/LazySet.js +3 -2
  203. package/lib/util/MapHelpers.js +1 -1
  204. package/lib/util/ParallelismFactorCalculator.js +1 -1
  205. package/lib/util/Semaphore.js +3 -3
  206. package/lib/util/SetHelpers.js +1 -1
  207. package/lib/util/SortableSet.js +9 -7
  208. package/lib/util/TupleQueue.js +9 -8
  209. package/lib/util/TupleSet.js +2 -2
  210. package/lib/util/WeakTupleMap.js +12 -11
  211. package/lib/util/binarySearchBounds.js +2 -1
  212. package/lib/util/cleverMerge.js +84 -54
  213. package/lib/util/comparators.js +22 -21
  214. package/lib/util/compileBooleanMatcher.js +3 -3
  215. package/lib/util/concatenate.js +6 -4
  216. package/lib/util/create-schema-validation.js +4 -4
  217. package/lib/util/createHash.js +2 -2
  218. package/lib/util/deprecation.js +35 -33
  219. package/lib/util/deterministicGrouping.js +6 -6
  220. package/lib/util/findGraphRoots.js +1 -1
  221. package/lib/util/fs.js +39 -39
  222. package/lib/util/hash/wasm-hash.js +2 -2
  223. package/lib/util/identifier.js +15 -18
  224. package/lib/util/makeSerializable.js +1 -1
  225. package/lib/util/memoize.js +4 -1
  226. package/lib/util/objectToMap.js +3 -2
  227. package/lib/util/processAsyncTree.js +2 -2
  228. package/lib/util/propertyName.js +0 -1
  229. package/lib/util/registerExternalSerializer.js +15 -18
  230. package/lib/util/removeBOM.js +25 -0
  231. package/lib/util/runtime.js +34 -27
  232. package/lib/util/serialization.js +5 -16
  233. package/lib/util/smartGrouping.js +3 -3
  234. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +3 -3
  235. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +11 -0
  236. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +10 -0
  237. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +4 -0
  238. package/lib/wasm-sync/WebAssemblyGenerator.js +28 -12
  239. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +10 -0
  240. package/lib/wasm-sync/WebAssemblyParser.js +9 -4
  241. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +3 -0
  242. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +30 -25
  243. package/package.json +19 -17
  244. package/schemas/WebpackOptions.check.js +1 -1
  245. package/schemas/WebpackOptions.json +48 -13
  246. package/schemas/plugins/JsonModulesPluginGenerator.check.d.ts +7 -0
  247. package/schemas/plugins/JsonModulesPluginGenerator.check.js +6 -0
  248. package/schemas/plugins/JsonModulesPluginGenerator.json +11 -0
  249. package/schemas/plugins/SourceMapDevToolPlugin.json +2 -2
  250. package/types.d.ts +918 -615
  251. package/lib/library/ModernModuleLibraryPlugin.js +0 -144
@@ -86,17 +86,18 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
86
86
  /** @typedef {import("estree").TaggedTemplateExpression} TaggedTemplateExpression */
87
87
  /** @typedef {import("estree").TemplateLiteral} TemplateLiteral */
88
88
  /** @typedef {import("estree").AssignmentProperty} AssignmentProperty */
89
+ /** @typedef {import("estree").MaybeNamedFunctionDeclaration} MaybeNamedFunctionDeclaration */
90
+ /** @typedef {import("estree").MaybeNamedClassDeclaration} MaybeNamedClassDeclaration */
89
91
  /**
90
92
  * @template T
91
93
  * @typedef {import("tapable").AsArray<T>} AsArray<T>
92
94
  */
93
95
  /** @typedef {import("../Parser").ParserState} ParserState */
94
96
  /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
95
- /** @typedef {{declaredScope: ScopeInfo, freeName: string | true | undefined, tagInfo: TagInfo | undefined}} VariableInfoInterface */
96
97
  /** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => string[], getMembersOptionals: () => boolean[], getMemberRanges: () => Range[] }} GetInfoResult */
97
- /** @typedef {Statement | ModuleDeclaration | Expression} StatementPathItem */
98
- /** @typedef {function(string): void} OnIdentString */
99
- /** @typedef {function(string, Identifier): void} OnIdent */
98
+ /** @typedef {Statement | ModuleDeclaration | Expression | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} StatementPathItem */
99
+ /** @typedef {(ident: string) => void} OnIdentString */
100
+ /** @typedef {(ident: string, identifier: Identifier) => void} OnIdent */
100
101
  /** @typedef {StatementPathItem[]} StatementPath */
101
102
 
102
103
  // TODO remove cast when @types/estree has been updated to import assertions
@@ -115,66 +116,68 @@ const ALLOWED_MEMBER_TYPES_ALL = 0b11;
115
116
 
116
117
  const LEGACY_ASSERT_ATTRIBUTES = Symbol("assert");
117
118
 
118
- /**
119
- * @param {any} Parser parser
120
- * @returns {typeof AcornParser} extender acorn parser
121
- */
119
+ /** @type {(BaseParser: typeof AcornParser) => typeof AcornParser} */
122
120
  const importAssertions = Parser =>
123
- /** @type {typeof AcornParser} */ (
124
- /** @type {unknown} */ (
125
- class extends Parser {
126
- parseWithClause() {
127
- const nodes = [];
128
-
129
- const isAssertLegacy = this.value === "assert";
130
-
131
- if (isAssertLegacy) {
132
- if (!this.eat(tokTypes.name)) {
133
- return nodes;
134
- }
135
- } else if (!this.eat(tokTypes._with)) {
136
- return nodes;
137
- }
121
+ class extends Parser {
122
+ /**
123
+ * @this {TODO}
124
+ * @returns {ImportAttribute[]} import attributes
125
+ */
126
+ parseWithClause() {
127
+ /** @type {ImportAttribute[]} */
128
+ const nodes = [];
138
129
 
139
- this.expect(tokTypes.braceL);
130
+ const isAssertLegacy = this.value === "assert";
140
131
 
141
- const attributeKeys = {};
142
- let first = true;
132
+ if (isAssertLegacy) {
133
+ if (!this.eat(tokTypes.name)) {
134
+ return nodes;
135
+ }
136
+ } else if (!this.eat(tokTypes._with)) {
137
+ return nodes;
138
+ }
143
139
 
144
- while (!this.eat(tokTypes.braceR)) {
145
- if (!first) {
146
- this.expect(tokTypes.comma);
147
- if (this.afterTrailingComma(tokTypes.braceR)) {
148
- break;
149
- }
150
- } else {
151
- first = false;
152
- }
140
+ this.expect(tokTypes.braceL);
153
141
 
154
- const attr = this.parseImportAttribute();
155
- const keyName =
156
- attr.key.type === "Identifier" ? attr.key.name : attr.key.value;
142
+ /** @type {Record<string, boolean>} */
143
+ const attributeKeys = {};
144
+ let first = true;
157
145
 
158
- if (Object.prototype.hasOwnProperty.call(attributeKeys, keyName)) {
159
- this.raiseRecoverable(
160
- attr.key.start,
161
- `Duplicate attribute key '${keyName}'`
162
- );
163
- }
164
-
165
- attributeKeys[keyName] = true;
166
- nodes.push(attr);
146
+ while (!this.eat(tokTypes.braceR)) {
147
+ if (!first) {
148
+ this.expect(tokTypes.comma);
149
+ if (this.afterTrailingComma(tokTypes.braceR)) {
150
+ break;
167
151
  }
152
+ } else {
153
+ first = false;
154
+ }
168
155
 
169
- if (isAssertLegacy) {
170
- nodes[LEGACY_ASSERT_ATTRIBUTES] = true;
171
- }
156
+ const attr =
157
+ /** @type {ImportAttribute} */
158
+ this.parseImportAttribute();
159
+ const keyName =
160
+ attr.key.type === "Identifier" ? attr.key.name : attr.key.value;
172
161
 
173
- return nodes;
162
+ if (Object.prototype.hasOwnProperty.call(attributeKeys, keyName)) {
163
+ this.raiseRecoverable(
164
+ attr.key.start,
165
+ `Duplicate attribute key '${keyName}'`
166
+ );
174
167
  }
168
+
169
+ attributeKeys[keyName] = true;
170
+ nodes.push(attr);
175
171
  }
176
- )
177
- );
172
+
173
+ if (isAssertLegacy) {
174
+ /** @type {EXPECTED_ANY} */
175
+ (nodes)[LEGACY_ASSERT_ATTRIBUTES] = true;
176
+ }
177
+
178
+ return nodes;
179
+ }
180
+ };
178
181
 
179
182
  // Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
180
183
  const parser = AcornParser.extend(importAssertions);
@@ -247,7 +250,7 @@ const getImportAttributes = node => {
247
250
  result[key] = /** @type {string} */ (attribute.value.value);
248
251
  }
249
252
 
250
- if (node.attributes[LEGACY_ASSERT_ATTRIBUTES]) {
253
+ if (/** @type {EXPECTED_ANY} */ (node.attributes)[LEGACY_ASSERT_ATTRIBUTES]) {
251
254
  result._isLegacyAssert = true;
252
255
  }
253
256
 
@@ -271,10 +274,13 @@ class VariableInfo {
271
274
  /** @typedef {Literal | string | null | undefined} ImportSource */
272
275
  /** @typedef {Omit<AcornOptions, "sourceType" | "ecmaVersion"> & { sourceType: "module" | "script" | "auto", ecmaVersion?: AcornOptions["ecmaVersion"] }} ParseOptions */
273
276
 
277
+ /** @typedef {symbol} Tag */
278
+ /** @typedef {Record<string, TODO>} TagData */
279
+
274
280
  /**
275
281
  * @typedef {object} TagInfo
276
- * @property {any} tag
277
- * @property {any} data
282
+ * @property {Tag} tag
283
+ * @property {TagData} [data]
278
284
  * @property {TagInfo | undefined} next
279
285
  */
280
286
 
@@ -287,6 +293,8 @@ class VariableInfo {
287
293
  * @property {boolean} inTry
288
294
  * @property {boolean} isStrict
289
295
  * @property {boolean} isAsmJs
296
+ * @property {boolean} inExecutedPath false for unknown state
297
+ * @property {undefined|"return"|"throw"} terminated
290
298
  */
291
299
 
292
300
  /** @typedef {[number, number]} Range */
@@ -388,7 +396,7 @@ class JavascriptParser extends Parser {
388
396
  this.hooks = Object.freeze({
389
397
  /** @type {HookMap<SyncBailHook<[UnaryExpression], BasicEvaluatedExpression | null | undefined>>} */
390
398
  evaluateTypeof: new HookMap(() => new SyncBailHook(["expression"])),
391
- /** @type {HookMap<SyncBailHook<[Expression | SpreadElement | PrivateIdentifier], BasicEvaluatedExpression | null | undefined>>} */
399
+ /** @type {HookMap<SyncBailHook<[Expression | SpreadElement | PrivateIdentifier | Super], BasicEvaluatedExpression | null | undefined>>} */
392
400
  evaluate: new HookMap(() => new SyncBailHook(["expression"])),
393
401
  /** @type {HookMap<SyncBailHook<[Identifier | ThisExpression | MemberExpression | MetaProperty], BasicEvaluatedExpression | null | undefined>>} */
394
402
  evaluateIdentifier: new HookMap(() => new SyncBailHook(["expression"])),
@@ -408,27 +416,27 @@ class JavascriptParser extends Parser {
408
416
  evaluateCallExpressionMember: new HookMap(
409
417
  () => new SyncBailHook(["expression", "param"])
410
418
  ),
411
- /** @type {HookMap<SyncBailHook<[Expression | Declaration | PrivateIdentifier, number], boolean | void>>} */
419
+ /** @type {HookMap<SyncBailHook<[Expression | Declaration | PrivateIdentifier | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration, number], boolean | void>>} */
412
420
  isPure: new HookMap(
413
421
  () => new SyncBailHook(["expression", "commentsStartPosition"])
414
422
  ),
415
- /** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */
423
+ /** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>} */
416
424
  preStatement: new SyncBailHook(["statement"]),
417
425
 
418
- /** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */
426
+ /** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>} */
419
427
  blockPreStatement: new SyncBailHook(["declaration"]),
420
- /** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */
428
+ /** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
421
429
  statement: new SyncBailHook(["statement"]),
422
430
  /** @type {SyncBailHook<[IfStatement], boolean | void>} */
423
431
  statementIf: new SyncBailHook(["statement"]),
424
- /** @type {SyncBailHook<[Expression, ClassExpression | ClassDeclaration], boolean | void>} */
432
+ /** @type {SyncBailHook<[Expression, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
425
433
  classExtendsExpression: new SyncBailHook([
426
434
  "expression",
427
435
  "classDefinition"
428
436
  ]),
429
- /** @type {SyncBailHook<[MethodDefinition | PropertyDefinition | StaticBlock, ClassExpression | ClassDeclaration], boolean | void>} */
437
+ /** @type {SyncBailHook<[MethodDefinition | PropertyDefinition | StaticBlock, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
430
438
  classBodyElement: new SyncBailHook(["element", "classDefinition"]),
431
- /** @type {SyncBailHook<[Expression, MethodDefinition | PropertyDefinition, ClassExpression | ClassDeclaration], boolean | void>} */
439
+ /** @type {SyncBailHook<[Expression, MethodDefinition | PropertyDefinition, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
432
440
  classBodyValue: new SyncBailHook([
433
441
  "expression",
434
442
  "element",
@@ -451,8 +459,8 @@ class JavascriptParser extends Parser {
451
459
  exportImport: new SyncBailHook(["statement", "source"]),
452
460
  /** @type {SyncBailHook<[ExportDefaultDeclaration | ExportNamedDeclaration | ExportAllDeclaration, Declaration], boolean | void>} */
453
461
  exportDeclaration: new SyncBailHook(["statement", "declaration"]),
454
- /** @type {SyncBailHook<[ExportDefaultDeclaration, FunctionDeclaration | ClassDeclaration], boolean | void>} */
455
- exportExpression: new SyncBailHook(["statement", "declaration"]),
462
+ /** @type {SyncBailHook<[ExportDefaultDeclaration, MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | Expression], boolean | void>} */
463
+ exportExpression: new SyncBailHook(["statement", "node"]),
456
464
  /** @type {SyncBailHook<[ExportDefaultDeclaration | ExportNamedDeclaration | ExportAllDeclaration, string, string, number | undefined], boolean | void>} */
457
465
  exportSpecifier: new SyncBailHook([
458
466
  "statement",
@@ -563,24 +571,27 @@ class JavascriptParser extends Parser {
563
571
  expressionLogicalOperator: new SyncBailHook(["expression"]),
564
572
  /** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */
565
573
  program: new SyncBailHook(["ast", "comments"]),
574
+ /** @type {SyncBailHook<[ThrowStatement | ReturnStatement], boolean | void>} */
575
+ terminate: new SyncBailHook(["statement"]),
566
576
  /** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */
567
577
  finish: new SyncBailHook(["ast", "comments"])
568
578
  });
569
579
  this.sourceType = sourceType;
570
580
  /** @type {ScopeInfo} */
571
- this.scope = undefined;
581
+ this.scope = /** @type {TODO} */ (undefined);
572
582
  /** @type {ParserState} */
573
- this.state = undefined;
583
+ this.state = /** @type {TODO} */ (undefined);
574
584
  /** @type {Comment[] | undefined} */
575
585
  this.comments = undefined;
576
586
  /** @type {Set<number> | undefined} */
577
587
  this.semicolons = undefined;
578
588
  /** @type {StatementPath | undefined} */
579
589
  this.statementPath = undefined;
580
- /** @type {Statement | ModuleDeclaration | Expression | undefined} */
590
+ /** @type {Statement | ModuleDeclaration | Expression | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | undefined} */
581
591
  this.prevStatement = undefined;
582
592
  /** @type {WeakMap<Expression, Set<DestructuringAssignmentProperty>> | undefined} */
583
593
  this.destructuringAssignmentProperties = undefined;
594
+ /** @type {TagData | undefined} */
584
595
  this.currentTagData = undefined;
585
596
  this.magicCommentContext = createMagicCommentContext();
586
597
  this._initializeEvaluating();
@@ -1242,7 +1253,8 @@ class JavascriptParser extends Parser {
1242
1253
  case "MetaProperty": {
1243
1254
  const res = this.callHooksForName(
1244
1255
  this.hooks.evaluateTypeof,
1245
- /** @type {string} */ (getRootName(expr.argument)),
1256
+ /** @type {string} */
1257
+ (getRootName(expr.argument)),
1246
1258
  expr
1247
1259
  );
1248
1260
  if (res !== undefined) return res;
@@ -1349,7 +1361,7 @@ class JavascriptParser extends Parser {
1349
1361
  });
1350
1362
  /**
1351
1363
  * @param {"Identifier" | "ThisExpression" | "MemberExpression"} exprType expression type name
1352
- * @param {function(Expression | SpreadElement): GetInfoResult | undefined} getInfo get info
1364
+ * @param {(node: Expression | SpreadElement) => GetInfoResult | undefined} getInfo get info
1353
1365
  * @returns {void}
1354
1366
  */
1355
1367
  const tapEvaluateWithVariableInfo = (exprType, getInfo) => {
@@ -1440,7 +1452,8 @@ class JavascriptParser extends Parser {
1440
1452
 
1441
1453
  return this.callHooksForName(
1442
1454
  this.hooks.evaluateIdentifier,
1443
- /** @type {string} */ (getRootName(metaProperty)),
1455
+ /** @type {string} */
1456
+ (getRootName(metaProperty)),
1444
1457
  metaProperty
1445
1458
  );
1446
1459
  });
@@ -1673,13 +1686,14 @@ class JavascriptParser extends Parser {
1673
1686
  continue;
1674
1687
  }
1675
1688
 
1676
- /** @type {string} */
1677
1689
  const value = argExpr.isString()
1678
1690
  ? /** @type {string} */ (argExpr.string)
1679
- : String(/** @type {number} */ (argExpr.number));
1691
+ : String(argExpr.number);
1680
1692
 
1681
1693
  /** @type {string} */
1682
- const newString = value + (stringSuffix ? stringSuffix.string : "");
1694
+ const newString =
1695
+ value +
1696
+ (stringSuffix ? /** @type {string} */ (stringSuffix.string) : "");
1683
1697
  const newRange = /** @type {Range} */ ([
1684
1698
  /** @type {Range} */ (argExpr.range)[0],
1685
1699
  /** @type {Range} */ ((stringSuffix || argExpr).range)[1]
@@ -1854,7 +1868,7 @@ class JavascriptParser extends Parser {
1854
1868
 
1855
1869
  /**
1856
1870
  * @param {Expression | SpreadElement} expr expression
1857
- * @returns {string | VariableInfoInterface | undefined} identifier
1871
+ * @returns {string | VariableInfo | undefined} identifier
1858
1872
  */
1859
1873
  getRenameIdentifier(expr) {
1860
1874
  const result = this.evaluateExpression(expr);
@@ -1864,7 +1878,7 @@ class JavascriptParser extends Parser {
1864
1878
  }
1865
1879
 
1866
1880
  /**
1867
- * @param {ClassExpression | ClassDeclaration} classy a class node
1881
+ * @param {ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration} classy a class node
1868
1882
  * @returns {void}
1869
1883
  */
1870
1884
  walkClass(classy) {
@@ -1941,12 +1955,13 @@ class JavascriptParser extends Parser {
1941
1955
  for (let index = 0, len = statements.length; index < len; index++) {
1942
1956
  const statement = statements[index];
1943
1957
  this.walkStatement(statement);
1958
+ if (this.scope.terminated) break;
1944
1959
  }
1945
1960
  }
1946
1961
 
1947
1962
  /**
1948
1963
  * Walking iterates the statements and expressions and processes them
1949
- * @param {Statement | ModuleDeclaration} statement statement
1964
+ * @param {Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration} statement statement
1950
1965
  */
1951
1966
  preWalkStatement(statement) {
1952
1967
  /** @type {StatementPath} */
@@ -2004,7 +2019,7 @@ class JavascriptParser extends Parser {
2004
2019
  }
2005
2020
 
2006
2021
  /**
2007
- * @param {Statement | ModuleDeclaration} statement statement
2022
+ * @param {Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration} statement statement
2008
2023
  */
2009
2024
  blockPreWalkStatement(statement) {
2010
2025
  /** @type {StatementPath} */
@@ -2043,7 +2058,7 @@ class JavascriptParser extends Parser {
2043
2058
  }
2044
2059
 
2045
2060
  /**
2046
- * @param {Statement | ModuleDeclaration} statement statement
2061
+ * @param {Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} statement statement
2047
2062
  */
2048
2063
  walkStatement(statement) {
2049
2064
  /** @type {StatementPath} */
@@ -2147,7 +2162,7 @@ class JavascriptParser extends Parser {
2147
2162
  this.blockPreWalkStatements(body);
2148
2163
  this.prevStatement = prev;
2149
2164
  this.walkStatements(body);
2150
- });
2165
+ }, this.scope.inExecutedPath);
2151
2166
  }
2152
2167
 
2153
2168
  /**
@@ -2173,15 +2188,21 @@ class JavascriptParser extends Parser {
2173
2188
  walkIfStatement(statement) {
2174
2189
  const result = this.hooks.statementIf.call(statement);
2175
2190
  if (result === undefined) {
2176
- this.walkExpression(statement.test);
2177
- this.walkNestedStatement(statement.consequent);
2178
- if (statement.alternate) {
2179
- this.walkNestedStatement(statement.alternate);
2180
- }
2181
- } else if (result) {
2182
- this.walkNestedStatement(statement.consequent);
2183
- } else if (statement.alternate) {
2184
- this.walkNestedStatement(statement.alternate);
2191
+ this.inExecutedPath(false, () => {
2192
+ this.walkExpression(statement.test);
2193
+ this.walkNestedStatement(statement.consequent);
2194
+ if (statement.alternate) {
2195
+ this.walkNestedStatement(statement.alternate);
2196
+ }
2197
+ });
2198
+ } else {
2199
+ this.inExecutedPath(true, () => {
2200
+ if (result) {
2201
+ this.walkNestedStatement(statement.consequent);
2202
+ } else if (statement.alternate) {
2203
+ this.walkNestedStatement(statement.alternate);
2204
+ }
2205
+ });
2185
2206
  }
2186
2207
  }
2187
2208
 
@@ -2239,6 +2260,12 @@ class JavascriptParser extends Parser {
2239
2260
  */
2240
2261
  walkTerminatingStatement(statement) {
2241
2262
  if (statement.argument) this.walkExpression(statement.argument);
2263
+ // Skip top level scope because to handle `export` and `module.exports` after terminate
2264
+ if (this.scope.topLevelScope === true) return;
2265
+ if (this.hooks.terminate.call(statement)) {
2266
+ this.scope.terminated =
2267
+ statement.type === "ReturnStatement" ? "return" : "throw";
2268
+ }
2242
2269
  }
2243
2270
 
2244
2271
  /**
@@ -2275,6 +2302,11 @@ class JavascriptParser extends Parser {
2275
2302
  this.walkStatement(statement.block);
2276
2303
  this.scope.inTry = false;
2277
2304
  }
2305
+ if (this.scope.terminated === "throw") {
2306
+ this.scope.terminated = undefined;
2307
+ } else if (this.scope.terminated === "return") {
2308
+ return;
2309
+ }
2278
2310
  if (statement.handler) this.walkCatchClause(statement.handler);
2279
2311
  if (statement.finalizer) this.walkStatement(statement.finalizer);
2280
2312
  }
@@ -2426,7 +2458,7 @@ class JavascriptParser extends Parser {
2426
2458
  }
2427
2459
 
2428
2460
  /**
2429
- * @param {FunctionDeclaration} statement function declaration
2461
+ * @param {FunctionDeclaration | MaybeNamedFunctionDeclaration} statement function declaration
2430
2462
  */
2431
2463
  preWalkFunctionDeclaration(statement) {
2432
2464
  if (statement.id) {
@@ -2435,7 +2467,7 @@ class JavascriptParser extends Parser {
2435
2467
  }
2436
2468
 
2437
2469
  /**
2438
- * @param {FunctionDeclaration} statement function declaration
2470
+ * @param {FunctionDeclaration | MaybeNamedFunctionDeclaration} statement function declaration
2439
2471
  */
2440
2472
  walkFunctionDeclaration(statement) {
2441
2473
  const wasTopLevel = this.scope.topLevelScope;
@@ -2444,15 +2476,14 @@ class JavascriptParser extends Parser {
2444
2476
  for (const param of statement.params) {
2445
2477
  this.walkPattern(param);
2446
2478
  }
2447
- if (statement.body.type === "BlockStatement") {
2448
- this.detectMode(statement.body.body);
2449
- const prev = this.prevStatement;
2450
- this.preWalkStatement(statement.body);
2451
- this.prevStatement = prev;
2452
- this.walkStatement(statement.body);
2453
- } else {
2454
- this.walkExpression(statement.body);
2455
- }
2479
+
2480
+ this.detectMode(statement.body.body);
2481
+
2482
+ const prev = this.prevStatement;
2483
+
2484
+ this.preWalkStatement(statement.body);
2485
+ this.prevStatement = prev;
2486
+ this.walkStatement(statement.body);
2456
2487
  });
2457
2488
  this.scope.topLevelScope = wasTopLevel;
2458
2489
  }
@@ -2647,26 +2678,29 @@ class JavascriptParser extends Parser {
2647
2678
  }
2648
2679
 
2649
2680
  /**
2650
- * @param {TODO} statement statement
2681
+ * @param {ExportDefaultDeclaration} statement statement
2651
2682
  */
2652
2683
  blockPreWalkExportDefaultDeclaration(statement) {
2653
2684
  const prev = this.prevStatement;
2654
- this.preWalkStatement(statement.declaration);
2685
+
2686
+ this.preWalkStatement(/** @type {TODO} */ (statement.declaration));
2655
2687
  this.prevStatement = prev;
2656
- this.blockPreWalkStatement(statement.declaration);
2688
+ this.blockPreWalkStatement(/** @type {TODO} */ (statement.declaration));
2689
+
2657
2690
  if (
2658
- /** @type {FunctionDeclaration | ClassDeclaration} */ (
2659
- statement.declaration
2660
- ).id &&
2691
+ /** @type {MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} */
2692
+ (statement.declaration).id &&
2661
2693
  statement.declaration.type !== "FunctionExpression" &&
2662
2694
  statement.declaration.type !== "ClassExpression"
2663
2695
  ) {
2664
2696
  const declaration =
2665
- /** @type {FunctionDeclaration | ClassDeclaration} */
2697
+ /** @type {MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} */
2666
2698
  (statement.declaration);
2699
+
2667
2700
  this.hooks.exportSpecifier.call(
2668
2701
  statement,
2669
- declaration.id.name,
2702
+ /** @type {Identifier} */
2703
+ (declaration.id).name,
2670
2704
  "default",
2671
2705
  undefined
2672
2706
  );
@@ -2679,9 +2713,8 @@ class JavascriptParser extends Parser {
2679
2713
  walkExportDefaultDeclaration(statement) {
2680
2714
  this.hooks.export.call(statement);
2681
2715
  if (
2682
- /** @type {FunctionDeclaration | ClassDeclaration} */ (
2683
- statement.declaration
2684
- ).id &&
2716
+ /** @type {FunctionDeclaration | ClassDeclaration} */
2717
+ (statement.declaration).id &&
2685
2718
  statement.declaration.type !== "FunctionExpression" &&
2686
2719
  statement.declaration.type !== "ClassExpression"
2687
2720
  ) {
@@ -2699,23 +2732,16 @@ class JavascriptParser extends Parser {
2699
2732
  statement.declaration.type === "FunctionDeclaration" ||
2700
2733
  statement.declaration.type === "ClassDeclaration"
2701
2734
  ) {
2702
- this.walkStatement(
2703
- /** @type {FunctionDeclaration | ClassDeclaration} */
2704
- (statement.declaration)
2705
- );
2735
+ this.walkStatement(statement.declaration);
2706
2736
  } else {
2707
2737
  this.walkExpression(statement.declaration);
2708
2738
  }
2709
2739
 
2710
- if (
2711
- !this.hooks.exportExpression.call(
2712
- statement,
2713
- /** @type {TODO} */ (statement).declaration
2714
- )
2715
- ) {
2740
+ if (!this.hooks.exportExpression.call(statement, statement.declaration)) {
2716
2741
  this.hooks.exportSpecifier.call(
2717
2742
  statement,
2718
- /** @type {TODO} */ (statement.declaration),
2743
+ /** @type {TODO} */
2744
+ (statement.declaration),
2719
2745
  "default",
2720
2746
  undefined
2721
2747
  );
@@ -2887,7 +2913,7 @@ class JavascriptParser extends Parser {
2887
2913
  }
2888
2914
 
2889
2915
  /**
2890
- * @param {ClassDeclaration} statement class declaration
2916
+ * @param {ClassDeclaration | MaybeNamedClassDeclaration} statement class declaration
2891
2917
  */
2892
2918
  blockPreWalkClassDeclaration(statement) {
2893
2919
  if (statement.id) {
@@ -2896,7 +2922,7 @@ class JavascriptParser extends Parser {
2896
2922
  }
2897
2923
 
2898
2924
  /**
2899
- * @param {ClassDeclaration} statement class declaration
2925
+ * @param {ClassDeclaration | MaybeNamedClassDeclaration} statement class declaration
2900
2926
  */
2901
2927
  walkClassDeclaration(statement) {
2902
2928
  this.walkClass(statement);
@@ -2943,8 +2969,10 @@ class JavascriptParser extends Parser {
2943
2969
  if (switchCase.test) {
2944
2970
  this.walkExpression(switchCase.test);
2945
2971
  }
2972
+
2946
2973
  if (switchCase.consequent.length > 0) {
2947
2974
  this.walkStatements(switchCase.consequent);
2975
+ this.scope.terminated = undefined;
2948
2976
  }
2949
2977
  }
2950
2978
  });
@@ -3052,7 +3080,7 @@ class JavascriptParser extends Parser {
3052
3080
  }
3053
3081
 
3054
3082
  /**
3055
- * @param {TODO} expression expression
3083
+ * @param {Expression | SpreadElement | PrivateIdentifier | Super} expression expression
3056
3084
  */
3057
3085
  walkExpression(expression) {
3058
3086
  switch (expression.type) {
@@ -3191,7 +3219,10 @@ class JavascriptParser extends Parser {
3191
3219
  this.walkIdentifier(prop.value);
3192
3220
  this.scope.inShorthand = false;
3193
3221
  } else {
3194
- this.walkExpression(prop.value);
3222
+ this.walkExpression(
3223
+ /** @type {Exclude<Property["value"], AssignmentPattern | ObjectPattern | ArrayPattern | RestElement>} */
3224
+ (prop.value)
3225
+ );
3195
3226
  }
3196
3227
  }
3197
3228
 
@@ -3212,15 +3243,14 @@ class JavascriptParser extends Parser {
3212
3243
  for (const param of expression.params) {
3213
3244
  this.walkPattern(param);
3214
3245
  }
3215
- if (expression.body.type === "BlockStatement") {
3216
- this.detectMode(expression.body.body);
3217
- const prev = this.prevStatement;
3218
- this.preWalkStatement(expression.body);
3219
- this.prevStatement = prev;
3220
- this.walkStatement(expression.body);
3221
- } else {
3222
- this.walkExpression(expression.body);
3223
- }
3246
+
3247
+ this.detectMode(expression.body.body);
3248
+
3249
+ const prev = this.prevStatement;
3250
+
3251
+ this.preWalkStatement(expression.body);
3252
+ this.prevStatement = prev;
3253
+ this.walkStatement(expression.body);
3224
3254
  });
3225
3255
  this.scope.topLevelScope = wasTopLevel;
3226
3256
  }
@@ -3379,12 +3409,13 @@ class JavascriptParser extends Parser {
3379
3409
  this.walkExpression(expression.right);
3380
3410
  this.enterPattern(expression.left, (name, decl) => {
3381
3411
  if (!this.callHooksForName(this.hooks.assign, name, expression)) {
3382
- this.walkExpression(expression.left);
3412
+ this.walkExpression(
3413
+ /** @type {MemberExpression} */
3414
+ (expression.left)
3415
+ );
3383
3416
  }
3384
3417
  });
3385
- return;
3386
- }
3387
- if (expression.left.type.endsWith("Pattern")) {
3418
+ } else if (expression.left.type.endsWith("Pattern")) {
3388
3419
  this.walkExpression(expression.right);
3389
3420
  this.enterPattern(expression.left, (name, decl) => {
3390
3421
  if (!this.callHooksForName(this.hooks.assign, name, expression)) {
@@ -3412,7 +3443,10 @@ class JavascriptParser extends Parser {
3412
3443
  this.walkExpression(expression.left);
3413
3444
  } else {
3414
3445
  this.walkExpression(expression.right);
3415
- this.walkExpression(expression.left);
3446
+ this.walkExpression(
3447
+ /** @type {Exclude<AssignmentExpression["left"], Identifier | RestElement | MemberExpression | ObjectPattern | ArrayPattern | AssignmentPattern>} */
3448
+ (expression.left)
3449
+ );
3416
3450
  }
3417
3451
  }
3418
3452
 
@@ -3422,15 +3456,21 @@ class JavascriptParser extends Parser {
3422
3456
  walkConditionalExpression(expression) {
3423
3457
  const result = this.hooks.expressionConditionalOperator.call(expression);
3424
3458
  if (result === undefined) {
3425
- this.walkExpression(expression.test);
3426
- this.walkExpression(expression.consequent);
3427
- if (expression.alternate) {
3428
- this.walkExpression(expression.alternate);
3429
- }
3430
- } else if (result) {
3431
- this.walkExpression(expression.consequent);
3432
- } else if (expression.alternate) {
3433
- this.walkExpression(expression.alternate);
3459
+ this.inExecutedPath(false, () => {
3460
+ this.walkExpression(expression.test);
3461
+ this.walkExpression(expression.consequent);
3462
+ if (expression.alternate) {
3463
+ this.walkExpression(expression.alternate);
3464
+ }
3465
+ });
3466
+ } else {
3467
+ this.inExecutedPath(true, () => {
3468
+ if (result) {
3469
+ this.walkExpression(expression.consequent);
3470
+ } else if (expression.alternate) {
3471
+ this.walkExpression(expression.alternate);
3472
+ }
3473
+ });
3434
3474
  }
3435
3475
  }
3436
3476
 
@@ -3513,7 +3553,7 @@ class JavascriptParser extends Parser {
3513
3553
  _walkIIFE(functionExpression, options, currentThis) {
3514
3554
  /**
3515
3555
  * @param {Expression | SpreadElement} argOrThis arg or this
3516
- * @returns {string | VariableInfoInterface | undefined} var info
3556
+ * @returns {string | VariableInfo | undefined} var info
3517
3557
  */
3518
3558
  const getVarInfo = argOrThis => {
3519
3559
  const renameIdentifier = this.getRenameIdentifier(argOrThis);
@@ -3603,13 +3643,13 @@ class JavascriptParser extends Parser {
3603
3643
  expression.callee.type === "MemberExpression" &&
3604
3644
  expression.callee.object.type.endsWith("FunctionExpression") &&
3605
3645
  !expression.callee.computed &&
3606
- // eslint-disable-next-line no-warning-comments
3607
- // @ts-ignore
3608
- // TODO check me and handle more cases
3609
- (expression.callee.property.name === "call" ||
3610
- // eslint-disable-next-line no-warning-comments
3611
- // @ts-ignore
3612
- expression.callee.property.name === "bind") &&
3646
+ /** @type {boolean} */
3647
+ (
3648
+ /** @type {Identifier} */
3649
+ (expression.callee.property).name === "call" ||
3650
+ /** @type {Identifier} */
3651
+ (expression.callee.property).name === "bind"
3652
+ ) &&
3613
3653
  expression.arguments.length > 0 &&
3614
3654
  isSimpleFunction(
3615
3655
  /** @type {FunctionExpression | ArrowFunctionExpression} */
@@ -3656,9 +3696,7 @@ class JavascriptParser extends Parser {
3656
3696
  if (result === true) return;
3657
3697
  }
3658
3698
  }
3659
- const callee = this.evaluateExpression(
3660
- /** @type {TODO} */ (expression.callee)
3661
- );
3699
+ const callee = this.evaluateExpression(expression.callee);
3662
3700
  if (callee.isIdentifier()) {
3663
3701
  const result1 = this.callHooksForInfo(
3664
3702
  this.hooks.callMemberChain,
@@ -3764,11 +3802,12 @@ class JavascriptParser extends Parser {
3764
3802
  }
3765
3803
 
3766
3804
  /**
3767
- * @param {TODO} expression member expression
3805
+ * @template R
3806
+ * @param {MemberExpression} expression member expression
3768
3807
  * @param {string} name name
3769
3808
  * @param {string | VariableInfo} rootInfo root info
3770
3809
  * @param {string[]} members members
3771
- * @param {TODO} onUnhandled on unhandled callback
3810
+ * @param {() => R | undefined} onUnhandled on unhandled callback
3772
3811
  */
3773
3812
  walkMemberExpressionWithExpressionName(
3774
3813
  expression,
@@ -3781,7 +3820,9 @@ class JavascriptParser extends Parser {
3781
3820
  // optimize the case where expression.object is a MemberExpression too.
3782
3821
  // we can keep info here when calling walkMemberExpression directly
3783
3822
  const property =
3784
- expression.property.name || `${expression.property.value}`;
3823
+ /** @type {Identifier} */
3824
+ (expression.property).name ||
3825
+ `${/** @type {Literal} */ (expression.property).value}`;
3785
3826
  name = name.slice(0, -property.length - 1);
3786
3827
  members.pop();
3787
3828
  const result = this.callHooksForInfo(
@@ -3847,8 +3888,8 @@ class JavascriptParser extends Parser {
3847
3888
  * @template R
3848
3889
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
3849
3890
  * @param {Expression | Super} expr expression info
3850
- * @param {(function(string, string | ScopeInfo | VariableInfo, function(): string[]): any) | undefined} fallback callback when variable in not handled by hooks
3851
- * @param {(function(string): any) | undefined} defined callback when variable is defined
3891
+ * @param {((name: string, rootInfo: string | ScopeInfo | VariableInfo, getMembers: () => string[]) => TODO) | undefined} fallback callback when variable in not handled by hooks
3892
+ * @param {((result?: string) => R | undefined) | undefined} defined callback when variable is defined
3852
3893
  * @param {AsArray<T>} args args for the hook
3853
3894
  * @returns {R | undefined} result of hook
3854
3895
  */
@@ -3899,7 +3940,7 @@ class JavascriptParser extends Parser {
3899
3940
  * @template R
3900
3941
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks that should be called
3901
3942
  * @param {ExportedVariableInfo} info variable info
3902
- * @param {AsArray<T>} args args for the hook
3943
+ * @param {AsArray<T>} args args for the hook
3903
3944
  * @returns {R | undefined} result of hook
3904
3945
  */
3905
3946
  callHooksForInfo(hookMap, info, ...args) {
@@ -3917,8 +3958,8 @@ class JavascriptParser extends Parser {
3917
3958
  * @template R
3918
3959
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
3919
3960
  * @param {ExportedVariableInfo} info variable info
3920
- * @param {(function(string): any) | undefined} fallback callback when variable in not handled by hooks
3921
- * @param {(function(string=): any) | undefined} defined callback when variable is defined
3961
+ * @param {((name: string) => TODO) | undefined} fallback callback when variable in not handled by hooks
3962
+ * @param {((result?: string) => TODO) | undefined} defined callback when variable is defined
3922
3963
  * @param {AsArray<T>} args args for the hook
3923
3964
  * @returns {R | undefined} result of hook
3924
3965
  */
@@ -3967,8 +4008,8 @@ class JavascriptParser extends Parser {
3967
4008
  * @template R
3968
4009
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
3969
4010
  * @param {string} name key in map
3970
- * @param {(function(string): any) | undefined} fallback callback when variable in not handled by hooks
3971
- * @param {(function(): any) | undefined} defined callback when variable is defined
4011
+ * @param {((value: string) => R | undefined) | undefined} fallback callback when variable in not handled by hooks
4012
+ * @param {(() => R) | undefined} defined callback when variable is defined
3972
4013
  * @param {AsArray<T>} args args for the hook
3973
4014
  * @returns {R | undefined} result of hook
3974
4015
  */
@@ -3984,8 +4025,8 @@ class JavascriptParser extends Parser {
3984
4025
 
3985
4026
  /**
3986
4027
  * @deprecated
3987
- * @param {any} params scope params
3988
- * @param {function(): void} fn inner function
4028
+ * @param {(string | Pattern | Property)[]} params scope params
4029
+ * @param {() => void} fn inner function
3989
4030
  * @returns {void}
3990
4031
  */
3991
4032
  inScope(params, fn) {
@@ -3997,6 +4038,8 @@ class JavascriptParser extends Parser {
3997
4038
  inTaggedTemplateTag: false,
3998
4039
  isStrict: oldScope.isStrict,
3999
4040
  isAsmJs: oldScope.isAsmJs,
4041
+ inExecutedPath: false,
4042
+ terminated: undefined,
4000
4043
  definitions: oldScope.definitions.createChild()
4001
4044
  };
4002
4045
 
@@ -4011,10 +4054,27 @@ class JavascriptParser extends Parser {
4011
4054
  this.scope = oldScope;
4012
4055
  }
4013
4056
 
4057
+ /**
4058
+ * @param {boolean} state executed state
4059
+ * @param {() => void} fn inner function
4060
+ */
4061
+ inExecutedPath(state, fn) {
4062
+ const oldState = this.scope.inExecutedPath;
4063
+ const oldTerminated = this.scope.terminated;
4064
+ this.scope.inExecutedPath = state;
4065
+
4066
+ fn();
4067
+
4068
+ if (!state) {
4069
+ this.scope.terminated = oldTerminated;
4070
+ }
4071
+ this.scope.inExecutedPath = oldState;
4072
+ }
4073
+
4014
4074
  /**
4015
4075
  * @param {boolean} hasThis true, when this is defined
4016
4076
  * @param {Identifier[]} params scope params
4017
- * @param {function(): void} fn inner function
4077
+ * @param {() => void} fn inner function
4018
4078
  * @returns {void}
4019
4079
  */
4020
4080
  inClassScope(hasThis, params, fn) {
@@ -4024,8 +4084,10 @@ class JavascriptParser extends Parser {
4024
4084
  inTry: false,
4025
4085
  inShorthand: false,
4026
4086
  inTaggedTemplateTag: false,
4087
+ inExecutedPath: true,
4027
4088
  isStrict: oldScope.isStrict,
4028
4089
  isAsmJs: oldScope.isAsmJs,
4090
+ terminated: undefined,
4029
4091
  definitions: oldScope.definitions.createChild()
4030
4092
  };
4031
4093
 
@@ -4045,7 +4107,7 @@ class JavascriptParser extends Parser {
4045
4107
  /**
4046
4108
  * @param {boolean} hasThis true, when this is defined
4047
4109
  * @param {(Pattern | string)[]} params scope params
4048
- * @param {function(): void} fn inner function
4110
+ * @param {() => void} fn inner function
4049
4111
  * @returns {void}
4050
4112
  */
4051
4113
  inFunctionScope(hasThis, params, fn) {
@@ -4055,8 +4117,10 @@ class JavascriptParser extends Parser {
4055
4117
  inTry: false,
4056
4118
  inShorthand: false,
4057
4119
  inTaggedTemplateTag: false,
4120
+ inExecutedPath: true,
4058
4121
  isStrict: oldScope.isStrict,
4059
4122
  isAsmJs: oldScope.isAsmJs,
4123
+ terminated: undefined,
4060
4124
  definitions: oldScope.definitions.createChild()
4061
4125
  };
4062
4126
 
@@ -4074,23 +4138,35 @@ class JavascriptParser extends Parser {
4074
4138
  }
4075
4139
 
4076
4140
  /**
4077
- * @param {function(): void} fn inner function
4141
+ * @param {() => void} fn inner function
4142
+ * @param {boolean} inExecutedPath executed state
4078
4143
  * @returns {void}
4079
4144
  */
4080
- inBlockScope(fn) {
4145
+ inBlockScope(fn, inExecutedPath = false) {
4081
4146
  const oldScope = this.scope;
4082
4147
  this.scope = {
4083
4148
  topLevelScope: oldScope.topLevelScope,
4084
4149
  inTry: oldScope.inTry,
4085
4150
  inShorthand: false,
4086
4151
  inTaggedTemplateTag: false,
4152
+ inExecutedPath,
4087
4153
  isStrict: oldScope.isStrict,
4088
4154
  isAsmJs: oldScope.isAsmJs,
4155
+ terminated: oldScope.terminated,
4089
4156
  definitions: oldScope.definitions.createChild()
4090
4157
  };
4091
4158
 
4092
4159
  fn();
4093
4160
 
4161
+ const terminated = this.scope.terminated;
4162
+
4163
+ if (
4164
+ inExecutedPath &&
4165
+ ((this.scope.inTry && terminated === "throw") || terminated === "return")
4166
+ ) {
4167
+ oldScope.terminated = terminated;
4168
+ }
4169
+
4094
4170
  this.scope = oldScope;
4095
4171
  }
4096
4172
 
@@ -4228,7 +4304,7 @@ class JavascriptParser extends Parser {
4228
4304
  }
4229
4305
 
4230
4306
  /**
4231
- * @param {Expression | SpreadElement | PrivateIdentifier} expression expression node
4307
+ * @param {Expression | SpreadElement | PrivateIdentifier | Super} expression expression node
4232
4308
  * @returns {BasicEvaluatedExpression} evaluation result
4233
4309
  */
4234
4310
  evaluateExpression(expression) {
@@ -4242,6 +4318,7 @@ class JavascriptParser extends Parser {
4242
4318
  }
4243
4319
  }
4244
4320
  } catch (err) {
4321
+ // eslint-disable-next-line no-console
4245
4322
  console.warn(err);
4246
4323
  // ignore error
4247
4324
  }
@@ -4274,7 +4351,7 @@ class JavascriptParser extends Parser {
4274
4351
 
4275
4352
  /**
4276
4353
  * @param {Expression} expression expression
4277
- * @returns {{ range?: Range, value: string, code: boolean, conditional: TODO }} result
4354
+ * @returns {{ range?: Range, value: string, code: boolean, conditional: boolean | TODO }} result
4278
4355
  */
4279
4356
  parseCalculatedString(expression) {
4280
4357
  switch (expression.type) {
@@ -4379,6 +4456,13 @@ class JavascriptParser extends Parser {
4379
4456
  if (typeof source === "object") {
4380
4457
  ast = /** @type {Program} */ (source);
4381
4458
  comments = source.comments;
4459
+ if (source.semicolons) {
4460
+ // Forward semicolon information from the preparsed AST if present
4461
+ // This ensures the output is consistent with that of a fresh AST
4462
+ for (const pos of source.semicolons) {
4463
+ semicolons.add(pos);
4464
+ }
4465
+ }
4382
4466
  } else {
4383
4467
  comments = [];
4384
4468
  ast = JavascriptParser._parse(source, {
@@ -4399,12 +4483,13 @@ class JavascriptParser extends Parser {
4399
4483
  inTry: false,
4400
4484
  inShorthand: false,
4401
4485
  inTaggedTemplateTag: false,
4486
+ inExecutedPath: false,
4402
4487
  isStrict: false,
4403
4488
  isAsmJs: false,
4489
+ terminated: undefined,
4404
4490
  definitions: new StackedMap()
4405
4491
  };
4406
- /** @type {ParserState} */
4407
- this.state = state;
4492
+ this.state = /** @type {ParserState} */ (state);
4408
4493
  this.comments = comments;
4409
4494
  this.semicolons = semicolons;
4410
4495
  this.statementPath = [];
@@ -4421,7 +4506,6 @@ class JavascriptParser extends Parser {
4421
4506
  }
4422
4507
  this.hooks.finish.call(ast, comments);
4423
4508
  this.scope = oldScope;
4424
- /** @type {ParserState} */
4425
4509
  this.state = oldState;
4426
4510
  this.comments = oldComments;
4427
4511
  this.semicolons = oldSemicolons;
@@ -4446,7 +4530,7 @@ class JavascriptParser extends Parser {
4446
4530
  }
4447
4531
 
4448
4532
  /**
4449
- * @param {Expression | Declaration | PrivateIdentifier | null | undefined} expr an expression
4533
+ * @param {Expression | Declaration | PrivateIdentifier | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | null | undefined} expr an expression
4450
4534
  * @param {number} commentsStartPos source position from which annotation comments are checked
4451
4535
  * @returns {boolean} true, when the expression is pure
4452
4536
  */
@@ -4666,8 +4750,8 @@ class JavascriptParser extends Parser {
4666
4750
 
4667
4751
  /**
4668
4752
  * @param {string} name name
4669
- * @param {symbol} tag tag info
4670
- * @returns {TODO} tag data
4753
+ * @param {Tag} tag tag info
4754
+ * @returns {TagData | undefined} tag data
4671
4755
  */
4672
4756
  getTagData(name, tag) {
4673
4757
  const info = this.scope.definitions.get(name);
@@ -4682,8 +4766,8 @@ class JavascriptParser extends Parser {
4682
4766
 
4683
4767
  /**
4684
4768
  * @param {string} name name
4685
- * @param {symbol} tag tag info
4686
- * @param {TODO=} data data
4769
+ * @param {Tag} tag tag info
4770
+ * @param {TagData=} data data
4687
4771
  */
4688
4772
  tagVariable(name, tag, data) {
4689
4773
  const oldInfo = this.scope.definitions.get(name);
@@ -4784,7 +4868,7 @@ class JavascriptParser extends Parser {
4784
4868
 
4785
4869
  /**
4786
4870
  * @param {Range} range range of the comment
4787
- * @returns {{ options: Record<string, any> | null, errors: (Error & { comment: Comment })[] | null }} result
4871
+ * @returns {{ options: Record<string, EXPECTED_ANY> | null, errors: (Error & { comment: Comment })[] | null }} result
4788
4872
  */
4789
4873
  parseCommentOptions(range) {
4790
4874
  const comments = this.getComments(range);