webpack 5.107.2 → 5.108.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 (357) hide show
  1. package/hot/dev-server.js +2 -0
  2. package/lib/APIPlugin.js +8 -4
  3. package/lib/CacheFacade.js +7 -0
  4. package/lib/Chunk.js +4 -0
  5. package/lib/ChunkGraph.js +30 -9
  6. package/lib/CircularModulesPlugin.js +190 -0
  7. package/lib/CleanPlugin.js +2 -1
  8. package/lib/Compilation.js +396 -65
  9. package/lib/Compiler.js +25 -11
  10. package/lib/ConcatenationScope.js +10 -3
  11. package/lib/ContextExclusionPlugin.js +1 -0
  12. package/lib/ContextModule.js +92 -47
  13. package/lib/ContextReplacementPlugin.js +4 -0
  14. package/lib/DefinePlugin.js +89 -15
  15. package/lib/Dependency.js +111 -7
  16. package/lib/EntryOptionPlugin.js +39 -2
  17. package/lib/EntryPlugin.js +2 -0
  18. package/lib/ExportsInfo.js +314 -73
  19. package/lib/ExternalModule.js +82 -34
  20. package/lib/ExternalModuleFactoryPlugin.js +1 -0
  21. package/lib/ExternalsPlugin.js +1 -0
  22. package/lib/FileSystemInfo.js +173 -23
  23. package/lib/FlagAllModulesAsUsedPlugin.js +1 -5
  24. package/lib/FlagDependencyExportsPlugin.js +23 -0
  25. package/lib/FlagDependencyUsagePlugin.js +87 -5
  26. package/lib/FlagEntryExportAsUsedPlugin.js +2 -0
  27. package/lib/Generator.js +8 -0
  28. package/lib/HotModuleReplacementPlugin.js +65 -28
  29. package/lib/IgnorePlugin.js +1 -0
  30. package/lib/InitFragment.js +5 -0
  31. package/lib/JavascriptMetaInfoPlugin.js +7 -5
  32. package/lib/LazyBarrel.js +361 -0
  33. package/lib/LoaderTargetPlugin.js +1 -0
  34. package/lib/Module.js +21 -42
  35. package/lib/ModuleGraph.js +3 -2
  36. package/lib/ModuleProfile.js +27 -1
  37. package/lib/ModuleTemplate.js +2 -0
  38. package/lib/MultiCompiler.js +2 -0
  39. package/lib/MultiStats.js +1 -0
  40. package/lib/MultiWatching.js +2 -0
  41. package/lib/NodeStuffPlugin.js +22 -17
  42. package/lib/NormalModule.js +142 -80
  43. package/lib/NormalModuleReplacementPlugin.js +2 -0
  44. package/lib/PrefetchPlugin.js +2 -0
  45. package/lib/ProgressPlugin.js +8 -0
  46. package/lib/ProvidePlugin.js +1 -0
  47. package/lib/RawModule.js +20 -16
  48. package/lib/RecordIdsPlugin.js +1 -0
  49. package/lib/RuntimeGlobals.js +5 -0
  50. package/lib/RuntimePlugin.js +58 -26
  51. package/lib/RuntimeTemplate.js +278 -21
  52. package/lib/SelfModuleFactory.js +1 -0
  53. package/lib/SourceMapDevToolPlugin.js +3 -5
  54. package/lib/Stats.js +1 -0
  55. package/lib/Template.js +8 -2
  56. package/lib/TemplatedPathPlugin.js +473 -131
  57. package/lib/WarnCaseSensitiveModulesPlugin.js +1 -0
  58. package/lib/WarnDeprecatedOptionPlugin.js +4 -0
  59. package/lib/WarnNoModeSetPlugin.js +1 -0
  60. package/lib/WatchIgnorePlugin.js +1 -0
  61. package/lib/Watching.js +9 -0
  62. package/lib/WebpackOptionsApply.js +50 -5
  63. package/lib/asset/AssetBytesGenerator.js +11 -3
  64. package/lib/asset/AssetGenerator.js +47 -22
  65. package/lib/asset/AssetModule.js +47 -0
  66. package/lib/asset/AssetModulesPlugin.js +14 -14
  67. package/lib/asset/AssetParser.js +2 -2
  68. package/lib/asset/AssetSourceGenerator.js +8 -0
  69. package/lib/asset/RawDataUrlModule.js +12 -13
  70. package/lib/buildChunkGraph.js +64 -7
  71. package/lib/bun/BunTargetPlugin.js +48 -0
  72. package/lib/cache/AddBuildDependenciesPlugin.js +1 -0
  73. package/lib/cache/AddManagedPathsPlugin.js +3 -0
  74. package/lib/cache/IdleFileCachePlugin.js +4 -0
  75. package/lib/cache/MemoryWithGcCachePlugin.js +1 -0
  76. package/lib/cache/PackFileCacheStrategy.js +1 -0
  77. package/lib/cache/ResolverCachePlugin.js +2 -0
  78. package/lib/cache/mergeEtags.js +2 -0
  79. package/lib/cli.js +109 -19
  80. package/lib/config/browserslistTargetHandler.js +99 -0
  81. package/lib/config/defaults.js +147 -7
  82. package/lib/config/defineConfig.js +31 -0
  83. package/lib/config/normalization.js +5 -0
  84. package/lib/config/target.js +181 -2
  85. package/lib/container/ContainerEntryModule.js +15 -14
  86. package/lib/container/ContainerExposedDependency.js +2 -2
  87. package/lib/container/ContainerReferencePlugin.js +1 -1
  88. package/lib/container/FallbackDependency.js +5 -7
  89. package/lib/container/FallbackModule.js +10 -9
  90. package/lib/container/RemoteModule.js +20 -10
  91. package/lib/container/RemoteRuntimeModule.js +14 -12
  92. package/lib/css/CssGenerator.js +353 -327
  93. package/lib/css/CssInjectStyleRuntimeModule.js +36 -8
  94. package/lib/css/CssLoadingRuntimeModule.js +118 -47
  95. package/lib/css/CssModule.js +52 -23
  96. package/lib/css/CssModulesPlugin.js +107 -124
  97. package/lib/css/CssParser.js +2759 -2205
  98. package/lib/css/syntax.js +2859 -0
  99. package/lib/debug/ProfilingPlugin.js +2 -0
  100. package/lib/deno/DenoTargetPlugin.js +47 -0
  101. package/lib/dependencies/AMDDefineDependency.js +22 -17
  102. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +1 -0
  103. package/lib/dependencies/AMDRequireArrayDependency.js +7 -11
  104. package/lib/dependencies/AMDRequireContextDependency.js +7 -11
  105. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +1 -0
  106. package/lib/dependencies/AMDRequireDependency.js +24 -20
  107. package/lib/dependencies/CachedConstDependency.js +3 -0
  108. package/lib/dependencies/CommonJsDependencyHelpers.js +1 -0
  109. package/lib/dependencies/CommonJsExportRequireDependency.js +79 -31
  110. package/lib/dependencies/CommonJsExportsDependency.js +21 -16
  111. package/lib/dependencies/CommonJsExportsParserPlugin.js +230 -7
  112. package/lib/dependencies/CommonJsFullRequireDependency.js +27 -19
  113. package/lib/dependencies/CommonJsImportsParserPlugin.js +51 -16
  114. package/lib/dependencies/CommonJsPlugin.js +1 -1
  115. package/lib/dependencies/CommonJsRequireContextDependency.js +10 -13
  116. package/lib/dependencies/CommonJsRequireDependency.js +42 -11
  117. package/lib/dependencies/CommonJsSelfReferenceDependency.js +22 -14
  118. package/lib/dependencies/ConstDependency.js +16 -11
  119. package/lib/dependencies/ContextDependency.js +4 -0
  120. package/lib/dependencies/ContextDependencyTemplateAsId.js +1 -1
  121. package/lib/dependencies/ContextElementDependency.js +23 -14
  122. package/lib/dependencies/CreateRequireParserPlugin.js +1 -0
  123. package/lib/dependencies/CreateScriptUrlDependency.js +5 -7
  124. package/lib/dependencies/CriticalDependencyWarning.js +1 -0
  125. package/lib/dependencies/CssIcssExportDependency.js +512 -574
  126. package/lib/dependencies/CssIcssImportDependency.js +9 -9
  127. package/lib/dependencies/CssIcssSymbolDependency.js +22 -15
  128. package/lib/dependencies/CssImportDependency.js +25 -1
  129. package/lib/dependencies/CssUrlDependency.js +23 -14
  130. package/lib/dependencies/DllEntryDependency.js +9 -13
  131. package/lib/dependencies/ExportBindingInitFragment.js +164 -0
  132. package/lib/dependencies/ExportsInfoDependency.js +12 -12
  133. package/lib/dependencies/ExternalModuleDependency.js +8 -5
  134. package/lib/dependencies/ExternalModuleInitFragment.js +7 -5
  135. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +13 -10
  136. package/lib/dependencies/HarmonyAcceptDependency.js +11 -11
  137. package/lib/dependencies/HarmonyAcceptImportDependency.js +1 -0
  138. package/lib/dependencies/HarmonyDetectionParserPlugin.js +47 -22
  139. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +28 -2
  140. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +46 -22
  141. package/lib/dependencies/HarmonyExportExpressionDependency.js +107 -30
  142. package/lib/dependencies/HarmonyExportHeaderDependency.js +7 -9
  143. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +109 -31
  144. package/lib/dependencies/HarmonyExportInitFragment.js +18 -15
  145. package/lib/dependencies/HarmonyExportSpecifierDependency.js +83 -18
  146. package/lib/dependencies/HarmonyExports.js +4 -1
  147. package/lib/dependencies/HarmonyImportDependency.js +24 -0
  148. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +110 -74
  149. package/lib/dependencies/HarmonyImportGuard.js +254 -0
  150. package/lib/dependencies/HarmonyImportSideEffectDependency.js +18 -1
  151. package/lib/dependencies/HarmonyImportSpecifierDependency.js +118 -14
  152. package/lib/dependencies/HarmonyLinkingError.js +1 -0
  153. package/lib/dependencies/HarmonyModulesPlugin.js +1 -0
  154. package/lib/dependencies/{HtmlScriptSrcDependency.js → HtmlEntryDependency.js} +261 -109
  155. package/lib/dependencies/HtmlInlineHtmlDependency.js +107 -0
  156. package/lib/dependencies/HtmlInlineScriptDependency.js +17 -13
  157. package/lib/dependencies/HtmlInlineStyleDependency.js +45 -11
  158. package/lib/dependencies/ImportContextDependency.js +5 -9
  159. package/lib/dependencies/ImportDependency.js +44 -2
  160. package/lib/dependencies/ImportMetaHotAcceptDependency.js +1 -0
  161. package/lib/dependencies/ImportMetaHotDeclineDependency.js +1 -0
  162. package/lib/dependencies/ImportMetaPlugin.js +74 -30
  163. package/lib/dependencies/ImportParserPlugin.js +19 -0
  164. package/lib/dependencies/ImportWeakDependency.js +1 -0
  165. package/lib/dependencies/JsonExportsDependency.js +9 -9
  166. package/lib/dependencies/LoaderImportDependency.js +1 -0
  167. package/lib/dependencies/LocalModule.js +11 -12
  168. package/lib/dependencies/LocalModuleDependency.js +11 -13
  169. package/lib/dependencies/ModuleDecoratorDependency.js +9 -9
  170. package/lib/dependencies/ModuleDependency.js +7 -0
  171. package/lib/dependencies/ModuleHotAcceptDependency.js +1 -0
  172. package/lib/dependencies/ModuleHotDeclineDependency.js +1 -0
  173. package/lib/dependencies/ModuleInitFragmentDependency.js +15 -11
  174. package/lib/dependencies/ProvidedDependency.js +31 -27
  175. package/lib/dependencies/PureExpressionDependency.js +7 -9
  176. package/lib/dependencies/RequireEnsureDependency.js +12 -13
  177. package/lib/dependencies/RequireHeaderDependency.js +3 -4
  178. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +3 -0
  179. package/lib/dependencies/RequireResolveContextDependency.js +7 -11
  180. package/lib/dependencies/RequireResolveDependency.js +1 -0
  181. package/lib/dependencies/RequireResolveHeaderDependency.js +3 -5
  182. package/lib/dependencies/RuntimeRequirementsDependency.js +6 -7
  183. package/lib/dependencies/StaticExportsDependency.js +10 -10
  184. package/lib/dependencies/SystemPlugin.js +2 -0
  185. package/lib/dependencies/URLContextDependency.js +5 -7
  186. package/lib/dependencies/URLDependency.js +14 -16
  187. package/lib/dependencies/UnsupportedDependency.js +8 -13
  188. package/lib/dependencies/WebAssemblyExportImportedDependency.js +11 -16
  189. package/lib/dependencies/WebAssemblyImportDependency.js +14 -16
  190. package/lib/dependencies/WebpackIsIncludedDependency.js +1 -0
  191. package/lib/dependencies/WorkerDependency.js +19 -8
  192. package/lib/dependencies/WorkerPlugin.js +22 -6
  193. package/lib/dependencies/processExportInfo.js +13 -11
  194. package/lib/dll/DelegatedModule.js +29 -15
  195. package/lib/dll/DelegatedModuleFactoryPlugin.js +1 -0
  196. package/lib/dll/DelegatedPlugin.js +1 -0
  197. package/lib/dll/DllEntryPlugin.js +3 -0
  198. package/lib/dll/DllModule.js +3 -2
  199. package/lib/dll/DllPlugin.js +16 -0
  200. package/lib/dll/DllReferencePlugin.js +3 -0
  201. package/lib/dll/LibManifestPlugin.js +1 -0
  202. package/lib/electron/ElectronTargetPlugin.js +22 -4
  203. package/lib/errors/ConcurrentCompilationError.js +1 -0
  204. package/lib/errors/HookWebpackError.js +11 -13
  205. package/lib/errors/IgnoreErrorModuleFactory.js +1 -0
  206. package/lib/errors/InvalidDependenciesModuleWarning.js +2 -0
  207. package/lib/errors/JSONParseError.js +9 -8
  208. package/lib/errors/ModuleBuildError.js +16 -13
  209. package/lib/errors/ModuleDependencyError.js +8 -1
  210. package/lib/errors/ModuleDependencyWarning.js +8 -1
  211. package/lib/errors/ModuleError.js +5 -11
  212. package/lib/errors/ModuleHashingError.js +4 -0
  213. package/lib/errors/ModuleNotFoundError.js +3 -0
  214. package/lib/errors/ModuleParseError.js +5 -11
  215. package/lib/errors/ModuleRestoreError.js +2 -0
  216. package/lib/errors/ModuleStoreError.js +3 -0
  217. package/lib/errors/ModuleWarning.js +7 -11
  218. package/lib/errors/NodeStuffInWebError.js +1 -0
  219. package/lib/errors/NonErrorEmittedError.js +2 -0
  220. package/lib/errors/UnhandledSchemeError.js +1 -0
  221. package/lib/esm/ModuleChunkLoadingPlugin.js +0 -1
  222. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +28 -23
  223. package/lib/hmr/HotModuleReplacement.runtime.js +175 -30
  224. package/lib/hmr/HotModuleReplacementRuntimeModule.js +7 -0
  225. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +173 -26
  226. package/lib/hmr/LazyCompilationPlugin.js +30 -6
  227. package/lib/html/HtmlGenerator.js +217 -23
  228. package/lib/html/HtmlModule.js +40 -0
  229. package/lib/html/HtmlModulesPlugin.js +219 -55
  230. package/lib/html/HtmlParser.js +1108 -1099
  231. package/lib/html/{walkHtmlTokens.js → syntax.js} +4701 -212
  232. package/lib/ids/IdHelpers.js +4 -2
  233. package/lib/index.js +19 -0
  234. package/lib/javascript/BasicEvaluatedExpression.js +1 -0
  235. package/lib/javascript/EnableChunkLoadingPlugin.js +1 -0
  236. package/lib/javascript/JavascriptGenerator.js +6 -2
  237. package/lib/javascript/JavascriptModule.js +54 -0
  238. package/lib/javascript/JavascriptModulesPlugin.js +257 -102
  239. package/lib/javascript/JavascriptParser.js +285 -158
  240. package/lib/json/JsonModule.js +40 -0
  241. package/lib/json/JsonModulesPlugin.js +7 -0
  242. package/lib/json/JsonParser.js +4 -2
  243. package/lib/library/AssignLibraryPlugin.js +5 -3
  244. package/lib/library/ExportPropertyLibraryPlugin.js +1 -0
  245. package/lib/library/FalseIIFEUmdWarning.js +1 -0
  246. package/lib/library/ModuleLibraryPlugin.js +24 -5
  247. package/lib/library/SystemLibraryPlugin.js +3 -3
  248. package/lib/node/NodeTargetPlugin.js +1 -0
  249. package/lib/node/NodeWatchFileSystem.js +1 -0
  250. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +10 -9
  251. package/lib/node/RequireChunkLoadingRuntimeModule.js +18 -16
  252. package/lib/optimize/ConcatenatedModule.js +395 -77
  253. package/lib/optimize/ConstExportsPlugin.js +211 -0
  254. package/lib/optimize/InlineExports.js +178 -0
  255. package/lib/optimize/InnerGraph.js +372 -275
  256. package/lib/optimize/InnerGraphPlugin.js +196 -99
  257. package/lib/optimize/ModuleConcatenationPlugin.js +56 -25
  258. package/lib/optimize/RealContentHashPlugin.js +14 -1
  259. package/lib/optimize/SideEffectsFlagPlugin.js +234 -64
  260. package/lib/runtime/AsyncModuleRuntimeModule.js +32 -30
  261. package/lib/runtime/AutoPublicPathRuntimeModule.js +11 -5
  262. package/lib/runtime/CompatGetDefaultExportRuntimeModule.js +1 -1
  263. package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +6 -4
  264. package/lib/runtime/DefinePropertyGettersRuntimeModule.js +33 -4
  265. package/lib/runtime/GetChunkFilenameRuntimeModule.js +82 -3
  266. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +1 -1
  267. package/lib/runtime/HasOwnPropertyRuntimeModule.js +1 -1
  268. package/lib/runtime/LoadScriptRuntimeModule.js +18 -13
  269. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +39 -26
  270. package/lib/runtime/MakeNamespaceObjectRuntimeModule.js +1 -1
  271. package/lib/runtime/OnChunksLoadedRuntimeModule.js +4 -4
  272. package/lib/runtime/RelativeUrlRuntimeModule.js +3 -2
  273. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +1 -1
  274. package/lib/runtime/StartupEntrypointRuntimeModule.js +4 -3
  275. package/lib/runtime/WorkerRuntimeModule.js +33 -0
  276. package/lib/schemes/HttpUriPlugin.js +3 -2
  277. package/lib/serialization/AggregateErrorSerializer.js +7 -6
  278. package/lib/serialization/ArraySerializer.js +4 -8
  279. package/lib/serialization/BinaryMiddleware.js +538 -468
  280. package/lib/serialization/DateObjectSerializer.js +2 -2
  281. package/lib/serialization/ErrorObjectSerializer.js +7 -6
  282. package/lib/serialization/MapObjectSerializer.js +5 -9
  283. package/lib/serialization/NullPrototypeObjectSerializer.js +7 -9
  284. package/lib/serialization/ObjectMiddleware.js +50 -13
  285. package/lib/serialization/PlainObjectSerializer.js +9 -8
  286. package/lib/serialization/RegExpObjectSerializer.js +2 -2
  287. package/lib/serialization/Serializer.js +1 -0
  288. package/lib/serialization/SetObjectSerializer.js +4 -8
  289. package/lib/sharing/ConsumeSharedModule.js +6 -7
  290. package/lib/sharing/ConsumeSharedPlugin.js +1 -0
  291. package/lib/sharing/ConsumeSharedRuntimeModule.js +46 -41
  292. package/lib/sharing/ProvideSharedDependency.js +30 -15
  293. package/lib/sharing/ProvideSharedModule.js +30 -11
  294. package/lib/sharing/ProvideSharedPlugin.js +4 -2
  295. package/lib/sharing/SharePlugin.js +3 -0
  296. package/lib/sharing/ShareRuntimeModule.js +18 -16
  297. package/lib/sharing/resolveMatchedConfigs.js +2 -1
  298. package/lib/sharing/utils.js +1 -1
  299. package/lib/stats/DefaultStatsFactoryPlugin.js +4 -6
  300. package/lib/stats/DefaultStatsPrinterPlugin.js +14 -14
  301. package/lib/stats/StatsFactory.js +11 -9
  302. package/lib/stats/StatsPrinter.js +9 -2
  303. package/lib/url/URLParserPlugin.js +5 -2
  304. package/lib/util/AsyncQueue.js +10 -0
  305. package/lib/util/LazyBucketSortedSet.js +5 -0
  306. package/lib/util/LazySet.js +6 -4
  307. package/lib/util/LocConverter.js +11 -1
  308. package/lib/util/Semaphore.js +1 -0
  309. package/lib/util/SourceProcessor.js +106 -0
  310. package/lib/util/TupleSet.js +1 -0
  311. package/lib/util/WeakTupleMap.js +27 -1
  312. package/lib/util/chainedImports.js +3 -3
  313. package/lib/util/comparators.js +2 -2
  314. package/lib/util/concatenate.js +31 -7
  315. package/lib/util/createHash.js +0 -1
  316. package/lib/util/deterministicGrouping.js +19 -12
  317. package/lib/util/extractSourceMap.js +1 -1
  318. package/lib/util/findGraphRoots.js +2 -0
  319. package/lib/util/fs.js +10 -5
  320. package/lib/util/hash/DebugHash.js +1 -0
  321. package/lib/util/hash/hash-digest.js +24 -15
  322. package/lib/util/identifier.js +7 -0
  323. package/lib/util/internalSerializables.js +11 -2
  324. package/lib/util/magicComment.js +42 -0
  325. package/lib/util/makeSerializable.js +1 -0
  326. package/lib/util/nonNumericOnlyHash.js +30 -1
  327. package/lib/util/property.js +7 -1
  328. package/lib/util/publicPathPlaceholder.js +64 -0
  329. package/lib/util/registerExternalSerializer.js +4 -4
  330. package/lib/wasm-async/AsyncWasmModule.js +77 -0
  331. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +1 -1
  332. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +1 -96
  333. package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
  334. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +1 -1
  335. package/lib/wasm-sync/SyncWasmModule.js +39 -0
  336. package/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +1 -0
  337. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +6 -3
  338. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +2 -1
  339. package/lib/wasm-sync/WebAssemblyGenerator.js +1 -0
  340. package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +2 -0
  341. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +10 -0
  342. package/lib/wasm-sync/WebAssemblyParser.js +7 -3
  343. package/lib/web/JsonpChunkLoadingRuntimeModule.js +45 -39
  344. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +11 -10
  345. package/package.json +35 -27
  346. package/schemas/WebpackOptions.check.js +1 -1
  347. package/schemas/WebpackOptions.json +212 -3
  348. package/schemas/plugins/HtmlGeneratorOptions.check.js +1 -1
  349. package/schemas/plugins/HtmlParserOptions.check.d.ts +7 -0
  350. package/schemas/plugins/HtmlParserOptions.check.js +6 -0
  351. package/schemas/plugins/HtmlParserOptions.json +3 -0
  352. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +1 -1
  353. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  354. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  355. package/types.d.ts +1456 -290
  356. package/lib/css/walkCssTokens.js +0 -2020
  357. package/lib/util/AppendOnlyStackedSet.js +0 -93
