webpack 5.98.0 → 5.99.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.
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 +287 -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);
171
+ }
172
+
173
+ if (isAssertLegacy) {
174
+ /** @type {EXPECTED_ANY} */
175
+ (nodes)[LEGACY_ASSERT_ATTRIBUTES] = true;
175
176
  }
176
- )
177
- );
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) {
@@ -1938,15 +1952,25 @@ class JavascriptParser extends Parser {
1938
1952
  * @param {(Statement | ModuleDeclaration)[]} statements statements
1939
1953
  */
1940
1954
  walkStatements(statements) {
1955
+ let onlyFunctionDeclaration = false;
1956
+
1941
1957
  for (let index = 0, len = statements.length; index < len; index++) {
1942
1958
  const statement = statements[index];
1959
+
1960
+ if (onlyFunctionDeclaration && statement.type !== "FunctionDeclaration")
1961
+ continue;
1962
+
1943
1963
  this.walkStatement(statement);
1964
+
1965
+ if (this.scope.terminated) {
1966
+ onlyFunctionDeclaration = true;
1967
+ }
1944
1968
  }
1945
1969
  }
1946
1970
 
1947
1971
  /**
1948
1972
  * Walking iterates the statements and expressions and processes them
1949
- * @param {Statement | ModuleDeclaration} statement statement
1973
+ * @param {Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration} statement statement
1950
1974
  */
1951
1975
  preWalkStatement(statement) {
1952
1976
  /** @type {StatementPath} */
@@ -2004,7 +2028,7 @@ class JavascriptParser extends Parser {
2004
2028
  }
2005
2029
 
2006
2030
  /**
2007
- * @param {Statement | ModuleDeclaration} statement statement
2031
+ * @param {Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration} statement statement
2008
2032
  */
2009
2033
  blockPreWalkStatement(statement) {
2010
2034
  /** @type {StatementPath} */
@@ -2043,7 +2067,7 @@ class JavascriptParser extends Parser {
2043
2067
  }
2044
2068
 
2045
2069
  /**
2046
- * @param {Statement | ModuleDeclaration} statement statement
2070
+ * @param {Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} statement statement
2047
2071
  */
2048
2072
  walkStatement(statement) {
2049
2073
  /** @type {StatementPath} */
@@ -2147,7 +2171,7 @@ class JavascriptParser extends Parser {
2147
2171
  this.blockPreWalkStatements(body);
2148
2172
  this.prevStatement = prev;
2149
2173
  this.walkStatements(body);
2150
- });
2174
+ }, this.scope.inExecutedPath);
2151
2175
  }
2152
2176
 
2153
2177
  /**
@@ -2173,15 +2197,21 @@ class JavascriptParser extends Parser {
2173
2197
  walkIfStatement(statement) {
2174
2198
  const result = this.hooks.statementIf.call(statement);
2175
2199
  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);
2200
+ this.inExecutedPath(false, () => {
2201
+ this.walkExpression(statement.test);
2202
+ this.walkNestedStatement(statement.consequent);
2203
+ if (statement.alternate) {
2204
+ this.walkNestedStatement(statement.alternate);
2205
+ }
2206
+ });
2207
+ } else {
2208
+ this.inExecutedPath(true, () => {
2209
+ if (result) {
2210
+ this.walkNestedStatement(statement.consequent);
2211
+ } else if (statement.alternate) {
2212
+ this.walkNestedStatement(statement.alternate);
2213
+ }
2214
+ });
2185
2215
  }
2186
2216
  }
2187
2217
 
@@ -2239,6 +2269,12 @@ class JavascriptParser extends Parser {
2239
2269
  */
2240
2270
  walkTerminatingStatement(statement) {
2241
2271
  if (statement.argument) this.walkExpression(statement.argument);
2272
+ // Skip top level scope because to handle `export` and `module.exports` after terminate
2273
+ if (this.scope.topLevelScope === true) return;
2274
+ if (this.hooks.terminate.call(statement)) {
2275
+ this.scope.terminated =
2276
+ statement.type === "ReturnStatement" ? "return" : "throw";
2277
+ }
2242
2278
  }
2243
2279
 
2244
2280
  /**
@@ -2275,8 +2311,19 @@ class JavascriptParser extends Parser {
2275
2311
  this.walkStatement(statement.block);
2276
2312
  this.scope.inTry = false;
2277
2313
  }
2314
+
2315
+ if (this.scope.terminated === "throw") {
2316
+ this.scope.terminated = undefined;
2317
+ }
2318
+
2319
+ const oldTerminate = this.scope.terminated;
2320
+
2321
+ this.scope.terminated = undefined;
2322
+
2278
2323
  if (statement.handler) this.walkCatchClause(statement.handler);
2279
2324
  if (statement.finalizer) this.walkStatement(statement.finalizer);
2325
+
2326
+ this.scope.terminated = oldTerminate;
2280
2327
  }
2281
2328
 
2282
2329
  /**
@@ -2426,7 +2473,7 @@ class JavascriptParser extends Parser {
2426
2473
  }
2427
2474
 
2428
2475
  /**
2429
- * @param {FunctionDeclaration} statement function declaration
2476
+ * @param {FunctionDeclaration | MaybeNamedFunctionDeclaration} statement function declaration
2430
2477
  */
2431
2478
  preWalkFunctionDeclaration(statement) {
2432
2479
  if (statement.id) {
@@ -2435,7 +2482,7 @@ class JavascriptParser extends Parser {
2435
2482
  }
2436
2483
 
2437
2484
  /**
2438
- * @param {FunctionDeclaration} statement function declaration
2485
+ * @param {FunctionDeclaration | MaybeNamedFunctionDeclaration} statement function declaration
2439
2486
  */
2440
2487
  walkFunctionDeclaration(statement) {
2441
2488
  const wasTopLevel = this.scope.topLevelScope;
@@ -2444,15 +2491,14 @@ class JavascriptParser extends Parser {
2444
2491
  for (const param of statement.params) {
2445
2492
  this.walkPattern(param);
2446
2493
  }
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
- }
2494
+
2495
+ this.detectMode(statement.body.body);
2496
+
2497
+ const prev = this.prevStatement;
2498
+
2499
+ this.preWalkStatement(statement.body);
2500
+ this.prevStatement = prev;
2501
+ this.walkStatement(statement.body);
2456
2502
  });
2457
2503
  this.scope.topLevelScope = wasTopLevel;
2458
2504
  }
@@ -2647,26 +2693,29 @@ class JavascriptParser extends Parser {
2647
2693
  }
2648
2694
 
2649
2695
  /**
2650
- * @param {TODO} statement statement
2696
+ * @param {ExportDefaultDeclaration} statement statement
2651
2697
  */
2652
2698
  blockPreWalkExportDefaultDeclaration(statement) {
2653
2699
  const prev = this.prevStatement;
2654
- this.preWalkStatement(statement.declaration);
2700
+
2701
+ this.preWalkStatement(/** @type {TODO} */ (statement.declaration));
2655
2702
  this.prevStatement = prev;
2656
- this.blockPreWalkStatement(statement.declaration);
2703
+ this.blockPreWalkStatement(/** @type {TODO} */ (statement.declaration));
2704
+
2657
2705
  if (
2658
- /** @type {FunctionDeclaration | ClassDeclaration} */ (
2659
- statement.declaration
2660
- ).id &&
2706
+ /** @type {MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} */
2707
+ (statement.declaration).id &&
2661
2708
  statement.declaration.type !== "FunctionExpression" &&
2662
2709
  statement.declaration.type !== "ClassExpression"
2663
2710
  ) {
2664
2711
  const declaration =
2665
- /** @type {FunctionDeclaration | ClassDeclaration} */
2712
+ /** @type {MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} */
2666
2713
  (statement.declaration);
2714
+
2667
2715
  this.hooks.exportSpecifier.call(
2668
2716
  statement,
2669
- declaration.id.name,
2717
+ /** @type {Identifier} */
2718
+ (declaration.id).name,
2670
2719
  "default",
2671
2720
  undefined
2672
2721
  );
@@ -2679,9 +2728,8 @@ class JavascriptParser extends Parser {
2679
2728
  walkExportDefaultDeclaration(statement) {
2680
2729
  this.hooks.export.call(statement);
2681
2730
  if (
2682
- /** @type {FunctionDeclaration | ClassDeclaration} */ (
2683
- statement.declaration
2684
- ).id &&
2731
+ /** @type {FunctionDeclaration | ClassDeclaration} */
2732
+ (statement.declaration).id &&
2685
2733
  statement.declaration.type !== "FunctionExpression" &&
2686
2734
  statement.declaration.type !== "ClassExpression"
2687
2735
  ) {
@@ -2699,23 +2747,16 @@ class JavascriptParser extends Parser {
2699
2747
  statement.declaration.type === "FunctionDeclaration" ||
2700
2748
  statement.declaration.type === "ClassDeclaration"
2701
2749
  ) {
2702
- this.walkStatement(
2703
- /** @type {FunctionDeclaration | ClassDeclaration} */
2704
- (statement.declaration)
2705
- );
2750
+ this.walkStatement(statement.declaration);
2706
2751
  } else {
2707
2752
  this.walkExpression(statement.declaration);
2708
2753
  }
2709
2754
 
2710
- if (
2711
- !this.hooks.exportExpression.call(
2712
- statement,
2713
- /** @type {TODO} */ (statement).declaration
2714
- )
2715
- ) {
2755
+ if (!this.hooks.exportExpression.call(statement, statement.declaration)) {
2716
2756
  this.hooks.exportSpecifier.call(
2717
2757
  statement,
2718
- /** @type {TODO} */ (statement.declaration),
2758
+ /** @type {TODO} */
2759
+ (statement.declaration),
2719
2760
  "default",
2720
2761
  undefined
2721
2762
  );
@@ -2887,7 +2928,7 @@ class JavascriptParser extends Parser {
2887
2928
  }
2888
2929
 
2889
2930
  /**
2890
- * @param {ClassDeclaration} statement class declaration
2931
+ * @param {ClassDeclaration | MaybeNamedClassDeclaration} statement class declaration
2891
2932
  */
2892
2933
  blockPreWalkClassDeclaration(statement) {
2893
2934
  if (statement.id) {
@@ -2896,7 +2937,7 @@ class JavascriptParser extends Parser {
2896
2937
  }
2897
2938
 
2898
2939
  /**
2899
- * @param {ClassDeclaration} statement class declaration
2940
+ * @param {ClassDeclaration | MaybeNamedClassDeclaration} statement class declaration
2900
2941
  */
2901
2942
  walkClassDeclaration(statement) {
2902
2943
  this.walkClass(statement);
@@ -2943,8 +2984,10 @@ class JavascriptParser extends Parser {
2943
2984
  if (switchCase.test) {
2944
2985
  this.walkExpression(switchCase.test);
2945
2986
  }
2987
+
2946
2988
  if (switchCase.consequent.length > 0) {
2947
2989
  this.walkStatements(switchCase.consequent);
2990
+ this.scope.terminated = undefined;
2948
2991
  }
2949
2992
  }
2950
2993
  });
@@ -3052,7 +3095,7 @@ class JavascriptParser extends Parser {
3052
3095
  }
3053
3096
 
3054
3097
  /**
3055
- * @param {TODO} expression expression
3098
+ * @param {Expression | SpreadElement | PrivateIdentifier | Super} expression expression
3056
3099
  */
3057
3100
  walkExpression(expression) {
3058
3101
  switch (expression.type) {
@@ -3191,7 +3234,10 @@ class JavascriptParser extends Parser {
3191
3234
  this.walkIdentifier(prop.value);
3192
3235
  this.scope.inShorthand = false;
3193
3236
  } else {
3194
- this.walkExpression(prop.value);
3237
+ this.walkExpression(
3238
+ /** @type {Exclude<Property["value"], AssignmentPattern | ObjectPattern | ArrayPattern | RestElement>} */
3239
+ (prop.value)
3240
+ );
3195
3241
  }
3196
3242
  }
3197
3243
 
@@ -3212,15 +3258,14 @@ class JavascriptParser extends Parser {
3212
3258
  for (const param of expression.params) {
3213
3259
  this.walkPattern(param);
3214
3260
  }
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
- }
3261
+
3262
+ this.detectMode(expression.body.body);
3263
+
3264
+ const prev = this.prevStatement;
3265
+
3266
+ this.preWalkStatement(expression.body);
3267
+ this.prevStatement = prev;
3268
+ this.walkStatement(expression.body);
3224
3269
  });
3225
3270
  this.scope.topLevelScope = wasTopLevel;
3226
3271
  }
@@ -3379,12 +3424,13 @@ class JavascriptParser extends Parser {
3379
3424
  this.walkExpression(expression.right);
3380
3425
  this.enterPattern(expression.left, (name, decl) => {
3381
3426
  if (!this.callHooksForName(this.hooks.assign, name, expression)) {
3382
- this.walkExpression(expression.left);
3427
+ this.walkExpression(
3428
+ /** @type {MemberExpression} */
3429
+ (expression.left)
3430
+ );
3383
3431
  }
3384
3432
  });
3385
- return;
3386
- }
3387
- if (expression.left.type.endsWith("Pattern")) {
3433
+ } else if (expression.left.type.endsWith("Pattern")) {
3388
3434
  this.walkExpression(expression.right);
3389
3435
  this.enterPattern(expression.left, (name, decl) => {
3390
3436
  if (!this.callHooksForName(this.hooks.assign, name, expression)) {
@@ -3412,7 +3458,10 @@ class JavascriptParser extends Parser {
3412
3458
  this.walkExpression(expression.left);
3413
3459
  } else {
3414
3460
  this.walkExpression(expression.right);
3415
- this.walkExpression(expression.left);
3461
+ this.walkExpression(
3462
+ /** @type {Exclude<AssignmentExpression["left"], Identifier | RestElement | MemberExpression | ObjectPattern | ArrayPattern | AssignmentPattern>} */
3463
+ (expression.left)
3464
+ );
3416
3465
  }
3417
3466
  }
3418
3467
 
@@ -3422,15 +3471,21 @@ class JavascriptParser extends Parser {
3422
3471
  walkConditionalExpression(expression) {
3423
3472
  const result = this.hooks.expressionConditionalOperator.call(expression);
3424
3473
  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);
3474
+ this.inExecutedPath(false, () => {
3475
+ this.walkExpression(expression.test);
3476
+ this.walkExpression(expression.consequent);
3477
+ if (expression.alternate) {
3478
+ this.walkExpression(expression.alternate);
3479
+ }
3480
+ });
3481
+ } else {
3482
+ this.inExecutedPath(true, () => {
3483
+ if (result) {
3484
+ this.walkExpression(expression.consequent);
3485
+ } else if (expression.alternate) {
3486
+ this.walkExpression(expression.alternate);
3487
+ }
3488
+ });
3434
3489
  }
3435
3490
  }
3436
3491
 
@@ -3513,7 +3568,7 @@ class JavascriptParser extends Parser {
3513
3568
  _walkIIFE(functionExpression, options, currentThis) {
3514
3569
  /**
3515
3570
  * @param {Expression | SpreadElement} argOrThis arg or this
3516
- * @returns {string | VariableInfoInterface | undefined} var info
3571
+ * @returns {string | VariableInfo | undefined} var info
3517
3572
  */
3518
3573
  const getVarInfo = argOrThis => {
3519
3574
  const renameIdentifier = this.getRenameIdentifier(argOrThis);
@@ -3603,13 +3658,13 @@ class JavascriptParser extends Parser {
3603
3658
  expression.callee.type === "MemberExpression" &&
3604
3659
  expression.callee.object.type.endsWith("FunctionExpression") &&
3605
3660
  !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") &&
3661
+ /** @type {boolean} */
3662
+ (
3663
+ /** @type {Identifier} */
3664
+ (expression.callee.property).name === "call" ||
3665
+ /** @type {Identifier} */
3666
+ (expression.callee.property).name === "bind"
3667
+ ) &&
3613
3668
  expression.arguments.length > 0 &&
3614
3669
  isSimpleFunction(
3615
3670
  /** @type {FunctionExpression | ArrowFunctionExpression} */
@@ -3656,9 +3711,7 @@ class JavascriptParser extends Parser {
3656
3711
  if (result === true) return;
3657
3712
  }
3658
3713
  }
3659
- const callee = this.evaluateExpression(
3660
- /** @type {TODO} */ (expression.callee)
3661
- );
3714
+ const callee = this.evaluateExpression(expression.callee);
3662
3715
  if (callee.isIdentifier()) {
3663
3716
  const result1 = this.callHooksForInfo(
3664
3717
  this.hooks.callMemberChain,
@@ -3764,11 +3817,12 @@ class JavascriptParser extends Parser {
3764
3817
  }
3765
3818
 
3766
3819
  /**
3767
- * @param {TODO} expression member expression
3820
+ * @template R
3821
+ * @param {MemberExpression} expression member expression
3768
3822
  * @param {string} name name
3769
3823
  * @param {string | VariableInfo} rootInfo root info
3770
3824
  * @param {string[]} members members
3771
- * @param {TODO} onUnhandled on unhandled callback
3825
+ * @param {() => R | undefined} onUnhandled on unhandled callback
3772
3826
  */
3773
3827
  walkMemberExpressionWithExpressionName(
3774
3828
  expression,
@@ -3781,7 +3835,9 @@ class JavascriptParser extends Parser {
3781
3835
  // optimize the case where expression.object is a MemberExpression too.
3782
3836
  // we can keep info here when calling walkMemberExpression directly
3783
3837
  const property =
3784
- expression.property.name || `${expression.property.value}`;
3838
+ /** @type {Identifier} */
3839
+ (expression.property).name ||
3840
+ `${/** @type {Literal} */ (expression.property).value}`;
3785
3841
  name = name.slice(0, -property.length - 1);
3786
3842
  members.pop();
3787
3843
  const result = this.callHooksForInfo(
@@ -3847,8 +3903,8 @@ class JavascriptParser extends Parser {
3847
3903
  * @template R
3848
3904
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
3849
3905
  * @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
3906
+ * @param {((name: string, rootInfo: string | ScopeInfo | VariableInfo, getMembers: () => string[]) => TODO) | undefined} fallback callback when variable in not handled by hooks
3907
+ * @param {((result?: string) => R | undefined) | undefined} defined callback when variable is defined
3852
3908
  * @param {AsArray<T>} args args for the hook
3853
3909
  * @returns {R | undefined} result of hook
3854
3910
  */
@@ -3899,7 +3955,7 @@ class JavascriptParser extends Parser {
3899
3955
  * @template R
3900
3956
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks that should be called
3901
3957
  * @param {ExportedVariableInfo} info variable info
3902
- * @param {AsArray<T>} args args for the hook
3958
+ * @param {AsArray<T>} args args for the hook
3903
3959
  * @returns {R | undefined} result of hook
3904
3960
  */
3905
3961
  callHooksForInfo(hookMap, info, ...args) {
@@ -3917,8 +3973,8 @@ class JavascriptParser extends Parser {
3917
3973
  * @template R
3918
3974
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
3919
3975
  * @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
3976
+ * @param {((name: string) => TODO) | undefined} fallback callback when variable in not handled by hooks
3977
+ * @param {((result?: string) => TODO) | undefined} defined callback when variable is defined
3922
3978
  * @param {AsArray<T>} args args for the hook
3923
3979
  * @returns {R | undefined} result of hook
3924
3980
  */
@@ -3967,8 +4023,8 @@ class JavascriptParser extends Parser {
3967
4023
  * @template R
3968
4024
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
3969
4025
  * @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
4026
+ * @param {((value: string) => R | undefined) | undefined} fallback callback when variable in not handled by hooks
4027
+ * @param {(() => R) | undefined} defined callback when variable is defined
3972
4028
  * @param {AsArray<T>} args args for the hook
3973
4029
  * @returns {R | undefined} result of hook
3974
4030
  */
@@ -3984,8 +4040,8 @@ class JavascriptParser extends Parser {
3984
4040
 
3985
4041
  /**
3986
4042
  * @deprecated
3987
- * @param {any} params scope params
3988
- * @param {function(): void} fn inner function
4043
+ * @param {(string | Pattern | Property)[]} params scope params
4044
+ * @param {() => void} fn inner function
3989
4045
  * @returns {void}
3990
4046
  */
3991
4047
  inScope(params, fn) {
@@ -3997,6 +4053,8 @@ class JavascriptParser extends Parser {
3997
4053
  inTaggedTemplateTag: false,
3998
4054
  isStrict: oldScope.isStrict,
3999
4055
  isAsmJs: oldScope.isAsmJs,
4056
+ inExecutedPath: false,
4057
+ terminated: undefined,
4000
4058
  definitions: oldScope.definitions.createChild()
4001
4059
  };
4002
4060
 
@@ -4011,10 +4069,27 @@ class JavascriptParser extends Parser {
4011
4069
  this.scope = oldScope;
4012
4070
  }
4013
4071
 
4072
+ /**
4073
+ * @param {boolean} state executed state
4074
+ * @param {() => void} fn inner function
4075
+ */
4076
+ inExecutedPath(state, fn) {
4077
+ const oldState = this.scope.inExecutedPath;
4078
+ const oldTerminated = this.scope.terminated;
4079
+ this.scope.inExecutedPath = state;
4080
+
4081
+ fn();
4082
+
4083
+ if (!state) {
4084
+ this.scope.terminated = oldTerminated;
4085
+ }
4086
+ this.scope.inExecutedPath = oldState;
4087
+ }
4088
+
4014
4089
  /**
4015
4090
  * @param {boolean} hasThis true, when this is defined
4016
4091
  * @param {Identifier[]} params scope params
4017
- * @param {function(): void} fn inner function
4092
+ * @param {() => void} fn inner function
4018
4093
  * @returns {void}
4019
4094
  */
4020
4095
  inClassScope(hasThis, params, fn) {
@@ -4024,8 +4099,10 @@ class JavascriptParser extends Parser {
4024
4099
  inTry: false,
4025
4100
  inShorthand: false,
4026
4101
  inTaggedTemplateTag: false,
4102
+ inExecutedPath: true,
4027
4103
  isStrict: oldScope.isStrict,
4028
4104
  isAsmJs: oldScope.isAsmJs,
4105
+ terminated: undefined,
4029
4106
  definitions: oldScope.definitions.createChild()
4030
4107
  };
4031
4108
 
@@ -4045,7 +4122,7 @@ class JavascriptParser extends Parser {
4045
4122
  /**
4046
4123
  * @param {boolean} hasThis true, when this is defined
4047
4124
  * @param {(Pattern | string)[]} params scope params
4048
- * @param {function(): void} fn inner function
4125
+ * @param {() => void} fn inner function
4049
4126
  * @returns {void}
4050
4127
  */
4051
4128
  inFunctionScope(hasThis, params, fn) {
@@ -4055,8 +4132,10 @@ class JavascriptParser extends Parser {
4055
4132
  inTry: false,
4056
4133
  inShorthand: false,
4057
4134
  inTaggedTemplateTag: false,
4135
+ inExecutedPath: true,
4058
4136
  isStrict: oldScope.isStrict,
4059
4137
  isAsmJs: oldScope.isAsmJs,
4138
+ terminated: undefined,
4060
4139
  definitions: oldScope.definitions.createChild()
4061
4140
  };
4062
4141
 
@@ -4074,23 +4153,35 @@ class JavascriptParser extends Parser {
4074
4153
  }
4075
4154
 
4076
4155
  /**
4077
- * @param {function(): void} fn inner function
4156
+ * @param {() => void} fn inner function
4157
+ * @param {boolean} inExecutedPath executed state
4078
4158
  * @returns {void}
4079
4159
  */
4080
- inBlockScope(fn) {
4160
+ inBlockScope(fn, inExecutedPath = false) {
4081
4161
  const oldScope = this.scope;
4082
4162
  this.scope = {
4083
4163
  topLevelScope: oldScope.topLevelScope,
4084
4164
  inTry: oldScope.inTry,
4085
4165
  inShorthand: false,
4086
4166
  inTaggedTemplateTag: false,
4167
+ inExecutedPath,
4087
4168
  isStrict: oldScope.isStrict,
4088
4169
  isAsmJs: oldScope.isAsmJs,
4170
+ terminated: oldScope.terminated,
4089
4171
  definitions: oldScope.definitions.createChild()
4090
4172
  };
4091
4173
 
4092
4174
  fn();
4093
4175
 
4176
+ const terminated = this.scope.terminated;
4177
+
4178
+ if (
4179
+ inExecutedPath &&
4180
+ ((this.scope.inTry && terminated === "throw") || terminated === "return")
4181
+ ) {
4182
+ oldScope.terminated = terminated;
4183
+ }
4184
+
4094
4185
  this.scope = oldScope;
4095
4186
  }
4096
4187
 
@@ -4228,7 +4319,7 @@ class JavascriptParser extends Parser {
4228
4319
  }
4229
4320
 
4230
4321
  /**
4231
- * @param {Expression | SpreadElement | PrivateIdentifier} expression expression node
4322
+ * @param {Expression | SpreadElement | PrivateIdentifier | Super} expression expression node
4232
4323
  * @returns {BasicEvaluatedExpression} evaluation result
4233
4324
  */
4234
4325
  evaluateExpression(expression) {
@@ -4242,6 +4333,7 @@ class JavascriptParser extends Parser {
4242
4333
  }
4243
4334
  }
4244
4335
  } catch (err) {
4336
+ // eslint-disable-next-line no-console
4245
4337
  console.warn(err);
4246
4338
  // ignore error
4247
4339
  }
@@ -4274,7 +4366,7 @@ class JavascriptParser extends Parser {
4274
4366
 
4275
4367
  /**
4276
4368
  * @param {Expression} expression expression
4277
- * @returns {{ range?: Range, value: string, code: boolean, conditional: TODO }} result
4369
+ * @returns {{ range?: Range, value: string, code: boolean, conditional: boolean | TODO }} result
4278
4370
  */
4279
4371
  parseCalculatedString(expression) {
4280
4372
  switch (expression.type) {
@@ -4379,6 +4471,13 @@ class JavascriptParser extends Parser {
4379
4471
  if (typeof source === "object") {
4380
4472
  ast = /** @type {Program} */ (source);
4381
4473
  comments = source.comments;
4474
+ if (source.semicolons) {
4475
+ // Forward semicolon information from the preparsed AST if present
4476
+ // This ensures the output is consistent with that of a fresh AST
4477
+ for (const pos of source.semicolons) {
4478
+ semicolons.add(pos);
4479
+ }
4480
+ }
4382
4481
  } else {
4383
4482
  comments = [];
4384
4483
  ast = JavascriptParser._parse(source, {
@@ -4399,12 +4498,13 @@ class JavascriptParser extends Parser {
4399
4498
  inTry: false,
4400
4499
  inShorthand: false,
4401
4500
  inTaggedTemplateTag: false,
4501
+ inExecutedPath: false,
4402
4502
  isStrict: false,
4403
4503
  isAsmJs: false,
4504
+ terminated: undefined,
4404
4505
  definitions: new StackedMap()
4405
4506
  };
4406
- /** @type {ParserState} */
4407
- this.state = state;
4507
+ this.state = /** @type {ParserState} */ (state);
4408
4508
  this.comments = comments;
4409
4509
  this.semicolons = semicolons;
4410
4510
  this.statementPath = [];
@@ -4421,7 +4521,6 @@ class JavascriptParser extends Parser {
4421
4521
  }
4422
4522
  this.hooks.finish.call(ast, comments);
4423
4523
  this.scope = oldScope;
4424
- /** @type {ParserState} */
4425
4524
  this.state = oldState;
4426
4525
  this.comments = oldComments;
4427
4526
  this.semicolons = oldSemicolons;
@@ -4446,7 +4545,7 @@ class JavascriptParser extends Parser {
4446
4545
  }
4447
4546
 
4448
4547
  /**
4449
- * @param {Expression | Declaration | PrivateIdentifier | null | undefined} expr an expression
4548
+ * @param {Expression | Declaration | PrivateIdentifier | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | null | undefined} expr an expression
4450
4549
  * @param {number} commentsStartPos source position from which annotation comments are checked
4451
4550
  * @returns {boolean} true, when the expression is pure
4452
4551
  */
@@ -4666,8 +4765,8 @@ class JavascriptParser extends Parser {
4666
4765
 
4667
4766
  /**
4668
4767
  * @param {string} name name
4669
- * @param {symbol} tag tag info
4670
- * @returns {TODO} tag data
4768
+ * @param {Tag} tag tag info
4769
+ * @returns {TagData | undefined} tag data
4671
4770
  */
4672
4771
  getTagData(name, tag) {
4673
4772
  const info = this.scope.definitions.get(name);
@@ -4682,8 +4781,8 @@ class JavascriptParser extends Parser {
4682
4781
 
4683
4782
  /**
4684
4783
  * @param {string} name name
4685
- * @param {symbol} tag tag info
4686
- * @param {TODO=} data data
4784
+ * @param {Tag} tag tag info
4785
+ * @param {TagData=} data data
4687
4786
  */
4688
4787
  tagVariable(name, tag, data) {
4689
4788
  const oldInfo = this.scope.definitions.get(name);
@@ -4784,7 +4883,7 @@ class JavascriptParser extends Parser {
4784
4883
 
4785
4884
  /**
4786
4885
  * @param {Range} range range of the comment
4787
- * @returns {{ options: Record<string, any> | null, errors: (Error & { comment: Comment })[] | null }} result
4886
+ * @returns {{ options: Record<string, EXPECTED_ANY> | null, errors: (Error & { comment: Comment })[] | null }} result
4788
4887
  */
4789
4888
  parseCommentOptions(range) {
4790
4889
  const comments = this.getComments(range);