@wyw-in-js/transform 2.0.0-alpha.0 → 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. package/esm/cache.js +7 -0
  2. package/esm/cache.js.map +1 -1
  3. package/esm/debug/fileReporter.js +35 -1
  4. package/esm/debug/fileReporter.js.map +1 -1
  5. package/esm/eval/broker.js +230 -89
  6. package/esm/eval/broker.js.map +1 -1
  7. package/esm/eval/protocol.js.map +1 -1
  8. package/esm/eval/runner.js +143 -24
  9. package/esm/eval/runner.js.map +1 -1
  10. package/esm/module.js +70 -43
  11. package/esm/module.js.map +1 -1
  12. package/esm/transform/Entrypoint.types.js.map +1 -1
  13. package/esm/transform/generators/processEntrypoint.js +35 -20
  14. package/esm/transform/generators/processEntrypoint.js.map +1 -1
  15. package/esm/transform/generators/resolveImports.js +48 -2
  16. package/esm/transform/generators/resolveImports.js.map +1 -1
  17. package/esm/transform/generators/resolveStaticOxcValues/cache.js +182 -0
  18. package/esm/transform/generators/resolveStaticOxcValues/cache.js.map +1 -0
  19. package/esm/transform/generators/resolveStaticOxcValues/candidateResolver.js +146 -0
  20. package/esm/transform/generators/resolveStaticOxcValues/candidateResolver.js.map +1 -0
  21. package/esm/transform/generators/resolveStaticOxcValues/dependencies.js +33 -0
  22. package/esm/transform/generators/resolveStaticOxcValues/dependencies.js.map +1 -0
  23. package/esm/transform/generators/resolveStaticOxcValues/environment.js +29 -0
  24. package/esm/transform/generators/resolveStaticOxcValues/environment.js.map +1 -0
  25. package/esm/transform/generators/resolveStaticOxcValues/exportResolver.js +351 -0
  26. package/esm/transform/generators/resolveStaticOxcValues/exportResolver.js.map +1 -0
  27. package/esm/transform/generators/resolveStaticOxcValues/exportTargets.js +253 -0
  28. package/esm/transform/generators/resolveStaticOxcValues/exportTargets.js.map +1 -0
  29. package/esm/transform/generators/resolveStaticOxcValues/objectAssign.js +310 -0
  30. package/esm/transform/generators/resolveStaticOxcValues/objectAssign.js.map +1 -0
  31. package/esm/transform/generators/resolveStaticOxcValues/objectAssignStaticExport.js +74 -0
  32. package/esm/transform/generators/resolveStaticOxcValues/objectAssignStaticExport.js.map +1 -0
  33. package/esm/transform/generators/resolveStaticOxcValues/opaqueRuntime.js +229 -0
  34. package/esm/transform/generators/resolveStaticOxcValues/opaqueRuntime.js.map +1 -0
  35. package/esm/transform/generators/resolveStaticOxcValues/processorStaticExport.js +172 -0
  36. package/esm/transform/generators/resolveStaticOxcValues/processorStaticExport.js.map +1 -0
  37. package/esm/transform/generators/resolveStaticOxcValues/processorStaticModel.js +476 -0
  38. package/esm/transform/generators/resolveStaticOxcValues/processorStaticModel.js.map +1 -0
  39. package/esm/transform/generators/resolveStaticOxcValues/processorTarget.js +55 -0
  40. package/esm/transform/generators/resolveStaticOxcValues/processorTarget.js.map +1 -0
  41. package/esm/transform/generators/resolveStaticOxcValues/programAnalysis.js +123 -0
  42. package/esm/transform/generators/resolveStaticOxcValues/programAnalysis.js.map +1 -0
  43. package/esm/transform/generators/resolveStaticOxcValues/prune.js +186 -0
  44. package/esm/transform/generators/resolveStaticOxcValues/prune.js.map +1 -0
  45. package/esm/transform/generators/resolveStaticOxcValues/resolveStaticOxcPreevalValues.js +183 -0
  46. package/esm/transform/generators/resolveStaticOxcValues/resolveStaticOxcPreevalValues.js.map +1 -0
  47. package/esm/transform/generators/resolveStaticOxcValues/staticExpression.js +298 -0
  48. package/esm/transform/generators/resolveStaticOxcValues/staticExpression.js.map +1 -0
  49. package/esm/transform/generators/resolveStaticOxcValues/staticExpressionDependencies.js +298 -0
  50. package/esm/transform/generators/resolveStaticOxcValues/staticExpressionDependencies.js.map +1 -0
  51. package/esm/transform/generators/resolveStaticOxcValues/types.js +3 -0
  52. package/esm/transform/generators/resolveStaticOxcValues/types.js.map +1 -0
  53. package/esm/transform/generators/resolveStaticOxcValues/zeroArgFunctionStaticExport.js +59 -0
  54. package/esm/transform/generators/resolveStaticOxcValues/zeroArgFunctionStaticExport.js.map +1 -0
  55. package/esm/transform/generators/resolveStaticOxcValues.js +1 -2910
  56. package/esm/transform/generators/resolveStaticOxcValues.js.map +1 -1
  57. package/esm/transform/generators/transform.js +57 -45
  58. package/esm/transform/generators/transform.js.map +1 -1
  59. package/esm/transform/helpers/loadWywOptions.js +33 -4
  60. package/esm/transform/helpers/loadWywOptions.js.map +1 -1
  61. package/esm/transform.js +3 -1
  62. package/esm/transform.js.map +1 -1
  63. package/esm/utils/EventEmitter.js +42 -9
  64. package/esm/utils/EventEmitter.js.map +1 -1
  65. package/esm/utils/applyOxcProcessors/applyOxcProcessors.js +160 -0
  66. package/esm/utils/applyOxcProcessors/applyOxcProcessors.js.map +1 -0
  67. package/esm/utils/applyOxcProcessors/cleanupBindings.js +157 -0
  68. package/esm/utils/applyOxcProcessors/cleanupBindings.js.map +1 -0
  69. package/esm/utils/applyOxcProcessors/cleanupRemovals.js +431 -0
  70. package/esm/utils/applyOxcProcessors/cleanupRemovals.js.map +1 -0
  71. package/esm/utils/applyOxcProcessors/displayName.js +93 -0
  72. package/esm/utils/applyOxcProcessors/displayName.js.map +1 -0
  73. package/esm/utils/applyOxcProcessors/expressionValues.js +152 -0
  74. package/esm/utils/applyOxcProcessors/expressionValues.js.map +1 -0
  75. package/esm/utils/applyOxcProcessors/processorFactory.js +62 -0
  76. package/esm/utils/applyOxcProcessors/processorFactory.js.map +1 -0
  77. package/esm/utils/applyOxcProcessors/processorUsages.js +143 -0
  78. package/esm/utils/applyOxcProcessors/processorUsages.js.map +1 -0
  79. package/esm/utils/applyOxcProcessors/sameFileStaticValues.js +207 -0
  80. package/esm/utils/applyOxcProcessors/sameFileStaticValues.js.map +1 -0
  81. package/esm/utils/applyOxcProcessors/shared.js +29 -0
  82. package/esm/utils/applyOxcProcessors/shared.js.map +1 -0
  83. package/esm/utils/applyOxcProcessors/types.js +2 -0
  84. package/esm/utils/applyOxcProcessors/types.js.map +1 -0
  85. package/esm/utils/applyOxcProcessors.js +1 -1216
  86. package/esm/utils/applyOxcProcessors.js.map +1 -1
  87. package/esm/utils/collectOxcRuntime/normalizeRuntimeCode.js +157 -0
  88. package/esm/utils/collectOxcRuntime/normalizeRuntimeCode.js.map +1 -0
  89. package/esm/utils/collectOxcRuntime/sourceMap.js +36 -0
  90. package/esm/utils/collectOxcRuntime/sourceMap.js.map +1 -0
  91. package/esm/utils/collectOxcRuntime/types.js +2 -0
  92. package/esm/utils/collectOxcRuntime/types.js.map +1 -0
  93. package/esm/utils/collectOxcRuntime.js +5 -193
  94. package/esm/utils/collectOxcRuntime.js.map +1 -1
  95. package/esm/utils/collectOxcTemplateDependencies/expressionExtraction.js +496 -0
  96. package/esm/utils/collectOxcTemplateDependencies/expressionExtraction.js.map +1 -0
  97. package/esm/utils/collectOxcTemplateDependencies/expressionReplacements.js +113 -0
  98. package/esm/utils/collectOxcTemplateDependencies/expressionReplacements.js.map +1 -0
  99. package/esm/utils/collectOxcTemplateDependencies/scopeAnalysis.js +387 -0
  100. package/esm/utils/collectOxcTemplateDependencies/scopeAnalysis.js.map +1 -0
  101. package/esm/utils/collectOxcTemplateDependencies/staticBindings.js +17 -0
  102. package/esm/utils/collectOxcTemplateDependencies/staticBindings.js.map +1 -0
  103. package/esm/utils/collectOxcTemplateDependencies/staticEvaluator.js +540 -0
  104. package/esm/utils/collectOxcTemplateDependencies/staticEvaluator.js.map +1 -0
  105. package/esm/utils/collectOxcTemplateDependencies/types.js +2 -0
  106. package/esm/utils/collectOxcTemplateDependencies/types.js.map +1 -0
  107. package/esm/utils/collectOxcTemplateDependencies.js +3 -1397
  108. package/esm/utils/collectOxcTemplateDependencies.js.map +1 -1
  109. package/esm/utils/nativeResolver.js +93 -0
  110. package/esm/utils/nativeResolver.js.map +1 -0
  111. package/esm/utils/oxc/ast.js +28 -0
  112. package/esm/utils/oxc/ast.js.map +1 -0
  113. package/esm/utils/oxc/parse.js +3 -0
  114. package/esm/utils/oxc/parse.js.map +1 -0
  115. package/esm/utils/oxc/replacements.js +14 -0
  116. package/esm/utils/oxc/replacements.js.map +1 -0
  117. package/esm/utils/oxc/sourceLocations.js +59 -0
  118. package/esm/utils/oxc/sourceLocations.js.map +1 -0
  119. package/esm/utils/oxcPreevalStage/evalStrategy.js +3 -0
  120. package/esm/utils/oxcPreevalStage/evalStrategy.js.map +1 -0
  121. package/esm/utils/oxcPreevalStage/prepareCode.js +21 -0
  122. package/esm/utils/oxcPreevalStage/prepareCode.js.map +1 -0
  123. package/esm/utils/oxcPreevalStage/prevalExport.js +23 -0
  124. package/esm/utils/oxcPreevalStage/prevalExport.js.map +1 -0
  125. package/esm/utils/oxcPreevalStage/processors.js +17 -0
  126. package/esm/utils/oxcPreevalStage/processors.js.map +1 -0
  127. package/esm/utils/oxcPreevalStage/staticOverlay.js +18 -0
  128. package/esm/utils/oxcPreevalStage/staticOverlay.js.map +1 -0
  129. package/esm/utils/oxcPreevalStage/types.js +2 -0
  130. package/esm/utils/oxcPreevalStage/types.js.map +1 -0
  131. package/esm/utils/oxcPreevalStage.js +17 -73
  132. package/esm/utils/oxcPreevalStage.js.map +1 -1
  133. package/esm/utils/oxcPreevalTransforms.js +12 -1
  134. package/esm/utils/oxcPreevalTransforms.js.map +1 -1
  135. package/esm/utils/processorStaticSemantics.js +157 -0
  136. package/esm/utils/processorStaticSemantics.js.map +1 -0
  137. package/esm/utils/resolveWithConditions.js +3 -3
  138. package/esm/utils/resolveWithConditions.js.map +1 -1
  139. package/package.json +4 -3
  140. package/types/cache.js +8 -0
  141. package/types/debug/fileReporter.js +46 -1
  142. package/types/eval/broker.d.ts +6 -2
  143. package/types/eval/broker.js +244 -95
  144. package/types/eval/protocol.d.ts +15 -1
  145. package/types/module.d.ts +4 -1
  146. package/types/module.js +97 -48
  147. package/types/transform/Entrypoint.types.d.ts +3 -0
  148. package/types/transform/generators/resolveImports.d.ts +3 -1
  149. package/types/transform/generators/resolveImports.js +49 -2
  150. package/types/transform/generators/resolveStaticOxcValues/cache.d.ts +25 -0
  151. package/types/transform/generators/resolveStaticOxcValues/cache.js +182 -0
  152. package/types/transform/generators/resolveStaticOxcValues/candidateResolver.d.ts +5 -0
  153. package/types/transform/generators/resolveStaticOxcValues/candidateResolver.js +149 -0
  154. package/types/transform/generators/resolveStaticOxcValues/dependencies.d.ts +6 -0
  155. package/types/transform/generators/resolveStaticOxcValues/dependencies.js +37 -0
  156. package/types/transform/generators/resolveStaticOxcValues/environment.d.ts +12 -0
  157. package/types/transform/generators/resolveStaticOxcValues/environment.js +32 -0
  158. package/types/transform/generators/resolveStaticOxcValues/exportResolver.d.ts +4 -0
  159. package/types/transform/generators/resolveStaticOxcValues/exportResolver.js +358 -0
  160. package/types/transform/generators/resolveStaticOxcValues/exportTargets.d.ts +20 -0
  161. package/types/transform/generators/resolveStaticOxcValues/exportTargets.js +285 -0
  162. package/types/transform/generators/resolveStaticOxcValues/objectAssign.d.ts +41 -0
  163. package/types/transform/generators/resolveStaticOxcValues/objectAssign.js +352 -0
  164. package/types/transform/generators/resolveStaticOxcValues/objectAssignStaticExport.d.ts +6 -0
  165. package/types/transform/generators/resolveStaticOxcValues/objectAssignStaticExport.js +88 -0
  166. package/types/transform/generators/resolveStaticOxcValues/opaqueRuntime.d.ts +13 -0
  167. package/types/transform/generators/resolveStaticOxcValues/opaqueRuntime.js +263 -0
  168. package/types/transform/generators/resolveStaticOxcValues/processorStaticExport.d.ts +4 -0
  169. package/types/transform/generators/resolveStaticOxcValues/processorStaticExport.js +191 -0
  170. package/types/transform/generators/resolveStaticOxcValues/processorStaticModel.d.ts +40 -0
  171. package/types/transform/generators/resolveStaticOxcValues/processorStaticModel.js +516 -0
  172. package/types/transform/generators/resolveStaticOxcValues/processorTarget.d.ts +5 -0
  173. package/types/transform/generators/resolveStaticOxcValues/processorTarget.js +62 -0
  174. package/types/transform/generators/resolveStaticOxcValues/programAnalysis.d.ts +11 -0
  175. package/types/transform/generators/resolveStaticOxcValues/programAnalysis.js +133 -0
  176. package/types/transform/generators/resolveStaticOxcValues/prune.d.ts +15 -0
  177. package/types/transform/generators/resolveStaticOxcValues/prune.js +220 -0
  178. package/types/transform/generators/resolveStaticOxcValues/resolveStaticOxcPreevalValues.d.ts +2 -0
  179. package/types/transform/generators/resolveStaticOxcValues/resolveStaticOxcPreevalValues.js +197 -0
  180. package/types/transform/generators/resolveStaticOxcValues/staticExpression.d.ts +25 -0
  181. package/types/transform/generators/resolveStaticOxcValues/staticExpression.js +391 -0
  182. package/types/transform/generators/resolveStaticOxcValues/staticExpressionDependencies.d.ts +14 -0
  183. package/types/transform/generators/resolveStaticOxcValues/staticExpressionDependencies.js +304 -0
  184. package/types/transform/generators/resolveStaticOxcValues/types.d.ts +99 -0
  185. package/types/transform/generators/resolveStaticOxcValues/types.js +2 -0
  186. package/types/transform/generators/resolveStaticOxcValues/zeroArgFunctionStaticExport.d.ts +7 -0
  187. package/types/transform/generators/resolveStaticOxcValues/zeroArgFunctionStaticExport.js +64 -0
  188. package/types/transform/generators/resolveStaticOxcValues.d.ts +1 -2
  189. package/types/transform/generators/resolveStaticOxcValues.js +1 -3235
  190. package/types/transform/generators/transform.js +63 -49
  191. package/types/transform/helpers/loadWywOptions.js +23 -3
  192. package/types/transform.js +3 -1
  193. package/types/utils/EventEmitter.d.ts +16 -1
  194. package/types/utils/EventEmitter.js +44 -9
  195. package/types/utils/applyOxcProcessors/applyOxcProcessors.d.ts +8 -0
  196. package/types/utils/applyOxcProcessors/applyOxcProcessors.js +167 -0
  197. package/types/utils/applyOxcProcessors/cleanupBindings.d.ts +12 -0
  198. package/types/utils/applyOxcProcessors/cleanupBindings.js +189 -0
  199. package/types/utils/applyOxcProcessors/cleanupRemovals.d.ts +16 -0
  200. package/types/utils/applyOxcProcessors/cleanupRemovals.js +482 -0
  201. package/types/utils/applyOxcProcessors/displayName.d.ts +9 -0
  202. package/types/utils/applyOxcProcessors/displayName.js +113 -0
  203. package/types/utils/applyOxcProcessors/expressionValues.d.ts +11 -0
  204. package/types/utils/applyOxcProcessors/expressionValues.js +170 -0
  205. package/types/utils/applyOxcProcessors/processorFactory.d.ts +7 -0
  206. package/types/utils/applyOxcProcessors/processorFactory.js +70 -0
  207. package/types/utils/applyOxcProcessors/processorUsages.d.ts +16 -0
  208. package/types/utils/applyOxcProcessors/processorUsages.js +163 -0
  209. package/types/utils/applyOxcProcessors/sameFileStaticValues.d.ts +23 -0
  210. package/types/utils/applyOxcProcessors/sameFileStaticValues.js +211 -0
  211. package/types/utils/applyOxcProcessors/shared.d.ts +10 -0
  212. package/types/utils/applyOxcProcessors/shared.js +37 -0
  213. package/types/utils/applyOxcProcessors/types.d.ts +88 -0
  214. package/types/utils/applyOxcProcessors/types.js +1 -0
  215. package/types/utils/applyOxcProcessors.d.ts +1 -16
  216. package/types/utils/applyOxcProcessors.js +1 -1391
  217. package/types/utils/collectOxcRuntime/normalizeRuntimeCode.d.ts +1 -0
  218. package/types/utils/collectOxcRuntime/normalizeRuntimeCode.js +185 -0
  219. package/types/utils/collectOxcRuntime/sourceMap.d.ts +2 -0
  220. package/types/utils/collectOxcRuntime/sourceMap.js +37 -0
  221. package/types/utils/collectOxcRuntime/types.d.ts +16 -0
  222. package/types/utils/collectOxcRuntime/types.js +1 -0
  223. package/types/utils/collectOxcRuntime.d.ts +2 -12
  224. package/types/utils/collectOxcRuntime.js +5 -224
  225. package/types/utils/collectOxcTemplateDependencies/expressionExtraction.d.ts +6 -0
  226. package/types/utils/collectOxcTemplateDependencies/expressionExtraction.js +550 -0
  227. package/types/utils/collectOxcTemplateDependencies/expressionReplacements.d.ts +11 -0
  228. package/types/utils/collectOxcTemplateDependencies/expressionReplacements.js +131 -0
  229. package/types/utils/collectOxcTemplateDependencies/scopeAnalysis.d.ts +20 -0
  230. package/types/utils/collectOxcTemplateDependencies/scopeAnalysis.js +434 -0
  231. package/types/utils/collectOxcTemplateDependencies/staticBindings.d.ts +7 -0
  232. package/types/utils/collectOxcTemplateDependencies/staticBindings.js +13 -0
  233. package/types/utils/collectOxcTemplateDependencies/staticEvaluator.d.ts +13 -0
  234. package/types/utils/collectOxcTemplateDependencies/staticEvaluator.js +626 -0
  235. package/types/utils/collectOxcTemplateDependencies/types.d.ts +116 -0
  236. package/types/utils/collectOxcTemplateDependencies/types.js +1 -0
  237. package/types/utils/collectOxcTemplateDependencies.d.ts +4 -38
  238. package/types/utils/collectOxcTemplateDependencies.js +3 -1580
  239. package/types/utils/nativeResolver.d.ts +13 -0
  240. package/types/utils/nativeResolver.js +91 -0
  241. package/types/utils/oxc/ast.d.ts +4 -0
  242. package/types/utils/oxc/ast.js +37 -0
  243. package/types/utils/oxc/parse.d.ts +3 -0
  244. package/types/utils/oxc/parse.js +2 -0
  245. package/types/utils/oxc/replacements.d.ts +12 -0
  246. package/types/utils/oxc/replacements.js +18 -0
  247. package/types/utils/oxc/sourceLocations.d.ts +5 -0
  248. package/types/utils/oxc/sourceLocations.js +63 -0
  249. package/types/utils/oxcPreevalStage/evalStrategy.d.ts +3 -0
  250. package/types/utils/oxcPreevalStage/evalStrategy.js +2 -0
  251. package/types/utils/oxcPreevalStage/prepareCode.d.ts +3 -0
  252. package/types/utils/oxcPreevalStage/prepareCode.js +20 -0
  253. package/types/utils/oxcPreevalStage/prevalExport.d.ts +1 -0
  254. package/types/utils/oxcPreevalStage/prevalExport.js +22 -0
  255. package/types/utils/oxcPreevalStage/processors.d.ts +10 -0
  256. package/types/utils/oxcPreevalStage/processors.js +16 -0
  257. package/types/utils/oxcPreevalStage/staticOverlay.d.ts +3 -0
  258. package/types/utils/oxcPreevalStage/staticOverlay.js +23 -0
  259. package/types/utils/oxcPreevalStage/types.d.ts +22 -0
  260. package/types/utils/oxcPreevalStage/types.js +1 -0
  261. package/types/utils/oxcPreevalStage.d.ts +2 -18
  262. package/types/utils/oxcPreevalStage.js +17 -79
  263. package/types/utils/oxcPreevalTransforms.js +14 -1
  264. package/types/utils/processorStaticSemantics.d.ts +13 -0
  265. package/types/utils/processorStaticSemantics.js +191 -0
  266. package/types/utils/resolveWithConditions.js +3 -3
  267. package/esm/eval/resolverStrategy.js +0 -51
  268. package/esm/eval/resolverStrategy.js.map +0 -1
  269. package/types/eval/resolverStrategy.d.ts +0 -13
  270. package/types/eval/resolverStrategy.js +0 -46