@@ -17,7 +17,6 @@ const {
17
17
  createMagicCommentContext,
18
18
  webpackCommentRegExp
19
19
  } = require("../util/magicComment");
20
- const memoize = require("../util/memoize");
21
20
  const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
22
21
 
23
22
  /** @typedef {import("acorn").Options} AcornOptions */
@@ -120,6 +119,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
120
119
  /** @typedef {import("../Module")} Module */
121
120
 
122
121
  /** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => Members, getMembersOptionals: () => MembersOptionals, getMemberRanges: () => MemberRanges }} GetInfoResult */
122
+ /** @typedef {{ consequent?: EXPECTED_OBJECT, alternate?: EXPECTED_OBJECT }} GuardCollection per-branch guard frames pushed onto the parser state guard stack */
123
123
  /** @typedef {Statement | ModuleDeclaration | Expression | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} StatementPathItem */
124
124
  /** @typedef {(ident: string) => void} OnIdentString */
125
125
  /** @typedef {(ident: string, identifier: Identifier) => void} OnIdent */
@@ -132,6 +132,26 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
132
132
 
133
133
  /** @type {string[]} */
134
134
  const EMPTY_ARRAY = [];
135
+
136
+ /**
137
+ * Getter that reverses `arr` in place on first access and caches it. Lighter
138
+ * than `memoize(() => arr.reverse())` (one closure instead of two) and called
139
+ * per member expression on hot parse paths.
140
+ * @template T
141
+ * @param {T[]} arr array reversed lazily on first access
142
+ * @returns {() => T[]} getter returning the reversed array
143
+ */
144
+ const lazyReverse = (arr) => {
145
+ let reversed = false;
146
+ return () => {
147
+ if (!reversed) {
148
+ arr.reverse();
149
+ reversed = true;
150
+ }
151
+ return arr;
152
+ };
153
+ };
154
+
135
155
  const ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = 0b01;
