@eriche/webpack 4.47.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 (361) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +784 -0
  3. package/SECURITY.md +9 -0
  4. package/bin/webpack.js +171 -0
  5. package/buildin/amd-define.js +3 -0
  6. package/buildin/amd-options.js +2 -0
  7. package/buildin/global.js +20 -0
  8. package/buildin/harmony-module.js +24 -0
  9. package/buildin/module.js +22 -0
  10. package/buildin/system.js +7 -0
  11. package/declarations/WebpackOptions.d.ts +1466 -0
  12. package/declarations/plugins/BannerPlugin.d.ts +49 -0
  13. package/declarations/plugins/DllPlugin.d.ts +32 -0
  14. package/declarations/plugins/DllReferencePlugin.d.ts +126 -0
  15. package/declarations/plugins/HashedModuleIdsPlugin.d.ts +24 -0
  16. package/declarations/plugins/IgnorePlugin.d.ts +27 -0
  17. package/declarations/plugins/LoaderOptionsPlugin.d.ts +27 -0
  18. package/declarations/plugins/ProgressPlugin.d.ts +42 -0
  19. package/declarations/plugins/SourceMapDevToolPlugin.d.ts +94 -0
  20. package/declarations/plugins/WatchIgnorePlugin.d.ts +10 -0
  21. package/declarations/plugins/debug/ProfilingPlugin.d.ts +12 -0
  22. package/declarations/plugins/optimize/AggressiveSplittingPlugin.d.ts +24 -0
  23. package/declarations/plugins/optimize/LimitChunkCountPlugin.d.ts +16 -0
  24. package/declarations/plugins/optimize/MinChunkSizePlugin.d.ts +12 -0
  25. package/declarations/plugins/optimize/OccurrenceOrderChunkIdsPlugin.d.ts +12 -0
  26. package/declarations/plugins/optimize/OccurrenceOrderModuleIdsPlugin.d.ts +12 -0
  27. package/hot/dev-server.js +61 -0
  28. package/hot/emitter.js +2 -0
  29. package/hot/log-apply-result.js +44 -0
  30. package/hot/log.js +59 -0
  31. package/hot/only-dev-server.js +102 -0
  32. package/hot/poll.js +37 -0
  33. package/hot/signal.js +62 -0
  34. package/lib/APIPlugin.js +84 -0
  35. package/lib/AbstractMethodError.js +43 -0
  36. package/lib/AmdMainTemplatePlugin.js +106 -0
  37. package/lib/AsyncDependenciesBlock.js +110 -0
  38. package/lib/AsyncDependencyToInitialChunkError.js +31 -0
  39. package/lib/AutomaticPrefetchPlugin.js +57 -0
  40. package/lib/BannerPlugin.js +122 -0
  41. package/lib/BasicEvaluatedExpression.js +248 -0
  42. package/lib/CachePlugin.js +100 -0
  43. package/lib/CaseSensitiveModulesWarning.js +67 -0
  44. package/lib/Chunk.js +875 -0
  45. package/lib/ChunkGroup.js +513 -0
  46. package/lib/ChunkRenderError.js +32 -0
  47. package/lib/ChunkTemplate.js +87 -0
  48. package/lib/CommentCompilationWarning.js +32 -0
  49. package/lib/CommonJsStuffPlugin.js +116 -0
  50. package/lib/CompatibilityPlugin.js +70 -0
  51. package/lib/Compilation.js +2327 -0
  52. package/lib/Compiler.js +735 -0
  53. package/lib/ConcurrentCompilationError.js +19 -0
  54. package/lib/ConstPlugin.js +348 -0
  55. package/lib/ContextExclusionPlugin.js +28 -0
  56. package/lib/ContextModule.js +872 -0
  57. package/lib/ContextModuleFactory.js +262 -0
  58. package/lib/ContextReplacementPlugin.js +133 -0
  59. package/lib/DefinePlugin.js +289 -0
  60. package/lib/DelegatedModule.js +114 -0
  61. package/lib/DelegatedModuleFactoryPlugin.js +95 -0
  62. package/lib/DelegatedPlugin.js +39 -0
  63. package/lib/DependenciesBlock.js +124 -0
  64. package/lib/DependenciesBlockVariable.js +72 -0
  65. package/lib/Dependency.js +89 -0
  66. package/lib/DllEntryPlugin.js +54 -0
  67. package/lib/DllModule.js +60 -0
  68. package/lib/DllModuleFactory.js +29 -0
  69. package/lib/DllPlugin.js +49 -0
  70. package/lib/DllReferencePlugin.js +156 -0
  71. package/lib/DynamicEntryPlugin.js +94 -0
  72. package/lib/EntryModuleNotFoundError.js +21 -0
  73. package/lib/EntryOptionPlugin.js +46 -0
  74. package/lib/Entrypoint.js +64 -0
  75. package/lib/EnvironmentPlugin.js +72 -0
  76. package/lib/ErrorHelpers.js +60 -0
  77. package/lib/EvalDevToolModulePlugin.js +27 -0
  78. package/lib/EvalDevToolModuleTemplatePlugin.js +61 -0
  79. package/lib/EvalSourceMapDevToolModuleTemplatePlugin.js +120 -0
  80. package/lib/EvalSourceMapDevToolPlugin.js +41 -0
  81. package/lib/ExportPropertyMainTemplatePlugin.js +53 -0
  82. package/lib/ExtendedAPIPlugin.js +88 -0
  83. package/lib/ExternalModule.js +179 -0
  84. package/lib/ExternalModuleFactoryPlugin.js +110 -0
  85. package/lib/ExternalsPlugin.js +23 -0
  86. package/lib/FlagAllModulesAsUsedPlugin.js +38 -0
  87. package/lib/FlagDependencyExportsPlugin.js +174 -0
  88. package/lib/FlagDependencyUsagePlugin.js +116 -0
  89. package/lib/FlagInitialModulesAsUsedPlugin.js +36 -0
  90. package/lib/FunctionModulePlugin.js +19 -0
  91. package/lib/FunctionModuleTemplatePlugin.js +102 -0
  92. package/lib/Generator.js +60 -0
  93. package/lib/GraphHelpers.js +65 -0
  94. package/lib/HarmonyLinkingError.js +17 -0
  95. package/lib/HashedModuleIdsPlugin.js +63 -0
  96. package/lib/HotModuleReplacement.runtime.js +721 -0
  97. package/lib/HotModuleReplacementPlugin.js +425 -0
  98. package/lib/HotUpdateChunk.js +17 -0
  99. package/lib/HotUpdateChunkTemplate.js +78 -0
  100. package/lib/IgnorePlugin.js +91 -0
  101. package/lib/JavascriptGenerator.js +229 -0
  102. package/lib/JavascriptModulesPlugin.js +185 -0
  103. package/lib/JsonGenerator.js +57 -0
  104. package/lib/JsonModulesPlugin.js +30 -0
  105. package/lib/JsonParser.js +27 -0
  106. package/lib/LibManifestPlugin.js +90 -0
  107. package/lib/LibraryTemplatePlugin.js +186 -0
  108. package/lib/LoaderOptionsPlugin.js +58 -0
  109. package/lib/LoaderTargetPlugin.js +24 -0
  110. package/lib/MainTemplate.js +568 -0
  111. package/lib/MemoryOutputFileSystem.js +5 -0
  112. package/lib/Module.js +435 -0
  113. package/lib/ModuleBuildError.js +52 -0
  114. package/lib/ModuleDependencyError.js +35 -0
  115. package/lib/ModuleDependencyWarning.js +25 -0
  116. package/lib/ModuleError.js +36 -0
  117. package/lib/ModuleFilenameHelpers.js +179 -0
  118. package/lib/ModuleNotFoundError.js +23 -0
  119. package/lib/ModuleParseError.js +67 -0
  120. package/lib/ModuleReason.js +48 -0
  121. package/lib/ModuleTemplate.js +93 -0
  122. package/lib/ModuleWarning.js +36 -0
  123. package/lib/MultiCompiler.js +290 -0
  124. package/lib/MultiEntryPlugin.js +80 -0
  125. package/lib/MultiModule.js +87 -0
  126. package/lib/MultiModuleFactory.js +23 -0
  127. package/lib/MultiStats.js +92 -0
  128. package/lib/MultiWatching.js +50 -0
  129. package/lib/NamedChunksPlugin.js +29 -0
  130. package/lib/NamedModulesPlugin.js +58 -0
  131. package/lib/NoEmitOnErrorsPlugin.js +20 -0
  132. package/lib/NoModeWarning.js +23 -0
  133. package/lib/NodeStuffPlugin.js +118 -0
  134. package/lib/NormalModule.js +582 -0
  135. package/lib/NormalModuleFactory.js +528 -0
  136. package/lib/NormalModuleReplacementPlugin.js +51 -0
  137. package/lib/NullFactory.js +12 -0
  138. package/lib/OptionsApply.js +10 -0
  139. package/lib/OptionsDefaulter.js +141 -0
  140. package/lib/Parser.js +2454 -0
  141. package/lib/ParserHelpers.js +103 -0
  142. package/lib/PrefetchPlugin.js +37 -0
  143. package/lib/ProgressPlugin.js +307 -0
  144. package/lib/ProvidePlugin.js +86 -0
  145. package/lib/RawModule.js +56 -0
  146. package/lib/RecordIdsPlugin.js +236 -0
  147. package/lib/RemovedPluginError.js +11 -0
  148. package/lib/RequestShortener.js +83 -0
  149. package/lib/RequireJsStuffPlugin.js +66 -0
  150. package/lib/ResolverFactory.js +74 -0
  151. package/lib/RuleSet.js +567 -0
  152. package/lib/RuntimeTemplate.js +336 -0
  153. package/lib/SetVarMainTemplatePlugin.js +69 -0
  154. package/lib/SingleEntryPlugin.js +63 -0
  155. package/lib/SizeFormatHelpers.js +24 -0
  156. package/lib/SourceMapDevToolModuleOptionsPlugin.js +49 -0
  157. package/lib/SourceMapDevToolPlugin.js +418 -0
  158. package/lib/Stats.js +1685 -0
  159. package/lib/SystemMainTemplatePlugin.js +137 -0
  160. package/lib/Template.js +291 -0
  161. package/lib/TemplatedPathPlugin.js +188 -0
  162. package/lib/UmdMainTemplatePlugin.js +305 -0
  163. package/lib/UnsupportedFeatureWarning.js +30 -0
  164. package/lib/UseStrictPlugin.js +54 -0
  165. package/lib/WarnCaseSensitiveModulesPlugin.js +37 -0
  166. package/lib/WarnNoModeSetPlugin.js +17 -0
  167. package/lib/WatchIgnorePlugin.js +106 -0
  168. package/lib/Watching.js +211 -0
  169. package/lib/WebpackError.js +31 -0
  170. package/lib/WebpackOptionsApply.js +546 -0
  171. package/lib/WebpackOptionsDefaulter.js +391 -0
  172. package/lib/WebpackOptionsValidationError.js +390 -0
  173. package/lib/buildChunkGraph.js +712 -0
  174. package/lib/compareLocations.js +52 -0
  175. package/lib/debug/ProfilingPlugin.js +442 -0
  176. package/lib/dependencies/AMDDefineDependency.js +137 -0
  177. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +336 -0
  178. package/lib/dependencies/AMDPlugin.js +249 -0
  179. package/lib/dependencies/AMDRequireArrayDependency.js +49 -0
  180. package/lib/dependencies/AMDRequireContextDependency.js +20 -0
  181. package/lib/dependencies/AMDRequireDependenciesBlock.js +47 -0
  182. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +274 -0
  183. package/lib/dependencies/AMDRequireDependency.js +135 -0
  184. package/lib/dependencies/AMDRequireItemDependency.js +22 -0
  185. package/lib/dependencies/CommonJsPlugin.js +158 -0
  186. package/lib/dependencies/CommonJsRequireContextDependency.js +23 -0
  187. package/lib/dependencies/CommonJsRequireDependency.js +22 -0
  188. package/lib/dependencies/CommonJsRequireDependencyParserPlugin.js +138 -0
  189. package/lib/dependencies/ConstDependency.js +33 -0
  190. package/lib/dependencies/ContextDependency.js +68 -0
  191. package/lib/dependencies/ContextDependencyHelpers.js +232 -0
  192. package/lib/dependencies/ContextDependencyTemplateAsId.js +43 -0
  193. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +39 -0
  194. package/lib/dependencies/ContextElementDependency.js +21 -0
  195. package/lib/dependencies/CriticalDependencyWarning.js +20 -0
  196. package/lib/dependencies/DelegatedExportsDependency.js +33 -0
  197. package/lib/dependencies/DelegatedSourceDependency.js +18 -0
  198. package/lib/dependencies/DependencyReference.js +64 -0
  199. package/lib/dependencies/DllEntryDependency.js +20 -0
  200. package/lib/dependencies/HarmonyAcceptDependency.js +48 -0
  201. package/lib/dependencies/HarmonyAcceptImportDependency.js +23 -0
  202. package/lib/dependencies/HarmonyCompatibilityDependency.js +31 -0
  203. package/lib/dependencies/HarmonyDetectionParserPlugin.js +96 -0
  204. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +154 -0
  205. package/lib/dependencies/HarmonyExportExpressionDependency.js +58 -0
  206. package/lib/dependencies/HarmonyExportHeaderDependency.js +30 -0
  207. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +659 -0
  208. package/lib/dependencies/HarmonyExportSpecifierDependency.js +54 -0
  209. package/lib/dependencies/HarmonyImportDependency.js +109 -0
  210. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +222 -0
  211. package/lib/dependencies/HarmonyImportSideEffectDependency.js +31 -0
  212. package/lib/dependencies/HarmonyImportSpecifierDependency.js +163 -0
  213. package/lib/dependencies/HarmonyInitDependency.js +60 -0
  214. package/lib/dependencies/HarmonyModulesPlugin.js +143 -0
  215. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +26 -0
  216. package/lib/dependencies/ImportContextDependency.js +23 -0
  217. package/lib/dependencies/ImportDependenciesBlock.js +18 -0
  218. package/lib/dependencies/ImportDependency.js +34 -0
  219. package/lib/dependencies/ImportEagerDependency.js +32 -0
  220. package/lib/dependencies/ImportParserPlugin.js +248 -0
  221. package/lib/dependencies/ImportPlugin.js +79 -0
  222. package/lib/dependencies/ImportWeakDependency.js +34 -0
  223. package/lib/dependencies/JsonExportsDependency.js +26 -0
  224. package/lib/dependencies/LoaderDependency.js +21 -0
  225. package/lib/dependencies/LoaderPlugin.js +115 -0
  226. package/lib/dependencies/LocalModule.js +23 -0
  227. package/lib/dependencies/LocalModuleDependency.js +28 -0
  228. package/lib/dependencies/LocalModulesHelpers.js +52 -0
  229. package/lib/dependencies/ModuleDependency.js +23 -0
  230. package/lib/dependencies/ModuleDependencyTemplateAsId.js +17 -0
  231. package/lib/dependencies/ModuleDependencyTemplateAsRequireId.js +17 -0
  232. package/lib/dependencies/ModuleHotAcceptDependency.js +23 -0
  233. package/lib/dependencies/ModuleHotDeclineDependency.js +23 -0
  234. package/lib/dependencies/MultiEntryDependency.js +25 -0
  235. package/lib/dependencies/NullDependency.js +20 -0
  236. package/lib/dependencies/PrefetchDependency.js +18 -0
  237. package/lib/dependencies/RequireContextDependency.js +22 -0
  238. package/lib/dependencies/RequireContextDependencyParserPlugin.js +56 -0
  239. package/lib/dependencies/RequireContextPlugin.js +143 -0
  240. package/lib/dependencies/RequireEnsureDependenciesBlock.js +33 -0
  241. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +116 -0
  242. package/lib/dependencies/RequireEnsureDependency.js +58 -0
  243. package/lib/dependencies/RequireEnsureItemDependency.js +21 -0
  244. package/lib/dependencies/RequireEnsurePlugin.js +74 -0
  245. package/lib/dependencies/RequireHeaderDependency.js +26 -0
  246. package/lib/dependencies/RequireIncludeDependency.js +39 -0
  247. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +23 -0
  248. package/lib/dependencies/RequireIncludePlugin.js +61 -0
  249. package/lib/dependencies/RequireResolveContextDependency.js +23 -0
  250. package/lib/dependencies/RequireResolveDependency.js +22 -0
  251. package/lib/dependencies/RequireResolveDependencyParserPlugin.js +86 -0
  252. package/lib/dependencies/RequireResolveHeaderDependency.js +26 -0
  253. package/lib/dependencies/SingleEntryDependency.js +21 -0
  254. package/lib/dependencies/SystemPlugin.js +122 -0
  255. package/lib/dependencies/UnsupportedDependency.js +27 -0
  256. package/lib/dependencies/WebAssemblyExportImportedDependency.js +31 -0
  257. package/lib/dependencies/WebAssemblyImportDependency.js +54 -0
  258. package/lib/dependencies/WebpackMissingModule.js +20 -0
  259. package/lib/dependencies/getFunctionExpression.js +52 -0
  260. package/lib/formatLocation.js +75 -0
  261. package/lib/logging/Logger.js +128 -0
  262. package/lib/logging/createConsoleLogger.js +210 -0
  263. package/lib/logging/runtime.js +36 -0
  264. package/lib/logging/truncateArgs.js +76 -0
  265. package/lib/node/NodeChunkTemplatePlugin.js +31 -0
  266. package/lib/node/NodeEnvironmentPlugin.js +44 -0
  267. package/lib/node/NodeHotUpdateChunkTemplatePlugin.js +36 -0
  268. package/lib/node/NodeMainTemplate.runtime.js +32 -0
  269. package/lib/node/NodeMainTemplateAsync.runtime.js +50 -0
  270. package/lib/node/NodeMainTemplatePlugin.js +321 -0
  271. package/lib/node/NodeOutputFileSystem.js +22 -0
  272. package/lib/node/NodeSourcePlugin.js +141 -0
  273. package/lib/node/NodeTargetPlugin.js +19 -0
  274. package/lib/node/NodeTemplatePlugin.js +31 -0
  275. package/lib/node/NodeWatchFileSystem.js +109 -0
  276. package/lib/node/ReadFileCompileWasmTemplatePlugin.js +61 -0
  277. package/lib/node/nodeConsole.js +135 -0
  278. package/lib/optimize/AggressiveMergingPlugin.js +87 -0
  279. package/lib/optimize/AggressiveSplittingPlugin.js +294 -0
  280. package/lib/optimize/ChunkModuleIdRangePlugin.js +66 -0
  281. package/lib/optimize/ConcatenatedModule.js +1477 -0
  282. package/lib/optimize/EnsureChunkConditionsPlugin.js +70 -0
  283. package/lib/optimize/FlagIncludedChunksPlugin.js +99 -0
  284. package/lib/optimize/LimitChunkCountPlugin.js +231 -0
  285. package/lib/optimize/MergeDuplicateChunksPlugin.js +78 -0
  286. package/lib/optimize/MinChunkSizePlugin.js +82 -0
  287. package/lib/optimize/MinMaxSizeWarning.js +29 -0
  288. package/lib/optimize/ModuleConcatenationPlugin.js +485 -0
  289. package/lib/optimize/NaturalChunkOrderPlugin.js +41 -0
  290. package/lib/optimize/OccurrenceChunkOrderPlugin.js +66 -0
  291. package/lib/optimize/OccurrenceModuleOrderPlugin.js +112 -0
  292. package/lib/optimize/OccurrenceOrderPlugin.js +135 -0
  293. package/lib/optimize/RemoveEmptyChunksPlugin.js +42 -0
  294. package/lib/optimize/RemoveParentModulesPlugin.js +127 -0
  295. package/lib/optimize/RuntimeChunkPlugin.js +41 -0
  296. package/lib/optimize/SideEffectsFlagPlugin.js +352 -0
  297. package/lib/optimize/SplitChunksPlugin.js +971 -0
  298. package/lib/performance/AssetsOverSizeLimitWarning.js +30 -0
  299. package/lib/performance/EntrypointsOverSizeLimitWarning.js +30 -0
  300. package/lib/performance/NoAsyncChunksWarning.js +21 -0
  301. package/lib/performance/SizeLimitsPlugin.js +125 -0
  302. package/lib/util/LazyBucketSortedSet.js +235 -0
  303. package/lib/util/Queue.js +46 -0
  304. package/lib/util/Semaphore.js +53 -0
  305. package/lib/util/SetHelpers.js +48 -0
  306. package/lib/util/SortableSet.js +140 -0
  307. package/lib/util/StackedSetMap.js +142 -0
  308. package/lib/util/TrackingSet.js +35 -0
  309. package/lib/util/cachedMerge.js +35 -0
  310. package/lib/util/cleverMerge.js +77 -0
  311. package/lib/util/createHash.js +174 -0
  312. package/lib/util/deterministicGrouping.js +274 -0
  313. package/lib/util/hash/BatchedHash.js +71 -0
  314. package/lib/util/hash/md4.js +25 -0
  315. package/lib/util/hash/wasm-hash.js +174 -0
  316. package/lib/util/identifier.js +127 -0
  317. package/lib/util/objectToMap.js +16 -0
  318. package/lib/validateSchema.js +67 -0
  319. package/lib/wasm/UnsupportedWebAssemblyFeatureError.js +17 -0
  320. package/lib/wasm/WasmFinalizeExportsPlugin.js +69 -0
  321. package/lib/wasm/WasmMainTemplatePlugin.js +341 -0
  322. package/lib/wasm/WebAssemblyGenerator.js +458 -0
  323. package/lib/wasm/WebAssemblyInInitialChunkError.js +88 -0
  324. package/lib/wasm/WebAssemblyJavascriptGenerator.js +152 -0
  325. package/lib/wasm/WebAssemblyModulesPlugin.js +128 -0
  326. package/lib/wasm/WebAssemblyParser.js +175 -0
  327. package/lib/wasm/WebAssemblyUtils.js +59 -0
  328. package/lib/web/FetchCompileWasmTemplatePlugin.js +37 -0
  329. package/lib/web/JsonpChunkTemplatePlugin.js +71 -0
  330. package/lib/web/JsonpExportMainTemplatePlugin.js +50 -0
  331. package/lib/web/JsonpHotUpdateChunkTemplatePlugin.js +39 -0
  332. package/lib/web/JsonpMainTemplate.runtime.js +71 -0
  333. package/lib/web/JsonpMainTemplatePlugin.js +615 -0
  334. package/lib/web/JsonpTemplatePlugin.js +23 -0
  335. package/lib/web/WebEnvironmentPlugin.js +18 -0
  336. package/lib/webpack.js +206 -0
  337. package/lib/webpack.web.js +31 -0
  338. package/lib/webworker/WebWorkerChunkTemplatePlugin.js +35 -0
  339. package/lib/webworker/WebWorkerHotUpdateChunkTemplatePlugin.js +40 -0
  340. package/lib/webworker/WebWorkerMainTemplate.runtime.js +73 -0
  341. package/lib/webworker/WebWorkerMainTemplatePlugin.js +192 -0
  342. package/lib/webworker/WebWorkerTemplatePlugin.js +25 -0
  343. package/package.json +211 -0
  344. package/schemas/WebpackOptions.json +2285 -0
  345. package/schemas/ajv.absolutePath.js +57 -0
  346. package/schemas/plugins/BannerPlugin.json +101 -0
  347. package/schemas/plugins/DllPlugin.json +36 -0
  348. package/schemas/plugins/DllReferencePlugin.json +205 -0
  349. package/schemas/plugins/HashedModuleIdsPlugin.json +26 -0
  350. package/schemas/plugins/IgnorePlugin.json +37 -0
  351. package/schemas/plugins/LoaderOptionsPlugin.json +27 -0
  352. package/schemas/plugins/ProgressPlugin.json +52 -0
  353. package/schemas/plugins/SourceMapDevToolPlugin.json +185 -0
  354. package/schemas/plugins/WatchIgnorePlugin.json +18 -0
  355. package/schemas/plugins/debug/ProfilingPlugin.json +13 -0
  356. package/schemas/plugins/optimize/AggressiveSplittingPlugin.json +23 -0
  357. package/schemas/plugins/optimize/LimitChunkCountPlugin.json +16 -0
  358. package/schemas/plugins/optimize/MinChunkSizePlugin.json +12 -0
  359. package/schemas/plugins/optimize/OccurrenceOrderChunkIdsPlugin.json +11 -0
  360. package/schemas/plugins/optimize/OccurrenceOrderModuleIdsPlugin.json +11 -0
  361. package/web_modules/node-libs-browser.js +0 -0