@@ -0,0 +1,189 @@
1
+ /* eslint-disable no-restricted-syntax */
2
+ import { isNotNull } from '../isNotNull';
3
+ import { getOxcNodeChildren, isOxcNode, walkOxc } from '../oxc/ast';
4
+ export const collectUsedNames = (program) => {
5
+ const names = new Set();
6
+ walkOxc(program, (node) => {
7
+ if (node.type === 'Identifier') {
8
+ names.add(node.name);
9
+ }
10
+ });
11
+ return names;
12
+ };
13
+ export const isNodeReference = (node, parent) => {
14
+ if (node.type === 'Identifier') {
15
+ const parentRecord = parent;
16
+ if (!parentRecord) {
17
+ return true;
18
+ }
19
+ if (parent?.type === 'ImportDeclaration' ||
20
+ parent?.type === 'ImportSpecifier' ||
21
+ parent?.type === 'ImportDefaultSpecifier' ||
22
+ parent?.type === 'ImportNamespaceSpecifier') {
23
+ return false;
24
+ }
25
+ if (parent?.type === 'MemberExpression' &&
26
+ parentRecord.property === node &&
27
+ !parentRecord.computed) {
28
+ return false;
29
+ }
30
+ if ((parent?.type === 'VariableDeclarator' ||
31
+ parent?.type === 'FunctionDeclaration' ||
32
+ parent?.type === 'ClassDeclaration' ||
33
+ parent?.type === 'ClassExpression') &&
34
+ parentRecord.id === node) {
35
+ return false;
36
+ }
37
+ if ((parent?.type === 'PropertyDefinition' ||
38
+ parent?.type === 'MethodDefinition') &&
39
+ parentRecord.key === node &&
40
+ !parentRecord.computed) {
41
+ return false;
42
+ }
43
+ if (parent?.type === 'Property' &&
44
+ parentRecord.key === node &&
45
+ parentRecord.value !== node &&
46
+ !parentRecord.computed) {
47
+ return false;
48
+ }
49
+ return true;
50
+ }
51
+ if (node.type === 'JSXIdentifier') {
52
+ const parentRecord = parent;
53
+ if (parent?.type === 'JSXAttribute' && parentRecord?.name === node) {
54
+ return false;
55
+ }
56
+ return true;
57
+ }
58
+ return false;
59
+ };
60
+ export const collectReferencedNames = (root) => {
61
+ const names = new Set();
62
+ const walk = (node, parent = null) => {
63
+ if (node.type === 'ImportDeclaration') {
64
+ return;
65
+ }
66
+ if (isNodeReference(node, parent) &&
67
+ 'name' in node &&
68
+ typeof node.name === 'string') {
69
+ names.add(node.name);
70
+ }
71
+ getOxcNodeChildren(node).forEach((child) => walk(child, node));
72
+ };
73
+ walk(root);
74
+ return names;
75
+ };
76
+ export const collectImportLocalNames = (node) => {
77
+ if (node.type !== 'ImportDeclaration') {
78
+ return [];
79
+ }
80
+ const { specifiers } = node;
81
+ if (!Array.isArray(specifiers)) {
82
+ return [];
83
+ }
84
+ return specifiers
85
+ .map((specifier) => {
86
+ const { local } = specifier;
87
+ return isOxcNode(local) &&
88
+ 'name' in local &&
89
+ typeof local.name === 'string'
90
+ ? local.name
91
+ : null;
92
+ })
93
+ .filter(isNotNull);
94
+ };
95
+ export const getImportSpecifierLocalName = (node) => {
96
+ const { local } = node;
97
+ return isOxcNode(local) && 'name' in local && typeof local.name === 'string'
98
+ ? local.name
99
+ : null;
100
+ };
101
+ export const collectDeclaredNames = (node) => {
102
+ if (node.type === 'Identifier') {
103
+ return [node.name];
104
+ }
105
+ if (node.type === 'RestElement') {
106
+ return collectDeclaredNames(node.argument);
107
+ }
108
+ if (node.type === 'AssignmentPattern') {
109
+ return collectDeclaredNames(node.left);
110
+ }
111
+ if (node.type === 'ObjectPattern') {
112
+ return node.properties.flatMap((property) => property.type === 'RestElement'
113
+ ? collectDeclaredNames(property.argument)
114
+ : collectDeclaredNames(property.value));
115
+ }
116
+ if (node.type === 'ArrayPattern') {
117
+ return node.elements.flatMap((element) => element ? collectDeclaredNames(element) : []);
118
+ }
119
+ if (node.type === 'TSParameterProperty') {
120
+ return collectDeclaredNames(node.parameter);
121
+ }
122
+ return [];
123
+ };
124
+ export const collectTopLevelBindings = (statement) => {
125
+ const bindings = new Set();
126
+ if (statement.type === 'ImportDeclaration') {
127
+ collectImportLocalNames(statement).forEach((name) => bindings.add(name));
128
+ return bindings;
129
+ }
130
+ if (statement.type === 'VariableDeclaration') {
131
+ const { declarations } = statement;
132
+ if (!Array.isArray(declarations)) {
133
+ return bindings;
134
+ }
135
+ declarations.forEach((declarator) => {
136
+ const { id } = declarator;
137
+ if (isOxcNode(id)) {
138
+ collectDeclaredNames(id).forEach((name) => bindings.add(name));
139
+ }
140
+ });
141
+ return bindings;
142
+ }
143
+ if ((statement.type === 'FunctionDeclaration' ||
144
+ statement.type === 'ClassDeclaration' ||
145
+ statement.type === 'TSEnumDeclaration') &&
146
+ 'id' in statement) {
147
+ const { id } = statement;
148
+ if (isOxcNode(id) && id.type === 'Identifier') {
149
+ bindings.add(id.name);
150
+ }
151
+ return bindings;
152
+ }
153
+ if (statement.type === 'ExportNamedDeclaration') {
154
+ const { declaration } = statement;
155
+ return isOxcNode(declaration)
156
+ ? collectTopLevelBindings(declaration)
157
+ : bindings;
158
+ }
159
+ return bindings;
160
+ };
161
+ export const collectTopLevelStatementInfos = (program) => program.body.map((statement) => ({
162
+ bindings: collectTopLevelBindings(statement),
163
+ node: statement,
164
+ references: collectReferencedNames(statement),
165
+ }));
166
+ export const collectTopLevelBindingsFromStatements = (statements) => new Set(statements.flatMap((statement) => [...statement.bindings]));
167
+ export const collectRemovableNamesFromStatements = (statements, initialNames) => {
168
+ const removable = new Set(initialNames);
169
+ const bindingToStatement = new Map();
170
+ statements.forEach((statement) => {
171
+ statement.bindings.forEach((name) => {
172
+ bindingToStatement.set(name, statement);
173
+ });
174
+ });
175
+ const queue = [...removable];
176
+ while (queue.length > 0) {
177
+ const name = queue.shift();
178
+ const statement = bindingToStatement.get(name);
179
+ if (statement) {
180
+ statement.references.forEach((reference) => {
181
+ if (bindingToStatement.has(reference) && !removable.has(reference)) {
182
+ removable.add(reference);
183
+ queue.push(reference);
184
+ }
185
+ });
186
+ }
187
+ }
188
+ return removable;
189
+ };
@@ -0,0 +1,16 @@
1
+ import type { Program } from 'oxc-parser';
2
+ import type { Replacement, ScopedBindingInfo, ScopedCleanupScope, TopLevelStatementInfo } from './types';
3
+ export declare const createScopedCleanupScope: (parent: ScopedCleanupScope | null) => ScopedCleanupScope;
4
+ export declare const resolveScopedBinding: (scope: ScopedCleanupScope, name: string) => string | null;
5
+ export declare const collectScopedBindingInfos: (program: Program) => Map<string, ScopedBindingInfo>;
6
+ export declare const collectScopedRemovableBindingIds: (bindings: Map<string, ScopedBindingInfo>, initialNames: Set<string>) => Set<string>;
7
+ export declare function expandImportRemovalRange(code: string, start: number, end: number): Replacement;
8
+ export declare const collectUnusedScopedDeclarationRemovals: (code: string, bindings: Map<string, ScopedBindingInfo>, initialRemovableNames: Set<string>) => Replacement[];
9
+ export declare const expandImportSpecifierRemovalRange: (code: string, start: number, end: number) => Replacement;
10
+ export declare const mergeEmptyRemovalRanges: (removals: Replacement[]) => Replacement[];
11
+ export declare const collectUnusedImportRemovals: (code: string, program: Program, referencedNames: Set<string>, removableNames: Set<string>, preserveSideEffectImportLocals: Set<string>) => Replacement[];
12
+ export declare const collectUnusedTopLevelDeclarationRemovals: (code: string, program: Program, referencedNames: Set<string>, removableNames: Set<string>) => Replacement[];
13
+ export declare const collectUnusedGeneratedHelperDeclarationRemovals: (code: string, program: Program, referencedNames: Set<string>) => Replacement[];
14
+ export declare const collectTopLevelExpressionStatementRemovals: (code: string, statements: TopLevelStatementInfo[], topLevelBindings: Set<string>, removableExpressionRefs: Set<string>) => Replacement[];
15
+ export declare const collectEmptyTopLevelBlockRemovals: (code: string, program: Program) => Replacement[];
16
+ export declare const removeUnusedAfterReplacement: (code: string, filename: string, initialRemovableNames: Set<string>, removableExpressionRefs: Set<string>, preserveSideEffectImportLocals: Set<string>) => string;
@@ -0,0 +1,482 @@
1
+ /* eslint-disable no-restricted-syntax,no-continue */
2
+ import { getOxcNodeChildren, isOxcNode } from '../oxc/ast';
3
+ import { applyOxcReplacements } from '../oxc/replacements';
4
+ import { collectDeclaredNames, collectImportLocalNames, collectReferencedNames, collectRemovableNamesFromStatements, collectTopLevelBindings, collectTopLevelBindingsFromStatements, collectTopLevelStatementInfos, getImportSpecifierLocalName, isNodeReference, } from './cleanupBindings';
5
+ import { GENERATED_HELPER_NAME_RE, parseOxc } from './shared';
6
+ export const createScopedCleanupScope = (parent) => ({
7
+ bindings: new Map(),
8
+ parent,
9
+ });
10
+ export const resolveScopedBinding = (scope, name) => {
11
+ let current = scope;
12
+ while (current) {
13
+ const bindingId = current.bindings.get(name);
14
+ if (bindingId) {
15
+ return bindingId;
16
+ }
17
+ current = current.parent;
18
+ }
19
+ return null;
20
+ };
21
+ export const collectScopedBindingInfos = (program) => {
22
+ const bindings = new Map();
23
+ let sequence = 0;
24
+ const addBinding = (scope, name, kind, declaration) => {
25
+ const id = `${kind}:${name}:${declaration.start}:${sequence}`;
26
+ sequence += 1;
27
+ bindings.set(id, {
28
+ declaration,
29
+ dependencies: new Set(),
30
+ externalReferences: 0,
31
+ id,
32
+ incomingFromBindings: new Set(),
33
+ kind,
34
+ name,
35
+ });
36
+ scope.bindings.set(name, id);
37
+ return id;
38
+ };
39
+ const addPatternBindings = (scope, pattern, kind, declaration) => {
40
+ collectDeclaredNames(pattern).forEach((name) => {
41
+ addBinding(scope, name, kind, declaration);
42
+ });
43
+ };
44
+ const recordReference = (scope, name, ownerBindingId) => {
45
+ const targetId = resolveScopedBinding(scope, name);
46
+ if (!targetId) {
47
+ return;
48
+ }
49
+ const target = bindings.get(targetId);
50
+ if (!target) {
51
+ return;
52
+ }
53
+ if (ownerBindingId && ownerBindingId !== targetId) {
54
+ target.incomingFromBindings.add(ownerBindingId);
55
+ bindings.get(ownerBindingId)?.dependencies.add(targetId);
56
+ return;
57
+ }
58
+ target.externalReferences += 1;
59
+ };
60
+ let walk;
61
+ function walkPatternReferenceSubexpressions(node, scope, ownerBindingId) {
62
+ if (node.type === 'Identifier') {
63
+ return;
64
+ }
65
+ if (node.type === 'TSParameterProperty') {
66
+ walkPatternReferenceSubexpressions(node.parameter, scope, ownerBindingId);
67
+ return;
68
+ }
69
+ if (node.type === 'RestElement') {
70
+ walkPatternReferenceSubexpressions(node.argument, scope, ownerBindingId);
71
+ return;
72
+ }
73
+ if (node.type === 'AssignmentPattern') {
74
+ walkPatternReferenceSubexpressions(node.left, scope, ownerBindingId);
75
+ walk(node.right, scope, node, ownerBindingId);
76
+ return;
77
+ }
78
+ if (node.type === 'ObjectPattern') {
79
+ node.properties.forEach((property) => {
80
+ if (property.type === 'RestElement') {
81
+ walkPatternReferenceSubexpressions(property.argument, scope, ownerBindingId);
82
+ return;
83
+ }
84
+ if (property.computed && isOxcNode(property.key)) {
85
+ walk(property.key, scope, property, ownerBindingId);
86
+ }
87
+ walkPatternReferenceSubexpressions(property.value, scope, ownerBindingId);
88
+ });
89
+ return;
90
+ }
91
+ if (node.type === 'ArrayPattern') {
92
+ node.elements.forEach((element) => {
93
+ if (element && isOxcNode(element)) {
94
+ walkPatternReferenceSubexpressions(element, scope, ownerBindingId);
95
+ }
96
+ });
97
+ }
98
+ }
99
+ walk = (node, scope, parent = null, ownerBindingId = null) => {
100
+ if (node.type === 'ImportDeclaration') {
101
+ const { specifiers } = node;
102
+ if (Array.isArray(specifiers)) {
103
+ specifiers.forEach((specifier) => {
104
+ const { local } = specifier;
105
+ if (isOxcNode(local) &&
106
+ local.type === 'Identifier' &&
107
+ typeof local.name === 'string') {
108
+ addBinding(scope, local.name, 'import', node);
109
+ }
110
+ });
111
+ }
112
+ return;
113
+ }
114
+ if (node.type === 'ExportNamedDeclaration' && node.declaration) {
115
+ walk(node.declaration, scope, node, ownerBindingId);
116
+ collectTopLevelBindings(node).forEach((name) => {
117
+ recordReference(scope, name, ownerBindingId);
118
+ });
119
+ return;
120
+ }
121
+ if (node.type === 'ExportDefaultDeclaration') {
122
+ const { declaration } = node;
123
+ if (isOxcNode(declaration)) {
124
+ walk(declaration, scope, node, ownerBindingId);
125
+ if ((declaration.type === 'FunctionDeclaration' ||
126
+ declaration.type === 'ClassDeclaration') &&
127
+ declaration.id) {
128
+ recordReference(scope, declaration.id.name, ownerBindingId);
129
+ }
130
+ }
131
+ return;
132
+ }
133
+ if (node.type === 'VariableDeclaration') {
134
+ const { declarations } = node;
135
+ if (!Array.isArray(declarations)) {
136
+ return;
137
+ }
138
+ declarations.forEach((declarator) => {
139
+ const { id } = declarator;
140
+ if (isOxcNode(id)) {
141
+ addPatternBindings(scope, id, 'variable', node);
142
+ }
143
+ });
144
+ declarations.forEach((declarator) => {
145
+ const { id } = declarator;
146
+ const { init } = declarator;
147
+ if (!isOxcNode(id) || !isOxcNode(init)) {
148
+ return;
149
+ }
150
+ const ownerName = collectDeclaredNames(id)[0] ?? null;
151
+ const nextOwner = ownerName !== null ? resolveScopedBinding(scope, ownerName) : null;
152
+ walk(init, scope, declarator, nextOwner);
153
+ });
154
+ return;
155
+ }
156
+ if (node.type === 'FunctionDeclaration' && node.id) {
157
+ const functionBindingId = addBinding(scope, node.id.name, 'function', node);
158
+ const fnScope = createScopedCleanupScope(scope);
159
+ node.params.forEach((param) => {
160
+ addPatternBindings(fnScope, param, 'param', param);
161
+ walkPatternReferenceSubexpressions(param, fnScope, functionBindingId);
162
+ });
163
+ if (node.body) {
164
+ walk(node.body, fnScope, node, functionBindingId);
165
+ }
166
+ return;
167
+ }
168
+ if (node.type === 'FunctionExpression' ||
169
+ node.type === 'ArrowFunctionExpression') {
170
+ const fnScope = createScopedCleanupScope(scope);
171
+ if (node.type === 'FunctionExpression' && node.id) {
172
+ addBinding(fnScope, node.id.name, 'function', node);
173
+ }
174
+ node.params.forEach((param) => {
175
+ addPatternBindings(fnScope, param, 'param', param);
176
+ walkPatternReferenceSubexpressions(param, fnScope, ownerBindingId);
177
+ });
178
+ if (node.body) {
179
+ walk(node.body, fnScope, node, ownerBindingId);
180
+ }
181
+ return;
182
+ }
183
+ if (node.type === 'BlockStatement') {
184
+ const blockScope = createScopedCleanupScope(scope);
185
+ getOxcNodeChildren(node).forEach((child) => walk(child, blockScope, node, ownerBindingId));
186
+ return;
187
+ }
188
+ if (isNodeReference(node, parent) &&
189
+ 'name' in node &&
190
+ typeof node.name === 'string') {
191
+ recordReference(scope, node.name, ownerBindingId);
192
+ }
193
+ getOxcNodeChildren(node).forEach((child) => walk(child, scope, node, ownerBindingId));
194
+ };
195
+ walk(program, createScopedCleanupScope(null));
196
+ return bindings;
197
+ };
198
+ export const collectScopedRemovableBindingIds = (bindings, initialNames) => {
199
+ const removable = new Set();
200
+ let changed = true;
201
+ while (changed) {
202
+ changed = false;
203
+ for (const binding of bindings.values()) {
204
+ if (!removable.has(binding.id) &&
205
+ binding.kind !== 'import' &&
206
+ binding.kind !== 'param' &&
207
+ binding.externalReferences === 0) {
208
+ const seededByName = initialNames.has(binding.name) ||
209
+ (GENERATED_HELPER_NAME_RE.test(binding.name) &&
210
+ binding.incomingFromBindings.size === 0);
211
+ const allIncomingRemovable = binding.incomingFromBindings.size > 0 &&
212
+ [...binding.incomingFromBindings].every((sourceId) => removable.has(sourceId));
213
+ if ((seededByName && binding.incomingFromBindings.size === 0) ||
214
+ allIncomingRemovable) {
215
+ removable.add(binding.id);
216
+ changed = true;
217
+ }
218
+ }
219
+ }
220
+ }
221
+ return removable;
222
+ };
223
+ export function expandImportRemovalRange(code, start, end) {
224
+ let removalStart = start;
225
+ while (removalStart > 0 &&
226
+ (code[removalStart - 1] === ' ' || code[removalStart - 1] === '\t')) {
227
+ removalStart -= 1;
228
+ }
229
+ let removalEnd = end;
230
+ if (code[removalEnd] === ';') {
231
+ removalEnd += 1;
232
+ }
233
+ while (removalEnd < code.length &&
234
+ (code[removalEnd] === ' ' || code[removalEnd] === '\t')) {
235
+ removalEnd += 1;
236
+ }
237
+ if (code[removalEnd] === '\r' && code[removalEnd + 1] === '\n') {
238
+ removalEnd += 2;
239
+ }
240
+ else if (code[removalEnd] === '\n') {
241
+ removalEnd += 1;
242
+ }
243
+ return {
244
+ end: removalEnd,
245
+ start: removalStart,
246
+ value: '',
247
+ };
248
+ }
249
+ export const collectUnusedScopedDeclarationRemovals = (code, bindings, initialRemovableNames) => {
250
+ const removableBindingIds = collectScopedRemovableBindingIds(bindings, initialRemovableNames);
251
+ const removals = new Map();
252
+ bindings.forEach((binding) => {
253
+ if (!removableBindingIds.has(binding.id) ||
254
+ binding.kind === 'import' ||
255
+ binding.kind === 'param' ||
256
+ binding.externalReferences > 0 ||
257
+ [...binding.incomingFromBindings].some((sourceId) => !removableBindingIds.has(sourceId))) {
258
+ return;
259
+ }
260
+ if (binding.kind === 'function' &&
261
+ binding.declaration.type === 'FunctionDeclaration') {
262
+ const range = expandImportRemovalRange(code, binding.declaration.start, binding.declaration.end);
263
+ removals.set(`${range.start}:${range.end}`, range);
264
+ return;
265
+ }
266
+ if (binding.declaration.type !== 'VariableDeclaration') {
267
+ return;
268
+ }
269
+ const { declarations } = binding.declaration;
270
+ if (!Array.isArray(declarations) || declarations.length !== 1) {
271
+ return;
272
+ }
273
+ const range = expandImportRemovalRange(code, binding.declaration.start, binding.declaration.end);
274
+ removals.set(`${range.start}:${range.end}`, range);
275
+ });
276
+ return [...removals.values()];
277
+ };
278
+ export const expandImportSpecifierRemovalRange = (code, start, end) => {
279
+ let removalStart = start;
280
+ let removalEnd = end;
281
+ let whitespaceStart = removalStart;
282
+ while (whitespaceStart > 0 &&
283
+ (code[whitespaceStart - 1] === ' ' || code[whitespaceStart - 1] === '\t')) {
284
+ whitespaceStart -= 1;
285
+ }
286
+ if (code[whitespaceStart - 1] !== '{') {
287
+ removalStart = whitespaceStart;
288
+ }
289
+ while (removalEnd < code.length &&
290
+ (code[removalEnd] === ' ' || code[removalEnd] === '\t')) {
291
+ removalEnd += 1;
292
+ }
293
+ if (code[removalEnd] === ',') {
294
+ removalEnd += 1;
295
+ while (removalEnd < code.length &&
296
+ (code[removalEnd] === ' ' || code[removalEnd] === '\t')) {
297
+ removalEnd += 1;
298
+ }
299
+ }
300
+ else {
301
+ while (removalStart > 0 &&
302
+ (code[removalStart - 1] === ' ' || code[removalStart - 1] === '\t')) {
303
+ removalStart -= 1;
304
+ }
305
+ if (code[removalStart - 1] === ',') {
306
+ removalStart -= 1;
307
+ while (removalStart > 0 &&
308
+ (code[removalStart - 1] === ' ' || code[removalStart - 1] === '\t')) {
309
+ removalStart -= 1;
310
+ }
311
+ }
312
+ }
313
+ return {
314
+ end: removalEnd,
315
+ start: removalStart,
316
+ value: '',
317
+ };
318
+ };
319
+ export const mergeEmptyRemovalRanges = (removals) => {
320
+ if (removals.length <= 1) {
321
+ return removals;
322
+ }
323
+ const sorted = [...removals].sort((a, b) => a.start - b.start);
324
+ const merged = [];
325
+ sorted.forEach((removal) => {
326
+ const previous = merged[merged.length - 1];
327
+ if (previous &&
328
+ previous.value === '' &&
329
+ removal.value === '' &&
330
+ removal.start <= previous.end) {
331
+ previous.end = Math.max(previous.end, removal.end);
332
+ return;
333
+ }
334
+ merged.push({ ...removal });
335
+ });
336
+ return merged;
337
+ };
338
+ export const collectUnusedImportRemovals = (code, program, referencedNames, removableNames, preserveSideEffectImportLocals) => {
339
+ const removals = [];
340
+ program.body.forEach((statement) => {
341
+ if (statement.type !== 'ImportDeclaration') {
342
+ return;
343
+ }
344
+ const localNames = collectImportLocalNames(statement);
345
+ const removableLocalNames = localNames.filter((localName) => removableNames.has(localName));
346
+ if (removableLocalNames.length > 0 &&
347
+ removableLocalNames.length === localNames.length &&
348
+ removableLocalNames.every((localName) => !referencedNames.has(localName))) {
349
+ if (removableLocalNames.some((localName) => preserveSideEffectImportLocals.has(localName))) {
350
+ removals.push({
351
+ end: statement.end,
352
+ start: statement.start,
353
+ value: `import ${code.slice(statement.source.start, statement.source.end)};`,
354
+ });
355
+ return;
356
+ }
357
+ removals.push(expandImportRemovalRange(code, statement.start, statement.end));
358
+ return;
359
+ }
360
+ const { specifiers } = statement;
361
+ if (!Array.isArray(specifiers) || specifiers.length <= 1) {
362
+ return;
363
+ }
364
+ specifiers.forEach((specifier) => {
365
+ if (!isOxcNode(specifier)) {
366
+ return;
367
+ }
368
+ const localName = getImportSpecifierLocalName(specifier);
369
+ if (localName &&
370
+ removableNames.has(localName) &&
371
+ !referencedNames.has(localName)) {
372
+ removals.push(expandImportSpecifierRemovalRange(code, specifier.start, specifier.end));
373
+ }
374
+ });
375
+ });
376
+ return removals;
377
+ };
378
+ export const collectUnusedTopLevelDeclarationRemovals = (code, program, referencedNames, removableNames) => {
379
+ const removals = [];
380
+ program.body.forEach((statement) => {
381
+ if (statement.type !== 'VariableDeclaration') {
382
+ return;
383
+ }
384
+ const localNames = [...collectTopLevelBindings(statement)];
385
+ if (localNames.length > 0 &&
386
+ localNames.every((localName) => removableNames.has(localName)) &&
387
+ localNames.every((localName) => !referencedNames.has(localName))) {
388
+ removals.push(expandImportRemovalRange(code, statement.start, statement.end));
389
+ }
390
+ });
391
+ return removals;
392
+ };
393
+ export const collectUnusedGeneratedHelperDeclarationRemovals = (code, program, referencedNames) => {
394
+ const removals = [];
395
+ program.body.forEach((statement) => {
396
+ if (statement.type !== 'VariableDeclaration') {
397
+ return;
398
+ }
399
+ const localNames = [...collectTopLevelBindings(statement)];
400
+ if (localNames.length > 0 &&
401
+ localNames.every((localName) => GENERATED_HELPER_NAME_RE.test(localName)) &&
402
+ localNames.every((localName) => !referencedNames.has(localName))) {
403
+ removals.push(expandImportRemovalRange(code, statement.start, statement.end));
404
+ }
405
+ });
406
+ return removals;
407
+ };
408
+ export const collectTopLevelExpressionStatementRemovals = (code, statements, topLevelBindings, removableExpressionRefs) => {
409
+ const removals = [];
410
+ statements.forEach((statement) => {
411
+ if (statement.node.type !== 'ExpressionStatement') {
412
+ return;
413
+ }
414
+ const { expression } = statement.node;
415
+ const isPureExpression = expression.type === 'Identifier' ||
416
+ expression.type === 'Literal' ||
417
+ expression.type === 'ObjectExpression' ||
418
+ expression.type === 'ArrayExpression' ||
419
+ expression.type === 'ArrowFunctionExpression' ||
420
+ expression.type === 'FunctionExpression' ||
421
+ (expression.type === 'TemplateLiteral' &&
422
+ expression.expressions.length === 0);
423
+ if (!isPureExpression) {
424
+ return;
425
+ }
426
+ const localReferences = [...statement.references].filter((name) => topLevelBindings.has(name));
427
+ if (localReferences.length > 0 &&
428
+ localReferences.every((name) => removableExpressionRefs.has(name))) {
429
+ removals.push(expandImportRemovalRange(code, statement.node.start, statement.node.end));
430
+ }
431
+ });
432
+ return removals;
433
+ };
434
+ export const collectEmptyTopLevelBlockRemovals = (code, program) => {
435
+ const removals = [];
436
+ program.body.forEach((statement) => {
437
+ if (statement.type !== 'BlockStatement' || statement.body.length > 0) {
438
+ return;
439
+ }
440
+ removals.push(expandImportRemovalRange(code, statement.start, statement.end));
441
+ });
442
+ return removals;
443
+ };
444
+ export const removeUnusedAfterReplacement = (code, filename, initialRemovableNames, removableExpressionRefs, preserveSideEffectImportLocals) => {
445
+ let current = code;
446
+ const cumulativeRemovableNames = new Set(initialRemovableNames);
447
+ const applyIfParsable = (next) => {
448
+ try {
449
+ parseOxc(next, filename);
450
+ return next;
451
+ }
452
+ catch {
453
+ return current;
454
+ }
455
+ };
456
+ for (let idx = 0; idx < 5; idx += 1) {
457
+ const previous = current;
458
+ const program = parseOxc(current, filename);
459
+ const statements = collectTopLevelStatementInfos(program);
460
+ const removableNames = collectRemovableNamesFromStatements(statements, cumulativeRemovableNames);
461
+ removableNames.forEach((name) => cumulativeRemovableNames.add(name));
462
+ const referencedNames = collectReferencedNames(program);
463
+ const topLevelBindings = collectTopLevelBindingsFromStatements(statements);
464
+ const scopedBindings = collectScopedBindingInfos(program);
465
+ const removals = mergeEmptyRemovalRanges([
466
+ ...collectUnusedScopedDeclarationRemovals(current, scopedBindings, cumulativeRemovableNames),
467
+ ...collectUnusedTopLevelDeclarationRemovals(current, program, referencedNames, cumulativeRemovableNames),
468
+ ...collectUnusedGeneratedHelperDeclarationRemovals(current, program, referencedNames),
469
+ ...collectUnusedImportRemovals(current, program, referencedNames, cumulativeRemovableNames, preserveSideEffectImportLocals),
470
+ ...collectTopLevelExpressionStatementRemovals(current, statements, topLevelBindings, removableExpressionRefs),
471
+ ...collectEmptyTopLevelBlockRemovals(current, program),
472
+ ]);
473
+ current =
474
+ removals.length > 0
475
+ ? applyIfParsable(applyOxcReplacements(current, removals))
476
+ : current;
477
+ if (current === previous) {
478
+ return current;
479
+ }
480
+ }
481
+ return current;
482
+ };