@depup/webpack 5.106.1-depup.0 → 5.109.2-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (669) hide show
  1. package/README.md +9 -11
  2. package/bin/webpack.js +12 -0
  3. package/changes.json +16 -24
  4. package/hot/dev-server.js +2 -0
  5. package/lib/APIPlugin.js +60 -35
  6. package/lib/AsyncDependenciesBlock.js +3 -0
  7. package/lib/AutomaticPrefetchPlugin.js +6 -1
  8. package/lib/BannerPlugin.js +13 -5
  9. package/lib/Cache.js +27 -5
  10. package/lib/CacheFacade.js +41 -0
  11. package/lib/Chunk.js +71 -25
  12. package/lib/ChunkGraph.js +153 -19
  13. package/lib/ChunkGroup.js +115 -28
  14. package/lib/ChunkTemplate.js +9 -0
  15. package/lib/CircularModulesPlugin.js +190 -0
  16. package/lib/CleanPlugin.js +27 -28
  17. package/lib/CodeGenerationResults.js +19 -0
  18. package/lib/CompatibilityPlugin.js +85 -37
  19. package/lib/Compilation.js +656 -112
  20. package/lib/Compiler.js +109 -35
  21. package/lib/ConcatenationScope.js +34 -4
  22. package/lib/ConditionalInitFragment.js +6 -0
  23. package/lib/ConstPlugin.js +15 -12
  24. package/lib/ContextExclusionPlugin.js +3 -1
  25. package/lib/ContextModule.js +345 -55
  26. package/lib/ContextModuleFactory.js +193 -51
  27. package/lib/ContextReplacementPlugin.js +8 -1
  28. package/lib/DefinePlugin.js +537 -139
  29. package/lib/DependenciesBlock.js +6 -1
  30. package/lib/Dependency.js +159 -11
  31. package/lib/DependencyTemplate.js +7 -1
  32. package/lib/DependencyTemplates.js +4 -0
  33. package/lib/DotenvPlugin.js +3 -0
  34. package/lib/DynamicEntryPlugin.js +3 -1
  35. package/lib/EntryOptionPlugin.js +42 -2
  36. package/lib/EntryPlugin.js +4 -1
  37. package/lib/Entrypoint.js +5 -1
  38. package/lib/EnvironmentPlugin.js +3 -2
  39. package/lib/ErrorHelpers.js +7 -0
  40. package/lib/EvalDevToolModulePlugin.js +3 -1
  41. package/lib/EvalSourceMapDevToolPlugin.js +11 -11
  42. package/lib/ExportsInfo.js +421 -113
  43. package/lib/ExportsInfoApiPlugin.js +4 -3
  44. package/lib/ExternalModule.js +381 -80
  45. package/lib/ExternalModuleFactoryPlugin.js +75 -3
  46. package/lib/ExternalsPlugin.js +3 -1
  47. package/lib/FileSystemInfo.js +701 -175
  48. package/lib/FlagAllModulesAsUsedPlugin.js +3 -6
  49. package/lib/FlagDependencyExportsPlugin.js +82 -9
  50. package/lib/FlagDependencyUsagePlugin.js +115 -8
  51. package/lib/FlagEntryExportAsUsedPlugin.js +4 -1
  52. package/lib/Generator.js +24 -3
  53. package/lib/HotModuleReplacementPlugin.js +110 -44
  54. package/lib/IgnorePlugin.js +5 -2
  55. package/lib/IgnoreWarningsPlugin.js +2 -1
  56. package/lib/InitFragment.js +33 -30
  57. package/lib/JavascriptMetaInfoPlugin.js +9 -6
  58. package/lib/LazyBarrel.js +389 -0
  59. package/lib/LibraryTemplatePlugin.js +2 -1
  60. package/lib/LoaderOptionsPlugin.js +3 -1
  61. package/lib/LoaderTargetPlugin.js +3 -1
  62. package/lib/MainTemplate.js +15 -0
  63. package/lib/ManifestPlugin.js +9 -2
  64. package/lib/Module.js +121 -57
  65. package/lib/ModuleFactory.js +6 -1
  66. package/lib/ModuleFilenameHelpers.js +18 -4
  67. package/lib/ModuleGraph.js +69 -2
  68. package/lib/ModuleGraphConnection.js +9 -0
  69. package/lib/ModuleInfoHeaderPlugin.js +5 -0
  70. package/lib/ModuleNotFoundError.js +3 -83
  71. package/lib/ModuleProfile.js +27 -1
  72. package/lib/ModuleSourceTypeConstants.js +52 -19
  73. package/lib/ModuleTemplate.js +10 -0
  74. package/lib/ModuleTypeConstants.js +20 -4
  75. package/lib/MultiCompiler.js +59 -4
  76. package/lib/MultiStats.js +9 -0
  77. package/lib/MultiWatching.js +6 -0
  78. package/lib/NoEmitOnErrorsPlugin.js +1 -1
  79. package/lib/NodeStuffPlugin.js +78 -46
  80. package/lib/NormalModule.js +519 -206
  81. package/lib/NormalModuleFactory.js +156 -31
  82. package/lib/NormalModuleReplacementPlugin.js +3 -1
  83. package/lib/NullFactory.js +1 -0
  84. package/lib/OptionsApply.js +1 -0
  85. package/lib/Parser.js +3 -1
  86. package/lib/PlatformPlugin.js +2 -1
  87. package/lib/PrefetchPlugin.js +4 -1
  88. package/lib/ProgressPlugin.js +351 -161
  89. package/lib/ProvidePlugin.js +6 -3
  90. package/lib/RawModule.js +32 -16
  91. package/lib/RecordIdsPlugin.js +9 -0
  92. package/lib/RequestShortener.js +8 -0
  93. package/lib/ResolverFactory.js +5 -0
  94. package/lib/RuntimeGlobals.js +58 -5
  95. package/lib/RuntimeModule.js +22 -7
  96. package/lib/RuntimePlugin.js +123 -118
  97. package/lib/RuntimeTemplate.js +616 -37
  98. package/lib/SelfModuleFactory.js +3 -0
  99. package/lib/SourceMapDevToolModuleOptionsPlugin.js +2 -0
  100. package/lib/SourceMapDevToolPlugin.js +341 -63
  101. package/lib/Stats.js +6 -0
  102. package/lib/Template.js +52 -6
  103. package/lib/TemplatedPathPlugin.js +505 -138
  104. package/lib/UseStrictPlugin.js +3 -2
  105. package/lib/WarnCaseSensitiveModulesPlugin.js +72 -3
  106. package/lib/WarnDeprecatedOptionPlugin.js +6 -2
  107. package/lib/WarnNoModeSetPlugin.js +18 -2
  108. package/lib/WatchIgnorePlugin.js +5 -1
  109. package/lib/Watching.js +25 -3
  110. package/lib/WebpackError.js +3 -74
  111. package/lib/WebpackIsIncludedPlugin.js +4 -2
  112. package/lib/WebpackOptionsApply.js +88 -25
  113. package/lib/WebpackOptionsDefaulter.js +1 -0
  114. package/lib/asset/AssetBytesGenerator.js +28 -10
  115. package/lib/asset/AssetBytesParser.js +1 -0
  116. package/lib/asset/AssetGenerator.js +199 -60
  117. package/lib/asset/AssetModule.js +47 -0
  118. package/lib/asset/AssetModulesPlugin.js +115 -24
  119. package/lib/asset/AssetParser.js +4 -2
  120. package/lib/asset/AssetSourceGenerator.js +26 -8
  121. package/lib/asset/AssetSourceParser.js +1 -0
  122. package/lib/asset/RawDataUrlModule.js +23 -13
  123. package/lib/asset/WebManifestGenerator.js +164 -0
  124. package/lib/asset/WebManifestParser.js +130 -0
  125. package/lib/async-modules/AsyncModuleHelpers.js +1 -0
  126. package/lib/async-modules/AwaitDependenciesInitFragment.js +18 -4
  127. package/lib/async-modules/InferAsyncModulesPlugin.js +1 -1
  128. package/lib/async-modules/isGeneratorLowered.js +26 -0
  129. package/lib/buildChunkGraph.js +107 -15
  130. package/lib/bun/BunTargetPlugin.js +42 -0
  131. package/lib/cache/AddBuildDependenciesPlugin.js +3 -1
  132. package/lib/cache/AddManagedPathsPlugin.js +5 -1
  133. package/lib/cache/IdleFileCachePlugin.js +6 -1
  134. package/lib/cache/MemoryCachePlugin.js +1 -1
  135. package/lib/cache/MemoryWithGcCachePlugin.js +4 -1
  136. package/lib/cache/PackFileCacheStrategy.js +302 -12
  137. package/lib/cache/ResolverCachePlugin.js +12 -1
  138. package/lib/cache/getLazyHashedEtag.js +13 -2
  139. package/lib/cache/mergeEtags.js +4 -0
  140. package/lib/cli.js +142 -20
  141. package/lib/config/browserslistTargetHandler.js +141 -0
  142. package/lib/config/defaults.js +612 -43
  143. package/lib/config/defineConfig.js +31 -0
  144. package/lib/config/normalization.js +46 -1
  145. package/lib/config/target.js +200 -2
  146. package/lib/container/ContainerEntryDependency.js +2 -0
  147. package/lib/container/ContainerEntryModule.js +27 -14
  148. package/lib/container/ContainerEntryModuleFactory.js +1 -0
  149. package/lib/container/ContainerExposedDependency.js +6 -2
  150. package/lib/container/ContainerPlugin.js +2 -1
  151. package/lib/container/ContainerReferencePlugin.js +3 -2
  152. package/lib/container/FallbackDependency.js +9 -7
  153. package/lib/container/FallbackItemDependency.js +1 -0
  154. package/lib/container/FallbackModule.js +22 -9
  155. package/lib/container/FallbackModuleFactory.js +1 -0
  156. package/lib/container/HoistContainerReferencesPlugin.js +47 -55
  157. package/lib/container/ModuleFederationPlugin.js +21 -29
  158. package/lib/container/RemoteModule.js +33 -10
  159. package/lib/container/RemoteRuntimeModule.js +15 -12
  160. package/lib/container/RemoteToExternalDependency.js +1 -0
  161. package/lib/container/options.js +7 -0
  162. package/lib/css/CssGenerator.js +540 -272
  163. package/lib/css/CssInjectStyleRuntimeModule.js +86 -70
  164. package/lib/css/CssLoadingRuntimeModule.js +173 -81
  165. package/lib/{CssModule.js → css/CssModule.js} +72 -37
  166. package/lib/css/CssModulesPlugin.js +371 -208
  167. package/lib/css/CssParser.js +3538 -1963
  168. package/lib/css/syntax.js +4155 -0
  169. package/lib/debug/ProfilingPlugin.js +33 -2
  170. package/lib/deno/DenoTargetPlugin.js +41 -0
  171. package/lib/dependencies/AMDDefineDependency.js +29 -17
  172. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +19 -6
  173. package/lib/dependencies/AMDPlugin.js +6 -3
  174. package/lib/dependencies/AMDRequireArrayDependency.js +13 -11
  175. package/lib/dependencies/AMDRequireContextDependency.js +10 -11
  176. package/lib/dependencies/AMDRequireDependenciesBlock.js +1 -0
  177. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +28 -14
  178. package/lib/dependencies/AMDRequireDependency.js +28 -20
  179. package/lib/dependencies/AMDRequireItemDependency.js +1 -0
  180. package/lib/dependencies/AMDRuntimeModules.js +3 -0
  181. package/lib/dependencies/CachedConstDependency.js +9 -1
  182. package/lib/dependencies/CommonJsDependencyHelpers.js +104 -0
  183. package/lib/dependencies/CommonJsExportRequireDependency.js +157 -38
  184. package/lib/dependencies/CommonJsExportsDependency.js +74 -20
  185. package/lib/dependencies/CommonJsExportsParserPlugin.js +246 -15
  186. package/lib/dependencies/CommonJsFullRequireDependency.js +91 -27
  187. package/lib/dependencies/CommonJsImportsParserPlugin.js +189 -24
  188. package/lib/dependencies/CommonJsPlugin.js +7 -4
  189. package/lib/dependencies/CommonJsRequireContextDependency.js +13 -13
  190. package/lib/dependencies/CommonJsRequireDependency.js +135 -13
  191. package/lib/dependencies/CommonJsSelfReferenceDependency.js +60 -16
  192. package/lib/dependencies/ConstDependency.js +22 -12
  193. package/lib/dependencies/ContextDependency.js +13 -2
  194. package/lib/dependencies/ContextDependencyHelpers.js +7 -4
  195. package/lib/dependencies/ContextDependencyTemplateAsId.js +2 -1
  196. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +1 -0
  197. package/lib/dependencies/ContextElementDependency.js +27 -14
  198. package/lib/dependencies/CreateRequireParserPlugin.js +14 -7
  199. package/lib/dependencies/CreateScriptUrlDependency.js +9 -7
  200. package/lib/dependencies/CriticalDependencyWarning.js +3 -1
  201. package/lib/dependencies/CssIcssExportDependency.js +681 -367
  202. package/lib/dependencies/CssIcssImportDependency.js +62 -17
  203. package/lib/dependencies/CssIcssSymbolDependency.js +36 -17
  204. package/lib/dependencies/CssImportDependency.js +37 -1
  205. package/lib/dependencies/CssUrlDependency.js +87 -14
  206. package/lib/dependencies/DelegatedSourceDependency.js +1 -0
  207. package/lib/dependencies/DllEntryDependency.js +12 -13
  208. package/lib/dependencies/DynamicExports.js +5 -0
  209. package/lib/dependencies/EntryDependency.js +1 -0
  210. package/lib/dependencies/ExportBindingInitFragment.js +164 -0
  211. package/lib/dependencies/ExportsInfoDependency.js +18 -12
  212. package/lib/dependencies/ExternalModuleDependency.js +13 -5
  213. package/lib/dependencies/ExternalModuleInitFragment.js +10 -5
  214. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +19 -12
  215. package/lib/dependencies/HarmonyAcceptDependency.js +24 -26
  216. package/lib/dependencies/HarmonyAcceptImportDependency.js +2 -0
  217. package/lib/dependencies/HarmonyCompatibilityDependency.js +33 -14
  218. package/lib/dependencies/HarmonyDetectionParserPlugin.js +108 -30
  219. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +34 -3
  220. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +70 -33
  221. package/lib/dependencies/HarmonyExportExpressionDependency.js +133 -43
  222. package/lib/dependencies/HarmonyExportHeaderDependency.js +11 -9
  223. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +268 -44
  224. package/lib/dependencies/HarmonyExportInitFragment.js +28 -20
  225. package/lib/dependencies/HarmonyExportSpecifierDependency.js +88 -18
  226. package/lib/dependencies/HarmonyExports.js +6 -1
  227. package/lib/dependencies/HarmonyImportDependency.js +60 -4
  228. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +139 -146
  229. package/lib/dependencies/HarmonyImportGuard.js +427 -0
  230. package/lib/dependencies/HarmonyImportSideEffectDependency.js +22 -1
  231. package/lib/dependencies/HarmonyImportSpecifierDependency.js +146 -24
  232. package/lib/{HarmonyLinkingError.js → dependencies/HarmonyLinkingError.js} +6 -3
  233. package/lib/dependencies/HarmonyModulesPlugin.js +11 -1
  234. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +2 -1
  235. package/lib/dependencies/HtmlEntryDependency.js +1295 -0
  236. package/lib/dependencies/HtmlInlineHtmlDependency.js +107 -0
  237. package/lib/dependencies/HtmlInlineScriptDependency.js +126 -0
  238. package/lib/dependencies/HtmlInlineStyleDependency.js +152 -0
  239. package/lib/dependencies/HtmlSourceDependency.js +172 -0
  240. package/lib/dependencies/ImportContextDependency.js +9 -9
  241. package/lib/dependencies/ImportDependency.js +92 -3
  242. package/lib/dependencies/ImportEagerDependency.js +2 -0
  243. package/lib/dependencies/ImportMetaContextDependency.js +1 -0
  244. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +35 -19
  245. package/lib/dependencies/ImportMetaContextPlugin.js +40 -8
  246. package/lib/dependencies/ImportMetaGlobDependency.js +81 -0
  247. package/lib/dependencies/ImportMetaGlobDependencyParserPlugin.js +78 -0
  248. package/lib/dependencies/ImportMetaGlobHelpers.js +660 -0
  249. package/lib/dependencies/ImportMetaHotAcceptDependency.js +2 -0
  250. package/lib/dependencies/ImportMetaHotDeclineDependency.js +2 -0
  251. package/lib/dependencies/ImportMetaPlugin.js +595 -209
  252. package/lib/dependencies/ImportMetaResolveDependency.js +90 -0
  253. package/lib/dependencies/ImportParserPlugin.js +114 -27
  254. package/lib/dependencies/ImportPhase.js +17 -11
  255. package/lib/dependencies/ImportPlugin.js +2 -1
  256. package/lib/dependencies/ImportWeakDependency.js +3 -0
  257. package/lib/dependencies/JsonExportsDependency.js +15 -10
  258. package/lib/dependencies/LoaderDependency.js +2 -0
  259. package/lib/dependencies/LoaderImportDependency.js +3 -0
  260. package/lib/dependencies/LoaderPlugin.js +9 -2
  261. package/lib/dependencies/LocalModule.js +15 -12
  262. package/lib/dependencies/LocalModuleDependency.js +15 -13
  263. package/lib/dependencies/LocalModulesHelpers.js +3 -0
  264. package/lib/dependencies/ModuleDecoratorDependency.js +16 -10
  265. package/lib/dependencies/ModuleDependency.js +14 -0
  266. package/lib/dependencies/ModuleDependencyTemplateAsId.js +1 -0
  267. package/lib/dependencies/ModuleDependencyTemplateAsRequireId.js +1 -0
  268. package/lib/dependencies/ModuleHotAcceptDependency.js +2 -0
  269. package/lib/dependencies/ModuleHotDeclineDependency.js +2 -0
  270. package/lib/dependencies/ModuleInitFragmentDependency.js +19 -11
  271. package/lib/dependencies/NullDependency.js +2 -0
  272. package/lib/dependencies/PrefetchDependency.js +1 -0
  273. package/lib/dependencies/ProvidedDependency.js +36 -27
  274. package/lib/dependencies/PureExpressionDependency.js +14 -10
  275. package/lib/dependencies/RequireContextDependency.js +1 -0
  276. package/lib/dependencies/RequireContextDependencyParserPlugin.js +2 -1
  277. package/lib/dependencies/RequireContextPlugin.js +2 -1
  278. package/lib/dependencies/RequireEnsureDependenciesBlock.js +1 -0
  279. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +4 -6
  280. package/lib/dependencies/RequireEnsureDependency.js +16 -13
  281. package/lib/dependencies/RequireEnsureItemDependency.js +1 -0
  282. package/lib/dependencies/RequireEnsurePlugin.js +2 -1
  283. package/lib/dependencies/RequireHeaderDependency.js +7 -4
  284. package/lib/dependencies/RequireIncludeDependency.js +2 -0
  285. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +11 -12
  286. package/lib/dependencies/RequireIncludePlugin.js +2 -1
  287. package/lib/{RequireJsStuffPlugin.js → dependencies/RequireJsStuffPlugin.js} +9 -8
  288. package/lib/dependencies/RequireResolveContextDependency.js +10 -11
  289. package/lib/dependencies/RequireResolveDependency.js +2 -0
  290. package/lib/dependencies/RequireResolveHeaderDependency.js +8 -5
  291. package/lib/dependencies/RuntimeRequirementsDependency.js +11 -8
  292. package/lib/dependencies/StaticExportsDependency.js +13 -10
  293. package/lib/dependencies/SystemPlugin.js +9 -6
  294. package/lib/dependencies/SystemRuntimeModule.js +1 -0
  295. package/lib/dependencies/TopLevelAwaitDependency.js +93 -0
  296. package/lib/dependencies/URLContextDependency.js +8 -7
  297. package/lib/dependencies/URLDependency.js +157 -33
  298. package/lib/dependencies/URLPlugin.js +2 -0
  299. package/lib/dependencies/UnsupportedDependency.js +12 -13
  300. package/lib/dependencies/WebAssemblyExportImportedDependency.js +15 -16
  301. package/lib/dependencies/WebAssemblyImportDependency.js +19 -18
  302. package/lib/dependencies/WebpackIsIncludedDependency.js +3 -0
  303. package/lib/dependencies/{WorkerPlugin.js → WorkerAndWorkletPlugin.js} +364 -114
  304. package/lib/dependencies/WorkerDependency.js +111 -27
  305. package/lib/dependencies/WorkletDependency.js +278 -0
  306. package/lib/dependencies/getFunctionExpression.js +1 -0
  307. package/lib/dependencies/processExportInfo.js +14 -11
  308. package/lib/{DelegatedModule.js → dll/DelegatedModule.js} +71 -44
  309. package/lib/{DelegatedModuleFactoryPlugin.js → dll/DelegatedModuleFactoryPlugin.js} +27 -4
  310. package/lib/{DelegatedPlugin.js → dll/DelegatedPlugin.js} +5 -3
  311. package/lib/{DllEntryPlugin.js → dll/DllEntryPlugin.js} +9 -5
  312. package/lib/{DllModule.js → dll/DllModule.js} +36 -24
  313. package/lib/{DllModuleFactory.js → dll/DllModuleFactory.js} +5 -4
  314. package/lib/{DllPlugin.js → dll/DllPlugin.js} +24 -6
  315. package/lib/{DllReferencePlugin.js → dll/DllReferencePlugin.js} +26 -18
  316. package/lib/{LibManifestPlugin.js → dll/LibManifestPlugin.js} +14 -10
  317. package/lib/electron/ElectronTargetPlugin.js +24 -5
  318. package/lib/{AbstractMethodError.js → errors/AbstractMethodError.js} +10 -1
  319. package/lib/{AsyncDependencyToInitialChunkError.js → errors/AsyncDependencyToInitialChunkError.js} +8 -3
  320. package/lib/errors/BuildCycleError.js +1 -1
  321. package/lib/{ChunkRenderError.js → errors/ChunkRenderError.js} +1 -1
  322. package/lib/{CodeGenerationError.js → errors/CodeGenerationError.js} +1 -1
  323. package/lib/{CommentCompilationWarning.js → errors/CommentCompilationWarning.js} +9 -3
  324. package/lib/{ConcurrentCompilationError.js → errors/ConcurrentCompilationError.js} +5 -2
  325. package/lib/{EnvironmentNotSupportAsyncWarning.js → errors/EnvironmentNotSupportAsyncWarning.js} +5 -5
  326. package/lib/{HookWebpackError.js → errors/HookWebpackError.js} +20 -16
  327. package/lib/{IgnoreErrorModuleFactory.js → errors/IgnoreErrorModuleFactory.js} +7 -4
  328. package/lib/{InvalidDependenciesModuleWarning.js → errors/InvalidDependenciesModuleWarning.js} +6 -3
  329. package/lib/errors/JSONParseError.js +115 -0
  330. package/lib/errors/LoaderLoadingError.js +20 -0
  331. package/lib/{ModuleBuildError.js → errors/ModuleBuildError.js} +22 -16
  332. package/lib/{ModuleDependencyError.js → errors/ModuleDependencyError.js} +10 -3
  333. package/lib/{ModuleDependencyWarning.js → errors/ModuleDependencyWarning.js} +13 -5
  334. package/lib/{ModuleError.js → errors/ModuleError.js} +10 -14
  335. package/lib/{ModuleHashingError.js → errors/ModuleHashingError.js} +5 -1
  336. package/lib/errors/ModuleNotFoundError.js +94 -0
  337. package/lib/errors/ModuleParseError.js +141 -0
  338. package/lib/{ModuleRestoreError.js → errors/ModuleRestoreError.js} +4 -1
  339. package/lib/{ModuleStoreError.js → errors/ModuleStoreError.js} +5 -1
  340. package/lib/{ModuleWarning.js → errors/ModuleWarning.js} +13 -14
  341. package/lib/{NodeStuffInWebError.js → errors/NodeStuffInWebError.js} +7 -5
  342. package/lib/errors/NonErrorEmittedError.js +30 -0
  343. package/lib/{UnhandledSchemeError.js → errors/UnhandledSchemeError.js} +9 -2
  344. package/lib/{UnsupportedFeatureWarning.js → errors/UnsupportedFeatureWarning.js} +4 -3
  345. package/lib/errors/WebpackError.js +84 -0
  346. package/lib/esm/ExportWebpackRequireRuntimeModule.js +2 -0
  347. package/lib/esm/ModuleChunkFormatPlugin.js +52 -15
  348. package/lib/esm/ModuleChunkLoadingPlugin.js +11 -3
  349. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +80 -52
  350. package/lib/hmr/HotModuleReplacement.runtime.js +175 -30
  351. package/lib/hmr/HotModuleReplacementRuntimeModule.js +8 -0
  352. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +173 -26
  353. package/lib/hmr/JavascriptHotModuleReplacementHelper.js +1 -0
  354. package/lib/hmr/LazyCompilationPlugin.js +154 -7
  355. package/lib/hmr/lazyCompilationBackend.js +53 -12
  356. package/lib/html/HtmlGenerator.js +1490 -0
  357. package/lib/html/HtmlModule.js +41 -0
  358. package/lib/html/HtmlModulesPlugin.js +1129 -0
  359. package/lib/html/HtmlParser.js +1970 -0
  360. package/lib/html/favicon.svg +1 -0
  361. package/lib/html/syntax.js +9106 -0
  362. package/lib/ids/ChunkModuleIdRangePlugin.js +3 -1
  363. package/lib/ids/DeterministicChunkIdsPlugin.js +3 -1
  364. package/lib/ids/DeterministicModuleIdsPlugin.js +3 -1
  365. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  366. package/lib/ids/IdHelpers.js +49 -12
  367. package/lib/ids/NamedChunkIdsPlugin.js +3 -1
  368. package/lib/ids/NamedModuleIdsPlugin.js +3 -1
  369. package/lib/ids/NaturalChunkIdsPlugin.js +1 -1
  370. package/lib/ids/NaturalModuleIdsPlugin.js +1 -1
  371. package/lib/ids/OccurrenceChunkIdsPlugin.js +2 -1
  372. package/lib/ids/OccurrenceModuleIdsPlugin.js +4 -1
  373. package/lib/ids/SyncModuleIdsPlugin.js +3 -1
  374. package/lib/index.js +66 -15
  375. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +5 -6
  376. package/lib/javascript/BasicEvaluatedExpression.js +370 -49
  377. package/lib/javascript/ChunkFormatHelpers.js +2 -1
  378. package/lib/javascript/ChunkHelpers.js +1 -0
  379. package/lib/javascript/CommonJsChunkFormatPlugin.js +1 -1
  380. package/lib/javascript/EnableChunkLoadingPlugin.js +6 -1
  381. package/lib/javascript/JavascriptGenerator.js +213 -51
  382. package/lib/javascript/JavascriptModule.js +54 -0
  383. package/lib/javascript/JavascriptModulesPlugin.js +628 -198
  384. package/lib/javascript/JavascriptParser.js +1334 -471
  385. package/lib/javascript/JavascriptParserHelpers.js +10 -7
  386. package/lib/javascript/StartupHelpers.js +5 -0
  387. package/lib/javascript/syntax.js +5037 -0
  388. package/lib/json/JsonData.js +5 -0
  389. package/lib/json/JsonGenerator.js +21 -0
  390. package/lib/json/JsonModule.js +40 -0
  391. package/lib/json/JsonModulesPlugin.js +8 -1
  392. package/lib/json/JsonParser.js +18 -27
  393. package/lib/library/AbstractLibraryPlugin.js +17 -2
  394. package/lib/library/AmdLibraryPlugin.js +8 -0
  395. package/lib/library/AssignLibraryPlugin.js +21 -3
  396. package/lib/library/EnableLibraryPlugin.js +8 -2
  397. package/lib/library/ExportPropertyLibraryPlugin.js +10 -0
  398. package/lib/{FalseIIFEUmdWarning.js → library/FalseIIFEUmdWarning.js} +2 -1
  399. package/lib/library/JsonpLibraryPlugin.js +8 -0
  400. package/lib/library/ModuleLibraryPlugin.js +154 -7
  401. package/lib/library/SystemLibraryPlugin.js +11 -3
  402. package/lib/library/UmdLibraryPlugin.js +16 -0
  403. package/lib/loaders/LoaderRunner.js +714 -0
  404. package/lib/loaders/loadLoader.js +100 -0
  405. package/lib/logging/Logger.js +17 -0
  406. package/lib/logging/createConsoleLogger.js +7 -0
  407. package/lib/logging/runtime.js +2 -0
  408. package/lib/logging/truncateArgs.js +2 -0
  409. package/lib/node/CommonJsChunkLoadingPlugin.js +5 -1
  410. package/lib/node/NodeEnvironmentPlugin.js +7 -3
  411. package/lib/node/NodeSourcePlugin.js +1 -1
  412. package/lib/node/NodeTargetPlugin.js +4 -63
  413. package/lib/node/NodeTemplatePlugin.js +3 -1
  414. package/lib/node/NodeWatchFileSystem.js +40 -22
  415. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +13 -9
  416. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +33 -3
  417. package/lib/node/ReadFileCompileWasmPlugin.js +28 -3
  418. package/lib/node/RequireChunkLoadingRuntimeModule.js +21 -16
  419. package/lib/node/nodeBuiltins.js +80 -0
  420. package/lib/node/nodeConsole.js +116 -64
  421. package/lib/optimize/AggressiveMergingPlugin.js +22 -16
  422. package/lib/optimize/AggressiveSplittingPlugin.js +6 -1
  423. package/lib/optimize/ConcatenatedModule.js +603 -130
  424. package/lib/optimize/ConstExportsPlugin.js +211 -0
  425. package/lib/optimize/EnsureChunkConditionsPlugin.js +2 -1
  426. package/lib/optimize/FlagIncludedChunksPlugin.js +15 -4
  427. package/lib/optimize/InlineExports.js +178 -0
  428. package/lib/optimize/InnerGraph.js +374 -262
  429. package/lib/optimize/InnerGraphPlugin.js +246 -117
  430. package/lib/optimize/LimitChunkCountPlugin.js +9 -0
  431. package/lib/optimize/MangleExportsPlugin.js +5 -1
  432. package/lib/optimize/MergeDuplicateChunksPlugin.js +2 -0
  433. package/lib/optimize/MinChunkSizePlugin.js +2 -1
  434. package/lib/optimize/MinMaxSizeWarning.js +5 -4
  435. package/lib/optimize/ModuleConcatenationPlugin.js +229 -55
  436. package/lib/optimize/RealContentHashPlugin.js +130 -52
  437. package/lib/optimize/RemoveEmptyChunksPlugin.js +2 -1
  438. package/lib/optimize/RemoveParentModulesPlugin.js +3 -1
  439. package/lib/optimize/RuntimeChunkPlugin.js +2 -1
  440. package/lib/optimize/SideEffectsFlagPlugin.js +381 -55
  441. package/lib/optimize/SplitChunksPlugin.js +200 -50
  442. package/lib/performance/AssetsOverSizeLimitWarning.js +3 -2
  443. package/lib/performance/EntrypointsOverSizeLimitWarning.js +3 -2
  444. package/lib/performance/NoAsyncChunksWarning.js +5 -3
  445. package/lib/performance/SizeLimitsPlugin.js +8 -2
  446. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +1 -0
  447. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +21 -0
  448. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +1 -0
  449. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +5 -1
  450. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +25 -13
  451. package/lib/prefetch/ResourceHintPlugin.js +687 -0
  452. package/lib/prefetch/ResourceHintRuntimeModule.js +149 -0
  453. package/lib/prefetch/StartupAssetHintRuntimeModule.js +210 -0
  454. package/lib/prefetch/parseResourceHintOptions.js +103 -0
  455. package/lib/rules/BasicEffectRulePlugin.js +3 -0
  456. package/lib/rules/BasicMatcherRulePlugin.js +3 -0
  457. package/lib/rules/ObjectMatcherRulePlugin.js +3 -0
  458. package/lib/rules/RuleSetCompiler.js +132 -0
  459. package/lib/rules/UseEffectRulePlugin.js +10 -3
  460. package/lib/runtime/AsyncModuleGeneratorRuntimeModule.js +56 -0
  461. package/lib/runtime/AsyncModuleRuntimeModule.js +52 -33
  462. package/lib/runtime/AutoPublicPathRuntimeModule.js +22 -9
  463. package/lib/runtime/BaseUriRuntimeModule.js +1 -0
  464. package/lib/runtime/ChunkNameRuntimeModule.js +1 -0
  465. package/lib/runtime/CommonJsWrapRuntimeModule.js +37 -0
  466. package/lib/runtime/CompatGetDefaultExportRuntimeModule.js +2 -1
  467. package/lib/runtime/CompatRuntimeModule.js +2 -0
  468. package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +7 -4
  469. package/lib/runtime/CreateScriptRuntimeModule.js +1 -0
  470. package/lib/runtime/CreateScriptUrlRuntimeModule.js +1 -0
  471. package/lib/runtime/DefinePropertyGettersRuntimeModule.js +34 -4
  472. package/lib/runtime/EnsureChunkRuntimeModule.js +1 -0
  473. package/lib/runtime/GetChunkFilenameRuntimeModule.js +88 -8
  474. package/lib/runtime/GetFullHashRuntimeModule.js +1 -0
  475. package/lib/runtime/GetMainFilenameRuntimeModule.js +1 -0
  476. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +2 -1
  477. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +59 -0
  478. package/lib/runtime/GlobalRuntimeModule.js +1 -0
  479. package/lib/runtime/HasOwnPropertyRuntimeModule.js +2 -1
  480. package/lib/runtime/HelperRuntimeModule.js +5 -0
  481. package/lib/runtime/LoadScriptRuntimeModule.js +28 -37
  482. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +354 -37
  483. package/lib/runtime/MakeNamespaceObjectRuntimeModule.js +2 -1
  484. package/lib/runtime/NonceRuntimeModule.js +1 -0
  485. package/lib/runtime/OnChunksLoadedRuntimeModule.js +5 -4
  486. package/lib/runtime/PublicPathRuntimeModule.js +1 -0
  487. package/lib/runtime/RelativeUrlRuntimeModule.js +4 -2
  488. package/lib/runtime/RuntimeIdRuntimeModule.js +1 -0
  489. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +38 -0
  490. package/lib/runtime/StartupChunkDependenciesPlugin.js +13 -1
  491. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +2 -1
  492. package/lib/runtime/StartupEntrypointRuntimeModule.js +5 -3
  493. package/lib/runtime/SystemContextRuntimeModule.js +1 -0
  494. package/lib/runtime/ToBinaryRuntimeModule.js +1 -0
  495. package/lib/runtime/WorkerRuntimeModule.js +33 -0
  496. package/lib/schemes/DataUriPlugin.js +14 -2
  497. package/lib/schemes/FileUriPlugin.js +1 -1
  498. package/lib/schemes/HttpUriPlugin.js +86 -4
  499. package/lib/schemes/VirtualUrlPlugin.js +8 -4
  500. package/lib/serialization/AggregateErrorSerializer.js +9 -6
  501. package/lib/serialization/ArraySerializer.js +6 -8
  502. package/lib/serialization/BinaryMiddleware.js +427 -1006
  503. package/lib/serialization/DateObjectSerializer.js +4 -2
  504. package/lib/serialization/ErrorObjectSerializer.js +10 -6
  505. package/lib/serialization/FileMiddleware.js +345 -59
  506. package/lib/serialization/MapObjectSerializer.js +7 -9
  507. package/lib/serialization/NullPrototypeObjectSerializer.js +9 -9
  508. package/lib/serialization/ObjectMiddleware.js +73 -13
  509. package/lib/serialization/PlainObjectSerializer.js +16 -8
  510. package/lib/serialization/RegExpObjectSerializer.js +4 -2
  511. package/lib/serialization/Serializer.js +6 -0
  512. package/lib/serialization/SerializerMiddleware.js +14 -2
  513. package/lib/serialization/SetObjectSerializer.js +6 -8
  514. package/lib/serialization/SingleItemMiddleware.js +3 -0
  515. package/lib/sharing/ConsumeSharedFallbackDependency.js +1 -0
  516. package/lib/sharing/ConsumeSharedModule.js +21 -7
  517. package/lib/sharing/ConsumeSharedPlugin.js +11 -11
  518. package/lib/sharing/ConsumeSharedRuntimeModule.js +55 -45
  519. package/lib/sharing/ProvideForSharedDependency.js +1 -0
  520. package/lib/sharing/ProvideSharedDependency.js +34 -15
  521. package/lib/sharing/ProvideSharedModule.js +42 -12
  522. package/lib/sharing/ProvideSharedModuleFactory.js +1 -0
  523. package/lib/sharing/ProvideSharedPlugin.js +13 -8
  524. package/lib/sharing/SharePlugin.js +5 -1
  525. package/lib/sharing/ShareRuntimeModule.js +19 -16
  526. package/lib/sharing/resolveMatchedConfigs.js +6 -2
  527. package/lib/sharing/utils.js +9 -1
  528. package/lib/stats/DefaultStatsFactoryPlugin.js +289 -201
  529. package/lib/stats/DefaultStatsPresetPlugin.js +14 -2
  530. package/lib/stats/DefaultStatsPrinterPlugin.js +74 -170
  531. package/lib/stats/StatsFactory.js +70 -27
  532. package/lib/stats/StatsPrinter.js +16 -2
  533. package/lib/typescript/TypeScriptPlugin.js +210 -0
  534. package/lib/url/URLParserPlugin.js +111 -23
  535. package/lib/util/ArrayHelpers.js +1 -0
  536. package/lib/util/ArrayQueue.js +10 -5
  537. package/lib/util/AsyncQueue.js +154 -74
  538. package/lib/util/Hash.js +2 -2
  539. package/lib/util/IterableHelpers.js +3 -0
  540. package/lib/util/LazyBucketSortedSet.js +26 -0
  541. package/lib/util/LazySet.js +45 -4
  542. package/lib/util/LocConverter.js +64 -0
  543. package/lib/util/ParallelismFactorCalculator.js +1 -0
  544. package/lib/util/Queue.js +6 -3
  545. package/lib/util/Semaphore.js +15 -1
  546. package/lib/util/SetHelpers.js +4 -1
  547. package/lib/util/SortableSet.js +7 -1
  548. package/lib/util/SourceProcessor.js +119 -0
  549. package/lib/util/StackedCacheMap.js +20 -3
  550. package/lib/util/StackedMap.js +162 -43
  551. package/lib/util/StringXor.js +1 -1
  552. package/lib/util/TupleQueue.js +7 -3
  553. package/lib/util/TupleSet.js +14 -0
  554. package/lib/util/URLAbsoluteSpecifier.js +1 -0
  555. package/lib/util/WeakTupleMap.js +60 -1
  556. package/lib/util/binarySearchBounds.js +3 -2
  557. package/lib/util/chainedImports.js +3 -3
  558. package/lib/util/cleverMerge.js +19 -2
  559. package/lib/util/comparators.js +35 -4
  560. package/lib/util/compileBooleanMatcher.js +9 -0
  561. package/lib/util/concatenate.js +80 -24
  562. package/lib/util/conventions.js +46 -1
  563. package/lib/util/createHash.js +0 -1
  564. package/lib/util/createHooksRegistry.js +43 -0
  565. package/lib/util/createMappings.js +118 -0
  566. package/lib/util/dataURL.js +3 -2
  567. package/lib/util/deprecation.js +19 -0
  568. package/lib/util/deterministicGrouping.js +46 -17
  569. package/lib/util/extractSourceMap.js +2 -1
  570. package/lib/util/extractUrlAndGlobal.js +1 -0
  571. package/lib/util/findGraphRoots.js +7 -0
  572. package/lib/{formatLocation.js → util/formatLocation.js} +4 -2
  573. package/lib/{SizeFormatHelpers.js → util/formatSize.js} +10 -3
  574. package/lib/util/fs.js +87 -14
  575. package/lib/util/generateDebugId.js +1 -0
  576. package/lib/util/globUtils.js +710 -0
  577. package/lib/util/hash/BatchedHash.js +1 -0
  578. package/lib/util/hash/BulkUpdateHash.js +1 -0
  579. package/lib/util/hash/DebugHash.js +1 -0
  580. package/lib/util/hash/hash-digest.js +32 -15
  581. package/lib/util/hash/md4.js +1 -1
  582. package/lib/util/hash/wasm-hash.js +5 -0
  583. package/lib/util/hash/xxhash64.js +1 -1
  584. package/lib/util/identifier.js +118 -7
  585. package/lib/util/implicitTypeLoaderFallback.js +62 -0
  586. package/lib/util/internalSerializables.js +102 -60
  587. package/lib/util/magicComment.js +149 -7
  588. package/lib/util/makeSerializable.js +7 -0
  589. package/lib/util/memoize.js +2 -0
  590. package/lib/util/mimeTypes.js +176 -0
  591. package/lib/util/nonNumericOnlyHash.js +31 -1
  592. package/lib/util/numberHash.js +2 -2
  593. package/lib/util/parseJson.js +41 -0
  594. package/lib/util/processAsyncTree.js +8 -0
  595. package/lib/util/property.js +9 -2
  596. package/lib/util/publicPathPlaceholder.js +64 -0
  597. package/lib/util/registerExternalSerializer.js +24 -4
  598. package/lib/util/removeBOM.js +1 -0
  599. package/lib/util/runtime.js +32 -0
  600. package/lib/util/semver.js +15 -0
  601. package/lib/util/serialization.js +2 -0
  602. package/lib/util/smartGrouping.js +8 -0
  603. package/lib/util/source.js +23 -0
  604. package/lib/util/topologicalSort.js +69 -0
  605. package/lib/validateSchema.js +1 -0
  606. package/lib/wasm/EnableWasmLoadingPlugin.js +15 -1
  607. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +25 -18
  608. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +34 -22
  609. package/lib/wasm-async/AsyncWasmModule.js +77 -0
  610. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -0
  611. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +6 -1
  612. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +22 -126
  613. package/lib/wasm-async/AsyncWebAssemblyParser.js +3 -2
  614. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +13 -2
  615. package/lib/wasm-sync/SyncWasmModule.js +39 -0
  616. package/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +7 -3
  617. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +86 -19
  618. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +4 -3
  619. package/lib/wasm-sync/WebAssemblyGenerator.js +27 -1
  620. package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +9 -3
  621. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +4 -0
  622. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +20 -1
  623. package/lib/wasm-sync/WebAssemblyParser.js +9 -3
  624. package/lib/wasm-sync/WebAssemblyUtils.js +2 -0
  625. package/lib/web/FetchCompileAsyncWasmPlugin.js +29 -1
  626. package/lib/web/FetchCompileWasmPlugin.js +27 -1
  627. package/lib/web/JsonpChunkLoadingPlugin.js +11 -1
  628. package/lib/web/JsonpChunkLoadingRuntimeModule.js +58 -64
  629. package/lib/web/JsonpTemplatePlugin.js +2 -1
  630. package/lib/webpack.js +78 -1
  631. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +10 -1
  632. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +15 -10
  633. package/lib/webworker/WebWorkerTemplatePlugin.js +1 -1
  634. package/module.d.ts +21 -0
  635. package/package.json +79 -77
  636. package/schemas/WebpackOptions.check.js +1 -1
  637. package/schemas/WebpackOptions.json +1173 -80
  638. package/schemas/plugins/{DllPlugin.check.d.ts → HtmlGeneratorOptions.check.d.ts} +1 -1
  639. package/schemas/plugins/HtmlGeneratorOptions.check.js +6 -0
  640. package/schemas/plugins/HtmlGeneratorOptions.json +3 -0
  641. package/schemas/plugins/{DllReferencePlugin.check.d.ts → HtmlParserOptions.check.d.ts} +1 -1
  642. package/schemas/plugins/HtmlParserOptions.check.js +6 -0
  643. package/schemas/plugins/HtmlParserOptions.json +3 -0
  644. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  645. package/schemas/plugins/ProgressPlugin.json +38 -0
  646. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  647. package/schemas/plugins/container/ContainerReferencePlugin.json +2 -0
  648. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  649. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  650. package/schemas/plugins/container/ModuleFederationPlugin.json +2 -0
  651. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.d.ts +7 -0
  652. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +6 -0
  653. package/schemas/plugins/css/CssAutoOrModuleParserOptions.json +3 -0
  654. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  655. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  656. package/schemas/plugins/dll/DllPlugin.check.d.ts +7 -0
  657. package/schemas/plugins/dll/DllReferencePlugin.check.d.ts +7 -0
  658. package/types.d.ts +11053 -3019
  659. package/lib/CaseSensitiveModulesWarning.js +0 -72
  660. package/lib/GraphHelpers.js +0 -46
  661. package/lib/ModuleParseError.js +0 -125
  662. package/lib/NoModeWarning.js +0 -23
  663. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +0 -56
  664. package/lib/css/walkCssTokens.js +0 -1843
  665. package/lib/util/AppendOnlyStackedSet.js +0 -78
  666. /package/schemas/plugins/{DllPlugin.check.js → dll/DllPlugin.check.js} +0 -0
  667. /package/schemas/plugins/{DllPlugin.json → dll/DllPlugin.json} +0 -0
  668. /package/schemas/plugins/{DllReferencePlugin.check.js → dll/DllReferencePlugin.check.js} +0 -0
  669. /package/schemas/plugins/{DllReferencePlugin.json → dll/DllReferencePlugin.json} +0 -0