package/lib/Parser.js ADDED
@@ -0,0 +1,2454 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+ "use strict";
6
+
7
+ // Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
8
+
9
+ const acorn = require("acorn");
10
+ const { Tapable, SyncBailHook, HookMap } = require("tapable");
11
+ const util = require("util");
12
+ const vm = require("vm");
13
+ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
14
+ const StackedSetMap = require("./util/StackedSetMap");
15
+
16
+ const acornParser = acorn.Parser;
17
+
18
+ const joinRanges = (startRange, endRange) => {
19
+ if (!endRange) return startRange;
20
+ if (!startRange) return endRange;
21
+ return [startRange[0], endRange[1]];
22
+ };
23
+
24
+ const defaultParserOptions = {
25
+ ranges: true,
26
+ locations: true,
27
+ ecmaVersion: 11,
28
+ sourceType: "module",
29
+ onComment: null
30
+ };
31
+
32
+ // regexp to match at least one "magic comment"
33
+ const webpackCommentRegExp = new RegExp(/(^|\W)webpack[A-Z]{1,}[A-Za-z]{1,}:/);
34
+
35
+ const EMPTY_COMMENT_OPTIONS = {
36
+ options: null,
37
+ errors: null
38
+ };
39
+
40
+ class Parser extends Tapable {
41
+ constructor(options, sourceType = "auto") {
42
+ super();
43
+ this.hooks = {
44
+ evaluateTypeof: new HookMap(() => new SyncBailHook(["expression"])),
45
+ evaluate: new HookMap(() => new SyncBailHook(["expression"])),
46
+ evaluateIdentifier: new HookMap(() => new SyncBailHook(["expression"])),
47
+ evaluateDefinedIdentifier: new HookMap(
48
+ () => new SyncBailHook(["expression"])
49
+ ),
50
+ evaluateCallExpressionMember: new HookMap(
51
+ () => new SyncBailHook(["expression", "param"])
52
+ ),
53
+ statement: new SyncBailHook(["statement"]),
54
+ statementIf: new SyncBailHook(["statement"]),
55
+ label: new HookMap(() => new SyncBailHook(["statement"])),
56
+ import: new SyncBailHook(["statement", "source"]),
57
+ importSpecifier: new SyncBailHook([
58
+ "statement",
59
+ "source",
60
+ "exportName",
61
+ "identifierName"
62
+ ]),
63
+ export: new SyncBailHook(["statement"]),
64
+ exportImport: new SyncBailHook(["statement", "source"]),
65
+ exportDeclaration: new SyncBailHook(["statement", "declaration"]),
66
+ exportExpression: new SyncBailHook(["statement", "declaration"]),
67
+ exportSpecifier: new SyncBailHook([
68
+ "statement",
69
+ "identifierName",
70
+ "exportName",
71
+ "index"
72
+ ]),
73
+ exportImportSpecifier: new SyncBailHook([
74
+ "statement",
75
+ "source",
76
+ "identifierName",
77
+ "exportName",
78
+ "index"
79
+ ]),
80
+ varDeclaration: new HookMap(() => new SyncBailHook(["declaration"])),
81
+ varDeclarationLet: new HookMap(() => new SyncBailHook(["declaration"])),
82
+ varDeclarationConst: new HookMap(() => new SyncBailHook(["declaration"])),
83
+ varDeclarationVar: new HookMap(() => new SyncBailHook(["declaration"])),
84
+ canRename: new HookMap(() => new SyncBailHook(["initExpression"])),
85
+ rename: new HookMap(() => new SyncBailHook(["initExpression"])),
86
+ assigned: new HookMap(() => new SyncBailHook(["expression"])),
87
+ assign: new HookMap(() => new SyncBailHook(["expression"])),
88
+ typeof: new HookMap(() => new SyncBailHook(["expression"])),
89
+ importCall: new SyncBailHook(["expression"]),
90
+ call: new HookMap(() => new SyncBailHook(["expression"])),
91
+ callAnyMember: new HookMap(() => new SyncBailHook(["expression"])),
92
+ new: new HookMap(() => new SyncBailHook(["expression"])),
93
+ expression: new HookMap(() => new SyncBailHook(["expression"])),
94
+ expressionAnyMember: new HookMap(() => new SyncBailHook(["expression"])),
95
+ expressionConditionalOperator: new SyncBailHook(["expression"]),
96
+ expressionLogicalOperator: new SyncBailHook(["expression"]),
97
+ program: new SyncBailHook(["ast", "comments"])
98
+ };
99
+ const HOOK_MAP_COMPAT_CONFIG = {
100
+ evaluateTypeof: /^evaluate typeof (.+)$/,
101
+ evaluateIdentifier: /^evaluate Identifier (.+)$/,
102
+ evaluateDefinedIdentifier: /^evaluate defined Identifier (.+)$/,
103
+ evaluateCallExpressionMember: /^evaluate CallExpression .(.+)$/,
104
+ evaluate: /^evaluate (.+)$/,
105
+ label: /^label (.+)$/,
106
+ varDeclarationLet: /^var-let (.+)$/,
107
+ varDeclarationConst: /^var-const (.+)$/,
108
+ varDeclarationVar: /^var-var (.+)$/,
109
+ varDeclaration: /^var (.+)$/,
110
+ canRename: /^can-rename (.+)$/,
111
+ rename: /^rename (.+)$/,
112
+ typeof: /^typeof (.+)$/,
113
+ assigned: /^assigned (.+)$/,
114
+ assign: /^assign (.+)$/,
115
+ callAnyMember: /^call (.+)\.\*$/,
116
+ call: /^call (.+)$/,
117
+ new: /^new (.+)$/,
118
+ expressionConditionalOperator: /^expression \?:$/,
119
+ expressionAnyMember: /^expression (.+)\.\*$/,
120
+ expression: /^expression (.+)$/
121
+ };
122
+ this._pluginCompat.tap("Parser", options => {
123
+ for (const name of Object.keys(HOOK_MAP_COMPAT_CONFIG)) {
124
+ const regexp = HOOK_MAP_COMPAT_CONFIG[name];
125
+ const match = regexp.exec(options.name);
126
+ if (match) {
127
+ if (match[1]) {
128
+ this.hooks[name].tap(
129
+ match[1],
130
+ options.fn.name || "unnamed compat plugin",
131
+ options.fn.bind(this)
132
+ );
133
+ } else {
134
+ this.hooks[name].tap(
135
+ options.fn.name || "unnamed compat plugin",
136
+ options.fn.bind(this)
137
+ );
138
+ }
139
+ return true;
140
+ }
141
+ }
142
+ });
143
+ this.options = options;
144
+ this.sourceType = sourceType;
145
+ this.scope = undefined;
146
+ this.state = undefined;
147
+ this.comments = undefined;
148
+ this.initializeEvaluating();
149
+ }
150
+
151
+ initializeEvaluating() {
152
+ this.hooks.evaluate.for("Literal").tap("Parser", expr => {
153
+ switch (typeof expr.value) {
154
+ case "number":
155
+ return new BasicEvaluatedExpression()
156
+ .setNumber(expr.value)
157
+ .setRange(expr.range);
158
+ case "string":
159
+ return new BasicEvaluatedExpression()
160
+ .setString(expr.value)
161
+ .setRange(expr.range);
162
+ case "boolean":
163
+ return new BasicEvaluatedExpression()
164
+ .setBoolean(expr.value)
165
+ .setRange(expr.range);
166
+ }
167
+ if (expr.value === null) {
168
+ return new BasicEvaluatedExpression().setNull().setRange(expr.range);
169
+ }
170
+ if (expr.value instanceof RegExp) {
171
+ return new BasicEvaluatedExpression()
172
+ .setRegExp(expr.value)
173
+ .setRange(expr.range);
174
+ }
175
+ });
176
+ this.hooks.evaluate.for("LogicalExpression").tap("Parser", expr => {
177
+ let left;
178
+ let leftAsBool;
179
+ let right;
180
+ if (expr.operator === "&&") {
181
+ left = this.evaluateExpression(expr.left);
182
+ leftAsBool = left && left.asBool();
183
+ if (leftAsBool === false) return left.setRange(expr.range);
184
+ if (leftAsBool !== true) return;
185
+ right = this.evaluateExpression(expr.right);
186
+ return right.setRange(expr.range);
187
+ } else if (expr.operator === "||") {
188
+ left = this.evaluateExpression(expr.left);
189
+ leftAsBool = left && left.asBool();
190
+ if (leftAsBool === true) return left.setRange(expr.range);
191
+ if (leftAsBool !== false) return;
192
+ right = this.evaluateExpression(expr.right);
193
+ return right.setRange(expr.range);
194
+ }
195
+ });
196
+ this.hooks.evaluate.for("BinaryExpression").tap("Parser", expr => {
197
+ let left;
198
+ let right;
199
+ let res;
200
+ if (expr.operator === "+") {
201
+ left = this.evaluateExpression(expr.left);
202
+ right = this.evaluateExpression(expr.right);
203
+ if (!left || !right) return;
204
+ res = new BasicEvaluatedExpression();
205
+ if (left.isString()) {
206
+ if (right.isString()) {
207
+ res.setString(left.string + right.string);
208
+ } else if (right.isNumber()) {
209
+ res.setString(left.string + right.number);
210
+ } else if (
211
+ right.isWrapped() &&
212
+ right.prefix &&
213
+ right.prefix.isString()
214
+ ) {
215
+ // "left" + ("prefix" + inner + "postfix")
216
+ // => ("leftprefix" + inner + "postfix")
217
+ res.setWrapped(
218
+ new BasicEvaluatedExpression()
219
+ .setString(left.string + right.prefix.string)
220
+ .setRange(joinRanges(left.range, right.prefix.range)),
221
+ right.postfix,
222
+ right.wrappedInnerExpressions
223
+ );
224
+ } else if (right.isWrapped()) {
225
+ // "left" + ([null] + inner + "postfix")
226
+ // => ("left" + inner + "postfix")
227
+ res.setWrapped(left, right.postfix, right.wrappedInnerExpressions);
228
+ } else {
229
+ // "left" + expr
230
+ // => ("left" + expr + "")
231
+ res.setWrapped(left, null, [right]);
232
+ }
233
+ } else if (left.isNumber()) {
234
+ if (right.isString()) {
235
+ res.setString(left.number + right.string);
236
+ } else if (right.isNumber()) {
237
+ res.setNumber(left.number + right.number);
238
+ } else {
239
+ return;
240
+ }
241
+ } else if (left.isWrapped()) {
242
+ if (left.postfix && left.postfix.isString() && right.isString()) {
243
+ // ("prefix" + inner + "postfix") + "right"
244
+ // => ("prefix" + inner + "postfixright")
245
+ res.setWrapped(
246
+ left.prefix,
247
+ new BasicEvaluatedExpression()
248
+ .setString(left.postfix.string + right.string)
249
+ .setRange(joinRanges(left.postfix.range, right.range)),
250
+ left.wrappedInnerExpressions
251
+ );
252
+ } else if (
253
+ left.postfix &&
254
+ left.postfix.isString() &&
255
+ right.isNumber()
256
+ ) {
257
+ // ("prefix" + inner + "postfix") + 123
258
+ // => ("prefix" + inner + "postfix123")
259
+ res.setWrapped(
260
+ left.prefix,
261
+ new BasicEvaluatedExpression()
262
+ .setString(left.postfix.string + right.number)
263
+ .setRange(joinRanges(left.postfix.range, right.range)),
264
+ left.wrappedInnerExpressions
265
+ );
266
+ } else if (right.isString()) {
267
+ // ("prefix" + inner + [null]) + "right"
268
+ // => ("prefix" + inner + "right")
269
+ res.setWrapped(left.prefix, right, left.wrappedInnerExpressions);
270
+ } else if (right.isNumber()) {
271
+ // ("prefix" + inner + [null]) + 123
272
+ // => ("prefix" + inner + "123")
273
+ res.setWrapped(
274
+ left.prefix,
275
+ new BasicEvaluatedExpression()
276
+ .setString(right.number + "")
277
+ .setRange(right.range),
278
+ left.wrappedInnerExpressions
279
+ );
280
+ } else if (right.isWrapped()) {
281
+ // ("prefix1" + inner1 + "postfix1") + ("prefix2" + inner2 + "postfix2")
282
+ // ("prefix1" + inner1 + "postfix1" + "prefix2" + inner2 + "postfix2")
283
+ res.setWrapped(
284
+ left.prefix,
285
+ right.postfix,
286
+ left.wrappedInnerExpressions &&
287
+ right.wrappedInnerExpressions &&
288
+ left.wrappedInnerExpressions
289
+ .concat(left.postfix ? [left.postfix] : [])
290
+ .concat(right.prefix ? [right.prefix] : [])
291
+ .concat(right.wrappedInnerExpressions)
292
+ );
293
+ } else {
294
+ // ("prefix" + inner + postfix) + expr
295
+ // => ("prefix" + inner + postfix + expr + [null])
296
+ res.setWrapped(
297
+ left.prefix,
298
+ null,
299
+ left.wrappedInnerExpressions &&
300
+ left.wrappedInnerExpressions.concat(
301
+ left.postfix ? [left.postfix, right] : [right]
302
+ )
303
+ );
304
+ }
305
+ } else {
306
+ if (right.isString()) {
307
+ // left + "right"
308
+ // => ([null] + left + "right")
309
+ res.setWrapped(null, right, [left]);
310
+ } else if (right.isWrapped()) {
311
+ // left + (prefix + inner + "postfix")
312
+ // => ([null] + left + prefix + inner + "postfix")
313
+ res.setWrapped(
314
+ null,
315
+ right.postfix,
316
+ right.wrappedInnerExpressions &&
317
+ (right.prefix ? [left, right.prefix] : [left]).concat(
318
+ right.wrappedInnerExpressions
319
+ )
320
+ );
321
+ } else {
322
+ return;
323
+ }
324
+ }
325
+ res.setRange(expr.range);
326
+ return res;
327
+ } else if (expr.operator === "-") {
328
+ left = this.evaluateExpression(expr.left);
329
+ right = this.evaluateExpression(expr.right);
330
+ if (!left || !right) return;
331
+ if (!left.isNumber() || !right.isNumber()) return;
332
+ res = new BasicEvaluatedExpression();
333
+ res.setNumber(left.number - right.number);
334
+ res.setRange(expr.range);
335
+ return res;
336
+ } else if (expr.operator === "*") {
337
+ left = this.evaluateExpression(expr.left);
338
+ right = this.evaluateExpression(expr.right);
339
+ if (!left || !right) return;
340
+ if (!left.isNumber() || !right.isNumber()) return;
341
+ res = new BasicEvaluatedExpression();
342
+ res.setNumber(left.number * right.number);
343
+ res.setRange(expr.range);
344
+ return res;
345
+ } else if (expr.operator === "/") {
346
+ left = this.evaluateExpression(expr.left);
347
+ right = this.evaluateExpression(expr.right);
348
+ if (!left || !right) return;
349
+ if (!left.isNumber() || !right.isNumber()) return;
350
+ res = new BasicEvaluatedExpression();
351
+ res.setNumber(left.number / right.number);
352
+ res.setRange(expr.range);
353
+ return res;
354
+ } else if (expr.operator === "**") {
355
+ left = this.evaluateExpression(expr.left);
356
+ right = this.evaluateExpression(expr.right);
357
+ if (!left || !right) return;
358
+ if (!left.isNumber() || !right.isNumber()) return;
359
+ res = new BasicEvaluatedExpression();
360
+ res.setNumber(Math.pow(left.number, right.number));
361
+ res.setRange(expr.range);
362
+ return res;
363
+ } else if (expr.operator === "==" || expr.operator === "===") {
364
+ left = this.evaluateExpression(expr.left);
365
+ right = this.evaluateExpression(expr.right);
366
+ if (!left || !right) return;
367
+ res = new BasicEvaluatedExpression();
368
+ res.setRange(expr.range);
369
+ if (left.isString() && right.isString()) {
370
+ return res.setBoolean(left.string === right.string);
371
+ } else if (left.isNumber() && right.isNumber()) {
372
+ return res.setBoolean(left.number === right.number);
373
+ } else if (left.isBoolean() && right.isBoolean()) {
374
+ return res.setBoolean(left.bool === right.bool);
375
+ }
376
+ } else if (expr.operator === "!=" || expr.operator === "!==") {
377
+ left = this.evaluateExpression(expr.left);
378
+ right = this.evaluateExpression(expr.right);
379
+ if (!left || !right) return;
380
+ res = new BasicEvaluatedExpression();
381
+ res.setRange(expr.range);
382
+ if (left.isString() && right.isString()) {
383
+ return res.setBoolean(left.string !== right.string);
384
+ } else if (left.isNumber() && right.isNumber()) {
385
+ return res.setBoolean(left.number !== right.number);
386
+ } else if (left.isBoolean() && right.isBoolean()) {
387
+ return res.setBoolean(left.bool !== right.bool);
388
+ }
389
+ } else if (expr.operator === "&") {
390
+ left = this.evaluateExpression(expr.left);
391
+ right = this.evaluateExpression(expr.right);
392
+ if (!left || !right) return;
393
+ if (!left.isNumber() || !right.isNumber()) return;
394
+ res = new BasicEvaluatedExpression();
395
+ res.setNumber(left.number & right.number);
396
+ res.setRange(expr.range);
397
+ return res;
398
+ } else if (expr.operator === "|") {
399
+ left = this.evaluateExpression(expr.left);
400
+ right = this.evaluateExpression(expr.right);
401
+ if (!left || !right) return;
402
+ if (!left.isNumber() || !right.isNumber()) return;
403
+ res = new BasicEvaluatedExpression();
404
+ res.setNumber(left.number | right.number);
405
+ res.setRange(expr.range);
406
+ return res;
407
+ } else if (expr.operator === "^") {
408
+ left = this.evaluateExpression(expr.left);
409
+ right = this.evaluateExpression(expr.right);
410
+ if (!left || !right) return;
411
+ if (!left.isNumber() || !right.isNumber()) return;
412
+ res = new BasicEvaluatedExpression();
413
+ res.setNumber(left.number ^ right.number);
414
+ res.setRange(expr.range);
415
+ return res;
416
+ } else if (expr.operator === ">>>") {
417
+ left = this.evaluateExpression(expr.left);
418
+ right = this.evaluateExpression(expr.right);
419
+ if (!left || !right) return;
420
+ if (!left.isNumber() || !right.isNumber()) return;
421
+ res = new BasicEvaluatedExpression();
422
+ res.setNumber(left.number >>> right.number);
423
+ res.setRange(expr.range);
424
+ return res;
425
+ } else if (expr.operator === ">>") {
426
+ left = this.evaluateExpression(expr.left);
427
+ right = this.evaluateExpression(expr.right);
428
+ if (!left || !right) return;
429
+ if (!left.isNumber() || !right.isNumber()) return;
430
+ res = new BasicEvaluatedExpression();
431
+ res.setNumber(left.number >> right.number);
432
+ res.setRange(expr.range);
433
+ return res;
434
+ } else if (expr.operator === "<<") {
435
+ left = this.evaluateExpression(expr.left);
436
+ right = this.evaluateExpression(expr.right);
437
+ if (!left || !right) return;
438
+ if (!left.isNumber() || !right.isNumber()) return;
439
+ res = new BasicEvaluatedExpression();
440
+ res.setNumber(left.number << right.number);
441
+ res.setRange(expr.range);
442
+ return res;
443
+ }
444
+ });
445
+ this.hooks.evaluate.for("UnaryExpression").tap("Parser", expr => {
446
+ if (expr.operator === "typeof") {
447
+ let res;
448
+ let name;
449
+ if (expr.argument.type === "Identifier") {
450
+ name =
451
+ this.scope.renames.get(expr.argument.name) || expr.argument.name;
452
+ if (!this.scope.definitions.has(name)) {
453
+ const hook = this.hooks.evaluateTypeof.get(name);
454
+ if (hook !== undefined) {
455
+ res = hook.call(expr);
456
+ if (res !== undefined) return res;
457
+ }
458
+ }
459
+ }
460
+ if (expr.argument.type === "MemberExpression") {
461
+ const exprName = this.getNameForExpression(expr.argument);
462
+ if (exprName && exprName.free) {
463
+ const hook = this.hooks.evaluateTypeof.get(exprName.name);
464
+ if (hook !== undefined) {
465
+ res = hook.call(expr);
466
+ if (res !== undefined) return res;
467
+ }
468
+ }
469
+ }
470
+ if (expr.argument.type === "FunctionExpression") {
471
+ return new BasicEvaluatedExpression()
472
+ .setString("function")
473
+ .setRange(expr.range);
474
+ }
475
+ const arg = this.evaluateExpression(expr.argument);
476
+ if (arg.isString() || arg.isWrapped()) {
477
+ return new BasicEvaluatedExpression()
478
+ .setString("string")
479
+ .setRange(expr.range);
480
+ }
481
+ if (arg.isNumber()) {
482
+ return new BasicEvaluatedExpression()
483
+ .setString("number")
484
+ .setRange(expr.range);
485
+ }
486
+ if (arg.isBoolean()) {
487
+ return new BasicEvaluatedExpression()
488
+ .setString("boolean")
489
+ .setRange(expr.range);
490
+ }
491
+ if (arg.isArray() || arg.isConstArray() || arg.isRegExp()) {
492
+ return new BasicEvaluatedExpression()
493
+ .setString("object")
494
+ .setRange(expr.range);
495
+ }
496
+ } else if (expr.operator === "!") {
497
+ const argument = this.evaluateExpression(expr.argument);
498
+ if (!argument) return;
499
+ if (argument.isBoolean()) {
500
+ return new BasicEvaluatedExpression()
501
+ .setBoolean(!argument.bool)
502
+ .setRange(expr.range);
503
+ }
504
+ if (argument.isTruthy()) {
505
+ return new BasicEvaluatedExpression()
506
+ .setBoolean(false)
507
+ .setRange(expr.range);
508
+ }
509
+ if (argument.isFalsy()) {
510
+ return new BasicEvaluatedExpression()
511
+ .setBoolean(true)
512
+ .setRange(expr.range);
513
+ }
514
+ if (argument.isString()) {
515
+ return new BasicEvaluatedExpression()
516
+ .setBoolean(!argument.string)
517
+ .setRange(expr.range);
518
+ }
519
+ if (argument.isNumber()) {
520
+ return new BasicEvaluatedExpression()
521
+ .setBoolean(!argument.number)
522
+ .setRange(expr.range);
523
+ }
524
+ } else if (expr.operator === "~") {
525
+ const argument = this.evaluateExpression(expr.argument);
526
+ if (!argument) return;
527
+ if (!argument.isNumber()) return;
528
+ const res = new BasicEvaluatedExpression();
529
+ res.setNumber(~argument.number);
530
+ res.setRange(expr.range);
531
+ return res;
532
+ }
533
+ });
534
+ this.hooks.evaluateTypeof.for("undefined").tap("Parser", expr => {
535
+ return new BasicEvaluatedExpression()
536
+ .setString("undefined")
537
+ .setRange(expr.range);
538
+ });
539
+ this.hooks.evaluate.for("Identifier").tap("Parser", expr => {
540
+ const name = this.scope.renames.get(expr.name) || expr.name;
541
+ if (!this.scope.definitions.has(expr.name)) {
542
+ const hook = this.hooks.evaluateIdentifier.get(name);
543
+ if (hook !== undefined) {
544
+ const result = hook.call(expr);
545
+ if (result) return result;
546
+ }
547
+ return new BasicEvaluatedExpression()
548
+ .setIdentifier(name)
549
+ .setRange(expr.range);
550
+ } else {
551
+ const hook = this.hooks.evaluateDefinedIdentifier.get(name);
552
+ if (hook !== undefined) {
553
+ return hook.call(expr);
554
+ }
555
+ }
556
+ });
557
+ this.hooks.evaluate.for("ThisExpression").tap("Parser", expr => {
558
+ const name = this.scope.renames.get("this");
559
+ if (name) {
560
+ const hook = this.hooks.evaluateIdentifier.get(name);
561
+ if (hook !== undefined) {
562
+ const result = hook.call(expr);
563
+ if (result) return result;
564
+ }
565
+ return new BasicEvaluatedExpression()
566
+ .setIdentifier(name)
567
+ .setRange(expr.range);
568
+ }
569
+ });
570
+ this.hooks.evaluate.for("MemberExpression").tap("Parser", expression => {
571
+ let exprName = this.getNameForExpression(expression);
572
+ if (exprName) {
573
+ if (exprName.free) {
574
+ const hook = this.hooks.evaluateIdentifier.get(exprName.name);
575
+ if (hook !== undefined) {
576
+ const result = hook.call(expression);
577
+ if (result) return result;
578
+ }
579
+ return new BasicEvaluatedExpression()
580
+ .setIdentifier(exprName.name)
581
+ .setRange(expression.range);
582
+ } else {
583
+ const hook = this.hooks.evaluateDefinedIdentifier.get(exprName.name);
584
+ if (hook !== undefined) {
585
+ return hook.call(expression);
586
+ }
587
+ }
588
+ }
589
+ });
590
+ this.hooks.evaluate.for("CallExpression").tap("Parser", expr => {
591
+ if (expr.callee.type !== "MemberExpression") return;
592
+ if (
593
+ expr.callee.property.type !==
594
+ (expr.callee.computed ? "Literal" : "Identifier")
595
+ )
596
+ return;
597
+ const param = this.evaluateExpression(expr.callee.object);
598
+ if (!param) return;
599
+ const property = expr.callee.property.name || expr.callee.property.value;
600
+ const hook = this.hooks.evaluateCallExpressionMember.get(property);
601
+ if (hook !== undefined) {
602
+ return hook.call(expr, param);
603
+ }
604
+ });
605
+ this.hooks.evaluateCallExpressionMember
606
+ .for("replace")
607
+ .tap("Parser", (expr, param) => {
608
+ if (!param.isString()) return;
609
+ if (expr.arguments.length !== 2) return;
610
+ let arg1 = this.evaluateExpression(expr.arguments[0]);
611
+ let arg2 = this.evaluateExpression(expr.arguments[1]);
612
+ if (!arg1.isString() && !arg1.isRegExp()) return;
613
+ arg1 = arg1.regExp || arg1.string;
614
+ if (!arg2.isString()) return;
615
+ arg2 = arg2.string;
616
+ return new BasicEvaluatedExpression()
617
+ .setString(param.string.replace(arg1, arg2))
618
+ .setRange(expr.range);
619
+ });
620
+ ["substr", "substring"].forEach(fn => {
621
+ this.hooks.evaluateCallExpressionMember
622
+ .for(fn)
623
+ .tap("Parser", (expr, param) => {
624
+ if (!param.isString()) return;
625
+ let arg1;
626
+ let result,
627
+ str = param.string;
628
+ switch (expr.arguments.length) {
629
+ case 1:
630
+ arg1 = this.evaluateExpression(expr.arguments[0]);
631
+ if (!arg1.isNumber()) return;
632
+ result = str[fn](arg1.number);
633
+ break;
634
+ case 2: {
635
+ arg1 = this.evaluateExpression(expr.arguments[0]);
636
+ const arg2 = this.evaluateExpression(expr.arguments[1]);
637
+ if (!arg1.isNumber()) return;
638
+ if (!arg2.isNumber()) return;
639
+ result = str[fn](arg1.number, arg2.number);
640
+ break;
641
+ }
642
+ default:
643
+ return;
644
+ }
645
+ return new BasicEvaluatedExpression()
646
+ .setString(result)
647
+ .setRange(expr.range);
648
+ });
649
+ });
650
+
651
+ /**
652
+ * @param {string} kind "cooked" | "raw"
653
+ * @param {TODO} templateLiteralExpr TemplateLiteral expr
654
+ * @returns {{quasis: BasicEvaluatedExpression[], parts: BasicEvaluatedExpression[]}} Simplified template
655
+ */
656
+ const getSimplifiedTemplateResult = (kind, templateLiteralExpr) => {
657
+ const quasis = [];
658
+ const parts = [];
659
+
660
+ for (let i = 0; i < templateLiteralExpr.quasis.length; i++) {
661
+ const quasiExpr = templateLiteralExpr.quasis[i];
662
+ const quasi = quasiExpr.value[kind];
663
+
664
+ if (i > 0) {
665
+ const prevExpr = parts[parts.length - 1];
666
+ const expr = this.evaluateExpression(
667
+ templateLiteralExpr.expressions[i - 1]
668
+ );
669
+ const exprAsString = expr.asString();
670
+ if (typeof exprAsString === "string") {
671
+ // We can merge quasi + expr + quasi when expr
672
+ // is a const string
673
+
674
+ prevExpr.setString(prevExpr.string + exprAsString + quasi);
675
+ prevExpr.setRange([prevExpr.range[0], quasiExpr.range[1]]);
676
+ // We unset the expression as it doesn't match to a single expression
677
+ prevExpr.setExpression(undefined);
678
+ continue;
679
+ }
680
+ parts.push(expr);
681
+ }
682
+
683
+ const part = new BasicEvaluatedExpression()
684
+ .setString(quasi)
685
+ .setRange(quasiExpr.range)
686
+ .setExpression(quasiExpr);
687
+ quasis.push(part);
688
+ parts.push(part);
689
+ }
690
+ return {
691
+ quasis,
692
+ parts
693
+ };
694
+ };
695
+
696
+ this.hooks.evaluate.for("TemplateLiteral").tap("Parser", node => {
697
+ const { quasis, parts } = getSimplifiedTemplateResult("cooked", node);
698
+ if (parts.length === 1) {
699
+ return parts[0].setRange(node.range);
700
+ }
701
+ return new BasicEvaluatedExpression()
702
+ .setTemplateString(quasis, parts, "cooked")
703
+ .setRange(node.range);
704
+ });
705
+ this.hooks.evaluate.for("TaggedTemplateExpression").tap("Parser", node => {
706
+ if (this.evaluateExpression(node.tag).identifier !== "String.raw") return;
707
+ const { quasis, parts } = getSimplifiedTemplateResult("raw", node.quasi);
708
+ if (parts.length === 1) {
709
+ return parts[0].setRange(node.range);
710
+ }
711
+ return new BasicEvaluatedExpression()
712
+ .setTemplateString(quasis, parts, "raw")
713
+ .setRange(node.range);
714
+ });
715
+
716
+ this.hooks.evaluateCallExpressionMember
717
+ .for("concat")
718
+ .tap("Parser", (expr, param) => {
719
+ if (!param.isString() && !param.isWrapped()) return;
720
+
721
+ let stringSuffix = null;
722
+ let hasUnknownParams = false;
723
+ for (let i = expr.arguments.length - 1; i >= 0; i--) {
724
+ const argExpr = this.evaluateExpression(expr.arguments[i]);
725
+ if (!argExpr.isString() && !argExpr.isNumber()) {
726
+ hasUnknownParams = true;
727
+ break;
728
+ }
729
+
730
+ const value = argExpr.isString()
731
+ ? argExpr.string
732
+ : "" + argExpr.number;
733
+
734
+ const newString = value + (stringSuffix ? stringSuffix.string : "");
735
+ const newRange = [
736
+ argExpr.range[0],
737
+ (stringSuffix || argExpr).range[1]
738
+ ];
739
+ stringSuffix = new BasicEvaluatedExpression()
740
+ .setString(newString)
741
+ .setRange(newRange);
742
+ }
743
+
744
+ if (hasUnknownParams) {
745
+ const prefix = param.isString() ? param : param.prefix;
746
+ return new BasicEvaluatedExpression()
747
+ .setWrapped(prefix, stringSuffix)
748
+ .setRange(expr.range);
749
+ } else if (param.isWrapped()) {
750
+ const postfix = stringSuffix || param.postfix;
751
+ return new BasicEvaluatedExpression()
752
+ .setWrapped(param.prefix, postfix)
753
+ .setRange(expr.range);
754
+ } else {
755
+ const newString =
756
+ param.string + (stringSuffix ? stringSuffix.string : "");
757
+ return new BasicEvaluatedExpression()
758
+ .setString(newString)
759
+ .setRange(expr.range);
760
+ }
761
+ });
762
+ this.hooks.evaluateCallExpressionMember
763
+ .for("split")
764
+ .tap("Parser", (expr, param) => {
765
+ if (!param.isString()) return;
766
+ if (expr.arguments.length !== 1) return;
767
+ let result;
768
+ const arg = this.evaluateExpression(expr.arguments[0]);
769
+ if (arg.isString()) {
770
+ result = param.string.split(arg.string);
771
+ } else if (arg.isRegExp()) {
772
+ result = param.string.split(arg.regExp);
773
+ } else {
774
+ return;
775
+ }
776
+ return new BasicEvaluatedExpression()
777
+ .setArray(result)
778
+ .setRange(expr.range);
779
+ });
780
+ this.hooks.evaluate.for("ConditionalExpression").tap("Parser", expr => {
781
+ const condition = this.evaluateExpression(expr.test);
782
+ const conditionValue = condition.asBool();
783
+ let res;
784
+ if (conditionValue === undefined) {
785
+ const consequent = this.evaluateExpression(expr.consequent);
786
+ const alternate = this.evaluateExpression(expr.alternate);
787
+ if (!consequent || !alternate) return;
788
+ res = new BasicEvaluatedExpression();
789
+ if (consequent.isConditional()) {
790
+ res.setOptions(consequent.options);
791
+ } else {
792
+ res.setOptions([consequent]);
793
+ }
794
+ if (alternate.isConditional()) {
795
+ res.addOptions(alternate.options);
796
+ } else {
797
+ res.addOptions([alternate]);
798
+ }
799
+ } else {
800
+ res = this.evaluateExpression(
801
+ conditionValue ? expr.consequent : expr.alternate
802
+ );
803
+ }
804
+ res.setRange(expr.range);
805
+ return res;
806
+ });
807
+ this.hooks.evaluate.for("ArrayExpression").tap("Parser", expr => {
808
+ const items = expr.elements.map(element => {
809
+ return element !== null && this.evaluateExpression(element);
810
+ });
811
+ if (!items.every(Boolean)) return;
812
+ return new BasicEvaluatedExpression()
813
+ .setItems(items)
814
+ .setRange(expr.range);
815
+ });
816
+ }
817
+
818
+ getRenameIdentifier(expr) {
819
+ const result = this.evaluateExpression(expr);
820
+ if (result && result.isIdentifier()) {
821
+ return result.identifier;
822
+ }
823
+ }
824
+
825
+ walkClass(classy) {
826
+ if (classy.superClass) this.walkExpression(classy.superClass);
827
+ if (classy.body && classy.body.type === "ClassBody") {
828
+ const wasTopLevel = this.scope.topLevelScope;
829
+ this.scope.topLevelScope = false;
830
+ for (const methodDefinition of classy.body.body) {
831
+ if (methodDefinition.type === "MethodDefinition") {
832
+ this.walkMethodDefinition(methodDefinition);
833
+ }
834
+ }
835
+ this.scope.topLevelScope = wasTopLevel;
836
+ }
837
+ }
838
+
839
+ walkMethodDefinition(methodDefinition) {
840
+ if (methodDefinition.computed && methodDefinition.key) {
841
+ this.walkExpression(methodDefinition.key);
842
+ }
843
+ if (methodDefinition.value) {
844
+ this.walkExpression(methodDefinition.value);
845
+ }
846
+ }
847
+
848
+ // Prewalking iterates the scope for variable declarations
849
+ prewalkStatements(statements) {
850
+ for (let index = 0, len = statements.length; index < len; index++) {
851
+ const statement = statements[index];
852
+ this.prewalkStatement(statement);
853
+ }
854
+ }
855
+
856
+ // Block-Prewalking iterates the scope for block variable declarations
857
+ blockPrewalkStatements(statements) {
858
+ for (let index = 0, len = statements.length; index < len; index++) {
859
+ const statement = statements[index];
860
+ this.blockPrewalkStatement(statement);
861
+ }
862
+ }
863
+
864
+ // Walking iterates the statements and expressions and processes them
865
+ walkStatements(statements) {
866
+ for (let index = 0, len = statements.length; index < len; index++) {
867
+ const statement = statements[index];
868
+ this.walkStatement(statement);
869
+ }
870
+ }
871
+
872
+ prewalkStatement(statement) {
873
+ switch (statement.type) {
874
+ case "BlockStatement":
875
+ this.prewalkBlockStatement(statement);
876
+ break;
877
+ case "DoWhileStatement":
878
+ this.prewalkDoWhileStatement(statement);
879
+ break;
880
+ case "ExportAllDeclaration":
881
+ this.prewalkExportAllDeclaration(statement);
882
+ break;
883
+ case "ExportDefaultDeclaration":
884
+ this.prewalkExportDefaultDeclaration(statement);
885
+ break;
886
+ case "ExportNamedDeclaration":
887
+ this.prewalkExportNamedDeclaration(statement);
888
+ break;
889
+ case "ForInStatement":
890
+ this.prewalkForInStatement(statement);
891
+ break;
892
+ case "ForOfStatement":
893
+ this.prewalkForOfStatement(statement);
894
+ break;
895
+ case "ForStatement":
896
+ this.prewalkForStatement(statement);
897
+ break;
898
+ case "FunctionDeclaration":
899
+ this.prewalkFunctionDeclaration(statement);
900
+ break;
901
+ case "IfStatement":
902
+ this.prewalkIfStatement(statement);
903
+ break;
904
+ case "ImportDeclaration":
905
+ this.prewalkImportDeclaration(statement);
906
+ break;
907
+ case "LabeledStatement":
908
+ this.prewalkLabeledStatement(statement);
909
+ break;
910
+ case "SwitchStatement":
911
+ this.prewalkSwitchStatement(statement);
912
+ break;
913
+ case "TryStatement":
914
+ this.prewalkTryStatement(statement);
915
+ break;
916
+ case "VariableDeclaration":
917
+ this.prewalkVariableDeclaration(statement);
918
+ break;
919
+ case "WhileStatement":
920
+ this.prewalkWhileStatement(statement);
921
+ break;
922
+ case "WithStatement":
923
+ this.prewalkWithStatement(statement);
924
+ break;
925
+ }
926
+ }
927
+
928
+ blockPrewalkStatement(statement) {
929
+ switch (statement.type) {
930
+ case "VariableDeclaration":
931
+ this.blockPrewalkVariableDeclaration(statement);
932
+ break;
933
+ case "ExportDefaultDeclaration":
934
+ this.blockPrewalkExportDefaultDeclaration(statement);
935
+ break;
936
+ case "ExportNamedDeclaration":
937
+ this.blockPrewalkExportNamedDeclaration(statement);
938
+ break;
939
+ case "ClassDeclaration":
940
+ this.blockPrewalkClassDeclaration(statement);
941
+ break;
942
+ }
943
+ }
944
+
945
+ walkStatement(statement) {
946
+ if (this.hooks.statement.call(statement) !== undefined) return;
947
+ switch (statement.type) {
948
+ case "BlockStatement":
949
+ this.walkBlockStatement(statement);
950
+ break;
951
+ case "ClassDeclaration":
952
+ this.walkClassDeclaration(statement);
953
+ break;
954
+ case "DoWhileStatement":
955
+ this.walkDoWhileStatement(statement);
956
+ break;
957
+ case "ExportDefaultDeclaration":
958
+ this.walkExportDefaultDeclaration(statement);
959
+ break;
960
+ case "ExportNamedDeclaration":
961
+ this.walkExportNamedDeclaration(statement);
962
+ break;
963
+ case "ExpressionStatement":
964
+ this.walkExpressionStatement(statement);
965
+ break;
966
+ case "ForInStatement":
967
+ this.walkForInStatement(statement);
968
+ break;
969
+ case "ForOfStatement":
970
+ this.walkForOfStatement(statement);
971
+ break;
972
+ case "ForStatement":
973
+ this.walkForStatement(statement);
974
+ break;
975
+ case "FunctionDeclaration":
976
+ this.walkFunctionDeclaration(statement);
977
+ break;
978
+ case "IfStatement":
979
+ this.walkIfStatement(statement);
980
+ break;
981
+ case "LabeledStatement":
982
+ this.walkLabeledStatement(statement);
983
+ break;
984
+ case "ReturnStatement":
985
+ this.walkReturnStatement(statement);
986
+ break;
987
+ case "SwitchStatement":
988
+ this.walkSwitchStatement(statement);
989
+ break;
990
+ case "ThrowStatement":
991
+ this.walkThrowStatement(statement);
992
+ break;
993
+ case "TryStatement":
994
+ this.walkTryStatement(statement);
995
+ break;
996
+ case "VariableDeclaration":
997
+ this.walkVariableDeclaration(statement);
998
+ break;
999
+ case "WhileStatement":
1000
+ this.walkWhileStatement(statement);
1001
+ break;
1002
+ case "WithStatement":
1003
+ this.walkWithStatement(statement);
1004
+ break;
1005
+ }
1006
+ }
1007
+
1008
+ // Real Statements
1009
+ prewalkBlockStatement(statement) {
1010
+ this.prewalkStatements(statement.body);
1011
+ }
1012
+
1013
+ walkBlockStatement(statement) {
1014
+ this.inBlockScope(() => {
1015
+ const body = statement.body;
1016
+ this.blockPrewalkStatements(body);
1017
+ this.walkStatements(body);
1018
+ });
1019
+ }
1020
+
1021
+ walkExpressionStatement(statement) {
1022
+ this.walkExpression(statement.expression);
1023
+ }
1024
+
1025
+ prewalkIfStatement(statement) {
1026
+ this.prewalkStatement(statement.consequent);
1027
+ if (statement.alternate) {
1028
+ this.prewalkStatement(statement.alternate);
1029
+ }
1030
+ }
1031
+
1032
+ walkIfStatement(statement) {
1033
+ const result = this.hooks.statementIf.call(statement);
1034
+ if (result === undefined) {
1035
+ this.walkExpression(statement.test);
1036
+ this.walkStatement(statement.consequent);
1037
+ if (statement.alternate) {
1038
+ this.walkStatement(statement.alternate);
1039
+ }
1040
+ } else {
1041
+ if (result) {
1042
+ this.walkStatement(statement.consequent);
1043
+ } else if (statement.alternate) {
1044
+ this.walkStatement(statement.alternate);
1045
+ }
1046
+ }
1047
+ }
1048
+
1049
+ prewalkLabeledStatement(statement) {
1050
+ this.prewalkStatement(statement.body);
1051
+ }
1052
+
1053
+ walkLabeledStatement(statement) {
1054
+ const hook = this.hooks.label.get(statement.label.name);
1055
+ if (hook !== undefined) {
1056
+ const result = hook.call(statement);
1057
+ if (result === true) return;
1058
+ }
1059
+ this.walkStatement(statement.body);
1060
+ }
1061
+
1062
+ prewalkWithStatement(statement) {
1063
+ this.prewalkStatement(statement.body);
1064
+ }
1065
+
1066
+ walkWithStatement(statement) {
1067
+ this.walkExpression(statement.object);
1068
+ this.walkStatement(statement.body);
1069
+ }
1070
+
1071
+ prewalkSwitchStatement(statement) {
1072
+ this.prewalkSwitchCases(statement.cases);
1073
+ }
1074
+
1075
+ walkSwitchStatement(statement) {
1076
+ this.walkExpression(statement.discriminant);
1077
+ this.walkSwitchCases(statement.cases);
1078
+ }
1079
+
1080
+ walkTerminatingStatement(statement) {
1081
+ if (statement.argument) this.walkExpression(statement.argument);
1082
+ }
1083
+
1084
+ walkReturnStatement(statement) {
1085
+ this.walkTerminatingStatement(statement);
1086
+ }
1087
+
1088
+ walkThrowStatement(statement) {
1089
+ this.walkTerminatingStatement(statement);
1090
+ }
1091
+
1092
+ prewalkTryStatement(statement) {
1093
+ this.prewalkStatement(statement.block);
1094
+ }
1095
+
1096
+ walkTryStatement(statement) {
1097
+ if (this.scope.inTry) {
1098
+ this.walkStatement(statement.block);
1099
+ } else {
1100
+ this.scope.inTry = true;
1101
+ this.walkStatement(statement.block);
1102
+ this.scope.inTry = false;
1103
+ }
1104
+ if (statement.handler) this.walkCatchClause(statement.handler);
1105
+ if (statement.finalizer) this.walkStatement(statement.finalizer);
1106
+ }
1107
+
1108
+ prewalkWhileStatement(statement) {
1109
+ this.prewalkStatement(statement.body);
1110
+ }
1111
+
1112
+ walkWhileStatement(statement) {
1113
+ this.walkExpression(statement.test);
1114
+ this.walkStatement(statement.body);
1115
+ }
1116
+
1117
+ prewalkDoWhileStatement(statement) {
1118
+ this.prewalkStatement(statement.body);
1119
+ }
1120
+
1121
+ walkDoWhileStatement(statement) {
1122
+ this.walkStatement(statement.body);
1123
+ this.walkExpression(statement.test);
1124
+ }
1125
+
1126
+ prewalkForStatement(statement) {
1127
+ if (statement.init) {
1128
+ if (statement.init.type === "VariableDeclaration") {
1129
+ this.prewalkStatement(statement.init);
1130
+ }
1131
+ }
1132
+ this.prewalkStatement(statement.body);
1133
+ }
1134
+
1135
+ walkForStatement(statement) {
1136
+ this.inBlockScope(() => {
1137
+ if (statement.init) {
1138
+ if (statement.init.type === "VariableDeclaration") {
1139
+ this.blockPrewalkVariableDeclaration(statement.init);
1140
+ this.walkStatement(statement.init);
1141
+ } else {
1142
+ this.walkExpression(statement.init);
1143
+ }
1144
+ }
1145
+ if (statement.test) {
1146
+ this.walkExpression(statement.test);
1147
+ }
1148
+ if (statement.update) {
1149
+ this.walkExpression(statement.update);
1150
+ }
1151
+ const body = statement.body;
1152
+ if (body.type === "BlockStatement") {
1153
+ // no need to add additional scope
1154
+ this.blockPrewalkStatements(body.body);
1155
+ this.walkStatements(body.body);
1156
+ } else {
1157
+ this.walkStatement(body);
1158
+ }
1159
+ });
1160
+ }
1161
+
1162
+ prewalkForInStatement(statement) {
1163
+ if (statement.left.type === "VariableDeclaration") {
1164
+ this.prewalkVariableDeclaration(statement.left);
1165
+ }
1166
+ this.prewalkStatement(statement.body);
1167
+ }
1168
+
1169
+ walkForInStatement(statement) {
1170
+ this.inBlockScope(() => {
1171
+ if (statement.left.type === "VariableDeclaration") {
1172
+ this.blockPrewalkVariableDeclaration(statement.left);
1173
+ this.walkVariableDeclaration(statement.left);
1174
+ } else {
1175
+ this.walkPattern(statement.left);
1176
+ }
1177
+ this.walkExpression(statement.right);
1178
+ const body = statement.body;
1179
+ if (body.type === "BlockStatement") {
1180
+ // no need to add additional scope
1181
+ this.blockPrewalkStatements(body.body);
1182
+ this.walkStatements(body.body);
1183
+ } else {
1184
+ this.walkStatement(body);
1185
+ }
1186
+ });
1187
+ }
1188
+
1189
+ prewalkForOfStatement(statement) {
1190
+ if (statement.left.type === "VariableDeclaration") {
1191
+ this.prewalkVariableDeclaration(statement.left);
1192
+ }
1193
+ this.prewalkStatement(statement.body);
1194
+ }
1195
+
1196
+ walkForOfStatement(statement) {
1197
+ this.inBlockScope(() => {
1198
+ if (statement.left.type === "VariableDeclaration") {
1199
+ this.blockPrewalkVariableDeclaration(statement.left);
1200
+ this.walkVariableDeclaration(statement.left);
1201
+ } else {
1202
+ this.walkPattern(statement.left);
1203
+ }
1204
+ this.walkExpression(statement.right);
1205
+ const body = statement.body;
1206
+ if (body.type === "BlockStatement") {
1207
+ // no need to add additional scope
1208
+ this.blockPrewalkStatements(body.body);
1209
+ this.walkStatements(body.body);
1210
+ } else {
1211
+ this.walkStatement(body);
1212
+ }
1213
+ });
1214
+ }
1215
+
1216
+ // Declarations
1217
+ prewalkFunctionDeclaration(statement) {
1218
+ if (statement.id) {
1219
+ this.scope.renames.set(statement.id.name, null);
1220
+ this.scope.definitions.add(statement.id.name);
1221
+ }
1222
+ }
1223
+
1224
+ walkFunctionDeclaration(statement) {
1225
+ const wasTopLevel = this.scope.topLevelScope;
1226
+ this.scope.topLevelScope = false;
1227
+ this.inFunctionScope(true, statement.params, () => {
1228
+ for (const param of statement.params) {
1229
+ this.walkPattern(param);
1230
+ }
1231
+ if (statement.body.type === "BlockStatement") {
1232
+ this.detectMode(statement.body.body);
1233
+ this.prewalkStatement(statement.body);
1234
+ this.walkStatement(statement.body);
1235
+ } else {
1236
+ this.walkExpression(statement.body);
1237
+ }
1238
+ });
1239
+ this.scope.topLevelScope = wasTopLevel;
1240
+ }
1241
+
1242
+ prewalkImportDeclaration(statement) {
1243
+ const source = statement.source.value;
1244
+ this.hooks.import.call(statement, source);
1245
+ for (const specifier of statement.specifiers) {
1246
+ const name = specifier.local.name;
1247
+ this.scope.renames.set(name, null);
1248
+ this.scope.definitions.add(name);
1249
+ switch (specifier.type) {
1250
+ case "ImportDefaultSpecifier":
1251
+ this.hooks.importSpecifier.call(statement, source, "default", name);
1252
+ break;
1253
+ case "ImportSpecifier":
1254
+ this.hooks.importSpecifier.call(
1255
+ statement,
1256
+ source,
1257
+ specifier.imported.name,
1258
+ name
1259
+ );
1260
+ break;
1261
+ case "ImportNamespaceSpecifier":
1262
+ this.hooks.importSpecifier.call(statement, source, null, name);
1263
+ break;
1264
+ }
1265
+ }
1266
+ }
1267
+
1268
+ enterDeclaration(declaration, onIdent) {
1269
+ switch (declaration.type) {
1270
+ case "VariableDeclaration":
1271
+ for (const declarator of declaration.declarations) {
1272
+ switch (declarator.type) {
1273
+ case "VariableDeclarator": {
1274
+ this.enterPattern(declarator.id, onIdent);
1275
+ break;
1276
+ }
1277
+ }
1278
+ }
1279
+ break;
1280
+ case "FunctionDeclaration":
1281
+ this.enterPattern(declaration.id, onIdent);
1282
+ break;
1283
+ case "ClassDeclaration":
1284
+ this.enterPattern(declaration.id, onIdent);
1285
+ break;
1286
+ }
1287
+ }
1288
+
1289
+ blockPrewalkExportNamedDeclaration(statement) {
1290
+ if (statement.declaration) {
1291
+ this.blockPrewalkStatement(statement.declaration);
1292
+ }
1293
+ }
1294
+
1295
+ prewalkExportNamedDeclaration(statement) {
1296
+ let source;
1297
+ if (statement.source) {
1298
+ source = statement.source.value;
1299
+ this.hooks.exportImport.call(statement, source);
1300
+ } else {
1301
+ this.hooks.export.call(statement);
1302
+ }
1303
+ if (statement.declaration) {
1304
+ if (
1305
+ !this.hooks.exportDeclaration.call(statement, statement.declaration)
1306
+ ) {
1307
+ this.prewalkStatement(statement.declaration);
1308
+ let index = 0;
1309
+ this.enterDeclaration(statement.declaration, def => {
1310
+ this.hooks.exportSpecifier.call(statement, def, def, index++);
1311
+ });
1312
+ }
1313
+ }
1314
+ if (statement.specifiers) {
1315
+ for (
1316
+ let specifierIndex = 0;
1317
+ specifierIndex < statement.specifiers.length;
1318
+ specifierIndex++
1319
+ ) {
1320
+ const specifier = statement.specifiers[specifierIndex];
1321
+ switch (specifier.type) {
1322
+ case "ExportSpecifier": {
1323
+ const name = specifier.exported.name;
1324
+ if (source) {
1325
+ this.hooks.exportImportSpecifier.call(
1326
+ statement,
1327
+ source,
1328
+ specifier.local.name,
1329
+ name,
1330
+ specifierIndex
1331
+ );
1332
+ } else {
1333
+ this.hooks.exportSpecifier.call(
1334
+ statement,
1335
+ specifier.local.name,
1336
+ name,
1337
+ specifierIndex
1338
+ );
1339
+ }
1340
+ break;
1341
+ }
1342
+ }
1343
+ }
1344
+ }
1345
+ }
1346
+
1347
+ walkExportNamedDeclaration(statement) {
1348
+ if (statement.declaration) {
1349
+ this.walkStatement(statement.declaration);
1350
+ }
1351
+ }
1352
+
1353
+ blockPrewalkExportDefaultDeclaration(statement) {
1354
+ if (statement.declaration.type === "ClassDeclaration") {
1355
+ this.blockPrewalkClassDeclaration(statement.declaration);
1356
+ }
1357
+ }
1358
+
1359
+ prewalkExportDefaultDeclaration(statement) {
1360
+ this.prewalkStatement(statement.declaration);
1361
+ if (
1362
+ statement.declaration.id &&
1363
+ statement.declaration.type !== "FunctionExpression" &&
1364
+ statement.declaration.type !== "ClassExpression"
1365
+ ) {
1366
+ this.hooks.exportSpecifier.call(
1367
+ statement,
1368
+ statement.declaration.id.name,
1369
+ "default"
1370
+ );
1371
+ }
1372
+ }
1373
+
1374
+ walkExportDefaultDeclaration(statement) {
1375
+ this.hooks.export.call(statement);
1376
+ if (
1377
+ statement.declaration.id &&
1378
+ statement.declaration.type !== "FunctionExpression" &&
1379
+ statement.declaration.type !== "ClassExpression"
1380
+ ) {
1381
+ if (
1382
+ !this.hooks.exportDeclaration.call(statement, statement.declaration)
1383
+ ) {
1384
+ this.walkStatement(statement.declaration);
1385
+ }
1386
+ } else {
1387
+ // Acorn parses `export default function() {}` as `FunctionDeclaration` and
1388
+ // `export default class {}` as `ClassDeclaration`, both with `id = null`.
1389
+ // These nodes must be treated as expressions.
1390
+ if (statement.declaration.type === "FunctionDeclaration") {
1391
+ this.walkFunctionDeclaration(statement.declaration);
1392
+ } else if (statement.declaration.type === "ClassDeclaration") {
1393
+ this.walkClassDeclaration(statement.declaration);
1394
+ } else {
1395
+ this.walkExpression(statement.declaration);
1396
+ }
1397
+ if (!this.hooks.exportExpression.call(statement, statement.declaration)) {
1398
+ this.hooks.exportSpecifier.call(
1399
+ statement,
1400
+ statement.declaration,
1401
+ "default"
1402
+ );
1403
+ }
1404
+ }
1405
+ }
1406
+
1407
+ prewalkExportAllDeclaration(statement) {
1408
+ const source = statement.source.value;
1409
+ this.hooks.exportImport.call(statement, source);
1410
+ this.hooks.exportImportSpecifier.call(statement, source, null, null, 0);
1411
+ }
1412
+
1413
+ prewalkVariableDeclaration(statement) {
1414
+ if (statement.kind !== "var") return;
1415
+ this._prewalkVariableDeclaration(statement, this.hooks.varDeclarationVar);
1416
+ }
1417
+
1418
+ blockPrewalkVariableDeclaration(statement) {
1419
+ if (statement.kind === "var") return;
1420
+ const hookMap =
1421
+ statement.kind === "const"
1422
+ ? this.hooks.varDeclarationConst
1423
+ : this.hooks.varDeclarationLet;
1424
+ this._prewalkVariableDeclaration(statement, hookMap);
1425
+ }
1426
+
1427
+ _prewalkVariableDeclaration(statement, hookMap) {
1428
+ for (const declarator of statement.declarations) {
1429
+ switch (declarator.type) {
1430
+ case "VariableDeclarator": {
1431
+ this.enterPattern(declarator.id, (name, decl) => {
1432
+ let hook = hookMap.get(name);
1433
+ if (hook === undefined || !hook.call(decl)) {
1434
+ hook = this.hooks.varDeclaration.get(name);
1435
+ if (hook === undefined || !hook.call(decl)) {
1436
+ this.scope.renames.set(name, null);
1437
+ this.scope.definitions.add(name);
1438
+ }
1439
+ }
1440
+ });
1441
+ break;
1442
+ }
1443
+ }
1444
+ }
1445
+ }
1446
+
1447
+ walkVariableDeclaration(statement) {
1448
+ for (const declarator of statement.declarations) {
1449
+ switch (declarator.type) {
1450
+ case "VariableDeclarator": {
1451
+ const renameIdentifier =
1452
+ declarator.init && this.getRenameIdentifier(declarator.init);
1453
+ if (renameIdentifier && declarator.id.type === "Identifier") {
1454
+ const hook = this.hooks.canRename.get(renameIdentifier);
1455
+ if (hook !== undefined && hook.call(declarator.init)) {
1456
+ // renaming with "var a = b;"
1457
+ const hook = this.hooks.rename.get(renameIdentifier);
1458
+ if (hook === undefined || !hook.call(declarator.init)) {
1459
+ this.scope.renames.set(
1460
+ declarator.id.name,
1461
+ this.scope.renames.get(renameIdentifier) || renameIdentifier
1462
+ );
1463
+ this.scope.definitions.delete(declarator.id.name);
1464
+ }
1465
+ break;
1466
+ }
1467
+ }
1468
+ this.walkPattern(declarator.id);
1469
+ if (declarator.init) this.walkExpression(declarator.init);
1470
+ break;
1471
+ }
1472
+ }
1473
+ }
1474
+ }
1475
+
1476
+ blockPrewalkClassDeclaration(statement) {
1477
+ if (statement.id) {
1478
+ this.scope.renames.set(statement.id.name, null);
1479
+ this.scope.definitions.add(statement.id.name);
1480
+ }
1481
+ }
1482
+
1483
+ walkClassDeclaration(statement) {
1484
+ this.walkClass(statement);
1485
+ }
1486
+
1487
+ prewalkSwitchCases(switchCases) {
1488
+ for (let index = 0, len = switchCases.length; index < len; index++) {
1489
+ const switchCase = switchCases[index];
1490
+ this.prewalkStatements(switchCase.consequent);
1491
+ }
1492
+ }
1493
+
1494
+ walkSwitchCases(switchCases) {
1495
+ for (let index = 0, len = switchCases.length; index < len; index++) {
1496
+ const switchCase = switchCases[index];
1497
+
1498
+ if (switchCase.test) {
1499
+ this.walkExpression(switchCase.test);
1500
+ }
1501
+ this.walkStatements(switchCase.consequent);
1502
+ }
1503
+ }
1504
+
1505
+ walkCatchClause(catchClause) {
1506
+ this.inBlockScope(() => {
1507
+ // Error binding is optional in catch clause since ECMAScript 2019
1508
+ if (catchClause.param !== null) {
1509
+ this.enterPattern(catchClause.param, ident => {
1510
+ this.scope.renames.set(ident, null);
1511
+ this.scope.definitions.add(ident);
1512
+ });
1513
+ this.walkPattern(catchClause.param);
1514
+ }
1515
+ this.prewalkStatement(catchClause.body);
1516
+ this.walkStatement(catchClause.body);
1517
+ });
1518
+ }
1519
+
1520
+ walkPattern(pattern) {
1521
+ switch (pattern.type) {
1522
+ case "ArrayPattern":
1523
+ this.walkArrayPattern(pattern);
1524
+ break;
1525
+ case "AssignmentPattern":
1526
+ this.walkAssignmentPattern(pattern);
1527
+ break;
1528
+ case "MemberExpression":
1529
+ this.walkMemberExpression(pattern);
1530
+ break;
1531
+ case "ObjectPattern":
1532
+ this.walkObjectPattern(pattern);
1533
+ break;
1534
+ case "RestElement":
1535
+ this.walkRestElement(pattern);
1536
+ break;
1537
+ }
1538
+ }
1539
+
1540
+ walkAssignmentPattern(pattern) {
1541
+ this.walkExpression(pattern.right);
1542
+ this.walkPattern(pattern.left);
1543
+ }
1544
+
1545
+ walkObjectPattern(pattern) {
1546
+ for (let i = 0, len = pattern.properties.length; i < len; i++) {
1547
+ const prop = pattern.properties[i];
1548
+ if (prop) {
1549
+ if (prop.computed) this.walkExpression(prop.key);
1550
+ if (prop.value) this.walkPattern(prop.value);
1551
+ }
1552
+ }
1553
+ }
1554
+
1555
+ walkArrayPattern(pattern) {
1556
+ for (let i = 0, len = pattern.elements.length; i < len; i++) {
1557
+ const element = pattern.elements[i];
1558
+ if (element) this.walkPattern(element);
1559
+ }
1560
+ }
1561
+
1562
+ walkRestElement(pattern) {
1563
+ this.walkPattern(pattern.argument);
1564
+ }
1565
+
1566
+ walkExpressions(expressions) {
1567
+ for (const expression of expressions) {
1568
+ if (expression) {
1569
+ this.walkExpression(expression);
1570
+ }
1571
+ }
1572
+ }
1573
+
1574
+ walkExpression(expression) {
1575
+ switch (expression.type) {
1576
+ case "ArrayExpression":
1577
+ this.walkArrayExpression(expression);
1578
+ break;
1579
+ case "ArrowFunctionExpression":
1580
+ this.walkArrowFunctionExpression(expression);
1581
+ break;
1582
+ case "AssignmentExpression":
1583
+ this.walkAssignmentExpression(expression);
1584
+ break;
1585
+ case "AwaitExpression":
1586
+ this.walkAwaitExpression(expression);
1587
+ break;
1588
+ case "BinaryExpression":
1589
+ this.walkBinaryExpression(expression);
1590
+ break;
1591
+ case "CallExpression":
1592
+ this.walkCallExpression(expression);
1593
+ break;
1594
+ case "ClassExpression":
1595
+ this.walkClassExpression(expression);
1596
+ break;
1597
+ case "ConditionalExpression":
1598
+ this.walkConditionalExpression(expression);
1599
+ break;
1600
+ case "FunctionExpression":
1601
+ this.walkFunctionExpression(expression);
1602
+ break;
1603
+ case "Identifier":
1604
+ this.walkIdentifier(expression);
1605
+ break;
1606
+ case "LogicalExpression":
1607
+ this.walkLogicalExpression(expression);
1608
+ break;
1609
+ case "MemberExpression":
1610
+ this.walkMemberExpression(expression);
1611
+ break;
1612
+ case "NewExpression":
1613
+ this.walkNewExpression(expression);
1614
+ break;
1615
+ case "ObjectExpression":
1616
+ this.walkObjectExpression(expression);
1617
+ break;
1618
+ case "SequenceExpression":
1619
+ this.walkSequenceExpression(expression);
1620
+ break;
1621
+ case "SpreadElement":
1622
+ this.walkSpreadElement(expression);
1623
+ break;
1624
+ case "TaggedTemplateExpression":
1625
+ this.walkTaggedTemplateExpression(expression);
1626
+ break;
1627
+ case "TemplateLiteral":
1628
+ this.walkTemplateLiteral(expression);
1629
+ break;
1630
+ case "ThisExpression":
1631
+ this.walkThisExpression(expression);
1632
+ break;
1633
+ case "UnaryExpression":
1634
+ this.walkUnaryExpression(expression);
1635
+ break;
1636
+ case "UpdateExpression":
1637
+ this.walkUpdateExpression(expression);
1638
+ break;
1639
+ case "YieldExpression":
1640
+ this.walkYieldExpression(expression);
1641
+ break;
1642
+ }
1643
+ }
1644
+
1645
+ walkAwaitExpression(expression) {
1646
+ this.walkExpression(expression.argument);
1647
+ }
1648
+
1649
+ walkArrayExpression(expression) {
1650
+ if (expression.elements) {
1651
+ this.walkExpressions(expression.elements);
1652
+ }
1653
+ }
1654
+
1655
+ walkSpreadElement(expression) {
1656
+ if (expression.argument) {
1657
+ this.walkExpression(expression.argument);
1658
+ }
1659
+ }
1660
+
1661
+ walkObjectExpression(expression) {
1662
+ for (
1663
+ let propIndex = 0, len = expression.properties.length;
1664
+ propIndex < len;
1665
+ propIndex++
1666
+ ) {
1667
+ const prop = expression.properties[propIndex];
1668
+ if (prop.type === "SpreadElement") {
1669
+ this.walkExpression(prop.argument);
1670
+ continue;
1671
+ }
1672
+ if (prop.computed) {
1673
+ this.walkExpression(prop.key);
1674
+ }
1675
+ if (prop.shorthand) {
1676
+ this.scope.inShorthand = true;
1677
+ }
1678
+ this.walkExpression(prop.value);
1679
+ if (prop.shorthand) {
1680
+ this.scope.inShorthand = false;
1681
+ }
1682
+ }
1683
+ }
1684
+
1685
+ walkFunctionExpression(expression) {
1686
+ const wasTopLevel = this.scope.topLevelScope;
1687
+ this.scope.topLevelScope = false;
1688
+ const scopeParams = expression.params;
1689
+
1690
+ // Add function name in scope for recursive calls
1691
+ if (expression.id) {
1692
+ scopeParams.push(expression.id.name);
1693
+ }
1694
+
1695
+ this.inFunctionScope(true, scopeParams, () => {
1696
+ for (const param of expression.params) {
1697
+ this.walkPattern(param);
1698
+ }
1699
+ if (expression.body.type === "BlockStatement") {
1700
+ this.detectMode(expression.body.body);
1701
+ this.prewalkStatement(expression.body);
1702
+ this.walkStatement(expression.body);
1703
+ } else {
1704
+ this.walkExpression(expression.body);
1705
+ }
1706
+ });
1707
+ this.scope.topLevelScope = wasTopLevel;
1708
+ }
1709
+
1710
+ walkArrowFunctionExpression(expression) {
1711
+ this.inFunctionScope(false, expression.params, () => {
1712
+ for (const param of expression.params) {
1713
+ this.walkPattern(param);
1714
+ }
1715
+ if (expression.body.type === "BlockStatement") {
1716
+ this.detectMode(expression.body.body);
1717
+ this.prewalkStatement(expression.body);
1718
+ this.walkStatement(expression.body);
1719
+ } else {
1720
+ this.walkExpression(expression.body);
1721
+ }
1722
+ });
1723
+ }
1724
+
1725
+ walkSequenceExpression(expression) {
1726
+ if (expression.expressions) this.walkExpressions(expression.expressions);
1727
+ }
1728
+
1729
+ walkUpdateExpression(expression) {
1730
+ this.walkExpression(expression.argument);
1731
+ }
1732
+
1733
+ walkUnaryExpression(expression) {
1734
+ if (expression.operator === "typeof") {
1735
+ const exprName = this.getNameForExpression(expression.argument);
1736
+ if (exprName && exprName.free) {
1737
+ const hook = this.hooks.typeof.get(exprName.name);
1738
+ if (hook !== undefined) {
1739
+ const result = hook.call(expression);
1740
+ if (result === true) return;
1741
+ }
1742
+ }
1743
+ }
1744
+ this.walkExpression(expression.argument);
1745
+ }
1746
+
1747
+ walkLeftRightExpression(expression) {
1748
+ this.walkExpression(expression.left);
1749
+ this.walkExpression(expression.right);
1750
+ }
1751
+
1752
+ walkBinaryExpression(expression) {
1753
+ this.walkLeftRightExpression(expression);
1754
+ }
1755
+
1756
+ walkLogicalExpression(expression) {
1757
+ const result = this.hooks.expressionLogicalOperator.call(expression);
1758
+ if (result === undefined) {
1759
+ this.walkLeftRightExpression(expression);
1760
+ } else {
1761
+ if (result) {
1762
+ this.walkExpression(expression.right);
1763
+ }
1764
+ }
1765
+ }
1766
+
1767
+ walkAssignmentExpression(expression) {
1768
+ const renameIdentifier = this.getRenameIdentifier(expression.right);
1769
+ if (expression.left.type === "Identifier" && renameIdentifier) {
1770
+ const hook = this.hooks.canRename.get(renameIdentifier);
1771
+ if (hook !== undefined && hook.call(expression.right)) {
1772
+ // renaming "a = b;"
1773
+ const hook = this.hooks.rename.get(renameIdentifier);
1774
+ if (hook === undefined || !hook.call(expression.right)) {
1775
+ this.scope.renames.set(expression.left.name, renameIdentifier);
1776
+ this.scope.definitions.delete(expression.left.name);
1777
+ }
1778
+ return;
1779
+ }
1780
+ }
1781
+ if (expression.left.type === "Identifier") {
1782
+ const assignedHook = this.hooks.assigned.get(expression.left.name);
1783
+ if (assignedHook === undefined || !assignedHook.call(expression)) {
1784
+ this.walkExpression(expression.right);
1785
+ }
1786
+ this.scope.renames.set(expression.left.name, null);
1787
+ const assignHook = this.hooks.assign.get(expression.left.name);
1788
+ if (assignHook === undefined || !assignHook.call(expression)) {
1789
+ this.walkExpression(expression.left);
1790
+ }
1791
+ return;
1792
+ }
1793
+ this.walkExpression(expression.right);
1794
+ this.walkPattern(expression.left);
1795
+ this.enterPattern(expression.left, (name, decl) => {
1796
+ this.scope.renames.set(name, null);
1797
+ });
1798
+ }
1799
+
1800
+ walkConditionalExpression(expression) {
1801
+ const result = this.hooks.expressionConditionalOperator.call(expression);
1802
+ if (result === undefined) {
1803
+ this.walkExpression(expression.test);
1804
+ this.walkExpression(expression.consequent);
1805
+ if (expression.alternate) {
1806
+ this.walkExpression(expression.alternate);
1807
+ }
1808
+ } else {
1809
+ if (result) {
1810
+ this.walkExpression(expression.consequent);
1811
+ } else if (expression.alternate) {
1812
+ this.walkExpression(expression.alternate);
1813
+ }
1814
+ }
1815
+ }
1816
+
1817
+ walkNewExpression(expression) {
1818
+ const callee = this.evaluateExpression(expression.callee);
1819
+ if (callee.isIdentifier()) {
1820
+ const hook = this.hooks.new.get(callee.identifier);
1821
+ if (hook !== undefined) {
1822
+ const result = hook.call(expression);
1823
+ if (result === true) {
1824
+ return;
1825
+ }
1826
+ }
1827
+ }
1828
+
1829
+ this.walkExpression(expression.callee);
1830
+ if (expression.arguments) {
1831
+ this.walkExpressions(expression.arguments);
1832
+ }
1833
+ }
1834
+
1835
+ walkYieldExpression(expression) {
1836
+ if (expression.argument) {
1837
+ this.walkExpression(expression.argument);
1838
+ }
1839
+ }
1840
+
1841
+ walkTemplateLiteral(expression) {
1842
+ if (expression.expressions) {
1843
+ this.walkExpressions(expression.expressions);
1844
+ }
1845
+ }
1846
+
1847
+ walkTaggedTemplateExpression(expression) {
1848
+ if (expression.tag) {
1849
+ this.walkExpression(expression.tag);
1850
+ }
1851
+ if (expression.quasi && expression.quasi.expressions) {
1852
+ this.walkExpressions(expression.quasi.expressions);
1853
+ }
1854
+ }
1855
+
1856
+ walkClassExpression(expression) {
1857
+ this.walkClass(expression);
1858
+ }
1859
+
1860
+ _walkIIFE(functionExpression, options, currentThis) {
1861
+ const renameArgOrThis = argOrThis => {
1862
+ const renameIdentifier = this.getRenameIdentifier(argOrThis);
1863
+ if (renameIdentifier) {
1864
+ const hook = this.hooks.canRename.get(renameIdentifier);
1865
+ if (hook !== undefined && hook.call(argOrThis)) {
1866
+ const hook = this.hooks.rename.get(renameIdentifier);
1867
+ if (hook === undefined || !hook.call(argOrThis)) {
1868
+ return renameIdentifier;
1869
+ }
1870
+ }
1871
+ }
1872
+ this.walkExpression(argOrThis);
1873
+ };
1874
+ const params = functionExpression.params;
1875
+ const renameThis = currentThis ? renameArgOrThis(currentThis) : null;
1876
+ const args = options.map(renameArgOrThis);
1877
+ const wasTopLevel = this.scope.topLevelScope;
1878
+ this.scope.topLevelScope = false;
1879
+ const scopeParams = params.filter((identifier, idx) => !args[idx]);
1880
+
1881
+ // Add function name in scope for recursive calls
1882
+ if (functionExpression.id) {
1883
+ scopeParams.push(functionExpression.id.name);
1884
+ }
1885
+
1886
+ this.inFunctionScope(true, scopeParams, () => {
1887
+ if (renameThis) {
1888
+ this.scope.renames.set("this", renameThis);
1889
+ }
1890
+ for (let i = 0; i < args.length; i++) {
1891
+ const param = args[i];
1892
+ if (!param) continue;
1893
+ if (!params[i] || params[i].type !== "Identifier") continue;
1894
+ this.scope.renames.set(params[i].name, param);
1895
+ }
1896
+ if (functionExpression.body.type === "BlockStatement") {
1897
+ this.detectMode(functionExpression.body.body);
1898
+ this.prewalkStatement(functionExpression.body);
1899
+ this.walkStatement(functionExpression.body);
1900
+ } else {
1901
+ this.walkExpression(functionExpression.body);
1902
+ }
1903
+ });
1904
+ this.scope.topLevelScope = wasTopLevel;
1905
+ }
1906
+
1907
+ walkCallExpression(expression) {
1908
+ if (
1909
+ expression.callee.type === "MemberExpression" &&
1910
+ expression.callee.object.type === "FunctionExpression" &&
1911
+ !expression.callee.computed &&
1912
+ (expression.callee.property.name === "call" ||
1913
+ expression.callee.property.name === "bind") &&
1914
+ expression.arguments.length > 0
1915
+ ) {
1916
+ // (function(…) { }.call/bind(?, …))
1917
+ this._walkIIFE(
1918
+ expression.callee.object,
1919
+ expression.arguments.slice(1),
1920
+ expression.arguments[0]
1921
+ );
1922
+ } else if (expression.callee.type === "FunctionExpression") {
1923
+ // (function(…) { }(…))
1924
+ this._walkIIFE(expression.callee, expression.arguments, null);
1925
+ } else if (expression.callee.type === "Import") {
1926
+ let result = this.hooks.importCall.call(expression);
1927
+ if (result === true) return;
1928
+
1929
+ if (expression.arguments) this.walkExpressions(expression.arguments);
1930
+ } else {
1931
+ const callee = this.evaluateExpression(expression.callee);
1932
+ if (callee.isIdentifier()) {
1933
+ const callHook = this.hooks.call.get(callee.identifier);
1934
+ if (callHook !== undefined) {
1935
+ let result = callHook.call(expression);
1936
+ if (result === true) return;
1937
+ }
1938
+ let identifier = callee.identifier.replace(/\.[^.]+$/, "");
1939
+ if (identifier !== callee.identifier) {
1940
+ const callAnyHook = this.hooks.callAnyMember.get(identifier);
1941
+ if (callAnyHook !== undefined) {
1942
+ let result = callAnyHook.call(expression);
1943
+ if (result === true) return;
1944
+ }
1945
+ }
1946
+ }
1947
+
1948
+ if (expression.callee) this.walkExpression(expression.callee);
1949
+ if (expression.arguments) this.walkExpressions(expression.arguments);
1950
+ }
1951
+ }
1952
+
1953
+ walkMemberExpression(expression) {
1954
+ const exprName = this.getNameForExpression(expression);
1955
+ if (exprName && exprName.free) {
1956
+ const expressionHook = this.hooks.expression.get(exprName.name);
1957
+ if (expressionHook !== undefined) {
1958
+ const result = expressionHook.call(expression);
1959
+ if (result === true) return;
1960
+ }
1961
+ const expressionAnyMemberHook = this.hooks.expressionAnyMember.get(
1962
+ exprName.nameGeneral
1963
+ );
1964
+ if (expressionAnyMemberHook !== undefined) {
1965
+ const result = expressionAnyMemberHook.call(expression);
1966
+ if (result === true) return;
1967
+ }
1968
+ }
1969
+ this.walkExpression(expression.object);
1970
+ if (expression.computed === true) this.walkExpression(expression.property);
1971
+ }
1972
+
1973
+ walkThisExpression(expression) {
1974
+ const expressionHook = this.hooks.expression.get("this");
1975
+ if (expressionHook !== undefined) {
1976
+ expressionHook.call(expression);
1977
+ }
1978
+ }
1979
+
1980
+ walkIdentifier(expression) {
1981
+ if (!this.scope.definitions.has(expression.name)) {
1982
+ const hook = this.hooks.expression.get(
1983
+ this.scope.renames.get(expression.name) || expression.name
1984
+ );
1985
+ if (hook !== undefined) {
1986
+ const result = hook.call(expression);
1987
+ if (result === true) return;
1988
+ }
1989
+ }
1990
+ }
1991
+
1992
+ /**
1993
+ * @deprecated
1994
+ * @param {any} params scope params
1995
+ * @param {function(): void} fn inner function
1996
+ * @returns {void}
1997
+ */
1998
+ inScope(params, fn) {
1999
+ const oldScope = this.scope;
2000
+ this.scope = {
2001
+ topLevelScope: oldScope.topLevelScope,
2002
+ inTry: false,
2003
+ inShorthand: false,
2004
+ isStrict: oldScope.isStrict,
2005
+ isAsmJs: oldScope.isAsmJs,
2006
+ definitions: oldScope.definitions.createChild(),
2007
+ renames: oldScope.renames.createChild()
2008
+ };
2009
+
2010
+ this.scope.renames.set("this", null);
2011
+
2012
+ this.enterPatterns(params, ident => {
2013
+ this.scope.renames.set(ident, null);
2014
+ this.scope.definitions.add(ident);
2015
+ });
2016
+
2017
+ fn();
2018
+
2019
+ this.scope = oldScope;
2020
+ }
2021
+
2022
+ inFunctionScope(hasThis, params, fn) {
2023
+ const oldScope = this.scope;
2024
+ this.scope = {
2025
+ topLevelScope: oldScope.topLevelScope,
2026
+ inTry: false,
2027
+ inShorthand: false,
2028
+ isStrict: oldScope.isStrict,
2029
+ isAsmJs: oldScope.isAsmJs,
2030
+ definitions: oldScope.definitions.createChild(),
2031
+ renames: oldScope.renames.createChild()
2032
+ };
2033
+
2034
+ if (hasThis) {
2035
+ this.scope.renames.set("this", null);
2036
+ }
2037
+
2038
+ this.enterPatterns(params, ident => {
2039
+ this.scope.renames.set(ident, null);
2040
+ this.scope.definitions.add(ident);
2041
+ });
2042
+
2043
+ fn();
2044
+
2045
+ this.scope = oldScope;
2046
+ }
2047
+
2048
+ inBlockScope(fn) {
2049
+ const oldScope = this.scope;
2050
+ this.scope = {
2051
+ topLevelScope: oldScope.topLevelScope,
2052
+ inTry: oldScope.inTry,
2053
+ inShorthand: false,
2054
+ isStrict: oldScope.isStrict,
2055
+ isAsmJs: oldScope.isAsmJs,
2056
+ definitions: oldScope.definitions.createChild(),
2057
+ renames: oldScope.renames.createChild()
2058
+ };
2059
+
2060
+ fn();
2061
+
2062
+ this.scope = oldScope;
2063
+ }
2064
+
2065
+ // TODO webpack 5: remove this methods
2066
+ // only for backward-compat
2067
+ detectStrictMode(statements) {
2068
+ this.detectMode(statements);
2069
+ }
2070
+
2071
+ detectMode(statements) {
2072
+ const isLiteral =
2073
+ statements.length >= 1 &&
2074
+ statements[0].type === "ExpressionStatement" &&
2075
+ statements[0].expression.type === "Literal";
2076
+ if (isLiteral && statements[0].expression.value === "use strict") {
2077
+ this.scope.isStrict = true;
2078
+ }
2079
+ if (isLiteral && statements[0].expression.value === "use asm") {
2080
+ this.scope.isAsmJs = true;
2081
+ }
2082
+ }
2083
+
2084
+ enterPatterns(patterns, onIdent) {
2085
+ for (const pattern of patterns) {
2086
+ if (typeof pattern !== "string") {
2087
+ this.enterPattern(pattern, onIdent);
2088
+ } else if (pattern) {
2089
+ onIdent(pattern);
2090
+ }
2091
+ }
2092
+ }
2093
+
2094
+ enterPattern(pattern, onIdent) {
2095
+ if (!pattern) return;
2096
+ switch (pattern.type) {
2097
+ case "ArrayPattern":
2098
+ this.enterArrayPattern(pattern, onIdent);
2099
+ break;
2100
+ case "AssignmentPattern":
2101
+ this.enterAssignmentPattern(pattern, onIdent);
2102
+ break;
2103
+ case "Identifier":
2104
+ this.enterIdentifier(pattern, onIdent);
2105
+ break;
2106
+ case "ObjectPattern":
2107
+ this.enterObjectPattern(pattern, onIdent);
2108
+ break;
2109
+ case "RestElement":
2110
+ this.enterRestElement(pattern, onIdent);
2111
+ break;
2112
+ case "Property":
2113
+ this.enterPattern(pattern.value, onIdent);
2114
+ break;
2115
+ }
2116
+ }
2117
+
2118
+ enterIdentifier(pattern, onIdent) {
2119
+ onIdent(pattern.name, pattern);
2120
+ }
2121
+
2122
+ enterObjectPattern(pattern, onIdent) {
2123
+ for (
2124
+ let propIndex = 0, len = pattern.properties.length;
2125
+ propIndex < len;
2126
+ propIndex++
2127
+ ) {
2128
+ const prop = pattern.properties[propIndex];
2129
+ this.enterPattern(prop, onIdent);
2130
+ }
2131
+ }
2132
+
2133
+ enterArrayPattern(pattern, onIdent) {
2134
+ for (
2135
+ let elementIndex = 0, len = pattern.elements.length;
2136
+ elementIndex < len;
2137
+ elementIndex++
2138
+ ) {
2139
+ const element = pattern.elements[elementIndex];
2140
+ this.enterPattern(element, onIdent);
2141
+ }
2142
+ }
2143
+
2144
+ enterRestElement(pattern, onIdent) {
2145
+ this.enterPattern(pattern.argument, onIdent);
2146
+ }
2147
+
2148
+ enterAssignmentPattern(pattern, onIdent) {
2149
+ this.enterPattern(pattern.left, onIdent);
2150
+ }
2151
+
2152
+ evaluateExpression(expression) {
2153
+ try {
2154
+ const hook = this.hooks.evaluate.get(expression.type);
2155
+ if (hook !== undefined) {
2156
+ const result = hook.call(expression);
2157
+ if (result !== undefined) {
2158
+ if (result) {
2159
+ result.setExpression(expression);
2160
+ }
2161
+ return result;
2162
+ }
2163
+ }
2164
+ } catch (e) {
2165
+ console.warn(e);
2166
+ // ignore error
2167
+ }
2168
+ return new BasicEvaluatedExpression()
2169
+ .setRange(expression.range)
2170
+ .setExpression(expression);
2171
+ }
2172
+
2173
+ parseString(expression) {
2174
+ switch (expression.type) {
2175
+ case "BinaryExpression":
2176
+ if (expression.operator === "+") {
2177
+ return (
2178
+ this.parseString(expression.left) +
2179
+ this.parseString(expression.right)
2180
+ );
2181
+ }
2182
+ break;
2183
+ case "Literal":
2184
+ return expression.value + "";
2185
+ }
2186
+ throw new Error(
2187
+ expression.type + " is not supported as parameter for require"
2188
+ );
2189
+ }
2190
+
2191
+ parseCalculatedString(expression) {
2192
+ switch (expression.type) {
2193
+ case "BinaryExpression":
2194
+ if (expression.operator === "+") {
2195
+ const left = this.parseCalculatedString(expression.left);
2196
+ const right = this.parseCalculatedString(expression.right);
2197
+ if (left.code) {
2198
+ return {
2199
+ range: left.range,
2200
+ value: left.value,
2201
+ code: true,
2202
+ conditional: false
2203
+ };
2204
+ } else if (right.code) {
2205
+ return {
2206
+ range: [
2207
+ left.range[0],
2208
+ right.range ? right.range[1] : left.range[1]
2209
+ ],
2210
+ value: left.value + right.value,
2211
+ code: true,
2212
+ conditional: false
2213
+ };
2214
+ } else {
2215
+ return {
2216
+ range: [left.range[0], right.range[1]],
2217
+ value: left.value + right.value,
2218
+ code: false,
2219
+ conditional: false
2220
+ };
2221
+ }
2222
+ }
2223
+ break;
2224
+ case "ConditionalExpression": {
2225
+ const consequent = this.parseCalculatedString(expression.consequent);
2226
+ const alternate = this.parseCalculatedString(expression.alternate);
2227
+ const items = [];
2228
+ if (consequent.conditional) {
2229
+ items.push(...consequent.conditional);
2230
+ } else if (!consequent.code) {
2231
+ items.push(consequent);
2232
+ } else {
2233
+ break;
2234
+ }
2235
+ if (alternate.conditional) {
2236
+ items.push(...alternate.conditional);
2237
+ } else if (!alternate.code) {
2238
+ items.push(alternate);
2239
+ } else {
2240
+ break;
2241
+ }
2242
+ return {
2243
+ range: undefined,
2244
+ value: "",
2245
+ code: true,
2246
+ conditional: items
2247
+ };
2248
+ }
2249
+ case "Literal":
2250
+ return {
2251
+ range: expression.range,
2252
+ value: expression.value + "",
2253
+ code: false,
2254
+ conditional: false
2255
+ };
2256
+ }
2257
+ return {
2258
+ range: undefined,
2259
+ value: "",
2260
+ code: true,
2261
+ conditional: false
2262
+ };
2263
+ }
2264
+
2265
+ parse(source, initialState) {
2266
+ let ast;
2267
+ let comments;
2268
+ if (typeof source === "object" && source !== null) {
2269
+ ast = source;
2270
+ comments = source.comments;
2271
+ } else {
2272
+ comments = [];
2273
+ ast = Parser.parse(source, {
2274
+ sourceType: this.sourceType,
2275
+ onComment: comments
2276
+ });
2277
+ }
2278
+
2279
+ const oldScope = this.scope;
2280
+ const oldState = this.state;
2281
+ const oldComments = this.comments;
2282
+ this.scope = {
2283
+ topLevelScope: true,
2284
+ inTry: false,
2285
+ inShorthand: false,
2286
+ isStrict: false,
2287
+ isAsmJs: false,
2288
+ definitions: new StackedSetMap(),
2289
+ renames: new StackedSetMap()
2290
+ };
2291
+ const state = (this.state = initialState || {});
2292
+ this.comments = comments;
2293
+ if (this.hooks.program.call(ast, comments) === undefined) {
2294
+ this.detectMode(ast.body);
2295
+ this.prewalkStatements(ast.body);
2296
+ this.blockPrewalkStatements(ast.body);
2297
+ this.walkStatements(ast.body);
2298
+ }
2299
+ this.scope = oldScope;
2300
+ this.state = oldState;
2301
+ this.comments = oldComments;
2302
+ return state;
2303
+ }
2304
+
2305
+ evaluate(source) {
2306
+ const ast = Parser.parse("(" + source + ")", {
2307
+ sourceType: this.sourceType,
2308
+ locations: false
2309
+ });
2310
+ // TODO(https://github.com/acornjs/acorn/issues/741)
2311
+ // @ts-ignore
2312
+ if (ast.body.length !== 1 || ast.body[0].type !== "ExpressionStatement") {
2313
+ throw new Error("evaluate: Source is not a expression");
2314
+ }
2315
+ // TODO(https://github.com/acornjs/acorn/issues/741)
2316
+ // @ts-ignore
2317
+ return this.evaluateExpression(ast.body[0].expression);
2318
+ }
2319
+
2320
+ getComments(range) {
2321
+ return this.comments.filter(
2322
+ comment => comment.range[0] >= range[0] && comment.range[1] <= range[1]
2323
+ );
2324
+ }
2325
+
2326
+ parseCommentOptions(range) {
2327
+ const comments = this.getComments(range);
2328
+ if (comments.length === 0) {
2329
+ return EMPTY_COMMENT_OPTIONS;
2330
+ }
2331
+ let options = {};
2332
+ let errors = [];
2333
+ for (const comment of comments) {
2334
+ const { value } = comment;
2335
+ if (value && webpackCommentRegExp.test(value)) {
2336
+ // try compile only if webpack options comment is present
2337
+ try {
2338
+ const val = vm.runInNewContext(`(function(){return {${value}};})()`);
2339
+ Object.assign(options, val);
2340
+ } catch (e) {
2341
+ e.comment = comment;
2342
+ errors.push(e);
2343
+ }
2344
+ }
2345
+ }
2346
+ return { options, errors };
2347
+ }
2348
+
2349
+ getNameForExpression(expression) {
2350
+ let expr = expression;
2351
+ const exprName = [];
2352
+ while (
2353
+ expr.type === "MemberExpression" &&
2354
+ expr.property.type === (expr.computed ? "Literal" : "Identifier")
2355
+ ) {
2356
+ exprName.push(expr.computed ? expr.property.value : expr.property.name);
2357
+ expr = expr.object;
2358
+ }
2359
+ let free;
2360
+ if (expr.type === "Identifier") {
2361
+ free = !this.scope.definitions.has(expr.name);
2362
+ exprName.push(this.scope.renames.get(expr.name) || expr.name);
2363
+ } else if (
2364
+ expr.type === "ThisExpression" &&
2365
+ this.scope.renames.get("this")
2366
+ ) {
2367
+ free = true;
2368
+ exprName.push(this.scope.renames.get("this"));
2369
+ } else if (expr.type === "ThisExpression") {
2370
+ free = this.scope.topLevelScope;
2371
+ exprName.push("this");
2372
+ } else {
2373
+ return null;
2374
+ }
2375
+ let prefix = "";
2376
+ for (let i = exprName.length - 1; i >= 2; i--) {
2377
+ prefix += exprName[i] + ".";
2378
+ }
2379
+ if (exprName.length > 1) {
2380
+ prefix += exprName[1];
2381
+ }
2382
+ const name = prefix ? prefix + "." + exprName[0] : exprName[0];
2383
+ const nameGeneral = prefix;
2384
+ return {
2385
+ name,
2386
+ nameGeneral,
2387
+ free
2388
+ };
2389
+ }
2390
+
2391
+ static parse(code, options) {
2392
+ const type = options ? options.sourceType : "module";
2393
+ const parserOptions = Object.assign(
2394
+ Object.create(null),
2395
+ defaultParserOptions,
2396
+ options
2397
+ );
2398
+
2399
+ if (type === "auto") {
2400
+ parserOptions.sourceType = "module";
2401
+ } else if (parserOptions.sourceType === "script") {
2402
+ parserOptions.allowReturnOutsideFunction = true;
2403
+ }
2404
+
2405
+ let ast;
2406
+ let error;
2407
+ let threw = false;
2408
+ try {
2409
+ ast = acornParser.parse(code, parserOptions);
2410
+ } catch (e) {
2411
+ error = e;
2412
+ threw = true;
2413
+ }
2414
+
2415
+ if (threw && type === "auto") {
2416
+ parserOptions.sourceType = "script";
2417
+ parserOptions.allowReturnOutsideFunction = true;
2418
+ if (Array.isArray(parserOptions.onComment)) {
2419
+ parserOptions.onComment.length = 0;
2420
+ }
2421
+ try {
2422
+ ast = acornParser.parse(code, parserOptions);
2423
+ threw = false;
2424
+ } catch (e) {
2425
+ threw = true;
2426
+ }
2427
+ }
2428
+
2429
+ if (threw) {
2430
+ throw error;
2431
+ }
2432
+
2433
+ return ast;
2434
+ }
2435
+ }
2436
+
2437
+ // TODO remove in webpack 5
2438
+ Object.defineProperty(Parser.prototype, "getCommentOptions", {
2439
+ configurable: false,
2440
+ value: util.deprecate(
2441
+ /**
2442
+ * @deprecated
2443
+ * @param {TODO} range Range
2444
+ * @returns {void}
2445
+ * @this {Parser}
2446
+ */
2447
+ function(range) {
2448
+ return this.parseCommentOptions(range).options;
2449
+ },
2450
+ "Parser.getCommentOptions: Use Parser.parseCommentOptions(range) instead"
2451
+ )
2452
+ });
2453
+
2454
+ module.exports = Parser;