136
156
  const ALLOWED_MEMBER_TYPES_EXPRESSION = 0b10;
137
157
  const ALLOWED_MEMBER_TYPES_ALL = 0b11;
@@ -299,9 +319,13 @@ class VariableInfo {
299
319
  * @param {TagInfo | undefined} tagInfo info about tags
300
320
  */
301
321
  constructor(declaredScope, name, flags, tagInfo) {
322
+ /** @type {ScopeInfo} */
302
323
  this.declaredScope = declaredScope;
324
+ /** @type {string | undefined} */
303
325
  this.name = name;
326
+ /** @type {VariableInfoFlagsType} */
304
327
  this.flags = flags;
328
+ /** @type {TagInfo | undefined} */
305
329
  this.tagInfo = tagInfo;
306
330
  }
307
331
 
@@ -359,13 +383,12 @@ class VariableInfo {
359
383
  /** @typedef {symbol} Tag */
360
384
 
361
385
  /** @typedef {import("../dependencies/HarmonyImportDependencyParserPlugin").HarmonySettings} HarmonySettings */
362
- /** @typedef {import("../dependencies/HarmonyImportDependencyParserPlugin").HarmonySpecifierGuards} HarmonySpecifierGuards */
363
386
  /** @typedef {import("../dependencies/ImportParserPlugin").ImportSettings} ImportSettings */
364
387
  /** @typedef {import("../dependencies/CommonJsImportsParserPlugin").CommonJsImportSettings} CommonJsImportSettings */
365
388
  /** @typedef {import("../CompatibilityPlugin").CompatibilitySettings} CompatibilitySettings */
366
389
  /** @typedef {import("../optimize/InnerGraph").TopLevelSymbol} TopLevelSymbol */
367
390
 
368
- /** @typedef {HarmonySettings | ImportSettings | CommonJsImportSettings | TopLevelSymbol | CompatibilitySettings | HarmonySpecifierGuards} KnownTagData */
391
+ /** @typedef {HarmonySettings | ImportSettings | CommonJsImportSettings | TopLevelSymbol | CompatibilitySettings} KnownTagData */
369
392
  /** @typedef {KnownTagData | Record<string, EXPECTED_ANY>} TagData */
370
393
 
371
394
  /**
@@ -474,6 +497,25 @@ const getRootName = (expression) => {
474
497
  }
475
498
  };
476
499
 
500
+ /**
501
+ * @param {string} type AST node type
502
+ * @returns {boolean} true for FunctionExpression or ArrowFunctionExpression
503
+ */
504
+ const isFunctionExpression = (type) =>
505
+ type === "FunctionExpression" || type === "ArrowFunctionExpression";
506
+
507
+ /**
508
+ * @param {FunctionExpression | ArrowFunctionExpression} fn function
509
+ * @returns {boolean} true when all params are plain identifiers
510
+ */
511
+ const isSimpleFunction = (fn) => {
512
+ const params = fn.params;
513
+ for (let i = 0; i < params.length; i++) {
514
+ if (params[i].type !== "Identifier") return false;
515
+ }
516
+ return true;
517
+ };
518
+
477
519
  /** @type {ParseOptions} */
478
520
  const defaultParserOptions = {
479
521
  sourceType: "module",
@@ -536,7 +578,7 @@ class JavascriptParser extends Parser {
536
578
  statement: new SyncBailHook(["statement"]),
537
579
  /** @type {SyncBailHook<[IfStatement], boolean | void>} */
538
580
  statementIf: new SyncBailHook(["statement"]),
539
- /** @type {SyncBailHook<[Expression], ((walk: () => void) => void) | void>} */
581
+ /** @type {SyncBailHook<[Expression], GuardCollection | void>} */
540
582
  collectGuards: new SyncBailHook(["expression"]),
541
583
  /** @type {SyncBailHook<[Expression, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
542
584
  classExtendsExpression: new SyncBailHook([
@@ -713,6 +755,9 @@ class JavascriptParser extends Parser {
713
755
  /** @type {TagData | undefined} */
714
756
  this.currentTagData = undefined;
715
757
  this.magicCommentContext = createMagicCommentContext();
758
+ // Reused for enterPatterns on every scope entry to avoid per-scope closures.
759
+ /** @type {OnIdentString} */
760
+ this._defineVariable = (ident) => this.defineVariable(ident);
716
761
  this._initializeEvaluating();
717
762
  }
718
763
 
@@ -1494,15 +1539,16 @@ class JavascriptParser extends Parser {
1494
1539
  /** @type {Identifier | ThisExpression | MemberExpression} */ (expr);
1495
1540
 
1496
1541
  const info = getInfo(expression);
1542
+ // Cache the result (even when undefined) so the stage-100 tap below
1543
+ // reuses it instead of recomputing getInfo — getMemberExpressionInfo
1544
+ // is expensive and previously ran twice for every rejected member.
1545
+ cachedExpression = expression;
1546
+ cachedInfo = info;
1497
1547
  if (info !== undefined) {
1498
1548
  return this.callHooksForInfoWithFallback(
1499
1549
  this.hooks.evaluateIdentifier,
1500
1550
  info.name,
1501
- (_name) => {
1502
- cachedExpression = expression;
1503
- cachedInfo = info;
1504
- return undefined;
1505
- },
1551
+ (_name) => undefined,
1506
1552
  (name) => {
1507
1553
  const hook = this.hooks.evaluateDefinedIdentifier.get(name);
1508
1554
  if (hook !== undefined) {
@@ -1542,7 +1588,11 @@ class JavascriptParser extends Parser {
1542
1588
  const info = this.getVariableInfo(/** @type {Identifier} */ (expr).name);
1543
1589
  if (
1544
1590
  typeof info === "string" ||
1545
- (info instanceof VariableInfo && (info.isFree() || info.isTagged()))
1591
+ (info instanceof VariableInfo &&
1592
+ (info.isFree() ||
1593
+ info.isTagged() ||
1594
+ // Walk `tagInfo` in `callHooksForInfo` if tagInfo is present.
1595
+ info.tagInfo !== undefined))
1546
1596
  ) {
1547
1597
  return {
1548
1598
  name: info,
@@ -2368,6 +2418,27 @@ class JavascriptParser extends Parser {
2368
2418
  }
2369
2419
  }
2370
2420
 
2421
+ /**
2422
+ * Walks a conditional branch with its guard frame (if any) pushed onto the
2423
+ * parser-state guard stack for the duration of the branch body.
2424
+ * @param {EXPECTED_OBJECT | undefined | null} frame guard frame, or falsy when the branch is unguarded
2425
+ * @param {() => void} walk branch walk
2426
+ * @returns {void}
2427
+ */
2428
+ walkGuardedBranch(frame, walk) {
2429
+ if (!frame) {
2430
+ walk();
2431
+ return;
2432
+ }
2433
+ const stack = this.state.guardStack || (this.state.guardStack = []);
2434
+ stack.push(frame);
2435
+ try {
2436
+ walk();
2437
+ } finally {
2438
+ stack.pop();
2439
+ }
2440
+ }
2441
+
2371
2442
  /**
2372
2443
  * Processes the provided statement.
2373
2444
  * @param {IfStatement} statement if statement
@@ -2375,22 +2446,20 @@ class JavascriptParser extends Parser {
2375
2446
  walkIfStatement(statement) {
2376
2447
  const result = this.hooks.statementIf.call(statement);
2377
2448
  if (result === undefined) {
2378
- const inGuard = this.hooks.collectGuards.call(statement.test);
2379
- if (inGuard) {
2380
- inGuard(() => {
2381
- this.walkExpression(statement.test);
2382
- this.walkNestedStatement(statement.consequent);
2383
- });
2384
- } else {
2385
- this.walkExpression(statement.test);
2386
- this.walkNestedStatement(statement.consequent);
2387
- }
2449
+ const guard = this.hooks.collectGuards.call(statement.test);
2450
+ this.walkExpression(statement.test);
2451
+ this.walkGuardedBranch(guard ? guard.consequent : undefined, () =>
2452
+ this.walkNestedStatement(statement.consequent)
2453
+ );
2388
2454
 
2389
2455
  const consequentTerminated = this.scope.terminated;
2390
2456
  this.scope.terminated = undefined;
2391
2457
 
2392
2458
  if (statement.alternate) {
2393
- this.walkNestedStatement(statement.alternate);
2459
+ const alternate = statement.alternate;
2460
+ this.walkGuardedBranch(guard ? guard.alternate : undefined, () =>
2461
+ this.walkNestedStatement(alternate)
2462
+ );
2394
2463
  }
2395
2464
 
2396
2465
  const alternateTerminated = this.scope.terminated;
@@ -3101,23 +3170,42 @@ class JavascriptParser extends Parser {
3101
3170
  * @param {HookMap<SyncBailHook<[Identifier], boolean | void>>} hookMap map of hooks
3102
3171
  */
3103
3172
  _preWalkVariableDeclaration(statement, hookMap) {
3173
+ /** @type {OnIdent | undefined} */
3174
+ let onIdent;
3104
3175
  for (const declarator of statement.declarations) {
3105
- switch (declarator.type) {
3106
- case "VariableDeclarator": {
3107
- this.preWalkVariableDeclarator(declarator);
3108
- if (!this.hooks.preDeclarator.call(declarator, statement)) {
3109
- this.enterPattern(declarator.id, (name, ident) => {
3110
- let hook = hookMap.get(name);
3111
- if (hook === undefined || !hook.call(ident)) {
3112
- hook = this.hooks.varDeclaration.get(name);
3113
- if (hook === undefined || !hook.call(ident)) {
3114
- this.defineVariable(name);
3115
- }
3116
- }
3117
- });
3118
- }
3119
- break;
3176
+ if (declarator.type !== "VariableDeclarator") continue;
3177
+ this.preWalkVariableDeclarator(declarator);
3178
+ if (this.hooks.preDeclarator.call(declarator, statement)) continue;
3179
+ const id = declarator.id;
3180
+ if (id.type === "Identifier") {
3181
+ // fast path: plain `const x =` skips the enterPattern dispatch and
3182
+ // the per-declaration onIdent closure (only patterns need it)
3183
+ if (!this.callHooksForName(this.hooks.pattern, id.name, id)) {
3184
+ this._defineVariableForDeclaration(id.name, id, hookMap);
3120
3185
  }
3186
+ } else {
3187
+ if (onIdent === undefined) {
3188
+ onIdent = (name, ident) =>
3189
+ this._defineVariableForDeclaration(name, ident, hookMap);
3190
+ }
3191
+ this.enterPattern(id, onIdent);
3192
+ }
3193
+ }
3194
+ }
3195
+
3196
+ /**
3197
+ * Defines a declared variable unless a declaration hook handles it.
3198
+ * @param {string} name variable name
3199
+ * @param {Identifier} ident identifier node
3200
+ * @param {HookMap<SyncBailHook<[Identifier], boolean | void>>} hookMap kind-specific declaration hooks
3201
+ * @returns {void}
3202
+ */
3203
+ _defineVariableForDeclaration(name, ident, hookMap) {
3204
+ let hook = hookMap.get(name);
3205
+ if (hook === undefined || !hook.call(ident)) {
3206
+ hook = this.hooks.varDeclaration.get(name);
3207
+ if (hook === undefined || !hook.call(ident)) {
3208
+ this.defineVariable(name);
3121
3209
  }
3122
3210
  }
3123
3211
  }
@@ -3437,7 +3525,8 @@ class JavascriptParser extends Parser {
3437
3525
  * @param {(Expression | SpreadElement | null)[]} expressions expressions
3438
3526
  */
3439
3527
  walkExpressions(expressions) {
3440
- for (const expression of expressions) {
3528
+ for (let i = 0, len = expressions.length; i < len; i++) {
3529
+ const expression = expressions[i];
3441
3530
  if (expression) {
3442
3531
  this.walkExpression(expression);
3443
3532
  }
@@ -3605,12 +3694,11 @@ class JavascriptParser extends Parser {
3605
3694
  walkFunctionExpression(expression) {
3606
3695
  const wasTopLevel = this.scope.topLevelScope;
3607
3696
  this.scope.topLevelScope = false;
3608
- const scopeParams = [...expression.params];
3609
-
3610
- // Add function name in scope for recursive calls
3611
- if (expression.id) {
3612
- scopeParams.push(expression.id);
3613
- }
3697
+ // Only copy params when the function name must be added (recursive calls);
3698
+ // inFunctionScope reads params without mutating, like arrow functions.
3699
+ const scopeParams = expression.id
3700
+ ? [...expression.params, expression.id]
3701
+ : expression.params;
3614
3702
 
3615
3703
  this.inFunctionScope(true, scopeParams, () => {
3616
3704
  for (const param of expression.params) {
@@ -3838,19 +3926,17 @@ class JavascriptParser extends Parser {
3838
3926
  walkConditionalExpression(expression) {
3839
3927
  const result = this.hooks.expressionConditionalOperator.call(expression);
3840
3928
  if (result === undefined) {
3841
- const inGuard = this.hooks.collectGuards.call(expression.test);
3842
- if (inGuard) {
3843
- inGuard(() => {
3844
- this.walkExpression(expression.test);
3845
- this.walkExpression(expression.consequent);
3846
- });
3847
- } else {
3848
- this.walkExpression(expression.test);
3849
- this.walkExpression(expression.consequent);
3850
- }
3929
+ const guard = this.hooks.collectGuards.call(expression.test);
3930
+ this.walkExpression(expression.test);
3931
+ this.walkGuardedBranch(guard ? guard.consequent : undefined, () =>
3932
+ this.walkExpression(expression.consequent)
3933
+ );
3851
3934
 
3852
3935
  if (expression.alternate) {
3853
- this.walkExpression(expression.alternate);
3936
+ const alternate = expression.alternate;
3937
+ this.walkGuardedBranch(guard ? guard.alternate : undefined, () =>
3938
+ this.walkExpression(alternate)
3939
+ );
3854
3940
  }
3855
3941
  } else if (result) {
3856
3942
  this.walkExpression(expression.consequent);
@@ -3864,35 +3950,36 @@ class JavascriptParser extends Parser {
3864
3950
  * @param {NewExpression} expression new expression
3865
3951
  */
3866
3952
  walkNewExpression(expression) {
3867
- // TODO: not a webpack bug `acorn-import-phases` accepts
3868
- // `new import.defer(...)` / `new import.source(...)` even though
3869
- // `ImportCall` is a `CallExpression` per spec and is therefore not a
3870
- // valid `new` operand. Acorn rejects bare `new import(...)` correctly.
3871
- // Drop this block once the upstream plugin (or acorn itself) reports
3872
- // the SyntaxError. Parenthesized forms (`new (import.defer(...))`)
3873
- // produce the same AST shape, so we look at the source between `new`
3874
- // and the callee (with comments stripped) to keep them valid.
3875
- if (
3876
- expression.callee.type === "ImportExpression" &&
3877
- typeof this.state.source === "string"
3878
- ) {
3879
- const newStart = /** @type {Range} */ (expression.range)[0];
3880
- const calleeStart = /** @type {Range} */ (expression.callee.range)[0];
3881
- const between = this.state.source
3882
- .slice(newStart, calleeStart)
3883
- .replace(/\/\*[\s\S]*?\*\//g, "")
3884
- .replace(/\/\/[^\n]*/g, "");
3885
- if (!between.includes("(")) {
3886
- const err =
3887
- /** @type {SyntaxError & { loc?: { line: number, column: number } }} */
3888
- (new SyntaxError("import call cannot be the target of `new`"));
3889
- if (expression.loc) {
3890
- err.loc = {
3891
- line: expression.loc.start.line,
3892
- column: expression.loc.start.column
3893
- };
3953
+ // TODO acorn-import-phases bug: it omits acorn's `!forNew` guard, so
3954
+ // `import.defer(...)`/`import.source(...)` are wrongly accepted as `new`
3955
+ // operands; drop once fixed. Parenthesized forms stay valid (check `(`).
3956
+ if (typeof this.state.source === "string") {
3957
+ let base = expression.callee;
3958
+ while (
3959
+ base.type === "MemberExpression" ||
3960
+ base.type === "CallExpression"
3961
+ ) {
3962
+ base = base.type === "MemberExpression" ? base.object : base.callee;
3963
+ }
3964
+ if (base.type === "ImportExpression") {
3965
+ const newStart = /** @type {Range} */ (expression.range)[0];
3966
+ const importStart = /** @type {Range} */ (base.range)[0];
3967
+ const between = this.state.source
3968
+ .slice(newStart, importStart)
3969
+ .replace(/\/\*[\s\S]*?\*\//g, "")
3970
+ .replace(/\/\/[^\n]*/g, "");
3971
+ if (!between.includes("(")) {
3972
+ const err =
3973
+ /** @type {SyntaxError & { loc?: { line: number, column: number } }} */
3974
+ (new SyntaxError("import call cannot be the target of `new`"));
3975
+ if (expression.loc) {
3976
+ err.loc = {
3977
+ line: expression.loc.start.line,
3978
+ column: expression.loc.start.column
3979
+ };
3980
+ }
3981
+ throw err;
3894
3982
  }
3895
- throw err;
3896
3983
  }
3897
3984
  }
3898
3985
  const result = this.callHooksForExpression(
@@ -4059,16 +4146,9 @@ class JavascriptParser extends Parser {
4059
4146
  * @param {CallExpression} expression expression
4060
4147
  */
4061
4148
  walkCallExpression(expression) {
4062
- /**
4063
- * Checks whether this javascript parser is simple function.
4064
- * @param {FunctionExpression | ArrowFunctionExpression} fn function
4065
- * @returns {boolean} true when simple function
4066
- */
4067
- const isSimpleFunction = (fn) =>
4068
- fn.params.every((p) => p.type === "Identifier");
4069
4149
  if (
4070
4150
  expression.callee.type === "MemberExpression" &&
4071
- expression.callee.object.type.endsWith("FunctionExpression") &&
4151
+ isFunctionExpression(expression.callee.object.type) &&
4072
4152
  !expression.callee.computed &&
4073
4153
  /** @type {boolean} */
4074
4154
  (
@@ -4091,7 +4171,7 @@ class JavascriptParser extends Parser {
4091
4171
  expression.arguments[0]
4092
4172
  );
4093
4173
  } else if (
4094
- expression.callee.type.endsWith("FunctionExpression") &&
4174
+ isFunctionExpression(expression.callee.type) &&
4095
4175
  isSimpleFunction(
4096
4176
  /** @type {FunctionExpression | ArrowFunctionExpression} */
4097
4177
  (expression.callee)
@@ -4106,21 +4186,29 @@ class JavascriptParser extends Parser {
4106
4186
  );
4107
4187
  } else {
4108
4188
  if (expression.callee.type === "MemberExpression") {
4109
- const exprInfo = this.getMemberExpressionInfo(
4110
- expression.callee,
4111
- ALLOWED_MEMBER_TYPES_CALL_EXPRESSION
4112
- );
4113
- if (exprInfo && exprInfo.type === "call") {
4114
- const result = this.callHooksForInfo(
4115
- this.hooks.callMemberChainOfCallMemberChain,
4116
- exprInfo.rootInfo,
4117
- expression,
4118
- exprInfo.getCalleeMembers(),
4119
- exprInfo.call,
4120
- exprInfo.getMembers(),
4121
- exprInfo.getMemberRanges()
4189
+ // callMemberChainOfCallMemberChain only applies to call-rooted
4190
+ // chains (e.g. `a().b()`); for the common identifier/this-rooted
4191
+ // callee the CALL lookup always rejects, so gate on the cheap root.
4192
+ if (
4193
+ this.getMemberExpressionRoot(expression.callee).type ===
4194
+ "CallExpression"
4195
+ ) {
4196
+ const exprInfo = this.getMemberExpressionInfo(
4197
+ expression.callee,
4198
+ ALLOWED_MEMBER_TYPES_CALL_EXPRESSION
4122
4199
  );
4123
- if (result === true) return;
4200
+ if (exprInfo && exprInfo.type === "call") {
4201
+ const result = this.callHooksForInfo(
4202
+ this.hooks.callMemberChainOfCallMemberChain,
4203
+ exprInfo.rootInfo,
4204
+ expression,
4205
+ exprInfo.getCalleeMembers(),
4206
+ exprInfo.call,
4207
+ exprInfo.getMembers(),
4208
+ exprInfo.getMemberRanges()
4209
+ );
4210
+ if (result === true) return;
4211
+ }
4124
4212
  }
4125
4213
  // import("./m").then(m => { ... })
4126
4214
  if (
@@ -4374,12 +4462,12 @@ class JavascriptParser extends Parser {
4374
4462
  * @returns {R | undefined} result of hook
4375
4463
  */
4376
4464
  callHooksForName(hookMap, name, ...args) {
4377
- return this.callHooksForNameWithFallback(
4465
+ return this._callHooksForInfo(
4378
4466
  hookMap,
4379
- name,
4467
+ this.getVariableInfo(name),
4380
4468
  undefined,
4381
4469
  undefined,
4382
- ...args
4470
+ args
4383
4471
  );
4384
4472
  }
4385
4473
 
@@ -4393,13 +4481,7 @@ class JavascriptParser extends Parser {
4393
4481
  * @returns {R | undefined} result of hook
4394
4482
  */
4395
4483
  callHooksForInfo(hookMap, info, ...args) {
4396
- return this.callHooksForInfoWithFallback(
4397
- hookMap,
4398
- info,
4399
- undefined,
4400
- undefined,
4401
- ...args
4402
- );
4484
+ return this._callHooksForInfo(hookMap, info, undefined, undefined, args);
4403
4485
  }
4404
4486
 
4405
4487
  /**
@@ -4414,6 +4496,23 @@ class JavascriptParser extends Parser {
4414
4496
  * @returns {R | undefined} result of hook
4415
4497
  */
4416
4498
  callHooksForInfoWithFallback(hookMap, info, fallback, defined, ...args) {
4499
+ return this._callHooksForInfo(hookMap, info, fallback, defined, args);
4500
+ }
4501
+
4502
+ /**
4503
+ * Shared core for the callHooksFor* helpers. Takes `args` as an already
4504
+ * collected array so the public wrappers each allocate it once instead of
4505
+ * re-collecting it through several rest-parameter layers (hot per identifier).
4506
+ * @template T
4507
+ * @template R
4508
+ * @param {HookMap<SyncBailHook<T, R>>} hookMap hooks that should be called
4509
+ * @param {ExportedVariableInfo} info variable info
4510
+ * @param {((name: string) => R | undefined) | undefined} fallback callback when variable is not handled by hooks
4511
+ * @param {((result?: string) => R | undefined) | undefined} defined callback when variable is defined
4512
+ * @param {AsArray<T>} args args for the hook
4513
+ * @returns {R | undefined} result of hook
4514
+ */
4515
+ _callHooksForInfo(hookMap, info, fallback, defined, args) {
4417
4516
  /** @type {string} */
4418
4517
  let name;
4419
4518
  if (typeof info === "string") {
@@ -4466,12 +4565,12 @@ class JavascriptParser extends Parser {
4466
4565
  * @returns {R | undefined} result of hook
4467
4566
  */
4468
4567
  callHooksForNameWithFallback(hookMap, name, fallback, defined, ...args) {
4469
- return this.callHooksForInfoWithFallback(
4568
+ return this._callHooksForInfo(
4470
4569
  hookMap,
4471
4570
  this.getVariableInfo(name),
4472
4571
  fallback,
4473
4572
  defined,
4474
- ...args
4573
+ args
4475
4574
  );
4476
4575
  }
4477
4576
 
@@ -4497,9 +4596,7 @@ class JavascriptParser extends Parser {
4497
4596
 
4498
4597
  this.undefineVariable("this");
4499
4598
 
4500
- this.enterPatterns(params, (ident) => {
4501
- this.defineVariable(ident);
4502
- });
4599
+ this.enterPatterns(params, this._defineVariable);
4503
4600
 
4504
4601
  fn();
4505
4602
 
@@ -4530,9 +4627,7 @@ class JavascriptParser extends Parser {
4530
4627
  this.undefineVariable("this");
4531
4628
  }
4532
4629
 
4533
- this.enterPatterns(params, (ident) => {
4534
- this.defineVariable(ident);
4535
- });
4630
+ this.enterPatterns(params, this._defineVariable);
4536
4631
 
4537
4632
  fn();
4538
4633
 
@@ -4563,9 +4658,7 @@ class JavascriptParser extends Parser {
4563
4658
  this.undefineVariable("this");
4564
4659
  }
4565
4660
 
4566
- this.enterPatterns(params, (ident) => {
4567
- this.defineVariable(ident);
4568
- });
4661
+ this.enterPatterns(params, this._defineVariable);
4569
4662
 
4570
4663
  fn();
4571
4664
 
@@ -4607,24 +4700,18 @@ class JavascriptParser extends Parser {
4607
4700
  * @param {(Directive | Statement | ModuleDeclaration)[]} statements statements
4608
4701
  */
4609
4702
  detectMode(statements) {
4610
- const isLiteral =
4611
- statements.length >= 1 &&
4612
- statements[0].type === "ExpressionStatement" &&
4613
- statements[0].expression.type === "Literal";
4703
+ const statement = statements.length >= 1 ? statements[0] : undefined;
4614
4704
  if (
4615
- isLiteral &&
4616
- /** @type {Literal} */
4617
- (/** @type {ExpressionStatement} */ (statements[0]).expression).value ===
4618
- "use strict"
4705
+ statement === undefined ||
4706
+ statement.type !== "ExpressionStatement" ||
4707
+ statement.expression.type !== "Literal"
4619
4708
  ) {
4620
- this.scope.isStrict = true;
4709
+ return;
4621
4710
  }
4622
- if (
4623
- isLiteral &&
4624
- /** @type {Literal} */
4625
- (/** @type {ExpressionStatement} */ (statements[0]).expression).value ===
4626
- "use asm"
4627
- ) {
4711
+ const value = /** @type {Literal} */ (statement.expression).value;
4712
+ if (value === "use strict") {
4713
+ this.scope.isStrict = true;
4714
+ } else if (value === "use asm") {
4628
4715
  this.scope.isAsmJs = true;
4629
4716
  }
4630
4717
  }
@@ -4635,7 +4722,8 @@ class JavascriptParser extends Parser {
4635
4722
  * @param {OnIdentString} onIdent on ident callback
4636
4723
  */
4637
4724
  enterPatterns(patterns, onIdent) {
4638
- for (const pattern of patterns) {
4725
+ for (let i = 0, len = patterns.length; i < len; i++) {
4726
+ const pattern = patterns[i];
4639
4727
  if (typeof pattern !== "string") {
4640
4728
  this.enterPattern(pattern, onIdent);
4641
4729
  } else if (pattern) {
@@ -5005,7 +5093,6 @@ class JavascriptParser extends Parser {
5005
5093
  .for(expr.type)
5006
5094
  .call(expr, commentsStartPos);
5007
5095
  if (typeof result === "boolean") return result;
5008
- // TODO handle more cases
5009
5096
  switch (expr.type) {
5010
5097
  case "ClassDeclaration":
5011
5098
  case "ClassExpression": {
@@ -5534,6 +5621,38 @@ class JavascriptParser extends Parser {
5534
5621
  return { options, errors };
5535
5622
  }
5536
5623
 
5624
+ /**
5625
+ * Finds the root object of a member expression chain without allocating the
5626
+ * member arrays. The traversal/break logic must stay in sync with
5627
+ * `extractMemberExpressionChain`; it lets `getMemberExpressionInfo` reject
5628
+ * unrecognized roots (~77% of calls) before paying for the arrays.
5629
+ * @param {Expression | Super} expression a member expression
5630
+ * @returns {Expression | Super} the root object of the chain
5631
+ */
5632
+ getMemberExpressionRoot(expression) {
5633
+ /** @type {Node} */
5634
+ let expr = expression;
5635
+ while (expr.type === "MemberExpression") {
5636
+ if (expr.computed) {
5637
+ const prop = expr.property;
5638
+ if (
5639
+ prop.type !== "Literal" &&
5640
+ !(
5641
+ prop.type === "TemplateLiteral" &&
5642
+ prop.expressions.length === 0 &&
5643
+ typeof prop.quasis[0].value.cooked === "string"
5644
+ )
5645
+ ) {
5646
+ break;
5647
+ }
5648
+ } else if (expr.property.type !== "Identifier") {
5649
+ break;
5650
+ }
5651
+ expr = expr.object;
5652
+ }
5653
+ return /** @type {Expression | Super} */ (expr);
5654
+ }
5655
+
5537
5656
  /**
5538
5657
  * Extract member expression chain.
5539
5658
  * @param {Expression | Super} expression a member expression
@@ -5631,33 +5750,39 @@ class JavascriptParser extends Parser {
5631
5750
  * @returns {CallExpressionInfo | ExpressionExpressionInfo | undefined} expression info
5632
5751
  */
5633
5752
  getMemberExpressionInfo(expression, allowedTypes) {
5634
- const { object, members, membersOptionals, memberRanges } =
5635
- this.extractMemberExpressionChain(expression);
5753
+ // Resolve the root first (no allocation); most calls reject here and so
5754
+ // never build the member arrays via extractMemberExpressionChain.
5755
+ const object = this.getMemberExpressionRoot(expression);
5636
5756
  switch (object.type) {
5637
5757
  case "CallExpression": {
5638
5758
  if ((allowedTypes & ALLOWED_MEMBER_TYPES_CALL_EXPRESSION) === 0) return;
5639
- let callee = object.callee;
5640
- let rootMembers = EMPTY_ARRAY;
5641
- if (callee.type === "MemberExpression") {
5642
- ({ object: callee, members: rootMembers } =
5643
- this.extractMemberExpressionChain(callee));
5644
- }
5759
+ const calleeExpr = object.callee;
5760
+ const callee =
5761
+ calleeExpr.type === "MemberExpression"
5762
+ ? this.getMemberExpressionRoot(calleeExpr)
5763
+ : calleeExpr;
5645
5764
  const rootName = getRootName(callee);
5646
5765
  if (!rootName) return;
5647
5766
  const result = this.getNameInfoFromVariable(rootName);
5648
5767
  if (!result) return;
5649
5768
  const { info: rootInfo, name: resolvedRoot } = result;
5769
+ const rootMembers =
5770
+ calleeExpr.type === "MemberExpression"
5771
+ ? this.extractMemberExpressionChain(calleeExpr).members
5772
+ : EMPTY_ARRAY;
5773
+ const { members, membersOptionals, memberRanges } =
5774
+ this.extractMemberExpressionChain(expression);
5650
5775
  const calleeName = objectAndMembersToName(resolvedRoot, rootMembers);
5651
5776
  return {
5652
5777
  type: "call",
5653
5778
  call: object,
5654
5779
  calleeName,
5655
5780
  rootInfo,
5656
- getCalleeMembers: memoize(() => rootMembers.reverse()),
5781
+ getCalleeMembers: lazyReverse(rootMembers),
5657
5782
  name: objectAndMembersToName(`${calleeName}()`, members),
5658
- getMembers: memoize(() => members.reverse()),
5659
- getMembersOptionals: memoize(() => membersOptionals.reverse()),
5660
- getMemberRanges: memoize(() => memberRanges.reverse())
5783
+ getMembers: lazyReverse(members),
5784
+ getMembersOptionals: lazyReverse(membersOptionals),
5785
+ getMemberRanges: lazyReverse(memberRanges)
5661
5786
  };
5662
5787
  }
5663
5788
  case "Identifier":
@@ -5670,13 +5795,15 @@ class JavascriptParser extends Parser {
5670
5795
  const result = this.getNameInfoFromVariable(rootName);
5671
5796
  if (!result) return;
5672
5797
  const { info: rootInfo, name: resolvedRoot } = result;
5798
+ const { members, membersOptionals, memberRanges } =
5799
+ this.extractMemberExpressionChain(expression);
5673
5800
  return {
5674
5801
  type: "expression",
5675
5802
  name: objectAndMembersToName(resolvedRoot, members),
5676
5803
  rootInfo,
5677
- getMembers: memoize(() => members.reverse()),
5678
- getMembersOptionals: memoize(() => membersOptionals.reverse()),
5679
- getMemberRanges: memoize(() => memberRanges.reverse())
5804
+ getMembers: lazyReverse(members),
5805
+ getMembersOptionals: lazyReverse(membersOptionals),
5806
+ getMemberRanges: lazyReverse(memberRanges)
5680
5807
  };
5681
5808
  }
5682
5809
  }