@@ -5,20 +5,27 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const vm = require("vm");
9
- const { Parser: AcornParser, tokTypes } = require("acorn");
10
8
  const { HookMap, SyncBailHook } = require("tapable");
11
9
  const NormalModule = require("../NormalModule");
12
10
  const Parser = require("../Parser");
11
+ const WebpackError = require("../WebpackError");
13
12
  const StackedMap = require("../util/StackedMap");
14
- const binarySearchBounds = require("../util/binarySearchBounds");
15
13
  const {
14
+ CompilerHintNotationRegExp,
16
15
  createMagicCommentContext,
17
- webpackCommentRegExp
16
+ getCommentsInRange,
17
+ parseCommentOptionsInRange
18
18
  } = require("../util/magicComment");
19
- const memoize = require("../util/memoize");
20
19
  const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
21
-
20
+ const {
21
+ LEGACY_ASSERT_ATTRIBUTES,
22
+ WebpackParser,
23
+ buildLineStarts,
24
+ hasOctalEscape,
25
+ positionAt
26
+ } = require("./syntax");
27
+
28
+ /** @typedef {typeof import("acorn").Parser} AcornParser */
22
29
  /** @typedef {import("acorn").Options} AcornOptions */
23
30
  /** @typedef {import("acorn").ecmaVersion} EcmaVersion */
24
31
  /** @typedef {import("estree").AssignmentExpression} AssignmentExpression */
@@ -32,7 +39,9 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
32
39
  /** @typedef {import("estree").SwitchStatement} SwitchStatement */
33
40
  /** @typedef {import("estree").ClassExpression} ClassExpression */
34
41
  /** @typedef {import("estree").SourceLocation} SourceLocation */
35
- /** @typedef {import("estree").Comment & { start: number, end: number, loc: SourceLocation }} Comment */
42
+ /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
43
+ /** @typedef {import("../Dependency").SourcePosition} SourcePosition */
44
+ /** @typedef {import("estree").Comment & { start: number, end: number, loc?: SourceLocation | null }} Comment */
36
45
  /** @typedef {import("estree").ConditionalExpression} ConditionalExpression */
37
46
  /** @typedef {import("estree").Declaration} Declaration */
38
47
  /** @typedef {import("estree").PrivateIdentifier} PrivateIdentifier */
@@ -94,6 +103,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
94
103
  /** @typedef {import("estree").MaybeNamedFunctionDeclaration} MaybeNamedFunctionDeclaration */
95
104
  /** @typedef {import("estree").MaybeNamedClassDeclaration} MaybeNamedClassDeclaration */
96
105
  /**
106
+ * Defines the shared type used by this module.
97
107
  * @template T
98
108
  * @typedef {import("tapable").AsArray<T>} AsArray<T>
99
109
  */
@@ -104,6 +114,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
104
114
  /** @typedef {import("../dependencies/HarmonyExportImportedSpecifierDependency").HarmonyStarExportsList} HarmonyStarExportsList */
105
115
 
106
116
  /**
117
+ * Defines the known javascript parser state type used by this module.
107
118
  * @typedef {object} KnownJavascriptParserState
108
119
  * @property {Set<string>=} harmonyNamedExports
109
120
  * @property {HarmonyStarExportsList=} harmonyStarExports
@@ -117,6 +128,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
117
128
  /** @typedef {import("../Module")} Module */
118
129
 
119
130
  /** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => Members, getMembersOptionals: () => MembersOptionals, getMemberRanges: () => MemberRanges }} GetInfoResult */
131
+ /** @typedef {{ consequent?: EXPECTED_OBJECT, alternate?: EXPECTED_OBJECT }} GuardCollection per-branch guard frames pushed onto the parser state guard stack */
120
132
  /** @typedef {Statement | ModuleDeclaration | Expression | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} StatementPathItem */
121
133
  /** @typedef {(ident: string) => void} OnIdentString */
122
134
  /** @typedef {(ident: string, identifier: Identifier) => void} OnIdent */
@@ -124,86 +136,52 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
124
136
 
125
137
  /** @typedef {Set<DestructuringAssignmentProperty>} DestructuringAssignmentProperties */
126
138
 
127
- // TODO remove cast when @types/estree has been updated to import assertions
139
+ // TODO remove cast when @types/estree has been updated to import phases
128
140
  /** @typedef {import("estree").ImportExpression & { phase?: "defer" | "source" }} ImportExpression */
129
141
 
130
142
  /** @type {string[]} */
131
143
  const EMPTY_ARRAY = [];
144
+
145
+ /**
146
+ * Getter that reverses `arr` in place on first access and caches it. Lighter
147
+ * than `memoize(() => arr.reverse())` (one closure instead of two) and called
148
+ * per member expression on hot parse paths.
149
+ * @template T
150
+ * @param {T[]} arr array reversed lazily on first access
151
+ * @returns {() => T[]} getter returning the reversed array
152
+ */
153
+ const lazyReverse = (arr) => {
154
+ let reversed = false;
155
+ return () => {
156
+ if (!reversed) {
157
+ arr.reverse();
158
+ reversed = true;
159
+ }
160
+ return arr;
161
+ };
162
+ };
163
+
132
164
  const ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = 0b01;
133
165
  const ALLOWED_MEMBER_TYPES_EXPRESSION = 0b10;
134
166
  const ALLOWED_MEMBER_TYPES_ALL = 0b11;
135
167
 
136
- const LEGACY_ASSERT_ATTRIBUTES = Symbol("assert");
137
-
138
- /** @type {(BaseParser: typeof AcornParser) => typeof AcornParser} */
139
- const importAssertions = (Parser) =>
140
- class extends Parser {
141
- /**
142
- * @this {InstanceType<AcornParser>}
143
- * @returns {ImportAttribute[]} import attributes
144
- */
145
- parseWithClause() {
146
- /** @type {ImportAttribute[]} */
147
- const nodes = [];
148
-
149
- const isAssertLegacy = this.value === "assert";
150
-
151
- if (isAssertLegacy) {
152
- if (!this.eat(tokTypes.name)) {
153
- return nodes;
154
- }
155
- } else if (!this.eat(tokTypes._with)) {
156
- return nodes;
157
- }
158
-
159
- this.expect(tokTypes.braceL);
160
-
161
- /** @type {Record<string, boolean>} */
162
- const attributeKeys = {};
163
- let first = true;
164
-
165
- while (!this.eat(tokTypes.braceR)) {
166
- if (!first) {
167
- this.expect(tokTypes.comma);
168
- if (this.afterTrailingComma(tokTypes.braceR)) {
169
- break;
170
- }
171
- } else {
172
- first = false;
173
- }
174
-
175
- const attr =
176
- /** @type {ImportAttribute} */
177
- this.parseImportAttribute();
178
- const keyName =
179
- attr.key.type === "Identifier" ? attr.key.name : attr.key.value;
180
-
181
- if (Object.prototype.hasOwnProperty.call(attributeKeys, keyName)) {
182
- this.raiseRecoverable(
183
- attr.key.start,
184
- `Duplicate attribute key '${keyName}'`
185
- );
186
- }
187
-
188
- attributeKeys[keyName] = true;
189
- nodes.push(attr);
190
- }
191
-
192
- if (isAssertLegacy) {
193
- /** @type {EXPECTED_ANY} */
194
- (nodes)[LEGACY_ASSERT_ATTRIBUTES] = true;
195
- }
168
+ // Shared `() => false` so the members-optionals fallback in walkCallExpression
169
+ // doesn't allocate a fresh closure per identifier-rooted call.
170
+ const RETURN_FALSE = () => false;
196
171
 
197
- return nodes;
198
- }
199
- };
172
+ // Shared `() => []` for the member-less identifier/this evaluation results,
173
+ // replacing three fresh closures per evaluated free variable.
174
+ const RETURN_EMPTY_ARRAY = () => [];
200
175
 
201
176
  // Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
202
- let parser = AcornParser.extend(importAssertions);
177
+ let parser = /** @type {AcornParser} */ (WebpackParser);
203
178
 
204
179
  /** @typedef {Record<string, string> & { _isLegacyAssert?: boolean }} ImportAttributes */
205
180
 
181
+ // Conceptually pairs with ./syntax's LEGACY_ASSERT_ATTRIBUTES marker, but is
182
+ // pinned here by its public `JavascriptParser.getImportAttributes` typing.
206
183
  /**
184
+ * Gets import attributes.
207
185
  * @param {ImportDeclaration | ExportNamedDeclaration | ExportAllDeclaration | ImportExpression} node node with assertions
208
186
  * @returns {ImportAttributes | undefined} import attributes
209
187
  */
@@ -287,19 +265,25 @@ const VariableInfoFlags = Object.freeze({
287
265
 
288
266
  class VariableInfo {
289
267
  /**
268
+ * Creates an instance of VariableInfo.
290
269
  * @param {ScopeInfo} declaredScope scope in which the variable is declared
291
270
  * @param {string | undefined} name which name the variable use, defined name or free name or tagged name
292
271
  * @param {VariableInfoFlagsType} flags how the variable is created
293
272
  * @param {TagInfo | undefined} tagInfo info about tags
294
273
  */
295
274
  constructor(declaredScope, name, flags, tagInfo) {
275
+ /** @type {ScopeInfo} */
296
276
  this.declaredScope = declaredScope;
277
+ /** @type {string | undefined} */
297
278
  this.name = name;
279
+ /** @type {VariableInfoFlagsType} */
298
280
  this.flags = flags;
281
+ /** @type {TagInfo | undefined} */
299
282
  this.tagInfo = tagInfo;
300
283
  }
301
284
 
302
285
  /**
286
+ * Checks whether this variable info is free.
303
287
  * @returns {boolean} the variable is free or not
304
288
  */
305
289
  isFree() {
@@ -307,6 +291,7 @@ class VariableInfo {
307
291
  }
308
292
 
309
293
  /**
294
+ * Checks whether this variable info is tagged.
310
295
  * @returns {boolean} the variable is tagged by tagVariable or not
311
296
  */
312
297
  isTagged() {
@@ -318,45 +303,51 @@ class VariableInfo {
318
303
  /** @typedef {Literal | string | null | undefined} ImportSource */
319
304
 
320
305
  /**
306
+ * Defines the internal parse options type used by this module.
321
307
  * @typedef {Omit<ParseOptions, "sourceType" | "ecmaVersion"> & { sourceType: "module" | "script" | "auto" }} InternalParseOptions
322
308
  */
323
309
 
324
310
  /**
311
+ * Defines the parse options type used by this module.
325
312
  * @typedef {object} ParseOptions
326
313
  * @property {"module" | "script"} sourceType
327
314
  * @property {EcmaVersion} ecmaVersion
328
315
  * @property {boolean=} locations
329
316
  * @property {boolean=} comments
330
317
  * @property {boolean=} ranges
331
- * @property {boolean=} semicolons
332
318
  * @property {boolean=} allowHashBang
333
319
  * @property {boolean=} allowReturnOutsideFunction
320
+ * @property {boolean=} lazyNodes internal: serve `range` lazily and skip acorn's location/range tracking
321
+ * @property {Comment[]=} lazyComments internal: collect comments here without slicing their text eagerly
322
+ * @property {boolean=} importPhases enable parsing of the import phase proposals (import defer / import source)
323
+ * @property {boolean=} moduleFallback internal: for `auto`, let the parser downgrade module->script in place instead of re-parsing
334
324
  */
335
325
 
336
326
  /**
327
+ * Defines the parse result type used by this module.
337
328
  * @typedef {object} ParseResult
338
329
  * @property {Program} ast
339
330
  * @property {Comment[]} comments
340
- * @property {Set<number>} semicolons
341
331
  */
342
332
 
343
333
  /**
334
+ * Defines the parse function type used by this module.
344
335
  * @typedef {(code: string, options: ParseOptions) => ParseResult} ParseFunction
345
336
  */
346
337
 
347
338
  /** @typedef {symbol} Tag */
348
339
 
349
340
  /** @typedef {import("../dependencies/HarmonyImportDependencyParserPlugin").HarmonySettings} HarmonySettings */
350
- /** @typedef {import("../dependencies/HarmonyImportDependencyParserPlugin").HarmonySpecifierGuards} HarmonySpecifierGuards */
351
341
  /** @typedef {import("../dependencies/ImportParserPlugin").ImportSettings} ImportSettings */
352
342
  /** @typedef {import("../dependencies/CommonJsImportsParserPlugin").CommonJsImportSettings} CommonJsImportSettings */
353
343
  /** @typedef {import("../CompatibilityPlugin").CompatibilitySettings} CompatibilitySettings */
354
344
  /** @typedef {import("../optimize/InnerGraph").TopLevelSymbol} TopLevelSymbol */
355
345
 
356
- /** @typedef {HarmonySettings | ImportSettings | CommonJsImportSettings | TopLevelSymbol | CompatibilitySettings | HarmonySpecifierGuards} KnownTagData */
346
+ /** @typedef {HarmonySettings | ImportSettings | CommonJsImportSettings | TopLevelSymbol | CompatibilitySettings} KnownTagData */
357
347
  /** @typedef {KnownTagData | Record<string, EXPECTED_ANY>} TagData */
358
348
 
359
349
  /**
350
+ * Defines the tag info type used by this module.
360
351
  * @typedef {object} TagInfo
361
352
  * @property {Tag} tag
362
353
  * @property {TagData=} data
@@ -372,6 +363,7 @@ const SCOPE_INFO_TERMINATED_RETURN = 1;
372
363
  const SCOPE_INFO_TERMINATED_THROW = 2;
373
364
 
374
365
  /**
366
+ * Defines the scope info type used by this module.
375
367
  * @typedef {object} ScopeInfo
376
368
  * @property {StackedMap<string, VariableInfo | ScopeInfo>} definitions
377
369
  * @property {boolean | "arrow"} topLevelScope
@@ -386,10 +378,11 @@ const SCOPE_INFO_TERMINATED_THROW = 2;
386
378
  /** @typedef {[number, number]} Range */
387
379
 
388
380
  /**
381
+ * Defines the destructuring assignment property type used by this module.
382
+ * Carries only the range — consumers derive line/column via `getLocation`.
389
383
  * @typedef {object} DestructuringAssignmentProperty
390
384
  * @property {string} id
391
385
  * @property {Range} range
392
- * @property {SourceLocation} loc
393
386
  * @property {Set<DestructuringAssignmentProperty> | undefined=} pattern
394
387
  * @property {boolean | string} shorthand
395
388
  */
@@ -459,6 +452,25 @@ const getRootName = (expression) => {
459
452
  }
460
453
  };
461
454
 
455
+ /**
456
+ * @param {string} type AST node type
457
+ * @returns {boolean} true for FunctionExpression or ArrowFunctionExpression
458
+ */
459
+ const isFunctionExpression = (type) =>
460
+ type === "FunctionExpression" || type === "ArrowFunctionExpression";
461
+
462
+ /**
463
+ * @param {FunctionExpression | ArrowFunctionExpression} fn function
464
+ * @returns {boolean} true when all params are plain identifiers
465
+ */
466
+ const isSimpleFunction = (fn) => {
467
+ const params = fn.params;
468
+ for (let i = 0; i < params.length; i++) {
469
+ if (params[i].type !== "Identifier") return false;
470
+ }
471
+ return true;
472
+ };
473
+
462
474
  /** @type {ParseOptions} */
463
475
  const defaultParserOptions = {
464
476
  sourceType: "module",
@@ -470,17 +482,24 @@ const defaultParserOptions = {
470
482
  allowHashBang: true
471
483
  };
472
484
 
473
- const EMPTY_COMMENT_OPTIONS = {
474
- options: null,
475
- errors: null
476
- };
485
+ // reused by _parse for every non-custom parse — all fields are reset per parse
486
+ /** @type {ParseOptions} */
487
+ const REUSED_PARSER_OPTIONS = { ...defaultParserOptions };
488
+
489
+ // Read-only snippet ASTs for `evaluate()`, released with the compilation;
490
+ // DefinePlugin evaluates the same strings once per usage per module.
491
+ /** @type {WeakMap<Compilation, Map<string, Program>>} */
492
+ const evaluateAstCaches = new WeakMap();
493
+ // The inner map is strong while the compilation lives, so cap it
494
+ const EVALUATE_AST_CACHE_LIMIT = 4096;
477
495
 
478
496
  const CLASS_NAME = "JavascriptParser";
479
497
 
480
498
  class JavascriptParser extends Parser {
481
499
  /**
500
+ * Creates an instance of JavascriptParser.
482
501
  * @param {"module" | "script" | "auto"=} sourceType default source type
483
- * @param {{ parse?: ParseFunction }=} options parser options
502
+ * @param {{ parse?: ParseFunction, typescript?: boolean, importPhases?: boolean, strictModeViolations?: "error" | "warn" | false }=} options parser options
484
503
  */
485
504
  constructor(sourceType = "auto", options = {}) {
486
505
  super();
@@ -495,11 +514,17 @@ class JavascriptParser extends Parser {
495
514
  evaluateDefinedIdentifier: new HookMap(
496
515
  () => new SyncBailHook(["expression"])
497
516
  ),
498
- /** @type {HookMap<SyncBailHook<[NewExpression], BasicEvaluatedExpression | null | undefined>>} */
517
+ /**
518
+ * @type {HookMap<SyncBailHook<[NewExpression], BasicEvaluatedExpression | null | undefined>>}
519
+ * @since 5.73.0
520
+ */
499
521
  evaluateNewExpression: new HookMap(
500
522
  () => new SyncBailHook(["expression"])
501
523
  ),
502
- /** @type {HookMap<SyncBailHook<[CallExpression], BasicEvaluatedExpression | null | undefined>>} */
524
+ /**
525
+ * @type {HookMap<SyncBailHook<[CallExpression], BasicEvaluatedExpression | null | undefined>>}
526
+ * @since 5.73.0
527
+ */
503
528
  evaluateCallExpression: new HookMap(
504
529
  () => new SyncBailHook(["expression"])
505
530
  ),
@@ -513,14 +538,29 @@ class JavascriptParser extends Parser {
513
538
  ),
514
539
  /** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>} */
515
540
  preStatement: new SyncBailHook(["statement"]),
541
+ /**
542
+ * @type {HookMap<SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>>}
543
+ * @since 5.109.0
544
+ */
545
+ preStatementByType: new HookMap(() => new SyncBailHook(["statement"])),
516
546
 
517
547
  /** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>} */
518
548
  blockPreStatement: new SyncBailHook(["declaration"]),
549
+ /**
550
+ * @type {HookMap<SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>>}
551
+ * @since 5.109.0
552
+ */
553
+ blockPreStatementByType: new HookMap(
554
+ () => new SyncBailHook(["declaration"])
555
+ ),
519
556
  /** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
520
557
  statement: new SyncBailHook(["statement"]),
521
558
  /** @type {SyncBailHook<[IfStatement], boolean | void>} */
522
559
  statementIf: new SyncBailHook(["statement"]),
523
- /** @type {SyncBailHook<[Expression], ((walk: () => void) => void) | void>} */
560
+ /**
561
+ * @type {SyncBailHook<[Expression], GuardCollection | void>}
562
+ * @since 5.105.0
563
+ */
524
564
  collectGuards: new SyncBailHook(["expression"]),
525
565
  /** @type {SyncBailHook<[Expression, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
526
566
  classExtendsExpression: new SyncBailHook([
@@ -529,7 +569,10 @@ class JavascriptParser extends Parser {
529
569
  ]),
530
570
  /** @type {SyncBailHook<[MethodDefinition | PropertyDefinition | StaticBlock, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
531
571
  classBodyElement: new SyncBailHook(["element", "classDefinition"]),
532
- /** @type {SyncBailHook<[Expression, MethodDefinition | PropertyDefinition, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
572
+ /**
573
+ * @type {SyncBailHook<[Expression, MethodDefinition | PropertyDefinition, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>}
574
+ * @since 5.36.0
575
+ */
533
576
  classBodyValue: new SyncBailHook([
534
577
  "expression",
535
578
  "element",
@@ -569,7 +612,7 @@ class JavascriptParser extends Parser {
569
612
  "exportName",
570
613
  "index"
571
614
  ]),
572
- /** @type {SyncBailHook<[VariableDeclarator, Statement], boolean | void>} */
615
+ /** @type {SyncBailHook<[VariableDeclarator, VariableDeclaration], boolean | void>} */
573
616
  preDeclarator: new SyncBailHook(["declarator", "statement"]),
574
617
  /** @type {SyncBailHook<[VariableDeclarator, Statement], boolean | void>} */
575
618
  declarator: new SyncBailHook(["declarator", "statement"]),
@@ -579,13 +622,19 @@ class JavascriptParser extends Parser {
579
622
  varDeclarationLet: new HookMap(() => new SyncBailHook(["declaration"])),
580
623
  /** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
581
624
  varDeclarationConst: new HookMap(() => new SyncBailHook(["declaration"])),
582
- /** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
625
+ /**
626
+ * @type {HookMap<SyncBailHook<[Identifier], boolean | void>>}
627
+ * @since 5.100.0
628
+ */
583
629
  varDeclarationUsing: new HookMap(() => new SyncBailHook(["declaration"])),
584
630
  /** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
585
631
  varDeclarationVar: new HookMap(() => new SyncBailHook(["declaration"])),
586
632
  /** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
587
633
  pattern: new HookMap(() => new SyncBailHook(["pattern"])),
588
- /** @type {SyncBailHook<[Expression], boolean | void>} */
634
+ /**
635
+ * @type {SyncBailHook<[Expression], boolean | void>}
636
+ * @since 5.101.3
637
+ */
589
638
  collectDestructuringAssignmentProperties: new SyncBailHook([
590
639
  "expression"
591
640
  ]),
@@ -646,7 +695,10 @@ class JavascriptParser extends Parser {
646
695
  optionalChaining: new SyncBailHook(["optionalChaining"]),
647
696
  /** @type {HookMap<SyncBailHook<[NewExpression], boolean | void>>} */
648
697
  new: new HookMap(() => new SyncBailHook(["expression"])),
649
- /** @type {SyncBailHook<[BinaryExpression], boolean | void>} */
698
+ /**
699
+ * @type {SyncBailHook<[BinaryExpression], boolean | void>}
700
+ * @since 5.71.0
701
+ */
650
702
  binaryExpression: new SyncBailHook(["binaryExpression"]),
651
703
  /** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
652
704
  expression: new HookMap(() => new SyncBailHook(["expression"])),
@@ -670,11 +722,17 @@ class JavascriptParser extends Parser {
670
722
  expressionLogicalOperator: new SyncBailHook(["expression"]),
671
723
  /** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */
672
724
  program: new SyncBailHook(["ast", "comments"]),
673
- /** @type {SyncBailHook<[ThrowStatement | ReturnStatement], boolean | void>} */
725
+ /**
726
+ * @type {SyncBailHook<[ThrowStatement | ReturnStatement], boolean | void>}
727
+ * @since 5.99.0
728
+ */
674
729
  terminate: new SyncBailHook(["statement"]),
675
730
  /** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */
676
731
  finish: new SyncBailHook(["ast", "comments"]),
677
- /** @type {SyncBailHook<[Statement], boolean | void>} */
732
+ /**
733
+ * @type {SyncBailHook<[Statement], boolean | void>}
734
+ * @since 5.99.9
735
+ */
678
736
  unusedStatement: new SyncBailHook(["statement"])
679
737
  });
680
738
  this.sourceType = sourceType;
@@ -686,7 +744,10 @@ class JavascriptParser extends Parser {
686
744
  this.state = /** @type {EXPECTED_ANY} */ (undefined);
687
745
  /** @type {Comment[] | undefined} */
688
746
  this.comments = undefined;
689
- /** @type {Set<number> | undefined} */
747
+ // ASI overrides keyed by statement-end offset: true forces an ASI
748
+ // position, false forces a real semicolon. Absent offsets are derived
749
+ // from the source text. Allocated lazily by set/unsetAsiPosition.
750
+ /** @type {Map<number, boolean> | undefined} */
690
751
  this.semicolons = undefined;
691
752
  /** @type {StatementPath | undefined} */
692
753
  this.statementPath = undefined;
@@ -696,8 +757,39 @@ class JavascriptParser extends Parser {
696
757
  this.destructuringAssignmentProperties = undefined;
697
758
  /** @type {TagData | undefined} */
698
759
  this.currentTagData = undefined;
760
+ // True while parsing a loose module whose code is emitted as strict ESM.
761
+ this._strictInModuleOutput = false;
762
+ // Source text of the current parse, for offset → line/column mapping.
763
+ /** @type {string | undefined} */
764
+ this._source = undefined;
765
+ // Offset of each line's first character, built on first getLocation use.
766
+ /** @type {number[] | undefined} */
767
+ this._lineStarts = undefined;
768
+ // True while only the parser's own taps sit on evaluate.for("Identifier");
769
+ // recomputed per parse, gates the defined-identifier fast paths.
770
+ this._evalIdentOwnTaps = false;
699
771
  this.magicCommentContext = createMagicCommentContext();
772
+ // Reused for enterPatterns on every scope entry to avoid per-scope closures.
773
+ /** @type {OnIdentString} */
774
+ this._defineVariable = (ident) => this.defineVariable(ident);
700
775
  this._initializeEvaluating();
776
+ // keyed taps are free for every other member chain, and a shadowed
777
+ // `arguments` binding never dispatches the free-variable hooks
778
+ this.hooks.expressionMemberChain
779
+ .for("arguments")
780
+ .tap(CLASS_NAME, (expression, members) => {
781
+ if (this._strictInModuleOutput) {
782
+ this._checkStrictModeArgumentsMember(members[0], expression);
783
+ }
784
+ });
785
+ this.hooks.callMemberChain
786
+ .for("arguments")
787
+ .tap(CLASS_NAME, (expression, members) => {
788
+ // longer chains re-enter the member walk, which reports them
789
+ if (this._strictInModuleOutput && members.length === 1) {
790
+ this._checkStrictModeArgumentsMember(members[0], expression);
791
+ }
792
+ });
701
793
  }
702
794
 
703
795
  _initializeEvaluating() {
@@ -956,6 +1048,7 @@ class JavascriptParser extends Parser {
956
1048
  (a === true && b === false) || (a === false && b === true);
957
1049
 
958
1050
  /**
1051
+ * Handle template string compare.
959
1052
  * @param {BasicEvaluatedExpression} left left
960
1053
  * @param {BasicEvaluatedExpression} right right
961
1054
  * @param {BasicEvaluatedExpression} res res
@@ -964,6 +1057,7 @@ class JavascriptParser extends Parser {
964
1057
  */
965
1058
  const handleTemplateStringCompare = (left, right, res, eql) => {
966
1059
  /**
1060
+ * Returns value.
967
1061
  * @param {BasicEvaluatedExpression[]} parts parts
968
1062
  * @returns {string} value
969
1063
  */
@@ -977,6 +1071,7 @@ class JavascriptParser extends Parser {
977
1071
  return value;
978
1072
  };
979
1073
  /**
1074
+ * Returns value.
980
1075
  * @param {BasicEvaluatedExpression[]} parts parts
981
1076
  * @returns {string} value
982
1077
  */
@@ -1319,6 +1414,16 @@ class JavascriptParser extends Parser {
1319
1414
  return handleConstOperation((l, r) => l <= r);
1320
1415
  } else if (expr.operator === ">=") {
1321
1416
  return handleConstOperation((l, r) => l >= r);
1417
+ } else if (expr.operator === "in") {
1418
+ // `x in y` always evaluates to a boolean, so it is never nullish
1419
+ const left = this.evaluateExpression(expr.left);
1420
+ const right = this.evaluateExpression(expr.right);
1421
+ return new BasicEvaluatedExpression()
1422
+ .setNullish(false)
1423
+ .setSideEffects(
1424
+ left.couldHaveSideEffects() || right.couldHaveSideEffects()
1425
+ )
1426
+ .setRange(/** @type {Range} */ (expr.range));
1322
1427
  }
1323
1428
  });
1324
1429
  this.hooks.evaluate.for("UnaryExpression").tap(CLASS_NAME, (_expr) => {
@@ -1460,6 +1565,7 @@ class JavascriptParser extends Parser {
1460
1565
  }
1461
1566
  });
1462
1567
  /**
1568
+ * Tap evaluate with variable info.
1463
1569
  * @param {"Identifier" | "ThisExpression" | "MemberExpression"} exprType expression type name
1464
1570
  * @param {(node: Expression | SpreadElement) => GetInfoResult | undefined} getInfo get info
1465
1571
  * @returns {void}
@@ -1474,15 +1580,16 @@ class JavascriptParser extends Parser {
1474
1580
  /** @type {Identifier | ThisExpression | MemberExpression} */ (expr);
1475
1581
 
1476
1582
  const info = getInfo(expression);
1583
+ // Cache the result (even when undefined) so the stage-100 tap below
1584
+ // reuses it instead of recomputing getInfo — getMemberExpressionInfo
1585
+ // is expensive and previously ran twice for every rejected member.
1586
+ cachedExpression = expression;
1587
+ cachedInfo = info;
1477
1588
  if (info !== undefined) {
1478
1589
  return this.callHooksForInfoWithFallback(
1479
1590
  this.hooks.evaluateIdentifier,
1480
1591
  info.name,
1481
- (_name) => {
1482
- cachedExpression = expression;
1483
- cachedInfo = info;
1484
- return undefined;
1485
- },
1592
+ (_name) => undefined,
1486
1593
  (name) => {
1487
1594
  const hook = this.hooks.evaluateDefinedIdentifier.get(name);
1488
1595
  if (hook !== undefined) {
@@ -1522,14 +1629,18 @@ class JavascriptParser extends Parser {
1522
1629
  const info = this.getVariableInfo(/** @type {Identifier} */ (expr).name);
1523
1630
  if (
1524
1631
  typeof info === "string" ||
1525
- (info instanceof VariableInfo && (info.isFree() || info.isTagged()))
1632
+ (info instanceof VariableInfo &&
1633
+ (info.isFree() ||
1634
+ info.isTagged() ||
1635
+ // Walk `tagInfo` in `callHooksForInfo` if tagInfo is present.
1636
+ info.tagInfo !== undefined))
1526
1637
  ) {
1527
1638
  return {
1528
1639
  name: info,
1529
1640
  rootInfo: info,
1530
- getMembers: () => [],
1531
- getMembersOptionals: () => [],
1532
- getMemberRanges: () => []
1641
+ getMembers: RETURN_EMPTY_ARRAY,
1642
+ getMembersOptionals: RETURN_EMPTY_ARRAY,
1643
+ getMemberRanges: RETURN_EMPTY_ARRAY
1533
1644
  };
1534
1645
  }
1535
1646
  });
@@ -1542,9 +1653,9 @@ class JavascriptParser extends Parser {
1542
1653
  return {
1543
1654
  name: info,
1544
1655
  rootInfo: info,
1545
- getMembers: () => [],
1546
- getMembersOptionals: () => [],
1547
- getMemberRanges: () => []
1656
+ getMembers: RETURN_EMPTY_ARRAY,
1657
+ getMembersOptionals: RETURN_EMPTY_ARRAY,
1658
+ getMemberRanges: RETURN_EMPTY_ARRAY
1548
1659
  };
1549
1660
  }
1550
1661
  });
@@ -1565,8 +1676,8 @@ class JavascriptParser extends Parser {
1565
1676
  )
1566
1677
  );
1567
1678
 
1568
- this.hooks.evaluate.for("CallExpression").tap(CLASS_NAME, (_expr) => {
1569
- const expr = /** @type {CallExpression} */ (_expr);
1679
+ this.hooks.evaluate.for("CallExpression").tap(CLASS_NAME, (expression) => {
1680
+ const expr = /** @type {CallExpression} */ (expression);
1570
1681
  if (
1571
1682
  expr.callee.type === "MemberExpression" &&
1572
1683
  expr.callee.property.type ===
@@ -1687,6 +1798,7 @@ class JavascriptParser extends Parser {
1687
1798
  }
1688
1799
 
1689
1800
  /**
1801
+ * Gets simplified template result.
1690
1802
  * @param {"cooked" | "raw"} kind kind of values to get
1691
1803
  * @param {TemplateLiteral} templateLiteralExpr TemplateLiteral expr
1692
1804
  * @returns {{ quasis: BasicEvaluatedExpression[], parts: BasicEvaluatedExpression[] }} Simplified template
@@ -1959,9 +2071,25 @@ class JavascriptParser extends Parser {
1959
2071
  }
1960
2072
  return this.evaluateExpression(expr.expression);
1961
2073
  });
2074
+ this.hooks.evaluate.for("SequenceExpression").tap(CLASS_NAME, (_expr) => {
2075
+ const expr = /** @type {SequenceExpression} */ (_expr);
2076
+ if (!expr.range) return;
2077
+ let commentsStartPos = /** @type {Range} */ (expr.range)[0];
2078
+ for (let i = 0; i < expr.expressions.length - 1; i++) {
2079
+ const item = expr.expressions[i];
2080
+ if (!item.range) return;
2081
+ if (!this.isPure(item, commentsStartPos)) return;
2082
+ commentsStartPos = /** @type {Range} */ (item.range)[1];
2083
+ }
2084
+ const last = expr.expressions[expr.expressions.length - 1];
2085
+ const evaluated = this.evaluateExpression(last);
2086
+ if (!evaluated.isCompileTimeValue()) return;
2087
+ return evaluated.setRange(/** @type {Range} */ (expr.range));
2088
+ });
1962
2089
  }
1963
2090
 
1964
2091
  /**
2092
+ * Destructuring assignment properties for.
1965
2093
  * @param {Expression} node node
1966
2094
  * @returns {DestructuringAssignmentProperties | undefined} destructured identifiers
1967
2095
  */
@@ -1971,10 +2099,20 @@ class JavascriptParser extends Parser {
1971
2099
  }
1972
2100
 
1973
2101
  /**
2102
+ * Gets rename identifier.
1974
2103
  * @param {Expression | SpreadElement} expr expression
1975
2104
  * @returns {string | VariableInfo | undefined} identifier
1976
2105
  */
1977
2106
  getRenameIdentifier(expr) {
2107
+ if (
2108
+ expr.type === "Identifier" &&
2109
+ this._evalIdentOwnTaps &&
2110
+ expr.name !== "undefined" &&
2111
+ this._isDefinedPlainVariable(expr.name)
2112
+ ) {
2113
+ // the evaluation could only fall through — never an identifier result
2114
+ return;
2115
+ }
1978
2116
  const result = this.evaluateExpression(expr);
1979
2117
  if (result.isIdentifier()) {
1980
2118
  return result.identifier;
@@ -1982,6 +2120,7 @@ class JavascriptParser extends Parser {
1982
2120
  }
1983
2121
 
1984
2122
  /**
2123
+ * Processes the provided classy.
1985
2124
  * @param {ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration} classy a class node
1986
2125
  * @returns {void}
1987
2126
  */
@@ -2113,49 +2252,60 @@ class JavascriptParser extends Parser {
2113
2252
  preWalkStatement(statement) {
2114
2253
  /** @type {StatementPath} */
2115
2254
  (this.statementPath).push(statement);
2116
- if (this.hooks.preStatement.call(statement)) {
2255
+ const { preStatement, preStatementByType } = this.hooks;
2256
+ // skip the broadcast entirely when nothing taps it; type-keyed taps
2257
+ // only run for their statement type
2258
+ let bail =
2259
+ preStatement.taps.length !== 0 ? preStatement.call(statement) : undefined;
2260
+ if (!bail) {
2261
+ const typed = preStatementByType.get(statement.type);
2262
+ if (typed !== undefined) bail = typed.call(statement);
2263
+ }
2264
+ if (bail) {
2117
2265
  this.prevStatement =
2118
2266
  /** @type {StatementPath} */
2119
2267
  (this.statementPath).pop();
2120
2268
  return;
2121
2269
  }
2270
+ // cases ordered by measured statement frequency; the commonest statements
2271
+ // (expressions, returns) intentionally match nothing here
2122
2272
  switch (statement.type) {
2123
- case "BlockStatement":
2124
- this.preWalkBlockStatement(statement);
2125
- break;
2126
- case "DoWhileStatement":
2127
- this.preWalkDoWhileStatement(statement);
2128
- break;
2129
- case "ForInStatement":
2130
- this.preWalkForInStatement(statement);
2273
+ case "VariableDeclaration":
2274
+ this.preWalkVariableDeclaration(statement);
2131
2275
  break;
2132
- case "ForOfStatement":
2133
- this.preWalkForOfStatement(statement);
2276
+ case "IfStatement":
2277
+ this.preWalkIfStatement(statement);
2134
2278
  break;
2135
- case "ForStatement":
2136
- this.preWalkForStatement(statement);
2279
+ case "BlockStatement":
2280
+ this.preWalkBlockStatement(statement);
2137
2281
  break;
2138
2282
  case "FunctionDeclaration":
2139
2283
  this.preWalkFunctionDeclaration(statement);
2140
2284
  break;
2141
- case "IfStatement":
2142
- this.preWalkIfStatement(statement);
2143
- break;
2144
- case "LabeledStatement":
2145
- this.preWalkLabeledStatement(statement);
2146
- break;
2147
- case "SwitchStatement":
2148
- this.preWalkSwitchStatement(statement);
2285
+ case "ForStatement":
2286
+ this.preWalkForStatement(statement);
2149
2287
  break;
2150
2288
  case "TryStatement":
2151
2289
  this.preWalkTryStatement(statement);
2152
2290
  break;
2153
- case "VariableDeclaration":
2154
- this.preWalkVariableDeclaration(statement);
2291
+ case "SwitchStatement":
2292
+ this.preWalkSwitchStatement(statement);
2155
2293
  break;
2156
2294
  case "WhileStatement":
2157
2295
  this.preWalkWhileStatement(statement);
2158
2296
  break;
2297
+ case "ForInStatement":
2298
+ this.preWalkForInStatement(statement);
2299
+ break;
2300
+ case "ForOfStatement":
2301
+ this.preWalkForOfStatement(statement);
2302
+ break;
2303
+ case "DoWhileStatement":
2304
+ this.preWalkDoWhileStatement(statement);
2305
+ break;
2306
+ case "LabeledStatement":
2307
+ this.preWalkLabeledStatement(statement);
2308
+ break;
2159
2309
  case "WithStatement":
2160
2310
  this.preWalkWithStatement(statement);
2161
2311
  break;
@@ -2166,32 +2316,43 @@ class JavascriptParser extends Parser {
2166
2316
  }
2167
2317
 
2168
2318
  /**
2319
+ * Block pre walk statement.
2169
2320
  * @param {Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration} statement statement
2170
2321
  */
2171
2322
  blockPreWalkStatement(statement) {
2172
2323
  /** @type {StatementPath} */
2173
2324
  (this.statementPath).push(statement);
2174
- if (this.hooks.blockPreStatement.call(statement)) {
2325
+ const { blockPreStatement, blockPreStatementByType } = this.hooks;
2326
+ let bail =
2327
+ blockPreStatement.taps.length !== 0
2328
+ ? blockPreStatement.call(statement)
2329
+ : undefined;
2330
+ if (!bail) {
2331
+ const typed = blockPreStatementByType.get(statement.type);
2332
+ if (typed !== undefined) bail = typed.call(statement);
2333
+ }
2334
+ if (bail) {
2175
2335
  this.prevStatement =
2176
2336
  /** @type {StatementPath} */
2177
2337
  (this.statementPath).pop();
2178
2338
  return;
2179
2339
  }
2340
+ // cases ordered by measured statement frequency
2180
2341
  switch (statement.type) {
2181
- case "ExportDefaultDeclaration":
2182
- this.blockPreWalkExportDefaultDeclaration(statement);
2183
- break;
2184
- case "ExportNamedDeclaration":
2185
- this.blockPreWalkExportNamedDeclaration(statement);
2186
- break;
2187
2342
  case "VariableDeclaration":
2188
2343
  this.blockPreWalkVariableDeclaration(statement);
2189
2344
  break;
2345
+ case "ExpressionStatement":
2346
+ this.blockPreWalkExpressionStatement(statement);
2347
+ break;
2190
2348
  case "ClassDeclaration":
2191
2349
  this.blockPreWalkClassDeclaration(statement);
2192
2350
  break;
2193
- case "ExpressionStatement":
2194
- this.blockPreWalkExpressionStatement(statement);
2351
+ case "ExportNamedDeclaration":
2352
+ this.blockPreWalkExportNamedDeclaration(statement);
2353
+ break;
2354
+ case "ExportDefaultDeclaration":
2355
+ this.blockPreWalkExportDefaultDeclaration(statement);
2195
2356
  }
2196
2357
  this.prevStatement =
2197
2358
  /** @type {StatementPath} */
@@ -2199,56 +2360,48 @@ class JavascriptParser extends Parser {
2199
2360
  }
2200
2361
 
2201
2362
  /**
2363
+ * Processes the provided statement.
2202
2364
  * @param {Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} statement statement
2203
2365
  */
2204
2366
  walkStatement(statement) {
2205
2367
  /** @type {StatementPath} */
2206
2368
  (this.statementPath).push(statement);
2207
- if (this.hooks.statement.call(statement) !== undefined) {
2369
+ const { statement: statementHook } = this.hooks;
2370
+ if (
2371
+ statementHook.taps.length !== 0 &&
2372
+ statementHook.call(statement) !== undefined
2373
+ ) {
2208
2374
  this.prevStatement =
2209
2375
  /** @type {StatementPath} */
2210
2376
  (this.statementPath).pop();
2211
2377
  return;
2212
2378
  }
2379
+ // cases ordered by measured statement frequency; V8 compiles this to
2380
+ // sequential compares, so hot types must come first
2213
2381
  switch (statement.type) {
2214
- case "BlockStatement":
2215
- this.walkBlockStatement(statement);
2216
- break;
2217
- case "ClassDeclaration":
2218
- this.walkClassDeclaration(statement);
2219
- break;
2220
- case "DoWhileStatement":
2221
- this.walkDoWhileStatement(statement);
2222
- break;
2223
- case "ExportDefaultDeclaration":
2224
- this.walkExportDefaultDeclaration(statement);
2225
- break;
2226
- case "ExportNamedDeclaration":
2227
- this.walkExportNamedDeclaration(statement);
2228
- break;
2229
2382
  case "ExpressionStatement":
2230
2383
  this.walkExpressionStatement(statement);
2231
2384
  break;
2232
- case "ForInStatement":
2233
- this.walkForInStatement(statement);
2385
+ case "VariableDeclaration":
2386
+ this.walkVariableDeclaration(statement);
2234
2387
  break;
2235
- case "ForOfStatement":
2236
- this.walkForOfStatement(statement);
2388
+ case "ReturnStatement":
2389
+ this.walkReturnStatement(statement);
2237
2390
  break;
2238
- case "ForStatement":
2239
- this.walkForStatement(statement);
2391
+ case "IfStatement":
2392
+ this.walkIfStatement(statement);
2393
+ break;
2394
+ case "BlockStatement":
2395
+ this.walkBlockStatement(statement);
2240
2396
  break;
2241
2397
  case "FunctionDeclaration":
2242
2398
  this.walkFunctionDeclaration(statement);
2243
2399
  break;
2244
- case "IfStatement":
2245
- this.walkIfStatement(statement);
2246
- break;
2247
- case "LabeledStatement":
2248
- this.walkLabeledStatement(statement);
2400
+ case "ForStatement":
2401
+ this.walkForStatement(statement);
2249
2402
  break;
2250
- case "ReturnStatement":
2251
- this.walkReturnStatement(statement);
2403
+ case "TryStatement":
2404
+ this.walkTryStatement(statement);
2252
2405
  break;
2253
2406
  case "SwitchStatement":
2254
2407
  this.walkSwitchStatement(statement);
@@ -2256,15 +2409,30 @@ class JavascriptParser extends Parser {
2256
2409
  case "ThrowStatement":
2257
2410
  this.walkThrowStatement(statement);
2258
2411
  break;
2259
- case "TryStatement":
2260
- this.walkTryStatement(statement);
2261
- break;
2262
- case "VariableDeclaration":
2263
- this.walkVariableDeclaration(statement);
2264
- break;
2265
2412
  case "WhileStatement":
2266
2413
  this.walkWhileStatement(statement);
2267
2414
  break;
2415
+ case "ClassDeclaration":
2416
+ this.walkClassDeclaration(statement);
2417
+ break;
2418
+ case "ForInStatement":
2419
+ this.walkForInStatement(statement);
2420
+ break;
2421
+ case "ForOfStatement":
2422
+ this.walkForOfStatement(statement);
2423
+ break;
2424
+ case "DoWhileStatement":
2425
+ this.walkDoWhileStatement(statement);
2426
+ break;
2427
+ case "ExportNamedDeclaration":
2428
+ this.walkExportNamedDeclaration(statement);
2429
+ break;
2430
+ case "ExportDefaultDeclaration":
2431
+ this.walkExportDefaultDeclaration(statement);
2432
+ break;
2433
+ case "LabeledStatement":
2434
+ this.walkLabeledStatement(statement);
2435
+ break;
2268
2436
  case "WithStatement":
2269
2437
  this.walkWithStatement(statement);
2270
2438
  break;
@@ -2287,6 +2455,7 @@ class JavascriptParser extends Parser {
2287
2455
 
2288
2456
  // Real Statements
2289
2457
  /**
2458
+ * Pre walk block statement.
2290
2459
  * @param {BlockStatement} statement block statement
2291
2460
  */
2292
2461
  preWalkBlockStatement(statement) {
@@ -2294,6 +2463,7 @@ class JavascriptParser extends Parser {
2294
2463
  }
2295
2464
 
2296
2465
  /**
2466
+ * Walk block statement.
2297
2467
  * @param {BlockStatement | StaticBlock} statement block statement
2298
2468
  */
2299
2469
  walkBlockStatement(statement) {
@@ -2307,6 +2477,7 @@ class JavascriptParser extends Parser {
2307
2477
  }
2308
2478
 
2309
2479
  /**
2480
+ * Walk expression statement.
2310
2481
  * @param {ExpressionStatement} statement expression statement
2311
2482
  */
2312
2483
  walkExpressionStatement(statement) {
@@ -2314,6 +2485,7 @@ class JavascriptParser extends Parser {
2314
2485
  }
2315
2486
 
2316
2487
  /**
2488
+ * Pre walk if statement.
2317
2489
  * @param {IfStatement} statement if statement
2318
2490
  */
2319
2491
  preWalkIfStatement(statement) {
@@ -2324,27 +2496,47 @@ class JavascriptParser extends Parser {
2324
2496
  }
2325
2497
 
2326
2498
  /**
2499
+ * Walks a conditional branch with its guard frame (if any) pushed onto the
2500
+ * parser-state guard stack for the duration of the branch body.
2501
+ * @param {EXPECTED_OBJECT | undefined | null} frame guard frame, or falsy when the branch is unguarded
2502
+ * @param {() => void} walk branch walk
2503
+ * @returns {void}
2504
+ */
2505
+ walkGuardedBranch(frame, walk) {
2506
+ if (!frame) {
2507
+ walk();
2508
+ return;
2509
+ }
2510
+ const stack = this.state.guardStack || (this.state.guardStack = []);
2511
+ stack.push(frame);
2512
+ try {
2513
+ walk();
2514
+ } finally {
2515
+ stack.pop();
2516
+ }
2517
+ }
2518
+
2519
+ /**
2520
+ * Processes the provided statement.
2327
2521
  * @param {IfStatement} statement if statement
2328
2522
  */
2329
2523
  walkIfStatement(statement) {
2330
2524
  const result = this.hooks.statementIf.call(statement);
2331
2525
  if (result === undefined) {
2332
- const inGuard = this.hooks.collectGuards.call(statement.test);
2333
- if (inGuard) {
2334
- inGuard(() => {
2335
- this.walkExpression(statement.test);
2336
- this.walkNestedStatement(statement.consequent);
2337
- });
2338
- } else {
2339
- this.walkExpression(statement.test);
2340
- this.walkNestedStatement(statement.consequent);
2341
- }
2526
+ const guard = this.hooks.collectGuards.call(statement.test);
2527
+ this.walkExpression(statement.test);
2528
+ this.walkGuardedBranch(guard ? guard.consequent : undefined, () =>
2529
+ this.walkNestedStatement(statement.consequent)
2530
+ );
2342
2531
 
2343
2532
  const consequentTerminated = this.scope.terminated;
2344
2533
  this.scope.terminated = undefined;
2345
2534
 
2346
2535
  if (statement.alternate) {
2347
- this.walkNestedStatement(statement.alternate);
2536
+ const alternate = statement.alternate;
2537
+ this.walkGuardedBranch(guard ? guard.alternate : undefined, () =>
2538
+ this.walkNestedStatement(alternate)
2539
+ );
2348
2540
  }
2349
2541
 
2350
2542
  const alternateTerminated = this.scope.terminated;
@@ -2361,6 +2553,7 @@ class JavascriptParser extends Parser {
2361
2553
  }
2362
2554
 
2363
2555
  /**
2556
+ * Pre walk labeled statement.
2364
2557
  * @param {LabeledStatement} statement with statement
2365
2558
  */
2366
2559
  preWalkLabeledStatement(statement) {
@@ -2368,6 +2561,7 @@ class JavascriptParser extends Parser {
2368
2561
  }
2369
2562
 
2370
2563
  /**
2564
+ * Walk labeled statement.
2371
2565
  * @param {LabeledStatement} statement with statement
2372
2566
  */
2373
2567
  walkLabeledStatement(statement) {
@@ -2382,6 +2576,7 @@ class JavascriptParser extends Parser {
2382
2576
  }
2383
2577
 
2384
2578
  /**
2579
+ * Pre walk with statement.
2385
2580
  * @param {WithStatement} statement with statement
2386
2581
  */
2387
2582
  preWalkWithStatement(statement) {
@@ -2389,9 +2584,16 @@ class JavascriptParser extends Parser {
2389
2584
  }
2390
2585
 
2391
2586
  /**
2587
+ * Walk with statement.
2392
2588
  * @param {WithStatement} statement with statement
2393
2589
  */
2394
2590
  walkWithStatement(statement) {
2591
+ if (this._strictInModuleOutput) {
2592
+ this._reportStrictModeViolation(
2593
+ "`with` statements are not allowed",
2594
+ statement
2595
+ );
2596
+ }
2395
2597
  this.inBlockScope(() => {
2396
2598
  this.walkExpression(statement.object);
2397
2599
  this.walkNestedStatement(statement.body);
@@ -2399,6 +2601,7 @@ class JavascriptParser extends Parser {
2399
2601
  }
2400
2602
 
2401
2603
  /**
2604
+ * Pre walk switch statement.
2402
2605
  * @param {SwitchStatement} statement switch statement
2403
2606
  */
2404
2607
  preWalkSwitchStatement(statement) {
@@ -2406,6 +2609,7 @@ class JavascriptParser extends Parser {
2406
2609
  }
2407
2610
 
2408
2611
  /**
2612
+ * Walk switch statement.
2409
2613
  * @param {SwitchStatement} statement switch statement
2410
2614
  */
2411
2615
  walkSwitchStatement(statement) {
@@ -2414,6 +2618,7 @@ class JavascriptParser extends Parser {
2414
2618
  }
2415
2619
 
2416
2620
  /**
2621
+ * Walk terminating statement.
2417
2622
  * @param {ReturnStatement | ThrowStatement} statement return or throw statement
2418
2623
  */
2419
2624
  walkTerminatingStatement(statement) {
@@ -2429,6 +2634,7 @@ class JavascriptParser extends Parser {
2429
2634
  }
2430
2635
 
2431
2636
  /**
2637
+ * Walk return statement.
2432
2638
  * @param {ReturnStatement} statement return statement
2433
2639
  */
2434
2640
  walkReturnStatement(statement) {
@@ -2436,6 +2642,7 @@ class JavascriptParser extends Parser {
2436
2642
  }
2437
2643
 
2438
2644
  /**
2645
+ * Walk throw statement.
2439
2646
  * @param {ThrowStatement} statement return statement
2440
2647
  */
2441
2648
  walkThrowStatement(statement) {
@@ -2443,6 +2650,7 @@ class JavascriptParser extends Parser {
2443
2650
  }
2444
2651
 
2445
2652
  /**
2653
+ * Pre walk try statement.
2446
2654
  * @param {TryStatement} statement try statement
2447
2655
  */
2448
2656
  preWalkTryStatement(statement) {
@@ -2452,6 +2660,7 @@ class JavascriptParser extends Parser {
2452
2660
  }
2453
2661
 
2454
2662
  /**
2663
+ * Walk try statement.
2455
2664
  * @param {TryStatement} statement try statement
2456
2665
  */
2457
2666
  walkTryStatement(statement) {
@@ -2489,6 +2698,7 @@ class JavascriptParser extends Parser {
2489
2698
  }
2490
2699
 
2491
2700
  /**
2701
+ * Pre walk while statement.
2492
2702
  * @param {WhileStatement} statement while statement
2493
2703
  */
2494
2704
  preWalkWhileStatement(statement) {
@@ -2496,6 +2706,7 @@ class JavascriptParser extends Parser {
2496
2706
  }
2497
2707
 
2498
2708
  /**
2709
+ * Walk while statement.
2499
2710
  * @param {WhileStatement} statement while statement
2500
2711
  */
2501
2712
  walkWhileStatement(statement) {
@@ -2506,6 +2717,7 @@ class JavascriptParser extends Parser {
2506
2717
  }
2507
2718
 
2508
2719
  /**
2720
+ * Pre walk do while statement.
2509
2721
  * @param {DoWhileStatement} statement do while statement
2510
2722
  */
2511
2723
  preWalkDoWhileStatement(statement) {
@@ -2513,6 +2725,7 @@ class JavascriptParser extends Parser {
2513
2725
  }
2514
2726
 
2515
2727
  /**
2728
+ * Walk do while statement.
2516
2729
  * @param {DoWhileStatement} statement do while statement
2517
2730
  */
2518
2731
  walkDoWhileStatement(statement) {
@@ -2523,6 +2736,7 @@ class JavascriptParser extends Parser {
2523
2736
  }
2524
2737
 
2525
2738
  /**
2739
+ * Pre walk for statement.
2526
2740
  * @param {ForStatement} statement for statement
2527
2741
  */
2528
2742
  preWalkForStatement(statement) {
@@ -2533,6 +2747,7 @@ class JavascriptParser extends Parser {
2533
2747
  }
2534
2748
 
2535
2749
  /**
2750
+ * Walk for statement.
2536
2751
  * @param {ForStatement} statement for statement
2537
2752
  */
2538
2753
  walkForStatement(statement) {
@@ -2568,6 +2783,7 @@ class JavascriptParser extends Parser {
2568
2783
  }
2569
2784
 
2570
2785
  /**
2786
+ * Pre walk for in statement.
2571
2787
  * @param {ForInStatement} statement for statement
2572
2788
  */
2573
2789
  preWalkForInStatement(statement) {
@@ -2578,6 +2794,7 @@ class JavascriptParser extends Parser {
2578
2794
  }
2579
2795
 
2580
2796
  /**
2797
+ * Walk for in statement.
2581
2798
  * @param {ForInStatement} statement for statement
2582
2799
  */
2583
2800
  walkForInStatement(statement) {
@@ -2606,6 +2823,7 @@ class JavascriptParser extends Parser {
2606
2823
  }
2607
2824
 
2608
2825
  /**
2826
+ * Pre walk for of statement.
2609
2827
  * @param {ForOfStatement} statement statement
2610
2828
  */
2611
2829
  preWalkForOfStatement(statement) {
@@ -2619,6 +2837,7 @@ class JavascriptParser extends Parser {
2619
2837
  }
2620
2838
 
2621
2839
  /**
2840
+ * Walk for of statement.
2622
2841
  * @param {ForOfStatement} statement for statement
2623
2842
  */
2624
2843
  walkForOfStatement(statement) {
@@ -2647,6 +2866,7 @@ class JavascriptParser extends Parser {
2647
2866
  }
2648
2867
 
2649
2868
  /**
2869
+ * Pre walk function declaration.
2650
2870
  * @param {FunctionDeclaration | MaybeNamedFunctionDeclaration} statement function declaration
2651
2871
  */
2652
2872
  preWalkFunctionDeclaration(statement) {
@@ -2656,11 +2876,15 @@ class JavascriptParser extends Parser {
2656
2876
  }
2657
2877
 
2658
2878
  /**
2879
+ * Walk function declaration.
2659
2880
  * @param {FunctionDeclaration | MaybeNamedFunctionDeclaration} statement function declaration
2660
2881
  */
2661
2882
  walkFunctionDeclaration(statement) {
2662
2883
  const wasTopLevel = this.scope.topLevelScope;
2663
2884
  this.scope.topLevelScope = false;
2885
+ if (this._strictInModuleOutput) {
2886
+ this._checkStrictModeParams(statement.params);
2887
+ }
2664
2888
  this.inFunctionScope(true, statement.params, () => {
2665
2889
  for (const param of statement.params) {
2666
2890
  this.walkPattern(param);
@@ -2678,6 +2902,7 @@ class JavascriptParser extends Parser {
2678
2902
  }
2679
2903
 
2680
2904
  /**
2905
+ * Block pre walk expression statement.
2681
2906
  * @param {ExpressionStatement} statement expression statement
2682
2907
  */
2683
2908
  blockPreWalkExpressionStatement(statement) {
@@ -2689,6 +2914,7 @@ class JavascriptParser extends Parser {
2689
2914
  }
2690
2915
 
2691
2916
  /**
2917
+ * Pre walk assignment expression.
2692
2918
  * @param {AssignmentExpression} expression assignment expression
2693
2919
  */
2694
2920
  preWalkAssignmentExpression(expression) {
@@ -2696,6 +2922,7 @@ class JavascriptParser extends Parser {
2696
2922
  }
2697
2923
 
2698
2924
  /**
2925
+ * Enter destructuring assignment.
2699
2926
  * @param {Pattern} pattern pattern
2700
2927
  * @param {Expression} expression assignment expression
2701
2928
  * @returns {Expression | undefined} destructuring expression
@@ -2737,6 +2964,7 @@ class JavascriptParser extends Parser {
2737
2964
  }
2738
2965
 
2739
2966
  /**
2967
+ * Module pre walk import declaration.
2740
2968
  * @param {ImportDeclaration} statement statement
2741
2969
  */
2742
2970
  modulePreWalkImportDeclaration(statement) {
@@ -2782,6 +3010,7 @@ class JavascriptParser extends Parser {
2782
3010
  }
2783
3011
 
2784
3012
  /**
3013
+ * Processes the provided declaration.
2785
3014
  * @param {Declaration} declaration declaration
2786
3015
  * @param {OnIdent} onIdent on ident callback
2787
3016
  */
@@ -2807,6 +3036,7 @@ class JavascriptParser extends Parser {
2807
3036
  }
2808
3037
 
2809
3038
  /**
3039
+ * Module pre walk export named declaration.
2810
3040
  * @param {ExportNamedDeclaration} statement statement
2811
3041
  */
2812
3042
  modulePreWalkExportNamedDeclaration(statement) {
@@ -2847,6 +3077,7 @@ class JavascriptParser extends Parser {
2847
3077
  }
2848
3078
 
2849
3079
  /**
3080
+ * Block pre walk export named declaration.
2850
3081
  * @param {ExportNamedDeclaration} statement statement
2851
3082
  */
2852
3083
  blockPreWalkExportNamedDeclaration(statement) {
@@ -2898,6 +3129,7 @@ class JavascriptParser extends Parser {
2898
3129
  }
2899
3130
 
2900
3131
  /**
3132
+ * Walk export named declaration.
2901
3133
  * @param {ExportNamedDeclaration} statement the statement
2902
3134
  */
2903
3135
  walkExportNamedDeclaration(statement) {
@@ -2907,6 +3139,7 @@ class JavascriptParser extends Parser {
2907
3139
  }
2908
3140
 
2909
3141
  /**
3142
+ * Block pre walk export default declaration.
2910
3143
  * @param {ExportDefaultDeclaration} statement statement
2911
3144
  */
2912
3145
  blockPreWalkExportDefaultDeclaration(statement) {
@@ -2942,6 +3175,7 @@ class JavascriptParser extends Parser {
2942
3175
  }
2943
3176
 
2944
3177
  /**
3178
+ * Walk export default declaration.
2945
3179
  * @param {ExportDefaultDeclaration} statement statement
2946
3180
  */
2947
3181
  walkExportDefaultDeclaration(statement) {
@@ -2976,6 +3210,7 @@ class JavascriptParser extends Parser {
2976
3210
  }
2977
3211
 
2978
3212
  /**
3213
+ * Module pre walk export all declaration.
2979
3214
  * @param {ExportAllDeclaration} statement statement
2980
3215
  */
2981
3216
  modulePreWalkExportAllDeclaration(statement) {
@@ -2991,6 +3226,7 @@ class JavascriptParser extends Parser {
2991
3226
  }
2992
3227
 
2993
3228
  /**
3229
+ * Pre walk variable declaration.
2994
3230
  * @param {VariableDeclaration} statement variable declaration
2995
3231
  */
2996
3232
  preWalkVariableDeclaration(statement) {
@@ -2999,6 +3235,7 @@ class JavascriptParser extends Parser {
2999
3235
  }
3000
3236
 
3001
3237
  /**
3238
+ * Block pre walk variable declaration.
3002
3239
  * @param {VariableDeclaration} statement variable declaration
3003
3240
  */
3004
3241
  blockPreWalkVariableDeclaration(statement) {
@@ -3014,32 +3251,53 @@ class JavascriptParser extends Parser {
3014
3251
  }
3015
3252
 
3016
3253
  /**
3254
+ * Pre walk variable declaration.
3017
3255
  * @param {VariableDeclaration} statement variable declaration
3018
3256
  * @param {HookMap<SyncBailHook<[Identifier], boolean | void>>} hookMap map of hooks
3019
3257
  */
3020
3258
  _preWalkVariableDeclaration(statement, hookMap) {
3259
+ /** @type {OnIdent | undefined} */
3260
+ let onIdent;
3021
3261
  for (const declarator of statement.declarations) {
3022
- switch (declarator.type) {
3023
- case "VariableDeclarator": {
3024
- this.preWalkVariableDeclarator(declarator);
3025
- if (!this.hooks.preDeclarator.call(declarator, statement)) {
3026
- this.enterPattern(declarator.id, (name, ident) => {
3027
- let hook = hookMap.get(name);
3028
- if (hook === undefined || !hook.call(ident)) {
3029
- hook = this.hooks.varDeclaration.get(name);
3030
- if (hook === undefined || !hook.call(ident)) {
3031
- this.defineVariable(name);
3032
- }
3033
- }
3034
- });
3035
- }
3036
- break;
3262
+ if (declarator.type !== "VariableDeclarator") continue;
3263
+ this.preWalkVariableDeclarator(declarator);
3264
+ if (this.hooks.preDeclarator.call(declarator, statement)) continue;
3265
+ const id = declarator.id;
3266
+ if (id.type === "Identifier") {
3267
+ // fast path: plain `const x =` skips the enterPattern dispatch and
3268
+ // the per-declaration onIdent closure (only patterns need it)
3269
+ if (!this.callHooksForName(this.hooks.pattern, id.name, id)) {
3270
+ this._defineVariableForDeclaration(id.name, id, hookMap);
3271
+ }
3272
+ } else {
3273
+ if (onIdent === undefined) {
3274
+ onIdent = (name, ident) =>
3275
+ this._defineVariableForDeclaration(name, ident, hookMap);
3037
3276
  }
3277
+ this.enterPattern(id, onIdent);
3278
+ }
3279
+ }
3280
+ }
3281
+
3282
+ /**
3283
+ * Defines a declared variable unless a declaration hook handles it.
3284
+ * @param {string} name variable name
3285
+ * @param {Identifier} ident identifier node
3286
+ * @param {HookMap<SyncBailHook<[Identifier], boolean | void>>} hookMap kind-specific declaration hooks
3287
+ * @returns {void}
3288
+ */
3289
+ _defineVariableForDeclaration(name, ident, hookMap) {
3290
+ let hook = hookMap.get(name);
3291
+ if (hook === undefined || !hook.call(ident)) {
3292
+ hook = this.hooks.varDeclaration.get(name);
3293
+ if (hook === undefined || !hook.call(ident)) {
3294
+ this.defineVariable(name);
3038
3295
  }
3039
3296
  }
3040
3297
  }
3041
3298
 
3042
3299
  /**
3300
+ * Pre walk object pattern.
3043
3301
  * @param {ObjectPattern} objectPattern object pattern
3044
3302
  * @returns {DestructuringAssignmentProperties | undefined} set of names or undefined if not all keys are identifiers
3045
3303
  */
@@ -3071,7 +3329,6 @@ class JavascriptParser extends Parser {
3071
3329
  props.add({
3072
3330
  id: key.name,
3073
3331
  range: /** @type {Range} */ (key.range),
3074
- loc: /** @type {SourceLocation} */ (key.loc),
3075
3332
  pattern,
3076
3333
  shorthand: this.scope.inShorthand
3077
3334
  });
@@ -3088,7 +3345,6 @@ class JavascriptParser extends Parser {
3088
3345
  props.add({
3089
3346
  id: str,
3090
3347
  range: /** @type {Range} */ (key.range),
3091
- loc: /** @type {SourceLocation} */ (key.loc),
3092
3348
  pattern,
3093
3349
  shorthand: this.scope.inShorthand
3094
3350
  });
@@ -3104,6 +3360,7 @@ class JavascriptParser extends Parser {
3104
3360
  }
3105
3361
 
3106
3362
  /**
3363
+ * Pre walk array pattern.
3107
3364
  * @param {ArrayPattern} arrayPattern array pattern
3108
3365
  * @returns {Set<DestructuringAssignmentProperty> | undefined} set of names or undefined if not all keys are identifiers
3109
3366
  */
@@ -3124,7 +3381,6 @@ class JavascriptParser extends Parser {
3124
3381
  props.add({
3125
3382
  id: `${i}`,
3126
3383
  range: /** @type {Range} */ (element.range),
3127
- loc: /** @type {SourceLocation} */ (element.loc),
3128
3384
  pattern,
3129
3385
  shorthand: false
3130
3386
  });
@@ -3134,6 +3390,7 @@ class JavascriptParser extends Parser {
3134
3390
  }
3135
3391
 
3136
3392
  /**
3393
+ * Pre walk variable declarator.
3137
3394
  * @param {VariableDeclarator} declarator variable declarator
3138
3395
  */
3139
3396
  preWalkVariableDeclarator(declarator) {
@@ -3143,6 +3400,7 @@ class JavascriptParser extends Parser {
3143
3400
  }
3144
3401
 
3145
3402
  /**
3403
+ * Walk variable declaration.
3146
3404
  * @param {VariableDeclaration} statement variable declaration
3147
3405
  */
3148
3406
  walkVariableDeclaration(statement) {
@@ -3179,6 +3437,7 @@ class JavascriptParser extends Parser {
3179
3437
  }
3180
3438
 
3181
3439
  /**
3440
+ * Block pre walk class declaration.
3182
3441
  * @param {ClassDeclaration | MaybeNamedClassDeclaration} statement class declaration
3183
3442
  */
3184
3443
  blockPreWalkClassDeclaration(statement) {
@@ -3188,6 +3447,7 @@ class JavascriptParser extends Parser {
3188
3447
  }
3189
3448
 
3190
3449
  /**
3450
+ * Walk class declaration.
3191
3451
  * @param {ClassDeclaration | MaybeNamedClassDeclaration} statement class declaration
3192
3452
  */
3193
3453
  walkClassDeclaration(statement) {
@@ -3195,6 +3455,7 @@ class JavascriptParser extends Parser {
3195
3455
  }
3196
3456
 
3197
3457
  /**
3458
+ * Pre walk switch cases.
3198
3459
  * @param {SwitchCase[]} switchCases switch statement
3199
3460
  */
3200
3461
  preWalkSwitchCases(switchCases) {
@@ -3205,6 +3466,7 @@ class JavascriptParser extends Parser {
3205
3466
  }
3206
3467
 
3207
3468
  /**
3469
+ * Processes the provided switch case.
3208
3470
  * @param {SwitchCase[]} switchCases switch statement
3209
3471
  */
3210
3472
  walkSwitchCases(switchCases) {
@@ -3245,6 +3507,7 @@ class JavascriptParser extends Parser {
3245
3507
  }
3246
3508
 
3247
3509
  /**
3510
+ * Pre walk catch clause.
3248
3511
  * @param {CatchClause} catchClause catch clause
3249
3512
  */
3250
3513
  preWalkCatchClause(catchClause) {
@@ -3252,6 +3515,7 @@ class JavascriptParser extends Parser {
3252
3515
  }
3253
3516
 
3254
3517
  /**
3518
+ * Processes the provided catch clause.
3255
3519
  * @param {CatchClause} catchClause catch clause
3256
3520
  */
3257
3521
  walkCatchClause(catchClause) {
@@ -3271,11 +3535,18 @@ class JavascriptParser extends Parser {
3271
3535
  }
3272
3536
 
3273
3537
  /**
3538
+ * Processes the provided pattern.
3274
3539
  * @param {Pattern} pattern pattern
3275
3540
  */
3276
3541
  walkPattern(pattern) {
3277
3542
  switch (pattern.type) {
3278
- case "ArrayPattern":
3543
+ // plain identifier bindings are the common case and walk nothing
3544
+ case "Identifier":
3545
+ break;
3546
+ case "ObjectPattern":
3547
+ this.walkObjectPattern(pattern);
3548
+ break;
3549
+ case "ArrayPattern":
3279
3550
  this.walkArrayPattern(pattern);
3280
3551
  break;
3281
3552
  case "AssignmentPattern":
@@ -3284,9 +3555,6 @@ class JavascriptParser extends Parser {
3284
3555
  case "MemberExpression":
3285
3556
  this.walkMemberExpression(pattern);
3286
3557
  break;
3287
- case "ObjectPattern":
3288
- this.walkObjectPattern(pattern);
3289
- break;
3290
3558
  case "RestElement":
3291
3559
  this.walkRestElement(pattern);
3292
3560
  break;
@@ -3294,6 +3562,7 @@ class JavascriptParser extends Parser {
3294
3562
  }
3295
3563
 
3296
3564
  /**
3565
+ * Walk assignment pattern.
3297
3566
  * @param {AssignmentPattern} pattern assignment pattern
3298
3567
  */
3299
3568
  walkAssignmentPattern(pattern) {
@@ -3302,6 +3571,7 @@ class JavascriptParser extends Parser {
3302
3571
  }
3303
3572
 
3304
3573
  /**
3574
+ * Walk object pattern.
3305
3575
  * @param {ObjectPattern} pattern pattern
3306
3576
  */
3307
3577
  walkObjectPattern(pattern) {
@@ -3318,6 +3588,7 @@ class JavascriptParser extends Parser {
3318
3588
  }
3319
3589
 
3320
3590
  /**
3591
+ * Walk array pattern.
3321
3592
  * @param {ArrayPattern} pattern array pattern
3322
3593
  */
3323
3594
  walkArrayPattern(pattern) {
@@ -3328,6 +3599,7 @@ class JavascriptParser extends Parser {
3328
3599
  }
3329
3600
 
3330
3601
  /**
3602
+ * Processes the provided pattern.
3331
3603
  * @param {RestElement} pattern rest element
3332
3604
  */
3333
3605
  walkRestElement(pattern) {
@@ -3335,10 +3607,12 @@ class JavascriptParser extends Parser {
3335
3607
  }
3336
3608
 
3337
3609
  /**
3610
+ * Processes the provided expression.
3338
3611
  * @param {(Expression | SpreadElement | null)[]} expressions expressions
3339
3612
  */
3340
3613
  walkExpressions(expressions) {
3341
- for (const expression of expressions) {
3614
+ for (let i = 0, len = expressions.length; i < len; i++) {
3615
+ const expression = expressions[i];
3342
3616
  if (expression) {
3343
3617
  this.walkExpression(expression);
3344
3618
  }
@@ -3346,81 +3620,90 @@ class JavascriptParser extends Parser {
3346
3620
  }
3347
3621
 
3348
3622
  /**
3623
+ * Processes the provided expression.
3349
3624
  * @param {Expression | SpreadElement | PrivateIdentifier | Super} expression expression
3350
3625
  */
3351
3626
  walkExpression(expression) {
3627
+ // cases ordered by measured node frequency (identifiers are ~40% of all
3628
+ // expressions) — V8 compiles this to sequential compares, so hot types
3629
+ // must come first
3352
3630
  switch (expression.type) {
3353
- case "ArrayExpression":
3354
- this.walkArrayExpression(expression);
3631
+ case "Identifier":
3632
+ this.walkIdentifier(expression);
3355
3633
  break;
3356
- case "ArrowFunctionExpression":
3357
- this.walkArrowFunctionExpression(expression);
3634
+ case "MemberExpression":
3635
+ this.walkMemberExpression(expression);
3358
3636
  break;
3359
- case "AssignmentExpression":
3360
- this.walkAssignmentExpression(expression);
3637
+ case "Literal":
3638
+ if (this._strictInModuleOutput) {
3639
+ this._checkStrictModeLiteral(expression);
3640
+ }
3361
3641
  break;
3362
- case "AwaitExpression":
3363
- this.walkAwaitExpression(expression);
3642
+ case "CallExpression":
3643
+ this.walkCallExpression(expression);
3364
3644
  break;
3365
3645
  case "BinaryExpression":
3366
3646
  this.walkBinaryExpression(expression);
3367
3647
  break;
3368
- case "CallExpression":
3369
- this.walkCallExpression(expression);
3370
- break;
3371
- case "ChainExpression":
3372
- this.walkChainExpression(expression);
3648
+ case "AssignmentExpression":
3649
+ this.walkAssignmentExpression(expression);
3373
3650
  break;
3374
- case "ClassExpression":
3375
- this.walkClassExpression(expression);
3651
+ case "UnaryExpression":
3652
+ this.walkUnaryExpression(expression);
3376
3653
  break;
3377
- case "ConditionalExpression":
3378
- this.walkConditionalExpression(expression);
3654
+ case "LogicalExpression":
3655
+ this.walkLogicalExpression(expression);
3379
3656
  break;
3380
- case "FunctionExpression":
3381
- this.walkFunctionExpression(expression);
3657
+ case "ArrowFunctionExpression":
3658
+ this.walkArrowFunctionExpression(expression);
3382
3659
  break;
3383
- case "Identifier":
3384
- this.walkIdentifier(expression);
3660
+ case "ThisExpression":
3661
+ this.walkThisExpression(expression);
3385
3662
  break;
3386
- case "ImportExpression":
3387
- this.walkImportExpression(expression);
3663
+ case "ConditionalExpression":
3664
+ this.walkConditionalExpression(expression);
3388
3665
  break;
3389
- case "LogicalExpression":
3390
- this.walkLogicalExpression(expression);
3666
+ case "ArrayExpression":
3667
+ this.walkArrayExpression(expression);
3391
3668
  break;
3392
- case "MetaProperty":
3393
- this.walkMetaProperty(expression);
3669
+ case "ObjectExpression":
3670
+ this.walkObjectExpression(expression);
3394
3671
  break;
3395
- case "MemberExpression":
3396
- this.walkMemberExpression(expression);
3672
+ case "FunctionExpression":
3673
+ this.walkFunctionExpression(expression);
3397
3674
  break;
3398
3675
  case "NewExpression":
3399
3676
  this.walkNewExpression(expression);
3400
3677
  break;
3401
- case "ObjectExpression":
3402
- this.walkObjectExpression(expression);
3678
+ case "TemplateLiteral":
3679
+ this.walkTemplateLiteral(expression);
3680
+ break;
3681
+ case "SpreadElement":
3682
+ this.walkSpreadElement(expression);
3403
3683
  break;
3404
3684
  case "SequenceExpression":
3405
3685
  this.walkSequenceExpression(expression);
3406
3686
  break;
3407
- case "SpreadElement":
3408
- this.walkSpreadElement(expression);
3687
+ case "UpdateExpression":
3688
+ this.walkUpdateExpression(expression);
3409
3689
  break;
3410
- case "TaggedTemplateExpression":
3411
- this.walkTaggedTemplateExpression(expression);
3690
+ case "AwaitExpression":
3691
+ this.walkAwaitExpression(expression);
3412
3692
  break;
3413
- case "TemplateLiteral":
3414
- this.walkTemplateLiteral(expression);
3693
+ case "ChainExpression":
3694
+ this.walkChainExpression(expression);
3415
3695
  break;
3416
- case "ThisExpression":
3417
- this.walkThisExpression(expression);
3696
+ case "ClassExpression":
3697
+ this.walkClassExpression(expression);
3418
3698
  break;
3419
- case "UnaryExpression":
3420
- this.walkUnaryExpression(expression);
3699
+ case "ImportExpression":
3700
+ this.walkImportExpression(expression);
3421
3701
  break;
3422
- case "UpdateExpression":
3423
- this.walkUpdateExpression(expression);
3702
+ case "MetaProperty":
3703
+ this.walkMetaProperty(expression);
3704
+ break;
3705
+ case "TaggedTemplateExpression":
3706
+ this.walkTaggedTemplateExpression(expression);
3424
3707
  break;
3425
3708
  case "YieldExpression":
3426
3709
  this.walkYieldExpression(expression);
@@ -3429,6 +3712,36 @@ class JavascriptParser extends Parser {
3429
3712
  }
3430
3713
 
3431
3714
  /**
3715
+ * Reports octal number literals (`0777`) and octal string escapes (`"\47"`),
3716
+ * both SyntaxErrors in strict-mode ESM output.
3717
+ * @param {Literal} expression literal
3718
+ */
3719
+ _checkStrictModeLiteral(expression) {
3720
+ const raw = /** @type {string | undefined} */ (expression.raw);
3721
+ if (raw === undefined) return;
3722
+ if (typeof expression.value === "number") {
3723
+ // Legacy octal (`0777`) or non-octal decimal (`08`) integer literal.
3724
+ if (
3725
+ raw.length > 1 &&
3726
+ raw.charCodeAt(0) === 48 &&
3727
+ raw.charCodeAt(1) >= 48 &&
3728
+ raw.charCodeAt(1) <= 57
3729
+ ) {
3730
+ this._reportStrictModeViolation(
3731
+ "Octal literals are not allowed",
3732
+ expression
3733
+ );
3734
+ }
3735
+ } else if (typeof expression.value === "string" && hasOctalEscape(raw)) {
3736
+ this._reportStrictModeViolation(
3737
+ "Octal escape sequences are not allowed",
3738
+ expression
3739
+ );
3740
+ }
3741
+ }
3742
+
3743
+ /**
3744
+ * Walk await expression.
3432
3745
  * @param {AwaitExpression} expression await expression
3433
3746
  */
3434
3747
  walkAwaitExpression(expression) {
@@ -3439,6 +3752,7 @@ class JavascriptParser extends Parser {
3439
3752
  }
3440
3753
 
3441
3754
  /**
3755
+ * Walk array expression.
3442
3756
  * @param {ArrayExpression} expression array expression
3443
3757
  */
3444
3758
  walkArrayExpression(expression) {
@@ -3448,6 +3762,7 @@ class JavascriptParser extends Parser {
3448
3762
  }
3449
3763
 
3450
3764
  /**
3765
+ * Walk spread element.
3451
3766
  * @param {SpreadElement} expression spread element
3452
3767
  */
3453
3768
  walkSpreadElement(expression) {
@@ -3457,6 +3772,7 @@ class JavascriptParser extends Parser {
3457
3772
  }
3458
3773
 
3459
3774
  /**
3775
+ * Walk object expression.
3460
3776
  * @param {ObjectExpression} expression object expression
3461
3777
  */
3462
3778
  walkObjectExpression(expression) {
@@ -3471,6 +3787,7 @@ class JavascriptParser extends Parser {
3471
3787
  }
3472
3788
 
3473
3789
  /**
3790
+ * Processes the provided prop.
3474
3791
  * @param {Property | SpreadElement} prop property or spread element
3475
3792
  */
3476
3793
  walkProperty(prop) {
@@ -3494,18 +3811,21 @@ class JavascriptParser extends Parser {
3494
3811
  }
3495
3812
 
3496
3813
  /**
3814
+ * Walk function expression.
3497
3815
  * @param {FunctionExpression} expression arrow function expression
3498
3816
  */
3499
3817
  walkFunctionExpression(expression) {
3500
3818
  const wasTopLevel = this.scope.topLevelScope;
3501
3819
  this.scope.topLevelScope = false;
3502
- const scopeParams = [...expression.params];
3503
-
3504
- // Add function name in scope for recursive calls
3505
- if (expression.id) {
3506
- scopeParams.push(expression.id);
3820
+ // Only copy params when the function name must be added (recursive calls);
3821
+ // inFunctionScope reads params without mutating, like arrow functions.
3822
+ const scopeParams = expression.id
3823
+ ? [...expression.params, expression.id]
3824
+ : expression.params;
3825
+
3826
+ if (this._strictInModuleOutput) {
3827
+ this._checkStrictModeParams(expression.params);
3507
3828
  }
3508
-
3509
3829
  this.inFunctionScope(true, scopeParams, () => {
3510
3830
  for (const param of expression.params) {
3511
3831
  this.walkPattern(param);
@@ -3523,11 +3843,15 @@ class JavascriptParser extends Parser {
3523
3843
  }
3524
3844
 
3525
3845
  /**
3846
+ * Walk arrow function expression.
3526
3847
  * @param {ArrowFunctionExpression} expression arrow function expression
3527
3848
  */
3528
3849
  walkArrowFunctionExpression(expression) {
3529
3850
  const wasTopLevel = this.scope.topLevelScope;
3530
3851
  this.scope.topLevelScope = wasTopLevel ? "arrow" : false;
3852
+ if (this._strictInModuleOutput) {
3853
+ this._checkStrictModeParams(expression.params);
3854
+ }
3531
3855
  this.inFunctionScope(false, expression.params, () => {
3532
3856
  for (const param of expression.params) {
3533
3857
  this.walkPattern(param);
@@ -3546,6 +3870,7 @@ class JavascriptParser extends Parser {
3546
3870
  }
3547
3871
 
3548
3872
  /**
3873
+ * Walk sequence expression.
3549
3874
  * @param {SequenceExpression} expression the sequence
3550
3875
  */
3551
3876
  walkSequenceExpression(expression) {
@@ -3584,13 +3909,90 @@ class JavascriptParser extends Parser {
3584
3909
  }
3585
3910
 
3586
3911
  /**
3912
+ * Walk update expression.
3587
3913
  * @param {UpdateExpression} expression the update expression
3588
3914
  */
3589
3915
  walkUpdateExpression(expression) {
3916
+ if (
3917
+ this._strictInModuleOutput &&
3918
+ expression.argument.type === "Identifier"
3919
+ ) {
3920
+ this._checkStrictModeAssignTarget(expression.argument.name, expression);
3921
+ }
3590
3922
  this.walkExpression(expression.argument);
3591
3923
  }
3592
3924
 
3593
3925
  /**
3926
+ * Reports `arguments.callee` / `arguments.caller` — both throw a TypeError
3927
+ * once the module runs in strict-mode ESM output.
3928
+ * @param {string} name accessed member name
3929
+ * @param {Expression} node node to report the violation at
3930
+ */
3931
+ _checkStrictModeArgumentsMember(name, node) {
3932
+ if ((name === "callee" || name === "caller") && !this.scope.isStrict) {
3933
+ this._reportStrictModeViolation(
3934
+ `Accessing "arguments.${name}" is not allowed`,
3935
+ node
3936
+ );
3937
+ }
3938
+ }
3939
+
3940
+ /**
3941
+ * Reports an assignment or update target that breaks in strict-mode ESM
3942
+ * output: `eval` / `arguments` are a SyntaxError, the read-only globals
3943
+ * (`undefined`, `NaN`, `Infinity`) a TypeError instead of a silent no-op.
3944
+ * @param {string} name target identifier name
3945
+ * @param {AssignmentExpression | UpdateExpression} node node to report the violation at
3946
+ */
3947
+ _checkStrictModeAssignTarget(name, node) {
3948
+ if (name === "eval" || name === "arguments") {
3949
+ this._reportStrictModeViolation(
3950
+ `Assigning to "${name}" is not allowed`,
3951
+ node
3952
+ );
3953
+ } else if (
3954
+ (name === "undefined" || name === "NaN" || name === "Infinity") &&
3955
+ !this.scope.isStrict &&
3956
+ !this.isVariableDefined(name)
3957
+ ) {
3958
+ this._reportStrictModeViolation(
3959
+ `Assigning to the read-only global "${name}" is not allowed`,
3960
+ node
3961
+ );
3962
+ }
3963
+ }
3964
+
3965
+ /**
3966
+ * Reports strict-mode-only errors in a function's parameter list: a duplicate
3967
+ * simple parameter, or a parameter named `eval` / `arguments`.
3968
+ * @param {(import("estree").Pattern)[]} params function parameters
3969
+ */
3970
+ _checkStrictModeParams(params) {
3971
+ /** @type {Set<string> | undefined} */
3972
+ let seen;
3973
+ for (const param of params) {
3974
+ if (param.type !== "Identifier") continue;
3975
+ const name = param.name;
3976
+ if (name === "eval" || name === "arguments") {
3977
+ this._reportStrictModeViolation(
3978
+ `"${name}" is not allowed as a parameter name`,
3979
+ param
3980
+ );
3981
+ }
3982
+ if (seen === undefined) seen = new Set();
3983
+ if (seen.has(name)) {
3984
+ this._reportStrictModeViolation(
3985
+ `Duplicate parameter name "${name}" is not allowed`,
3986
+ param
3987
+ );
3988
+ } else {
3989
+ seen.add(name);
3990
+ }
3991
+ }
3992
+ }
3993
+
3994
+ /**
3995
+ * Walk unary expression.
3594
3996
  * @param {UnaryExpression} expression the unary expression
3595
3997
  */
3596
3998
  walkUnaryExpression(expression) {
@@ -3609,11 +4011,41 @@ class JavascriptParser extends Parser {
3609
4011
  );
3610
4012
  if (result === true) return;
3611
4013
  }
4014
+ } else if (
4015
+ this._strictInModuleOutput &&
4016
+ expression.operator === "delete" &&
4017
+ expression.argument.type === "Identifier"
4018
+ ) {
4019
+ this._reportStrictModeViolation(
4020
+ `Deleting the unqualified identifier "${expression.argument.name}" is not allowed`,
4021
+ expression
4022
+ );
3612
4023
  }
3613
4024
  this.walkExpression(expression.argument);
3614
4025
  }
3615
4026
 
3616
4027
  /**
4028
+ * Reports a construct that a loose script allows but that breaks once the
4029
+ * module is emitted as strict-mode ESM output. Severity comes from the
4030
+ * `strictModeViolations` parser option (`false` disables the checks upfront).
4031
+ * The location is computed here, on the rare violation path only.
4032
+ * @param {string} reason what is not allowed
4033
+ * @param {Statement | Expression | Identifier} node node to report the violation at
4034
+ */
4035
+ _reportStrictModeViolation(reason, node) {
4036
+ const diagnostic = new WebpackError(
4037
+ `${reason}. The output is an ES module, which runs in strict mode.`
4038
+ );
4039
+ diagnostic.loc = this.getLocation(node);
4040
+ if (this.options.strictModeViolations === "error") {
4041
+ this.state.module.addError(diagnostic);
4042
+ } else {
4043
+ this.state.module.addWarning(diagnostic);
4044
+ }
4045
+ }
4046
+
4047
+ /**
4048
+ * Walk left right expression.
3617
4049
  * @param {LogicalExpression | BinaryExpression} expression the expression
3618
4050
  */
3619
4051
  walkLeftRightExpression(expression) {
@@ -3622,6 +4054,7 @@ class JavascriptParser extends Parser {
3622
4054
  }
3623
4055
 
3624
4056
  /**
4057
+ * Walk binary expression.
3625
4058
  * @param {BinaryExpression} expression the binary expression
3626
4059
  */
3627
4060
  walkBinaryExpression(expression) {
@@ -3631,6 +4064,7 @@ class JavascriptParser extends Parser {
3631
4064
  }
3632
4065
 
3633
4066
  /**
4067
+ * Walk logical expression.
3634
4068
  * @param {LogicalExpression} expression the logical expression
3635
4069
  */
3636
4070
  walkLogicalExpression(expression) {
@@ -3643,10 +4077,14 @@ class JavascriptParser extends Parser {
3643
4077
  }
3644
4078
 
3645
4079
  /**
4080
+ * Walk assignment expression.
3646
4081
  * @param {AssignmentExpression} expression assignment expression
3647
4082
  */
3648
4083
  walkAssignmentExpression(expression) {
3649
4084
  if (expression.left.type === "Identifier") {
4085
+ if (this._strictInModuleOutput) {
4086
+ this._checkStrictModeAssignTarget(expression.left.name, expression);
4087
+ }
3650
4088
  const renameIdentifier = this.getRenameIdentifier(expression.right);
3651
4089
  if (
3652
4090
  renameIdentifier &&
@@ -3718,24 +4156,23 @@ class JavascriptParser extends Parser {
3718
4156
  }
3719
4157
 
3720
4158
  /**
4159
+ * Walk conditional expression.
3721
4160
  * @param {ConditionalExpression} expression conditional expression
3722
4161
  */
3723
4162
  walkConditionalExpression(expression) {
3724
4163
  const result = this.hooks.expressionConditionalOperator.call(expression);
3725
4164
  if (result === undefined) {
3726
- const inGuard = this.hooks.collectGuards.call(expression.test);
3727
- if (inGuard) {
3728
- inGuard(() => {
3729
- this.walkExpression(expression.test);
3730
- this.walkExpression(expression.consequent);
3731
- });
3732
- } else {
3733
- this.walkExpression(expression.test);
3734
- this.walkExpression(expression.consequent);
3735
- }
4165
+ const guard = this.hooks.collectGuards.call(expression.test);
4166
+ this.walkExpression(expression.test);
4167
+ this.walkGuardedBranch(guard ? guard.consequent : undefined, () =>
4168
+ this.walkExpression(expression.consequent)
4169
+ );
3736
4170
 
3737
4171
  if (expression.alternate) {
3738
- this.walkExpression(expression.alternate);
4172
+ const alternate = expression.alternate;
4173
+ this.walkGuardedBranch(guard ? guard.alternate : undefined, () =>
4174
+ this.walkExpression(alternate)
4175
+ );
3739
4176
  }
3740
4177
  } else if (result) {
3741
4178
  this.walkExpression(expression.consequent);
@@ -3745,6 +4182,7 @@ class JavascriptParser extends Parser {
3745
4182
  }
3746
4183
 
3747
4184
  /**
4185
+ * Walk new expression.
3748
4186
  * @param {NewExpression} expression new expression
3749
4187
  */
3750
4188
  walkNewExpression(expression) {
@@ -3761,6 +4199,7 @@ class JavascriptParser extends Parser {
3761
4199
  }
3762
4200
 
3763
4201
  /**
4202
+ * Walk yield expression.
3764
4203
  * @param {YieldExpression} expression yield expression
3765
4204
  */
3766
4205
  walkYieldExpression(expression) {
@@ -3770,6 +4209,7 @@ class JavascriptParser extends Parser {
3770
4209
  }
3771
4210
 
3772
4211
  /**
4212
+ * Walk template literal.
3773
4213
  * @param {TemplateLiteral} expression template literal
3774
4214
  */
3775
4215
  walkTemplateLiteral(expression) {
@@ -3779,6 +4219,7 @@ class JavascriptParser extends Parser {
3779
4219
  }
3780
4220
 
3781
4221
  /**
4222
+ * Walk tagged template expression.
3782
4223
  * @param {TaggedTemplateExpression} expression tagged template expression
3783
4224
  */
3784
4225
  walkTaggedTemplateExpression(expression) {
@@ -3793,6 +4234,7 @@ class JavascriptParser extends Parser {
3793
4234
  }
3794
4235
 
3795
4236
  /**
4237
+ * Walk class expression.
3796
4238
  * @param {ClassExpression} expression the class expression
3797
4239
  */
3798
4240
  walkClassExpression(expression) {
@@ -3800,6 +4242,7 @@ class JavascriptParser extends Parser {
3800
4242
  }
3801
4243
 
3802
4244
  /**
4245
+ * Walk chain expression.
3803
4246
  * @param {ChainExpression} expression expression
3804
4247
  */
3805
4248
  walkChainExpression(expression) {
@@ -3815,6 +4258,7 @@ class JavascriptParser extends Parser {
3815
4258
  }
3816
4259
 
3817
4260
  /**
4261
+ * Processes the provided function expression.
3818
4262
  * @private
3819
4263
  * @param {FunctionExpression | ArrowFunctionExpression} functionExpression function expression
3820
4264
  * @param {(Expression | SpreadElement)[]} options options
@@ -3822,6 +4266,7 @@ class JavascriptParser extends Parser {
3822
4266
  */
3823
4267
  _walkIIFE(functionExpression, options, currentThis) {
3824
4268
  /**
4269
+ * Returns var info.
3825
4270
  * @param {Expression | SpreadElement} argOrThis arg or this
3826
4271
  * @returns {string | VariableInfo | undefined} var info
3827
4272
  */
@@ -3890,6 +4335,7 @@ class JavascriptParser extends Parser {
3890
4335
  }
3891
4336
 
3892
4337
  /**
4338
+ * Walk import expression.
3893
4339
  * @param {ImportExpression} expression import expression
3894
4340
  */
3895
4341
  walkImportExpression(expression) {
@@ -3900,18 +4346,13 @@ class JavascriptParser extends Parser {
3900
4346
  }
3901
4347
 
3902
4348
  /**
4349
+ * Walk call expression.
3903
4350
  * @param {CallExpression} expression expression
3904
4351
  */
3905
4352
  walkCallExpression(expression) {
3906
- /**
3907
- * @param {FunctionExpression | ArrowFunctionExpression} fn function
3908
- * @returns {boolean} true when simple function
3909
- */
3910
- const isSimpleFunction = (fn) =>
3911
- fn.params.every((p) => p.type === "Identifier");
3912
4353
  if (
3913
4354
  expression.callee.type === "MemberExpression" &&
3914
- expression.callee.object.type.endsWith("FunctionExpression") &&
4355
+ isFunctionExpression(expression.callee.object.type) &&
3915
4356
  !expression.callee.computed &&
3916
4357
  /** @type {boolean} */
3917
4358
  (
@@ -3934,7 +4375,7 @@ class JavascriptParser extends Parser {
3934
4375
  expression.arguments[0]
3935
4376
  );
3936
4377
  } else if (
3937
- expression.callee.type.endsWith("FunctionExpression") &&
4378
+ isFunctionExpression(expression.callee.type) &&
3938
4379
  isSimpleFunction(
3939
4380
  /** @type {FunctionExpression | ArrowFunctionExpression} */
3940
4381
  (expression.callee)
@@ -3949,21 +4390,29 @@ class JavascriptParser extends Parser {
3949
4390
  );
3950
4391
  } else {
3951
4392
  if (expression.callee.type === "MemberExpression") {
3952
- const exprInfo = this.getMemberExpressionInfo(
3953
- expression.callee,
3954
- ALLOWED_MEMBER_TYPES_CALL_EXPRESSION
3955
- );
3956
- if (exprInfo && exprInfo.type === "call") {
3957
- const result = this.callHooksForInfo(
3958
- this.hooks.callMemberChainOfCallMemberChain,
3959
- exprInfo.rootInfo,
3960
- expression,
3961
- exprInfo.getCalleeMembers(),
3962
- exprInfo.call,
3963
- exprInfo.getMembers(),
3964
- exprInfo.getMemberRanges()
4393
+ // callMemberChainOfCallMemberChain only applies to call-rooted
4394
+ // chains (e.g. `a().b()`); for the common identifier/this-rooted
4395
+ // callee the CALL lookup always rejects, so gate on the cheap root.
4396
+ if (
4397
+ this.getMemberExpressionRoot(expression.callee).type ===
4398
+ "CallExpression"
4399
+ ) {
4400
+ const exprInfo = this.getMemberExpressionInfo(
4401
+ expression.callee,
4402
+ ALLOWED_MEMBER_TYPES_CALL_EXPRESSION
3965
4403
  );
3966
- if (result === true) return;
4404
+ if (exprInfo && exprInfo.type === "call") {
4405
+ const result = this.callHooksForInfo(
4406
+ this.hooks.callMemberChainOfCallMemberChain,
4407
+ exprInfo.rootInfo,
4408
+ expression,
4409
+ exprInfo.getCalleeMembers(),
4410
+ exprInfo.call,
4411
+ exprInfo.getMembers(),
4412
+ exprInfo.getMemberRanges()
4413
+ );
4414
+ if (result === true) return;
4415
+ }
3967
4416
  }
3968
4417
  // import("./m").then(m => { ... })
3969
4418
  if (
@@ -3978,19 +4427,33 @@ class JavascriptParser extends Parser {
3978
4427
  if (result === true) return;
3979
4428
  }
3980
4429
  }
4430
+ if (
4431
+ expression.callee.type === "Identifier" &&
4432
+ this._evalIdentOwnTaps &&
4433
+ expression.callee.name !== "undefined" &&
4434
+ this._isDefinedPlainVariable(expression.callee.name)
4435
+ ) {
4436
+ // a defined, untagged callee can only evaluate to the fallthrough
4437
+ // result, so no call hooks apply — walk callee and arguments
4438
+ // directly, skipping the hook dispatch and its result object
4439
+ this.walkExpression(expression.callee);
4440
+ if (expression.arguments) this.walkExpressions(expression.arguments);
4441
+ return;
4442
+ }
3981
4443
  const callee = this.evaluateExpression(expression.callee);
3982
4444
  if (callee.isIdentifier()) {
4445
+ const members =
4446
+ /** @type {NonNullable<BasicEvaluatedExpression["getMembers"]>} */
4447
+ (callee.getMembers)();
3983
4448
  const result1 = this.callHooksForInfo(
3984
4449
  this.hooks.callMemberChain,
3985
4450
  /** @type {NonNullable<BasicEvaluatedExpression["rootInfo"]>} */
3986
4451
  (callee.rootInfo),
3987
4452
  expression,
3988
- /** @type {NonNullable<BasicEvaluatedExpression["getMembers"]>} */
3989
- (callee.getMembers)(),
4453
+ members,
3990
4454
  callee.getMembersOptionals
3991
4455
  ? callee.getMembersOptionals()
3992
- : /** @type {NonNullable<BasicEvaluatedExpression["getMembers"]>} */
3993
- (callee.getMembers)().map(() => false),
4456
+ : members.map(RETURN_FALSE),
3994
4457
  callee.getMemberRanges ? callee.getMemberRanges() : []
3995
4458
  );
3996
4459
  if (result1 === true) return;
@@ -4019,6 +4482,7 @@ class JavascriptParser extends Parser {
4019
4482
  }
4020
4483
 
4021
4484
  /**
4485
+ * Walk member expression.
4022
4486
  * @param {MemberExpression} expression member expression
4023
4487
  */
4024
4488
  walkMemberExpression(expression) {
@@ -4085,6 +4549,7 @@ class JavascriptParser extends Parser {
4085
4549
  }
4086
4550
 
4087
4551
  /**
4552
+ * Walk member expression with expression name.
4088
4553
  * @template R
4089
4554
  * @param {MemberExpression} expression member expression
4090
4555
  * @param {string} name name
@@ -4102,10 +4567,10 @@ class JavascriptParser extends Parser {
4102
4567
  if (expression.object.type === "MemberExpression") {
4103
4568
  // optimize the case where expression.object is a MemberExpression too.
4104
4569
  // we can keep info here when calling walkMemberExpression directly
4105
- const property =
4106
- /** @type {Identifier} */
4107
- (expression.property).name ||
4108
- `${/** @type {Literal} */ (expression.property).value}`;
4570
+ // Read the property from `members` (already extracted by
4571
+ // extractMemberExpressionChain) since the AST node may be a
4572
+ // TemplateLiteral, which has neither .name nor .value.
4573
+ const property = members[members.length - 1];
4109
4574
  name = name.slice(0, -property.length - 1);
4110
4575
  members.pop();
4111
4576
  const result = this.callHooksForInfo(
@@ -4128,6 +4593,7 @@ class JavascriptParser extends Parser {
4128
4593
  }
4129
4594
 
4130
4595
  /**
4596
+ * Walk this expression.
4131
4597
  * @param {ThisExpression} expression this expression
4132
4598
  */
4133
4599
  walkThisExpression(expression) {
@@ -4135,6 +4601,7 @@ class JavascriptParser extends Parser {
4135
4601
  }
4136
4602
 
4137
4603
  /**
4604
+ * Processes the provided expression.
4138
4605
  * @param {Identifier} expression identifier
4139
4606
  */
4140
4607
  walkIdentifier(expression) {
@@ -4142,6 +4609,7 @@ class JavascriptParser extends Parser {
4142
4609
  }
4143
4610
 
4144
4611
  /**
4612
+ * Walk meta property.
4145
4613
  * @param {MetaProperty} metaProperty meta property
4146
4614
  */
4147
4615
  walkMetaProperty(metaProperty) {
@@ -4149,6 +4617,7 @@ class JavascriptParser extends Parser {
4149
4617
  }
4150
4618
 
4151
4619
  /**
4620
+ * Call hooks for expression.
4152
4621
  * @template T
4153
4622
  * @template R
4154
4623
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
@@ -4167,6 +4636,7 @@ class JavascriptParser extends Parser {
4167
4636
  }
4168
4637
 
4169
4638
  /**
4639
+ * Call hooks for expression with fallback.
4170
4640
  * @template T
4171
4641
  * @template R
4172
4642
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
@@ -4201,6 +4671,7 @@ class JavascriptParser extends Parser {
4201
4671
  }
4202
4672
 
4203
4673
  /**
4674
+ * Call hooks for name.
4204
4675
  * @template T
4205
4676
  * @template R
4206
4677
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
@@ -4209,16 +4680,17 @@ class JavascriptParser extends Parser {
4209
4680
  * @returns {R | undefined} result of hook
4210
4681
  */
4211
4682
  callHooksForName(hookMap, name, ...args) {
4212
- return this.callHooksForNameWithFallback(
4683
+ return this._callHooksForInfo(
4213
4684
  hookMap,
4214
- name,
4685
+ this.getVariableInfo(name),
4215
4686
  undefined,
4216
4687
  undefined,
4217
- ...args
4688
+ args
4218
4689
  );
4219
4690
  }
4220
4691
 
4221
4692
  /**
4693
+ * Call hooks for info.
4222
4694
  * @template T
4223
4695
  * @template R
4224
4696
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks that should be called
@@ -4227,16 +4699,11 @@ class JavascriptParser extends Parser {
4227
4699
  * @returns {R | undefined} result of hook
4228
4700
  */
4229
4701
  callHooksForInfo(hookMap, info, ...args) {
4230
- return this.callHooksForInfoWithFallback(
4231
- hookMap,
4232
- info,
4233
- undefined,
4234
- undefined,
4235
- ...args
4236
- );
4702
+ return this._callHooksForInfo(hookMap, info, undefined, undefined, args);
4237
4703
  }
4238
4704
 
4239
4705
  /**
4706
+ * Call hooks for info with fallback.
4240
4707
  * @template T
4241
4708
  * @template R
4242
4709
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
@@ -4247,6 +4714,23 @@ class JavascriptParser extends Parser {
4247
4714
  * @returns {R | undefined} result of hook
4248
4715
  */
4249
4716
  callHooksForInfoWithFallback(hookMap, info, fallback, defined, ...args) {
4717
+ return this._callHooksForInfo(hookMap, info, fallback, defined, args);
4718
+ }
4719
+
4720
+ /**
4721
+ * Shared core for the callHooksFor* helpers. Takes `args` as an already
4722
+ * collected array so the public wrappers each allocate it once instead of
4723
+ * re-collecting it through several rest-parameter layers (hot per identifier).
4724
+ * @template T
4725
+ * @template R
4726
+ * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks that should be called
4727
+ * @param {ExportedVariableInfo} info variable info
4728
+ * @param {((name: string) => R | undefined) | undefined} fallback callback when variable is not handled by hooks
4729
+ * @param {((result?: string) => R | undefined) | undefined} defined callback when variable is defined
4730
+ * @param {AsArray<T>} args args for the hook
4731
+ * @returns {R | undefined} result of hook
4732
+ */
4733
+ _callHooksForInfo(hookMap, info, fallback, defined, args) {
4250
4734
  /** @type {string} */
4251
4735
  let name;
4252
4736
  if (typeof info === "string") {
@@ -4288,6 +4772,7 @@ class JavascriptParser extends Parser {
4288
4772
  }
4289
4773
 
4290
4774
  /**
4775
+ * Call hooks for name with fallback.
4291
4776
  * @template T
4292
4777
  * @template R
4293
4778
  * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
@@ -4298,16 +4783,17 @@ class JavascriptParser extends Parser {
4298
4783
  * @returns {R | undefined} result of hook
4299
4784
  */
4300
4785
  callHooksForNameWithFallback(hookMap, name, fallback, defined, ...args) {
4301
- return this.callHooksForInfoWithFallback(
4786
+ return this._callHooksForInfo(
4302
4787
  hookMap,
4303
4788
  this.getVariableInfo(name),
4304
4789
  fallback,
4305
4790
  defined,
4306
- ...args
4791
+ args
4307
4792
  );
4308
4793
  }
4309
4794
 
4310
4795
  /**
4796
+ * Processes the provided param.
4311
4797
  * @deprecated
4312
4798
  * @param {(string | Pattern | Property)[]} params scope params
4313
4799
  * @param {() => void} fn inner function
@@ -4328,9 +4814,7 @@ class JavascriptParser extends Parser {
4328
4814
 
4329
4815
  this.undefineVariable("this");
4330
4816
 
4331
- this.enterPatterns(params, (ident) => {
4332
- this.defineVariable(ident);
4333
- });
4817
+ this.enterPatterns(params, this._defineVariable);
4334
4818
 
4335
4819
  fn();
4336
4820
 
@@ -4338,6 +4822,7 @@ class JavascriptParser extends Parser {
4338
4822
  }
4339
4823
 
4340
4824
  /**
4825
+ * Processes the provided has thi.
4341
4826
  * @param {boolean} hasThis true, when this is defined
4342
4827
  * @param {Identifier[]} params scope params
4343
4828
  * @param {() => void} fn inner function
@@ -4360,9 +4845,7 @@ class JavascriptParser extends Parser {
4360
4845
  this.undefineVariable("this");
4361
4846
  }
4362
4847
 
4363
- this.enterPatterns(params, (ident) => {
4364
- this.defineVariable(ident);
4365
- });
4848
+ this.enterPatterns(params, this._defineVariable);
4366
4849
 
4367
4850
  fn();
4368
4851
 
@@ -4370,6 +4853,7 @@ class JavascriptParser extends Parser {
4370
4853
  }
4371
4854
 
4372
4855
  /**
4856
+ * Processes the provided has thi.
4373
4857
  * @param {boolean} hasThis true, when this is defined
4374
4858
  * @param {(Pattern | string)[]} params scope params
4375
4859
  * @param {() => void} fn inner function
@@ -4392,9 +4876,7 @@ class JavascriptParser extends Parser {
4392
4876
  this.undefineVariable("this");
4393
4877
  }
4394
4878
 
4395
- this.enterPatterns(params, (ident) => {
4396
- this.defineVariable(ident);
4397
- });
4879
+ this.enterPatterns(params, this._defineVariable);
4398
4880
 
4399
4881
  fn();
4400
4882
 
@@ -4402,6 +4884,7 @@ class JavascriptParser extends Parser {
4402
4884
  }
4403
4885
 
4404
4886
  /**
4887
+ * Processes the provided fn.
4405
4888
  * @param {() => void} fn inner function
4406
4889
  * @param {boolean} inExecutedPath executed state
4407
4890
  * @returns {void}
@@ -4431,37 +4914,34 @@ class JavascriptParser extends Parser {
4431
4914
  }
4432
4915
 
4433
4916
  /**
4917
+ * Processes the provided statement.
4434
4918
  * @param {(Directive | Statement | ModuleDeclaration)[]} statements statements
4435
4919
  */
4436
4920
  detectMode(statements) {
4437
- const isLiteral =
4438
- statements.length >= 1 &&
4439
- statements[0].type === "ExpressionStatement" &&
4440
- statements[0].expression.type === "Literal";
4921
+ const statement = statements.length >= 1 ? statements[0] : undefined;
4441
4922
  if (
4442
- isLiteral &&
4443
- /** @type {Literal} */
4444
- (/** @type {ExpressionStatement} */ (statements[0]).expression).value ===
4445
- "use strict"
4923
+ statement === undefined ||
4924
+ statement.type !== "ExpressionStatement" ||
4925
+ statement.expression.type !== "Literal"
4446
4926
  ) {
4447
- this.scope.isStrict = true;
4927
+ return;
4448
4928
  }
4449
- if (
4450
- isLiteral &&
4451
- /** @type {Literal} */
4452
- (/** @type {ExpressionStatement} */ (statements[0]).expression).value ===
4453
- "use asm"
4454
- ) {
4929
+ const value = /** @type {Literal} */ (statement.expression).value;
4930
+ if (value === "use strict") {
4931
+ this.scope.isStrict = true;
4932
+ } else if (value === "use asm") {
4455
4933
  this.scope.isAsmJs = true;
4456
4934
  }
4457
4935
  }
4458
4936
 
4459
4937
  /**
4938
+ * Processes the provided pattern.
4460
4939
  * @param {(string | Pattern | Property)[]} patterns patterns
4461
4940
  * @param {OnIdentString} onIdent on ident callback
4462
4941
  */
4463
4942
  enterPatterns(patterns, onIdent) {
4464
- for (const pattern of patterns) {
4943
+ for (let i = 0, len = patterns.length; i < len; i++) {
4944
+ const pattern = patterns[i];
4465
4945
  if (typeof pattern !== "string") {
4466
4946
  this.enterPattern(pattern, onIdent);
4467
4947
  } else if (pattern) {
@@ -4471,27 +4951,20 @@ class JavascriptParser extends Parser {
4471
4951
  }
4472
4952
 
4473
4953
  /**
4954
+ * Processes the provided pattern.
4474
4955
  * @param {Pattern | Property} pattern pattern
4475
4956
  * @param {OnIdent} onIdent on ident callback
4476
4957
  */
4477
4958
  enterPattern(pattern, onIdent) {
4478
4959
  if (!pattern) return;
4960
+ // plain identifiers dominate bindings, so match them first
4479
4961
  switch (pattern.type) {
4480
- case "ArrayPattern":
4481
- this.enterArrayPattern(pattern, onIdent);
4482
- break;
4483
- case "AssignmentPattern":
4484
- this.enterAssignmentPattern(pattern, onIdent);
4485
- break;
4486
4962
  case "Identifier":
4487
4963
  this.enterIdentifier(pattern, onIdent);
4488
4964
  break;
4489
4965
  case "ObjectPattern":
4490
4966
  this.enterObjectPattern(pattern, onIdent);
4491
4967
  break;
4492
- case "RestElement":
4493
- this.enterRestElement(pattern, onIdent);
4494
- break;
4495
4968
  case "Property":
4496
4969
  if (pattern.shorthand && pattern.value.type === "Identifier") {
4497
4970
  this.scope.inShorthand = pattern.value.name;
@@ -4501,10 +4974,20 @@ class JavascriptParser extends Parser {
4501
4974
  this.enterPattern(/** @type {Pattern} */ (pattern.value), onIdent);
4502
4975
  }
4503
4976
  break;
4977
+ case "ArrayPattern":
4978
+ this.enterArrayPattern(pattern, onIdent);
4979
+ break;
4980
+ case "AssignmentPattern":
4981
+ this.enterAssignmentPattern(pattern, onIdent);
4982
+ break;
4983
+ case "RestElement":
4984
+ this.enterRestElement(pattern, onIdent);
4985
+ break;
4504
4986
  }
4505
4987
  }
4506
4988
 
4507
4989
  /**
4990
+ * Processes the provided pattern.
4508
4991
  * @param {Identifier} pattern identifier pattern
4509
4992
  * @param {OnIdent} onIdent callback
4510
4993
  */
@@ -4515,6 +4998,7 @@ class JavascriptParser extends Parser {
4515
4998
  }
4516
4999
 
4517
5000
  /**
5001
+ * Enter object pattern.
4518
5002
  * @param {ObjectPattern} pattern object pattern
4519
5003
  * @param {OnIdent} onIdent callback
4520
5004
  */
@@ -4530,6 +5014,7 @@ class JavascriptParser extends Parser {
4530
5014
  }
4531
5015
 
4532
5016
  /**
5017
+ * Enter array pattern.
4533
5018
  * @param {ArrayPattern} pattern object pattern
4534
5019
  * @param {OnIdent} onIdent callback
4535
5020
  */
@@ -4548,6 +5033,7 @@ class JavascriptParser extends Parser {
4548
5033
  }
4549
5034
 
4550
5035
  /**
5036
+ * Enter rest element.
4551
5037
  * @param {RestElement} pattern object pattern
4552
5038
  * @param {OnIdent} onIdent callback
4553
5039
  */
@@ -4556,6 +5042,7 @@ class JavascriptParser extends Parser {
4556
5042
  }
4557
5043
 
4558
5044
  /**
5045
+ * Enter assignment pattern.
4559
5046
  * @param {AssignmentPattern} pattern object pattern
4560
5047
  * @param {OnIdent} onIdent callback
4561
5048
  */
@@ -4564,6 +5051,7 @@ class JavascriptParser extends Parser {
4564
5051
  }
4565
5052
 
4566
5053
  /**
5054
+ * Evaluate expression.
4567
5055
  * @param {Expression | SpreadElement | PrivateIdentifier | Super} expression expression node
4568
5056
  * @returns {BasicEvaluatedExpression} evaluation result
4569
5057
  */
@@ -4582,12 +5070,13 @@ class JavascriptParser extends Parser {
4582
5070
  console.warn(err);
4583
5071
  // ignore error
4584
5072
  }
4585
- return new BasicEvaluatedExpression()
4586
- .setRange(/** @type {Range} */ (expression.range))
4587
- .setExpression(expression);
5073
+ // no setRange: the range is served lazily from the expression on first
5074
+ // read, so plain results don't materialize the node's range array at all
5075
+ return new BasicEvaluatedExpression().setExpression(expression);
4588
5076
  }
4589
5077
 
4590
5078
  /**
5079
+ * Returns parsed string.
4591
5080
  * @param {Expression} expression expression
4592
5081
  * @returns {string} parsed string
4593
5082
  */
@@ -4612,6 +5101,7 @@ class JavascriptParser extends Parser {
4612
5101
  /** @typedef {{ range?: Range, value: string, code: boolean, conditional: false | CalculatedStringResult[] }} CalculatedStringResult */
4613
5102
 
4614
5103
  /**
5104
+ * Parses calculated string.
4615
5105
  * @param {Expression} expression expression
4616
5106
  * @returns {CalculatedStringResult} result
4617
5107
  */
@@ -4701,6 +5191,7 @@ class JavascriptParser extends Parser {
4701
5191
  }
4702
5192
 
4703
5193
  /**
5194
+ * Parses the provided source and updates the parser state.
4704
5195
  * @param {string | Buffer | PreparsedAst} source the source to parse
4705
5196
  * @param {ParserState} state the parser state
4706
5197
  * @returns {ParserState} the parser state
@@ -4712,35 +5203,29 @@ class JavascriptParser extends Parser {
4712
5203
 
4713
5204
  if (Buffer.isBuffer(source)) {
4714
5205
  source = source.toString("utf8");
5206
+ // Keep `state.source` as a string so downstream walkers can read
5207
+ // the original text without re-decoding the Buffer on every use.
5208
+ state.source = source;
4715
5209
  }
4716
5210
 
4717
5211
  let ast;
4718
5212
  /** @type {Comment[]} */
4719
5213
  let comments;
4720
- /** @type {Set<number>} */
4721
- let semicolons;
4722
5214
 
4723
5215
  if (typeof source === "object") {
4724
- semicolons = new Set();
4725
-
4726
5216
  ast = /** @type {Program} */ (source);
4727
5217
  comments = source.comments;
4728
- if (source.semicolons) {
4729
- // Forward semicolon information from the preparsed AST if present
4730
- // This ensures the output is consistent with that of a fresh AST
4731
- for (const pos of source.semicolons) {
4732
- semicolons.add(pos);
4733
- }
4734
- }
4735
5218
  } else {
4736
- ({ ast, comments, semicolons } = JavascriptParser._parse(
5219
+ ({ ast, comments } = JavascriptParser._parse(
4737
5220
  source,
4738
5221
  {
4739
5222
  sourceType: this.sourceType,
4740
- locations: true,
5223
+ // line/column locations are derived from node offsets via
5224
+ // getLocation — parsers never need to track them
5225
+ locations: false,
4741
5226
  ranges: true,
4742
5227
  comments: true,
4743
- semicolons: true
5228
+ importPhases: this.options.importPhases === true
4744
5229
  },
4745
5230
  this.options.parse
4746
5231
  ));
@@ -4752,6 +5237,18 @@ class JavascriptParser extends Parser {
4752
5237
  const oldSemicolons = this.semicolons;
4753
5238
  const oldStatementPath = this.statementPath;
4754
5239
  const oldPrevStatement = this.prevStatement;
5240
+ const oldStrictInModuleOutput = this._strictInModuleOutput;
5241
+ const oldSource = this._source;
5242
+ const oldLineStarts = this._lineStarts;
5243
+ // a preparsed AST carries no text, but the build passes the module
5244
+ // source in the state — offsets still map for it
5245
+ this._source =
5246
+ typeof source === "string"
5247
+ ? source
5248
+ : typeof state.source === "string"
5249
+ ? state.source
5250
+ : undefined;
5251
+ this._lineStarts = undefined;
4755
5252
  this.scope = {
4756
5253
  topLevelScope: true,
4757
5254
  inTry: false,
@@ -4764,13 +5261,34 @@ class JavascriptParser extends Parser {
4764
5261
  };
4765
5262
  this.state = state;
4766
5263
  this.comments = comments;
4767
- this.semicolons = semicolons;
5264
+ this.semicolons = undefined;
5265
+ // evaluating a defined, untagged identifier can only fall through when
5266
+ // every `evaluate.for("Identifier")` tap is the parser's own — plugins
5267
+ // tapping or intercepting it disable the callee/rename fast paths
5268
+ const identifierEvalHook = this.hooks.evaluate.get("Identifier");
5269
+ this._evalIdentOwnTaps =
5270
+ identifierEvalHook !== undefined &&
5271
+ identifierEvalHook.interceptors.length === 0 &&
5272
+ identifierEvalHook.taps.every((tap) => tap.name === CLASS_NAME);
4768
5273
  this.statementPath = [];
4769
5274
  this.prevStatement = undefined;
5275
+ // The output is emitted as strict-mode ESM, but this module was parsed as
5276
+ // a loose script — acorn skipped the strict early errors that will break
5277
+ // the bundle at runtime. Enables the strict-mode diagnostics below.
5278
+ this._strictInModuleOutput =
5279
+ this.options.strictModeViolations !== false &&
5280
+ state.compilation !== undefined &&
5281
+ state.compilation.runtimeTemplate.isModule();
4770
5282
  if (this.hooks.program.call(ast, comments) === undefined) {
4771
5283
  this.destructuringAssignmentProperties = new WeakMap();
4772
5284
  this.detectMode(ast.body);
5285
+ // a strict program (ESM source, `"use strict"`) keeps its behavior in
5286
+ // strict output — drop the flag so the walk pays no per-node checks
5287
+ if (this._strictInModuleOutput && this.scope.isStrict) {
5288
+ this._strictInModuleOutput = false;
5289
+ }
4773
5290
  this.modulePreWalkStatements(ast.body);
5291
+ this.prevStatement = undefined;
4774
5292
  this.preWalkStatements(ast.body);
4775
5293
  this.prevStatement = undefined;
4776
5294
  this.blockPreWalkStatements(ast.body);
@@ -4785,19 +5303,54 @@ class JavascriptParser extends Parser {
4785
5303
  this.semicolons = oldSemicolons;
4786
5304
  this.statementPath = oldStatementPath;
4787
5305
  this.prevStatement = oldPrevStatement;
5306
+ this._strictInModuleOutput = oldStrictInModuleOutput;
5307
+ // release — these retain the whole source string and its line table
5308
+ this._source = oldSource;
5309
+ this._lineStarts = oldLineStarts;
4788
5310
  return state;
4789
5311
  }
4790
5312
 
4791
5313
  /**
5314
+ * Returns evaluation result.
4792
5315
  * @param {string} source source code
4793
5316
  * @returns {BasicEvaluatedExpression} evaluation result
4794
5317
  */
4795
5318
  evaluate(source) {
4796
- const { ast } = JavascriptParser._parse(
4797
- `(${source})`,
4798
- { sourceType: this.sourceType },
4799
- this.options.parse
4800
- );
5319
+ const importPhases = this.options.importPhases === true;
5320
+ const compilation = this.state && this.state.compilation;
5321
+ /** @type {Map<string, Program> | undefined} */
5322
+ let cache;
5323
+ // custom parse functions are not necessarily pure, do not cache for them
5324
+ if (compilation !== undefined && typeof this.options.parse !== "function") {
5325
+ cache = evaluateAstCaches.get(compilation);
5326
+ if (cache === undefined) {
5327
+ cache = new Map();
5328
+ evaluateAstCaches.set(compilation, cache);
5329
+ }
5330
+ }
5331
+ const cacheKey =
5332
+ cache === undefined
5333
+ ? undefined
5334
+ : `${this.sourceType}|${importPhases}|${source}`;
5335
+ let ast =
5336
+ cacheKey === undefined
5337
+ ? undefined
5338
+ : /** @type {Map<string, Program>} */ (cache).get(cacheKey);
5339
+ if (ast === undefined) {
5340
+ ({ ast } = JavascriptParser._parse(
5341
+ `(${source})`,
5342
+ {
5343
+ sourceType: this.sourceType,
5344
+ importPhases
5345
+ },
5346
+ this.options.parse
5347
+ ));
5348
+ if (cacheKey !== undefined) {
5349
+ const map = /** @type {Map<string, Program>} */ (cache);
5350
+ if (map.size >= EVALUATE_AST_CACHE_LIMIT) map.clear();
5351
+ map.set(cacheKey, ast);
5352
+ }
5353
+ }
4801
5354
  if (ast.body.length !== 1 || ast.body[0].type !== "ExpressionStatement") {
4802
5355
  throw new Error("evaluate: Source is not a expression");
4803
5356
  }
@@ -4805,6 +5358,7 @@ class JavascriptParser extends Parser {
4805
5358
  }
4806
5359
 
4807
5360
  /**
5361
+ * Checks whether this javascript parser is pure.
4808
5362
  * @param {Expression | Declaration | PrivateIdentifier | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | null | undefined} expr an expression
4809
5363
  * @param {number} commentsStartPos source position from which annotation comments are checked
4810
5364
  * @returns {boolean} true, when the expression is pure
@@ -4816,7 +5370,6 @@ class JavascriptParser extends Parser {
4816
5370
  .call(expr, commentsStartPos);
4817
5371
  if (typeof result === "boolean") return result;
4818
5372
  switch (expr.type) {
4819
- // TODO handle more cases
4820
5373
  case "ClassDeclaration":
4821
5374
  case "ClassExpression": {
4822
5375
  if (expr.body.type !== "ClassBody") return false;
@@ -4869,9 +5422,15 @@ class JavascriptParser extends Parser {
4869
5422
  });
4870
5423
  }
4871
5424
  case "TemplateLiteral":
4872
- return expr.expressions.every((expr) =>
4873
- this.isPure(expr, /** @type {Range} */ (expr.range)[0])
4874
- );
5425
+ // Thread `commentsStartPos` through the interpolations so a
5426
+ // /*#__PURE__*/ comment that sits inside `${ ... }` (or before
5427
+ // the first interpolation) is part of the scanned range when
5428
+ // the inner expression's purity is evaluated.
5429
+ return expr.expressions.every((e) => {
5430
+ const pureFlag = this.isPure(e, commentsStartPos);
5431
+ commentsStartPos = /** @type {Range} */ (e.range)[1];
5432
+ return pureFlag;
5433
+ });
4875
5434
  case "FunctionDeclaration":
4876
5435
  case "FunctionExpression":
4877
5436
  case "ArrowFunctionExpression":
@@ -4886,6 +5445,78 @@ class JavascriptParser extends Parser {
4886
5445
  this.isPure(decl.init, /** @type {Range} */ (decl.range)[0])
4887
5446
  );
4888
5447
 
5448
+ case "ArrayExpression":
5449
+ return expr.elements.every((element) => {
5450
+ if (element === null) return true;
5451
+ if (element.type === "SpreadElement") return false;
5452
+ const pureFlag = this.isPure(element, commentsStartPos);
5453
+ commentsStartPos = /** @type {Range} */ (element.range)[1];
5454
+ return pureFlag;
5455
+ });
5456
+
5457
+ case "ObjectExpression": {
5458
+ return expr.properties.every((property) => {
5459
+ if (property.type === "SpreadElement") return false;
5460
+
5461
+ if (
5462
+ property.computed &&
5463
+ !this.isPure(property.key, commentsStartPos)
5464
+ ) {
5465
+ return false;
5466
+ }
5467
+
5468
+ const pureFlag = this.isPure(
5469
+ /** @type {Exclude<Property["value"], AssignmentPattern | ObjectPattern | ArrayPattern | RestElement>} */
5470
+ (property.value),
5471
+ /** @type {Range} */ (property.key.range)[1]
5472
+ );
5473
+ commentsStartPos = /** @type {Range} */ (property.range)[1];
5474
+ return pureFlag;
5475
+ });
5476
+ }
5477
+
5478
+ case "ChainExpression":
5479
+ return this.isPure(expr.expression, commentsStartPos);
5480
+
5481
+ case "UnaryExpression":
5482
+ // Safe unary operators — produce their result without invoking
5483
+ // user code on the operand:
5484
+ // - `typeof` returns a type tag and never throws, even for
5485
+ // undeclared identifiers; no coercion.
5486
+ // - `void` evaluates the operand and discards it, returning
5487
+ // `undefined`; pure iff the operand is pure.
5488
+ // - `!` coerces via ToBoolean, which is defined to not call
5489
+ // any user code (objects → true, etc.).
5490
+ // Other operators (`+`, `-`, `~`, `delete`) fall through to
5491
+ // the generic evaluator which can still recognize literal
5492
+ // cases (e.g. `-1`, `+5`).
5493
+ if (
5494
+ expr.operator === "typeof" ||
5495
+ expr.operator === "void" ||
5496
+ expr.operator === "!"
5497
+ ) {
5498
+ return this.isPure(expr.argument, commentsStartPos);
5499
+ }
5500
+ break;
5501
+
5502
+ case "MetaProperty":
5503
+ return true;
5504
+
5505
+ case "BinaryExpression":
5506
+ // Strict (in)equality compares without coercion and never invokes
5507
+ // user code on its operands, so the result is pure iff both sides
5508
+ // are pure. All other binary operators may invoke `valueOf` /
5509
+ // `toString` / `[Symbol.hasInstance]` / Proxy traps and fall through
5510
+ // to the generic evaluator, which can still recognize the cases
5511
+ // where both sides evaluate to known primitive literals.
5512
+ if (expr.operator === "===" || expr.operator === "!==") {
5513
+ return (
5514
+ this.isPure(expr.left, commentsStartPos) &&
5515
+ this.isPure(expr.right, /** @type {Range} */ (expr.left.range)[1])
5516
+ );
5517
+ }
5518
+ break;
5519
+
4889
5520
  case "ConditionalExpression":
4890
5521
  return (
4891
5522
  this.isPure(expr.test, commentsStartPos) &&
@@ -4921,7 +5552,7 @@ class JavascriptParser extends Parser {
4921
5552
  ]).some(
4922
5553
  (comment) =>
4923
5554
  comment.type === "Block" &&
4924
- /^\s*(?:#|@)__PURE__\s*$/.test(comment.value)
5555
+ CompilerHintNotationRegExp.Pure.test(comment.value)
4925
5556
  );
4926
5557
  if (!pureFlag) return false;
4927
5558
  commentsStartPos = /** @type {Range} */ (expr.callee.range)[1];
@@ -4932,40 +5563,180 @@ class JavascriptParser extends Parser {
4932
5563
  return pureFlag;
4933
5564
  });
4934
5565
  }
5566
+
5567
+ case "NewExpression": {
5568
+ const pureFlag =
5569
+ /** @type {Range} */ (expr.range)[0] - commentsStartPos > 12 &&
5570
+ this.getComments([
5571
+ commentsStartPos,
5572
+ /** @type {Range} */ (expr.range)[0]
5573
+ ]).some(
5574
+ (comment) =>
5575
+ comment.type === "Block" &&
5576
+ CompilerHintNotationRegExp.Pure.test(comment.value)
5577
+ );
5578
+ if (!pureFlag) return false;
5579
+ commentsStartPos = /** @type {Range} */ (expr.callee.range)[1];
5580
+ return expr.arguments.every((arg) => {
5581
+ if (arg.type === "SpreadElement") return false;
5582
+ const pureFlag = this.isPure(arg, commentsStartPos);
5583
+ commentsStartPos = /** @type {Range} */ (arg.range)[1];
5584
+ return pureFlag;
5585
+ });
5586
+ }
5587
+
5588
+ case "TaggedTemplateExpression": {
5589
+ const pureFlag =
5590
+ /** @type {Range} */ (expr.range)[0] - commentsStartPos > 12 &&
5591
+ this.getComments([
5592
+ commentsStartPos,
5593
+ /** @type {Range} */ (expr.range)[0]
5594
+ ]).some(
5595
+ (comment) =>
5596
+ comment.type === "Block" &&
5597
+ CompilerHintNotationRegExp.Pure.test(comment.value)
5598
+ );
5599
+ if (!pureFlag) return false;
5600
+ commentsStartPos = /** @type {Range} */ (expr.tag.range)[1];
5601
+ return expr.quasi.expressions.every((e) => {
5602
+ const pureFlag = this.isPure(e, commentsStartPos);
5603
+ commentsStartPos = /** @type {Range} */ (e.range)[1];
5604
+ return pureFlag;
5605
+ });
5606
+ }
4935
5607
  }
4936
5608
  const evaluated = this.evaluateExpression(expr);
4937
5609
  return !evaluated.couldHaveSideEffects();
4938
5610
  }
4939
5611
 
4940
5612
  /**
5613
+ * Returns the location of a node or comment, computed from its offsets so
5614
+ * ASTs from parsers without location support work too. Falls back to the
5615
+ * node's own `loc` only when no source text is available (preparsed ASTs).
5616
+ * Offsets can only be mapped while parsing — callbacks deferred past the
5617
+ * `parse()` call must take the location upfront.
5618
+ * @param {{ start?: number, end?: number, range?: Range, loc?: SourceLocation | null }} node node or comment
5619
+ * @returns {DependencyLocation} location of the node
5620
+ */
5621
+ getLocation(node) {
5622
+ const source = this._source;
5623
+ if (source !== undefined) {
5624
+ const start =
5625
+ typeof node.start === "number"
5626
+ ? node.start
5627
+ : node.range
5628
+ ? node.range[0]
5629
+ : undefined;
5630
+ if (start !== undefined) {
5631
+ const end =
5632
+ typeof node.end === "number"
5633
+ ? node.end
5634
+ : node.range
5635
+ ? node.range[1]
5636
+ : start;
5637
+ const lineStarts =
5638
+ this._lineStarts || (this._lineStarts = buildLineStarts(source));
5639
+ return {
5640
+ start: positionAt(lineStarts, start),
5641
+ end: positionAt(lineStarts, end)
5642
+ };
5643
+ }
5644
+ }
5645
+ return /** @type {DependencyLocation} */ (node.loc);
5646
+ }
5647
+
5648
+ /**
5649
+ * Returns comments in the range.
4941
5650
  * @param {Range} range range
4942
5651
  * @returns {Comment[]} comments in the range
4943
5652
  */
4944
5653
  getComments(range) {
4945
- const [rangeStart, rangeEnd] = range;
4946
- /**
4947
- * @param {Comment} comment comment
4948
- * @param {number} needle needle
4949
- * @returns {number} compared
4950
- */
4951
- const compare = (comment, needle) =>
4952
- /** @type {Range} */ (comment.range)[0] - needle;
4953
- const comments = /** @type {Comment[]} */ (this.comments);
4954
- let idx = binarySearchBounds.ge(comments, rangeStart, compare);
4955
- /** @type {Comment[]} */
4956
- const commentsInRange = [];
4957
- while (
4958
- comments[idx] &&
4959
- /** @type {Range} */ (comments[idx].range)[1] <= rangeEnd
4960
- ) {
4961
- commentsInRange.push(comments[idx]);
4962
- idx++;
5654
+ return getCommentsInRange(
5655
+ /** @type {(Comment & { range: [number, number] })[]} */ (this.comments),
5656
+ range
5657
+ );
5658
+ }
5659
+
5660
+ /**
5661
+ * First significant char code at or after `pos`, skipping whitespace,
5662
+ * comments and grouping `)` (a parenthesized node's range excludes its
5663
+ * wrapping parens, so a `,`/`;` separator can sit behind them), or -1 at
5664
+ * end of source.
5665
+ * @param {string} source source text
5666
+ * @param {number} pos start offset
5667
+ * @returns {number} char code of the next token, or -1
5668
+ */
5669
+ _nextTokenCharCode(source, pos) {
5670
+ const len = source.length;
5671
+ for (let i = pos; i < len; i++) {
5672
+ const c = source.charCodeAt(i);
5673
+ // whitespace and line terminators acorn skips between tokens
5674
+ if (
5675
+ c === 32 ||
5676
+ c === 9 ||
5677
+ c === 10 ||
5678
+ c === 13 ||
5679
+ c === 11 ||
5680
+ c === 12 ||
5681
+ c === 41 /* ) */ ||
5682
+ c === 0xa0 ||
5683
+ c === 0xfeff ||
5684
+ c === 0x2028 ||
5685
+ c === 0x2029
5686
+ ) {
5687
+ continue;
5688
+ }
5689
+ if (c === 47 /* / */) {
5690
+ const n = source.charCodeAt(i + 1);
5691
+ if (n === 47 /* / */) {
5692
+ i += 2;
5693
+ while (i < len) {
5694
+ const cc = source.charCodeAt(i);
5695
+ if (cc === 10 || cc === 13 || cc === 0x2028 || cc === 0x2029) break;
5696
+ i++;
5697
+ }
5698
+ continue;
5699
+ }
5700
+ if (n === 42 /* * */) {
5701
+ i += 2;
5702
+ while (
5703
+ i < len &&
5704
+ !(source.charCodeAt(i) === 42 && source.charCodeAt(i + 1) === 47)
5705
+ ) {
5706
+ i++;
5707
+ }
5708
+ i++;
5709
+ continue;
5710
+ }
5711
+ }
5712
+ return c;
4963
5713
  }
5714
+ return -1;
5715
+ }
4964
5716
 
4965
- return commentsInRange;
5717
+ /**
5718
+ * Whether a statement ending at `pos` relies on ASI (no real separator).
5719
+ * Derived from the source text unless overridden by set/unsetAsiPosition.
5720
+ * A statement terminated by a real `;` or continued by a `,` (a sequence
5721
+ * element) is not an ASI position; anything else (newline, `}`, eof) is.
5722
+ * @param {number} pos statement end offset
5723
+ * @returns {boolean} true when ASI inserts a semicolon at this position
5724
+ */
5725
+ _isAsiPosition(pos) {
5726
+ if (this.semicolons !== undefined) {
5727
+ const override = this.semicolons.get(pos);
5728
+ if (override !== undefined) return override;
5729
+ }
5730
+ const source = this._source;
5731
+ if (source === undefined) return true;
5732
+ // a real semicolon is the statement's last char (exclusive end at pos)
5733
+ if (source.charCodeAt(pos - 1) === 59 /* ; */) return false;
5734
+ const next = this._nextTokenCharCode(source, pos);
5735
+ return next !== 44 /* , */ && next !== 59; /* ; */
4966
5736
  }
4967
5737
 
4968
5738
  /**
5739
+ * Checks whether this javascript parser is asi position.
4969
5740
  * @param {number} pos source code position
4970
5741
  * @returns {boolean} true when a semicolon has been inserted before this position, false if not
4971
5742
  */
@@ -4981,37 +5752,37 @@ class JavascriptParser extends Parser {
4981
5752
 
4982
5753
  return (
4983
5754
  // Either asking directly for the end position of the current statement
4984
- (range[1] === pos &&
4985
- /** @type {Set<number>} */ (this.semicolons).has(pos)) ||
5755
+ (range[1] === pos && this._isAsiPosition(pos)) ||
4986
5756
  // Or asking for the start position of the current statement,
4987
5757
  // here we have to check multiple things
4988
5758
  (range[0] === pos &&
4989
5759
  // is there a previous statement which might be relevant?
4990
5760
  this.prevStatement !== undefined &&
4991
5761
  // is the end position of the previous statement an ASI position?
4992
- /** @type {Set<number>} */ (this.semicolons).has(
4993
- /** @type {Range} */ (this.prevStatement.range)[1]
4994
- ))
5762
+ this._isAsiPosition(/** @type {Range} */ (this.prevStatement.range)[1]))
4995
5763
  );
4996
5764
  }
4997
5765
 
4998
5766
  /**
5767
+ * Updates asi position using the provided po.
4999
5768
  * @param {number} pos source code position
5000
5769
  * @returns {void}
5001
5770
  */
5002
5771
  setAsiPosition(pos) {
5003
- /** @type {Set<number>} */ (this.semicolons).add(pos);
5772
+ (this.semicolons || (this.semicolons = new Map())).set(pos, true);
5004
5773
  }
5005
5774
 
5006
5775
  /**
5776
+ * Unset asi position.
5007
5777
  * @param {number} pos source code position
5008
5778
  * @returns {void}
5009
5779
  */
5010
5780
  unsetAsiPosition(pos) {
5011
- /** @type {Set<number>} */ (this.semicolons).delete(pos);
5781
+ (this.semicolons || (this.semicolons = new Map())).set(pos, false);
5012
5782
  }
5013
5783
 
5014
5784
  /**
5785
+ * Checks whether this javascript parser is statement level expression.
5015
5786
  * @param {Expression} expr expression
5016
5787
  * @returns {boolean} true, when the expression is a statement level expression
5017
5788
  */
@@ -5030,6 +5801,7 @@ class JavascriptParser extends Parser {
5030
5801
  }
5031
5802
 
5032
5803
  /**
5804
+ * Returns tag data.
5033
5805
  * @param {string} name name
5034
5806
  * @param {Tag} tag tag info
5035
5807
  * @returns {TagData | undefined} tag data
@@ -5046,6 +5818,7 @@ class JavascriptParser extends Parser {
5046
5818
  }
5047
5819
 
5048
5820
  /**
5821
+ * Processes the provided name.
5049
5822
  * @param {string} name name
5050
5823
  * @param {Tag} tag tag info
5051
5824
  * @param {TagData=} data data
@@ -5083,6 +5856,7 @@ class JavascriptParser extends Parser {
5083
5856
  }
5084
5857
 
5085
5858
  /**
5859
+ * Processes the provided name.
5086
5860
  * @param {string} name variable name
5087
5861
  */
5088
5862
  defineVariable(name) {
@@ -5098,6 +5872,7 @@ class JavascriptParser extends Parser {
5098
5872
  }
5099
5873
 
5100
5874
  /**
5875
+ * Processes the provided name.
5101
5876
  * @param {string} name variable name
5102
5877
  */
5103
5878
  undefineVariable(name) {
@@ -5105,6 +5880,7 @@ class JavascriptParser extends Parser {
5105
5880
  }
5106
5881
 
5107
5882
  /**
5883
+ * Checks whether this javascript parser is variable defined.
5108
5884
  * @param {string} name variable name
5109
5885
  * @returns {boolean} true, when variable is defined
5110
5886
  */
@@ -5118,6 +5894,23 @@ class JavascriptParser extends Parser {
5118
5894
  }
5119
5895
 
5120
5896
  /**
5897
+ * Whether evaluating an identifier of this name can only fall through:
5898
+ * the exact negative of the identifier evaluator's `getInfo` — defined in
5899
+ * some scope and neither free nor tagged nor carrying tag info.
5900
+ * @param {string} name variable name
5901
+ * @returns {boolean} true when the identifier evaluates to nothing
5902
+ */
5903
+ _isDefinedPlainVariable(name) {
5904
+ const info = this.scope.definitions.get(name);
5905
+ if (info === undefined) return false;
5906
+ if (info instanceof VariableInfo) {
5907
+ return !(info.isFree() || info.isTagged() || info.tagInfo !== undefined);
5908
+ }
5909
+ return true;
5910
+ }
5911
+
5912
+ /**
5913
+ * Gets variable info.
5121
5914
  * @param {string} name variable name
5122
5915
  * @returns {ExportedVariableInfo} info for this variable
5123
5916
  */
@@ -5130,6 +5923,7 @@ class JavascriptParser extends Parser {
5130
5923
  }
5131
5924
 
5132
5925
  /**
5926
+ * Updates variable using the provided name.
5133
5927
  * @param {string} name variable name
5134
5928
  * @param {ExportedVariableInfo} variableInfo new info for this variable
5135
5929
  * @returns {void}
@@ -5155,6 +5949,7 @@ class JavascriptParser extends Parser {
5155
5949
  }
5156
5950
 
5157
5951
  /**
5952
+ * Evaluated variable.
5158
5953
  * @param {TagInfo} tagInfo tag info
5159
5954
  * @returns {VariableInfo} variable info
5160
5955
  */
@@ -5168,49 +5963,54 @@ class JavascriptParser extends Parser {
5168
5963
  }
5169
5964
 
5170
5965
  /**
5966
+ * Parses comment options.
5171
5967
  * @param {Range} range range of the comment
5172
5968
  * @returns {{ options: Record<string, EXPECTED_ANY> | null, errors: (Error & { comment: Comment })[] | null }} result
5173
5969
  */
5174
5970
  parseCommentOptions(range) {
5175
- const comments = this.getComments(range);
5176
- if (comments.length === 0) {
5177
- return EMPTY_COMMENT_OPTIONS;
5178
- }
5179
- /** @type {Record<string, EXPECTED_ANY>} */
5180
- const options = {};
5181
- /** @type {(Error & { comment: Comment })[]} */
5182
- const errors = [];
5183
- for (const comment of comments) {
5184
- const { value } = comment;
5185
- if (value && webpackCommentRegExp.test(value)) {
5186
- // try compile only if webpack options comment is present
5187
- try {
5188
- for (let [key, val] of Object.entries(
5189
- vm.runInContext(
5190
- `(function(){return {${value}};})()`,
5191
- this.magicCommentContext
5192
- )
5193
- )) {
5194
- if (typeof val === "object" && val !== null) {
5195
- val =
5196
- val.constructor.name === "RegExp"
5197
- ? new RegExp(val)
5198
- : JSON.parse(JSON.stringify(val));
5199
- }
5200
- options[key] = val;
5201
- }
5202
- } catch (err) {
5203
- const newErr = new Error(String(/** @type {Error} */ (err).message));
5204
- newErr.stack = String(/** @type {Error} */ (err).stack);
5205
- Object.assign(newErr, { comment });
5206
- errors.push(/** @type {(Error & { comment: Comment })} */ (newErr));
5971
+ return parseCommentOptionsInRange(
5972
+ /** @type {(Comment & { range: [number, number], value: string })[]} */ (
5973
+ this.comments
5974
+ ),
5975
+ range,
5976
+ this.magicCommentContext
5977
+ );
5978
+ }
5979
+
5980
+ /**
5981
+ * Finds the root object of a member expression chain without allocating the
5982
+ * member arrays. The traversal/break logic must stay in sync with
5983
+ * `extractMemberExpressionChain`; it lets `getMemberExpressionInfo` reject
5984
+ * unrecognized roots (~77% of calls) before paying for the arrays.
5985
+ * @param {Expression | Super} expression a member expression
5986
+ * @returns {Expression | Super} the root object of the chain
5987
+ */
5988
+ getMemberExpressionRoot(expression) {
5989
+ /** @type {Node} */
5990
+ let expr = expression;
5991
+ while (expr.type === "MemberExpression") {
5992
+ if (expr.computed) {
5993
+ const prop = expr.property;
5994
+ if (
5995
+ prop.type !== "Literal" &&
5996
+ !(
5997
+ prop.type === "TemplateLiteral" &&
5998
+ prop.expressions.length === 0 &&
5999
+ typeof prop.quasis[0].value.cooked === "string"
6000
+ )
6001
+ ) {
6002
+ break;
5207
6003
  }
6004
+ } else if (expr.property.type !== "Identifier") {
6005
+ break;
5208
6006
  }
6007
+ expr = expr.object;
5209
6008
  }
5210
- return { options, errors };
6009
+ return /** @type {Expression | Super} */ (expr);
5211
6010
  }
5212
6011
 
5213
6012
  /**
6013
+ * Extract member expression chain.
5214
6014
  * @param {Expression | Super} expression a member expression
5215
6015
  * @returns {{ members: Members, object: Expression | Super, membersOptionals: MembersOptionals, memberRanges: MemberRanges }} member names (reverse order) and remaining object
5216
6016
  */
@@ -5225,9 +6025,20 @@ class JavascriptParser extends Parser {
5225
6025
  const memberRanges = [];
5226
6026
  while (expr.type === "MemberExpression") {
5227
6027
  if (expr.computed) {
5228
- if (expr.property.type !== "Literal") break;
5229
- members.push(`${expr.property.value}`); // the literal
5230
- memberRanges.push(/** @type {Range} */ (expr.object.range)); // the range of the expression fragment before the literal
6028
+ const prop = expr.property;
6029
+ if (prop.type === "Literal") {
6030
+ members.push(`${prop.value}`); // the literal
6031
+ } else if (
6032
+ prop.type === "TemplateLiteral" &&
6033
+ prop.expressions.length === 0 &&
6034
+ typeof prop.quasis[0].value.cooked === "string"
6035
+ ) {
6036
+ // `[`url`]` is statically a string just like `["url"]`
6037
+ members.push(prop.quasis[0].value.cooked);
6038
+ } else {
6039
+ break;
6040
+ }
6041
+ memberRanges.push(/** @type {Range} */ (expr.object.range)); // the range of the expression fragment before the property
5231
6042
  } else {
5232
6043
  if (expr.property.type !== "Identifier") break;
5233
6044
  members.push(expr.property.name); // the identifier
@@ -5246,6 +6057,7 @@ class JavascriptParser extends Parser {
5246
6057
  }
5247
6058
 
5248
6059
  /**
6060
+ * Gets free info from variable.
5249
6061
  * @param {string} varName variable name
5250
6062
  * @returns {{ name: string, info: VariableInfo | string } | undefined} name of the free variable and variable info for that
5251
6063
  */
@@ -5265,6 +6077,7 @@ class JavascriptParser extends Parser {
5265
6077
  }
5266
6078
 
5267
6079
  /**
6080
+ * Gets name info from variable.
5268
6081
  * @param {string} varName variable name
5269
6082
  * @returns {{ name: string, info: VariableInfo | string } | undefined} name of the free variable and variable info for that
5270
6083
  */
@@ -5287,38 +6100,45 @@ class JavascriptParser extends Parser {
5287
6100
  /** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => Members, getMembersOptionals: () => MembersOptionals, getMemberRanges: () => MemberRanges }} ExpressionExpressionInfo */
5288
6101
 
5289
6102
  /**
6103
+ * Gets member expression info.
5290
6104
  * @param {Expression | Super} expression a member expression
5291
6105
  * @param {number} allowedTypes which types should be returned, presented in bit mask
5292
6106
  * @returns {CallExpressionInfo | ExpressionExpressionInfo | undefined} expression info
5293
6107
  */
5294
6108
  getMemberExpressionInfo(expression, allowedTypes) {
5295
- const { object, members, membersOptionals, memberRanges } =
5296
- this.extractMemberExpressionChain(expression);
6109
+ // Resolve the root first (no allocation); most calls reject here and so
6110
+ // never build the member arrays via extractMemberExpressionChain.
6111
+ const object = this.getMemberExpressionRoot(expression);
5297
6112
  switch (object.type) {
5298
6113
  case "CallExpression": {
5299
6114
  if ((allowedTypes & ALLOWED_MEMBER_TYPES_CALL_EXPRESSION) === 0) return;
5300
- let callee = object.callee;
5301
- let rootMembers = EMPTY_ARRAY;
5302
- if (callee.type === "MemberExpression") {
5303
- ({ object: callee, members: rootMembers } =
5304
- this.extractMemberExpressionChain(callee));
5305
- }
6115
+ const calleeExpr = object.callee;
6116
+ const callee =
6117
+ calleeExpr.type === "MemberExpression"
6118
+ ? this.getMemberExpressionRoot(calleeExpr)
6119
+ : calleeExpr;
5306
6120
  const rootName = getRootName(callee);
5307
6121
  if (!rootName) return;
5308
6122
  const result = this.getNameInfoFromVariable(rootName);
5309
6123
  if (!result) return;
5310
6124
  const { info: rootInfo, name: resolvedRoot } = result;
6125
+ const rootMembers =
6126
+ calleeExpr.type === "MemberExpression"
6127
+ ? this.extractMemberExpressionChain(calleeExpr).members
6128
+ : EMPTY_ARRAY;
6129
+ const { members, membersOptionals, memberRanges } =
6130
+ this.extractMemberExpressionChain(expression);
5311
6131
  const calleeName = objectAndMembersToName(resolvedRoot, rootMembers);
5312
6132
  return {
5313
6133
  type: "call",
5314
6134
  call: object,
5315
6135
  calleeName,
5316
6136
  rootInfo,
5317
- getCalleeMembers: memoize(() => rootMembers.reverse()),
6137
+ getCalleeMembers: lazyReverse(rootMembers),
5318
6138
  name: objectAndMembersToName(`${calleeName}()`, members),
5319
- getMembers: memoize(() => members.reverse()),
5320
- getMembersOptionals: memoize(() => membersOptionals.reverse()),
5321
- getMemberRanges: memoize(() => memberRanges.reverse())
6139
+ getMembers: lazyReverse(members),
6140
+ getMembersOptionals: lazyReverse(membersOptionals),
6141
+ getMemberRanges: lazyReverse(memberRanges)
5322
6142
  };
5323
6143
  }
5324
6144
  case "Identifier":
@@ -5331,19 +6151,22 @@ class JavascriptParser extends Parser {
5331
6151
  const result = this.getNameInfoFromVariable(rootName);
5332
6152
  if (!result) return;
5333
6153
  const { info: rootInfo, name: resolvedRoot } = result;
6154
+ const { members, membersOptionals, memberRanges } =
6155
+ this.extractMemberExpressionChain(expression);
5334
6156
  return {
5335
6157
  type: "expression",
5336
6158
  name: objectAndMembersToName(resolvedRoot, members),
5337
6159
  rootInfo,
5338
- getMembers: memoize(() => members.reverse()),
5339
- getMembersOptionals: memoize(() => membersOptionals.reverse()),
5340
- getMemberRanges: memoize(() => memberRanges.reverse())
6160
+ getMembers: lazyReverse(members),
6161
+ getMembersOptionals: lazyReverse(membersOptionals),
6162
+ getMemberRanges: lazyReverse(memberRanges)
5341
6163
  };
5342
6164
  }
5343
6165
  }
5344
6166
  }
5345
6167
 
5346
6168
  /**
6169
+ * Gets name for expression.
5347
6170
  * @param {Expression} expression an expression
5348
6171
  * @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => Members } | undefined} name info
5349
6172
  */
@@ -5355,6 +6178,7 @@ class JavascriptParser extends Parser {
5355
6178
  }
5356
6179
 
5357
6180
  /**
6181
+ * Get module parse function.
5358
6182
  * @param {Compilation} compilation compilation
5359
6183
  * @param {Module} module module
5360
6184
  * @returns {ParseFunction | undefined} parser
@@ -5375,6 +6199,7 @@ class JavascriptParser extends Parser {
5375
6199
  }
5376
6200
 
5377
6201
  /**
6202
+ * Returns parse result.
5378
6203
  * @param {string} code source code
5379
6204
  * @param {InternalParseOptions} options parsing options
5380
6205
  * @param {ParseFunction=} customParse custom function to parse
@@ -5383,13 +6208,32 @@ class JavascriptParser extends Parser {
5383
6208
  static _parse(code, options, customParse) {
5384
6209
  const type = options ? options.sourceType : "module";
5385
6210
  /** @type {ParseOptions} */
5386
- const parserOptions = {
5387
- ...defaultParserOptions,
5388
- allowReturnOutsideFunction: type === "script",
5389
- ...options,
5390
- sourceType: type === "auto" ? "module" : type
5391
- };
6211
+ let parserOptions;
6212
+ if (typeof customParse === "function") {
6213
+ // a user parse function may retain the options object — keep it fresh
6214
+ parserOptions = {
6215
+ ...defaultParserOptions,
6216
+ allowReturnOutsideFunction: type === "script",
6217
+ ...options,
6218
+ sourceType: type === "auto" ? "module" : type
6219
+ };
6220
+ } else {
6221
+ // reuse one options object across parses (parsing is synchronous) to
6222
+ // skip re-materializing it per module; acorn copies it via getOptions.
6223
+ // Every non-default key a caller may pass must be reset here.
6224
+ parserOptions = REUSED_PARSER_OPTIONS;
6225
+ parserOptions.importPhases = false;
6226
+ Object.assign(parserOptions, defaultParserOptions);
6227
+ parserOptions.allowReturnOutsideFunction = type === "script";
6228
+ if (options) Object.assign(parserOptions, options);
6229
+ parserOptions.sourceType = type === "auto" ? "module" : type;
6230
+ // let WebpackParser downgrade module->script in place on script-only
6231
+ // syntax so `auto` avoids a second full parse in the common case
6232
+ parserOptions.moduleFallback = type === "auto";
6233
+ }
6234
+ const wantRanges = parserOptions.ranges === true;
5392
6235
  /**
6236
+ * Returns parse result.
5393
6237
  * @param {string} code source code
5394
6238
  * @param {ParseOptions} options parsing options
5395
6239
  * @returns {ParseResult} parse result
@@ -5402,36 +6246,46 @@ class JavascriptParser extends Parser {
5402
6246
  /** @type {Comment[]} */
5403
6247
  const comments = [];
5404
6248
 
5405
- if (options.comments) {
5406
- /** @type {AcornOptions} */
5407
- (options).onComment = comments;
6249
+ // Whenever ranges are wanted (the main parse path and the concatenation
6250
+ // re-parse), have the parser plugin serve `range` on demand instead of
6251
+ // eagerly. `wantRanges` is hoisted since the auto-fallback re-enters
6252
+ // with the same (mutated) options object.
6253
+ options.lazyNodes = wantRanges;
6254
+ if (wantRanges) {
6255
+ // the lazy plugin replaces acorn's native tracking — disabling it
6256
+ // here lets WebpackParser skip its defensive options copy
6257
+ options.locations = false;
6258
+ options.ranges = false;
5408
6259
  }
5409
6260
 
5410
- /** @type {Set<number>} */
5411
- const semicolons = new Set();
5412
-
5413
- if (options.semicolons) {
5414
- /** @type {AcornOptions} */
5415
- (options).onInsertedSemicolon = (pos) => semicolons.add(pos);
6261
+ if (options.comments) {
6262
+ if (wantRanges) {
6263
+ // the parser plugin collects the comments itself, deferring the
6264
+ // text slice until some hook actually reads `value`
6265
+ options.lazyComments = comments;
6266
+ } else {
6267
+ /** @type {AcornOptions} */
6268
+ (options).onComment =
6269
+ /** @type {import("acorn").Comment[]} */
6270
+ (/** @type {unknown} */ (comments));
6271
+ }
5416
6272
  }
5417
6273
 
5418
6274
  const ast =
5419
6275
  /** @type {Program} */
5420
6276
  (parser.parse(code, /** @type {AcornOptions} */ (options)));
5421
6277
 
5422
- return { ast, comments, semicolons };
6278
+ return { ast, comments };
5423
6279
  };
5424
6280
 
5425
6281
  /** @type {Program | undefined} */
5426
6282
  let ast;
5427
6283
  /** @type {Comment[] | undefined} */
5428
6284
  let comments;
5429
- /** @type {Set<number> | undefined} */
5430
- let semicolons;
5431
6285
  let error;
5432
6286
  let threw = false;
5433
6287
  try {
5434
- ({ ast, comments, semicolons } = internalParse(code, parserOptions));
6288
+ ({ ast, comments } = internalParse(code, parserOptions));
5435
6289
  } catch (err) {
5436
6290
  error = err;
5437
6291
  threw = true;
@@ -5440,9 +6294,11 @@ class JavascriptParser extends Parser {
5440
6294
  if (threw && type === "auto") {
5441
6295
  parserOptions.sourceType = "script";
5442
6296
  parserOptions.allowReturnOutsideFunction = true;
6297
+ // the retry is already a full script parse — no in-place downgrade
6298
+ parserOptions.moduleFallback = false;
5443
6299
 
5444
6300
  try {
5445
- ({ ast, comments, semicolons } = internalParse(code, parserOptions));
6301
+ ({ ast, comments } = internalParse(code, parserOptions));
5446
6302
  threw = false;
5447
6303
  } catch (_err) {
5448
6304
  // we use the error from first parse try
@@ -5450,15 +6306,22 @@ class JavascriptParser extends Parser {
5450
6306
  }
5451
6307
  }
5452
6308
 
6309
+ // release per-parse state retained on the (possibly reused) options
6310
+ // object — the comments array retains source text slices
6311
+ parserOptions.lazyComments = undefined;
6312
+ /** @type {AcornOptions} */
6313
+ (parserOptions).onComment = undefined;
6314
+
5453
6315
  if (threw) {
5454
6316
  throw error;
5455
6317
  }
5456
6318
 
5457
- return /** @type {ParseResult} */ ({ ast, comments, semicolons });
6319
+ return /** @type {ParseResult} */ ({ ast, comments });
5458
6320
  }
5459
6321
 
5460
6322
  /**
5461
- * @param {((BaseParser: typeof AcornParser) => typeof AcornParser)[]} plugins parser plugin
6323
+ * Returns parser.
6324
+ * @param {((BaseParser: AcornParser) => AcornParser)[]} plugins parser plugin
5462
6325
  * @returns {typeof JavascriptParser} parser
5463
6326
  */
5464
6327
  static extend(...plugins) {