webfuscator 0.9.4

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 (289) hide show
  1. package/DISCLOSURE +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +83 -0
  4. package/dist/analysis/constant.d.ts +11 -0
  5. package/dist/analysis/constant.d.ts.map +1 -0
  6. package/dist/analysis/constant.js +261 -0
  7. package/dist/analysis/constant.js.map +1 -0
  8. package/dist/analysis/document-order.d.ts +5 -0
  9. package/dist/analysis/document-order.d.ts.map +1 -0
  10. package/dist/analysis/document-order.js +124 -0
  11. package/dist/analysis/document-order.js.map +1 -0
  12. package/dist/analysis/inlineability.d.ts +13 -0
  13. package/dist/analysis/inlineability.d.ts.map +1 -0
  14. package/dist/analysis/inlineability.js +270 -0
  15. package/dist/analysis/inlineability.js.map +1 -0
  16. package/dist/analysis/purity.d.ts +5 -0
  17. package/dist/analysis/purity.d.ts.map +1 -0
  18. package/dist/analysis/purity.js +281 -0
  19. package/dist/analysis/purity.js.map +1 -0
  20. package/dist/index.d.ts +3 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +2 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/obfuscator.d.ts +4 -0
  25. package/dist/obfuscator.d.ts.map +1 -0
  26. package/dist/obfuscator.js +222 -0
  27. package/dist/obfuscator.js.map +1 -0
  28. package/dist/options.d.ts +73 -0
  29. package/dist/options.d.ts.map +1 -0
  30. package/dist/options.js +2 -0
  31. package/dist/options.js.map +1 -0
  32. package/dist/preparation/dot-to-bracket.d.ts +16 -0
  33. package/dist/preparation/dot-to-bracket.d.ts.map +1 -0
  34. package/dist/preparation/dot-to-bracket.js +36 -0
  35. package/dist/preparation/dot-to-bracket.js.map +1 -0
  36. package/dist/preparation/expand-destructuring.d.ts +26 -0
  37. package/dist/preparation/expand-destructuring.d.ts.map +1 -0
  38. package/dist/preparation/expand-destructuring.js +154 -0
  39. package/dist/preparation/expand-destructuring.js.map +1 -0
  40. package/dist/preparation/expand-template-literals.d.ts +23 -0
  41. package/dist/preparation/expand-template-literals.d.ts.map +1 -0
  42. package/dist/preparation/expand-template-literals.js +78 -0
  43. package/dist/preparation/expand-template-literals.js.map +1 -0
  44. package/dist/preparation/rewrite-class-fields.d.ts +43 -0
  45. package/dist/preparation/rewrite-class-fields.d.ts.map +1 -0
  46. package/dist/preparation/rewrite-class-fields.js +270 -0
  47. package/dist/preparation/rewrite-class-fields.js.map +1 -0
  48. package/dist/preparation/split-sequence-expressions.d.ts +15 -0
  49. package/dist/preparation/split-sequence-expressions.d.ts.map +1 -0
  50. package/dist/preparation/split-sequence-expressions.js +36 -0
  51. package/dist/preparation/split-sequence-expressions.js.map +1 -0
  52. package/dist/preparation/split-variable-declarations.d.ts +20 -0
  53. package/dist/preparation/split-variable-declarations.d.ts.map +1 -0
  54. package/dist/preparation/split-variable-declarations.js +36 -0
  55. package/dist/preparation/split-variable-declarations.js.map +1 -0
  56. package/dist/preparation/stringify-object-keys.d.ts +21 -0
  57. package/dist/preparation/stringify-object-keys.d.ts.map +1 -0
  58. package/dist/preparation/stringify-object-keys.js +96 -0
  59. package/dist/preparation/stringify-object-keys.js.map +1 -0
  60. package/dist/preparation/wrap-single-statements.d.ts +24 -0
  61. package/dist/preparation/wrap-single-statements.d.ts.map +1 -0
  62. package/dist/preparation/wrap-single-statements.js +53 -0
  63. package/dist/preparation/wrap-single-statements.js.map +1 -0
  64. package/dist/transforms/arguments-to-parameters.d.ts +20 -0
  65. package/dist/transforms/arguments-to-parameters.d.ts.map +1 -0
  66. package/dist/transforms/arguments-to-parameters.js +162 -0
  67. package/dist/transforms/arguments-to-parameters.js.map +1 -0
  68. package/dist/transforms/arrow-to-function.d.ts +46 -0
  69. package/dist/transforms/arrow-to-function.d.ts.map +1 -0
  70. package/dist/transforms/arrow-to-function.js +203 -0
  71. package/dist/transforms/arrow-to-function.js.map +1 -0
  72. package/dist/transforms/collapse-single-use-temps.d.ts +16 -0
  73. package/dist/transforms/collapse-single-use-temps.d.ts.map +1 -0
  74. package/dist/transforms/collapse-single-use-temps.js +805 -0
  75. package/dist/transforms/collapse-single-use-temps.js.map +1 -0
  76. package/dist/transforms/const-let-to-var.d.ts +21 -0
  77. package/dist/transforms/const-let-to-var.d.ts.map +1 -0
  78. package/dist/transforms/const-let-to-var.js +217 -0
  79. package/dist/transforms/const-let-to-var.js.map +1 -0
  80. package/dist/transforms/const-to-let.d.ts +17 -0
  81. package/dist/transforms/const-to-let.d.ts.map +1 -0
  82. package/dist/transforms/const-to-let.js +33 -0
  83. package/dist/transforms/const-to-let.js.map +1 -0
  84. package/dist/transforms/do-while-to-while.d.ts +26 -0
  85. package/dist/transforms/do-while-to-while.d.ts.map +1 -0
  86. package/dist/transforms/do-while-to-while.js +54 -0
  87. package/dist/transforms/do-while-to-while.js.map +1 -0
  88. package/dist/transforms/drop-console.d.ts +27 -0
  89. package/dist/transforms/drop-console.d.ts.map +1 -0
  90. package/dist/transforms/drop-console.js +107 -0
  91. package/dist/transforms/drop-console.js.map +1 -0
  92. package/dist/transforms/drop-debugger.d.ts +18 -0
  93. package/dist/transforms/drop-debugger.d.ts.map +1 -0
  94. package/dist/transforms/drop-debugger.js +34 -0
  95. package/dist/transforms/drop-debugger.js.map +1 -0
  96. package/dist/transforms/expand-binary-assignment.d.ts +26 -0
  97. package/dist/transforms/expand-binary-assignment.d.ts.map +1 -0
  98. package/dist/transforms/expand-binary-assignment.js +78 -0
  99. package/dist/transforms/expand-binary-assignment.js.map +1 -0
  100. package/dist/transforms/expand-logical-assignment.d.ts +22 -0
  101. package/dist/transforms/expand-logical-assignment.d.ts.map +1 -0
  102. package/dist/transforms/expand-logical-assignment.js +73 -0
  103. package/dist/transforms/expand-logical-assignment.js.map +1 -0
  104. package/dist/transforms/extract-object-properties.d.ts +21 -0
  105. package/dist/transforms/extract-object-properties.d.ts.map +1 -0
  106. package/dist/transforms/extract-object-properties.js +340 -0
  107. package/dist/transforms/extract-object-properties.js.map +1 -0
  108. package/dist/transforms/fold-builtin-methods.d.ts +23 -0
  109. package/dist/transforms/fold-builtin-methods.d.ts.map +1 -0
  110. package/dist/transforms/fold-builtin-methods.js +839 -0
  111. package/dist/transforms/fold-builtin-methods.js.map +1 -0
  112. package/dist/transforms/fold-constants.d.ts +16 -0
  113. package/dist/transforms/fold-constants.d.ts.map +1 -0
  114. package/dist/transforms/fold-constants.js +421 -0
  115. package/dist/transforms/fold-constants.js.map +1 -0
  116. package/dist/transforms/for-to-while.d.ts +29 -0
  117. package/dist/transforms/for-to-while.d.ts.map +1 -0
  118. package/dist/transforms/for-to-while.js +91 -0
  119. package/dist/transforms/for-to-while.js.map +1 -0
  120. package/dist/transforms/function-declaration-to-expression.d.ts +28 -0
  121. package/dist/transforms/function-declaration-to-expression.d.ts.map +1 -0
  122. package/dist/transforms/function-declaration-to-expression.js +95 -0
  123. package/dist/transforms/function-declaration-to-expression.js.map +1 -0
  124. package/dist/transforms/inline-functions.d.ts +16 -0
  125. package/dist/transforms/inline-functions.d.ts.map +1 -0
  126. package/dist/transforms/inline-functions.js +896 -0
  127. package/dist/transforms/inline-functions.js.map +1 -0
  128. package/dist/transforms/logical-to-ternary.d.ts +20 -0
  129. package/dist/transforms/logical-to-ternary.d.ts.map +1 -0
  130. package/dist/transforms/logical-to-ternary.js +78 -0
  131. package/dist/transforms/logical-to-ternary.js.map +1 -0
  132. package/dist/transforms/mangle-properties.d.ts +27 -0
  133. package/dist/transforms/mangle-properties.d.ts.map +1 -0
  134. package/dist/transforms/mangle-properties.js +703 -0
  135. package/dist/transforms/mangle-properties.js.map +1 -0
  136. package/dist/transforms/nullish-coalescing-to-ternary.d.ts +18 -0
  137. package/dist/transforms/nullish-coalescing-to-ternary.d.ts.map +1 -0
  138. package/dist/transforms/nullish-coalescing-to-ternary.js +61 -0
  139. package/dist/transforms/nullish-coalescing-to-ternary.js.map +1 -0
  140. package/dist/transforms/numbers-to-strings.d.ts +19 -0
  141. package/dist/transforms/numbers-to-strings.d.ts.map +1 -0
  142. package/dist/transforms/numbers-to-strings.js +51 -0
  143. package/dist/transforms/numbers-to-strings.js.map +1 -0
  144. package/dist/transforms/object-method-to-property.d.ts +34 -0
  145. package/dist/transforms/object-method-to-property.d.ts.map +1 -0
  146. package/dist/transforms/object-method-to-property.js +78 -0
  147. package/dist/transforms/object-method-to-property.js.map +1 -0
  148. package/dist/transforms/optional-chaining-to-ternary.d.ts +19 -0
  149. package/dist/transforms/optional-chaining-to-ternary.d.ts.map +1 -0
  150. package/dist/transforms/optional-chaining-to-ternary.js +206 -0
  151. package/dist/transforms/optional-chaining-to-ternary.js.map +1 -0
  152. package/dist/transforms/pack-declarations-into-parameters.d.ts +22 -0
  153. package/dist/transforms/pack-declarations-into-parameters.d.ts.map +1 -0
  154. package/dist/transforms/pack-declarations-into-parameters.js +208 -0
  155. package/dist/transforms/pack-declarations-into-parameters.js.map +1 -0
  156. package/dist/transforms/remove-anonymous-function-names.d.ts +17 -0
  157. package/dist/transforms/remove-anonymous-function-names.d.ts.map +1 -0
  158. package/dist/transforms/remove-anonymous-function-names.js +72 -0
  159. package/dist/transforms/remove-anonymous-function-names.js.map +1 -0
  160. package/dist/transforms/remove-unreachable-code.d.ts +21 -0
  161. package/dist/transforms/remove-unreachable-code.d.ts.map +1 -0
  162. package/dist/transforms/remove-unreachable-code.js +103 -0
  163. package/dist/transforms/remove-unreachable-code.js.map +1 -0
  164. package/dist/transforms/remove-unused-code.d.ts +18 -0
  165. package/dist/transforms/remove-unused-code.d.ts.map +1 -0
  166. package/dist/transforms/remove-unused-code.js +249 -0
  167. package/dist/transforms/remove-unused-code.js.map +1 -0
  168. package/dist/transforms/rename-identifiers.d.ts +24 -0
  169. package/dist/transforms/rename-identifiers.d.ts.map +1 -0
  170. package/dist/transforms/rename-identifiers.js +264 -0
  171. package/dist/transforms/rename-identifiers.js.map +1 -0
  172. package/dist/transforms/specials-to-strings.d.ts +30 -0
  173. package/dist/transforms/specials-to-strings.d.ts.map +1 -0
  174. package/dist/transforms/specials-to-strings.js +101 -0
  175. package/dist/transforms/specials-to-strings.js.map +1 -0
  176. package/dist/transforms/switch-to-if.d.ts +28 -0
  177. package/dist/transforms/switch-to-if.d.ts.map +1 -0
  178. package/dist/transforms/switch-to-if.js +279 -0
  179. package/dist/transforms/switch-to-if.js.map +1 -0
  180. package/dist/transforms/ternary-to-if.d.ts +20 -0
  181. package/dist/transforms/ternary-to-if.d.ts.map +1 -0
  182. package/dist/transforms/ternary-to-if.js +315 -0
  183. package/dist/transforms/ternary-to-if.js.map +1 -0
  184. package/dist/transforms/update-to-assignment.d.ts +26 -0
  185. package/dist/transforms/update-to-assignment.d.ts.map +1 -0
  186. package/dist/transforms/update-to-assignment.js +120 -0
  187. package/dist/transforms/update-to-assignment.js.map +1 -0
  188. package/dist/transforms/yodify-conditions.d.ts +22 -0
  189. package/dist/transforms/yodify-conditions.d.ts.map +1 -0
  190. package/dist/transforms/yodify-conditions.js +91 -0
  191. package/dist/transforms/yodify-conditions.js.map +1 -0
  192. package/dist/utils/ast.d.ts +10 -0
  193. package/dist/utils/ast.d.ts.map +1 -0
  194. package/dist/utils/ast.js +112 -0
  195. package/dist/utils/ast.js.map +1 -0
  196. package/dist/utils/change-tracking.d.ts +8 -0
  197. package/dist/utils/change-tracking.d.ts.map +1 -0
  198. package/dist/utils/change-tracking.js +8 -0
  199. package/dist/utils/change-tracking.js.map +1 -0
  200. package/dist/utils/dom-properties.d.ts +2 -0
  201. package/dist/utils/dom-properties.d.ts.map +1 -0
  202. package/dist/utils/dom-properties.js +9252 -0
  203. package/dist/utils/dom-properties.js.map +1 -0
  204. package/dist/utils/evaluation-order.d.ts +4 -0
  205. package/dist/utils/evaluation-order.d.ts.map +1 -0
  206. package/dist/utils/evaluation-order.js +152 -0
  207. package/dist/utils/evaluation-order.js.map +1 -0
  208. package/dist/utils/literal.d.ts +5 -0
  209. package/dist/utils/literal.d.ts.map +1 -0
  210. package/dist/utils/literal.js +90 -0
  211. package/dist/utils/literal.js.map +1 -0
  212. package/dist/utils/logical-lowering.d.ts +4 -0
  213. package/dist/utils/logical-lowering.d.ts.map +1 -0
  214. package/dist/utils/logical-lowering.js +104 -0
  215. package/dist/utils/logical-lowering.js.map +1 -0
  216. package/dist/utils/loop-lowering.d.ts +23 -0
  217. package/dist/utils/loop-lowering.d.ts.map +1 -0
  218. package/dist/utils/loop-lowering.js +88 -0
  219. package/dist/utils/loop-lowering.js.map +1 -0
  220. package/dist/utils/paths.d.ts +9 -0
  221. package/dist/utils/paths.d.ts.map +1 -0
  222. package/dist/utils/paths.js +90 -0
  223. package/dist/utils/paths.js.map +1 -0
  224. package/dist/utils/random.d.ts +3 -0
  225. package/dist/utils/random.d.ts.map +1 -0
  226. package/dist/utils/random.js +22 -0
  227. package/dist/utils/random.js.map +1 -0
  228. package/dist/utils/string-generator.d.ts +37 -0
  229. package/dist/utils/string-generator.d.ts.map +1 -0
  230. package/dist/utils/string-generator.js +175 -0
  231. package/dist/utils/string-generator.js.map +1 -0
  232. package/package.json +76 -0
  233. package/src/analysis/constant.ts +310 -0
  234. package/src/analysis/document-order.ts +141 -0
  235. package/src/analysis/inlineability.ts +336 -0
  236. package/src/analysis/purity.ts +315 -0
  237. package/src/index.ts +2 -0
  238. package/src/obfuscator.ts +271 -0
  239. package/src/options.ts +114 -0
  240. package/src/preparation/dot-to-bracket.ts +41 -0
  241. package/src/preparation/expand-destructuring.ts +211 -0
  242. package/src/preparation/expand-template-literals.ts +92 -0
  243. package/src/preparation/rewrite-class-fields.ts +320 -0
  244. package/src/preparation/split-sequence-expressions.ts +40 -0
  245. package/src/preparation/split-variable-declarations.ts +39 -0
  246. package/src/preparation/stringify-object-keys.ts +107 -0
  247. package/src/preparation/wrap-single-statements.ts +63 -0
  248. package/src/transforms/arguments-to-parameters.ts +187 -0
  249. package/src/transforms/arrow-to-function.ts +225 -0
  250. package/src/transforms/collapse-single-use-temps.ts +957 -0
  251. package/src/transforms/const-let-to-var.ts +246 -0
  252. package/src/transforms/const-to-let.ts +38 -0
  253. package/src/transforms/do-while-to-while.ts +69 -0
  254. package/src/transforms/drop-console.ts +119 -0
  255. package/src/transforms/drop-debugger.ts +38 -0
  256. package/src/transforms/expand-binary-assignment.ts +94 -0
  257. package/src/transforms/expand-logical-assignment.ts +84 -0
  258. package/src/transforms/extract-object-properties.ts +404 -0
  259. package/src/transforms/fold-builtin-methods.ts +949 -0
  260. package/src/transforms/fold-constants.ts +462 -0
  261. package/src/transforms/for-to-while.ts +109 -0
  262. package/src/transforms/function-declaration-to-expression.ts +108 -0
  263. package/src/transforms/inline-functions.ts +1074 -0
  264. package/src/transforms/logical-to-ternary.ts +92 -0
  265. package/src/transforms/mangle-properties.ts +819 -0
  266. package/src/transforms/nullish-coalescing-to-ternary.ts +77 -0
  267. package/src/transforms/numbers-to-strings.ts +61 -0
  268. package/src/transforms/object-method-to-property.ts +86 -0
  269. package/src/transforms/optional-chaining-to-ternary.ts +225 -0
  270. package/src/transforms/pack-declarations-into-parameters.ts +233 -0
  271. package/src/transforms/remove-anonymous-function-names.ts +84 -0
  272. package/src/transforms/remove-unreachable-code.ts +115 -0
  273. package/src/transforms/remove-unused-code.ts +296 -0
  274. package/src/transforms/rename-identifiers.ts +289 -0
  275. package/src/transforms/specials-to-strings.ts +116 -0
  276. package/src/transforms/switch-to-if.ts +339 -0
  277. package/src/transforms/ternary-to-if.ts +387 -0
  278. package/src/transforms/update-to-assignment.ts +132 -0
  279. package/src/transforms/yodify-conditions.ts +103 -0
  280. package/src/utils/ast.ts +129 -0
  281. package/src/utils/change-tracking.ts +15 -0
  282. package/src/utils/dom-properties.ts +9252 -0
  283. package/src/utils/evaluation-order.ts +178 -0
  284. package/src/utils/literal.ts +96 -0
  285. package/src/utils/logical-lowering.ts +132 -0
  286. package/src/utils/loop-lowering.ts +109 -0
  287. package/src/utils/paths.ts +103 -0
  288. package/src/utils/random.ts +22 -0
  289. package/src/utils/string-generator.ts +206 -0
@@ -0,0 +1,101 @@
1
+ import traverse from '@babel/traverse';
2
+ import * as t from '@babel/types';
3
+ import { enclosingScopeHasDirectEval, isInsideWith } from '../utils/ast.js';
4
+ import { mulberry32 } from '../utils/random.js';
5
+ import { StringGenerator } from '../utils/string-generator.js';
6
+ /**
7
+ * Rewrites five constant-like values through strings for later string mangling:
8
+ *
9
+ * - `true` -> `!!"<random>"`
10
+ * - `false` -> `!"<random>"`
11
+ * - `NaN` -> `+"<random>"`
12
+ * - `undefined`-> `void "<random>"`
13
+ * - `Infinity` -> `1/!"<random>"`
14
+ *
15
+ * Generated strings are nonempty and nonnumeric, fixing their truthiness and
16
+ * numeric coercion.
17
+ *
18
+ * `NaN`, `Infinity`, and `undefined` require genuine global reads. Delete and
19
+ * write positions stay unchanged because the replacement is not a reference.
20
+ *
21
+ * @example
22
+ * // ◀️ before
23
+ * if (x === undefined) return NaN;
24
+ * var lim = !done ? Infinity : 0;
25
+ * var flag = !x ? true : false;
26
+ *
27
+ * // ▶️ after
28
+ * if (x === void "ab") return +"cd";
29
+ * var lim = !done ? 1 / !"ef" : 0;
30
+ * var flag = !x ? !!"gh" : !"ij";
31
+ */
32
+ export function specialsToStrings(ast, ctx) {
33
+ const state = {
34
+ changed: false,
35
+ generator: new StringGenerator(ctx.stringGeneratorMode, mulberry32(ctx.seed)),
36
+ };
37
+ traverse(ast, visitor, undefined, state);
38
+ return state.changed;
39
+ }
40
+ const GLOBAL_SPECIALS = new Set(['NaN', 'Infinity', 'undefined']);
41
+ const visitor = {
42
+ BooleanLiteral(path, state) {
43
+ const str = t.stringLiteral(state.generator.next());
44
+ const negated = t.unaryExpression('!', str);
45
+ path.replaceWith(path.node.value ? t.unaryExpression('!', negated) : negated);
46
+ path.skip();
47
+ state.changed = true;
48
+ },
49
+ Identifier(path, state) {
50
+ const { name } = path.node;
51
+ if (!GLOBAL_SPECIALS.has(name)) {
52
+ return;
53
+ }
54
+ if (!path.isReferencedIdentifier()) {
55
+ return;
56
+ }
57
+ if (path.scope.getBinding(name)) {
58
+ return;
59
+ }
60
+ // Replacements are not write targets. `with` and eval can also shadow globals.
61
+ if (isWriteTarget(path) || isInsideWith(path) || enclosingScopeHasDirectEval(path)) {
62
+ return;
63
+ }
64
+ const str = t.stringLiteral(state.generator.next());
65
+ path.replaceWith(buildGlobalReplacement(name, str));
66
+ path.skip();
67
+ state.changed = true;
68
+ },
69
+ };
70
+ function buildGlobalReplacement(name, str) {
71
+ if (name === 'undefined') {
72
+ return t.unaryExpression('void', str);
73
+ }
74
+ if (name === 'NaN') {
75
+ return t.unaryExpression('+', str);
76
+ }
77
+ return t.binaryExpression('/', t.numericLiteral(1), t.unaryExpression('!', str));
78
+ }
79
+ // Babel calls update and iterator targets references, but replacements there
80
+ // would not be assignable. Delete also distinguishes references from values.
81
+ function isWriteTarget(path) {
82
+ const { parentPath } = path;
83
+ if (!parentPath) {
84
+ return false;
85
+ }
86
+ if (parentPath.isUpdateExpression({ argument: path.node })) {
87
+ return true;
88
+ }
89
+ if (parentPath.isAssignmentExpression({ left: path.node })) {
90
+ return true;
91
+ }
92
+ if (parentPath.isUnaryExpression({ argument: path.node, operator: 'delete' })) {
93
+ return true;
94
+ }
95
+ if ((parentPath.isForInStatement() || parentPath.isForOfStatement()) &&
96
+ parentPath.node.left === path.node) {
97
+ return true;
98
+ }
99
+ return false;
100
+ }
101
+ //# sourceMappingURL=specials-to-strings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specials-to-strings.js","sourceRoot":"","sources":["../../src/transforms/specials-to-strings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { File } from '@babel/types';
2
+ /**
3
+ * Lowers `switch` to an `if` chain or, when cases fall through, a labeled block
4
+ * with a fallthrough flag. Case tests keep source order and evaluation count.
5
+ * Cases with lexical or function declarations stay unchanged because separate
6
+ * `if` blocks cannot preserve the shared switch scope.
7
+ *
8
+ * @example
9
+ * // ◀️ before
10
+ * switch (x) {
11
+ * case 1: a(); break;
12
+ * case 2: b();
13
+ * case 3: c(); break;
14
+ * default: d();
15
+ * }
16
+ *
17
+ * // ▶️ after
18
+ * _switch: {
19
+ * var _switchValue = x;
20
+ * var _switchFall = false;
21
+ * if (_switchFall || _switchValue === 1) { _switchFall = true; a(); break _switch; }
22
+ * if (_switchFall || _switchValue === 2) { _switchFall = true; b(); }
23
+ * if (_switchFall || _switchValue === 3) { _switchFall = true; c(); break _switch; }
24
+ * d();
25
+ * }
26
+ */
27
+ export declare function switchToIf(ast: File): boolean;
28
+ //# sourceMappingURL=switch-to-if.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switch-to-if.d.ts","sourceRoot":"","sources":["../../src/transforms/switch-to-if.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAQxC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAE7C"}
@@ -0,0 +1,279 @@
1
+ import * as t from '@babel/types';
2
+ import { isPure } from '../analysis/purity.js';
3
+ import { traverseForChanges } from '../utils/change-tracking.js';
4
+ import { isPrimitiveLiteral } from '../utils/literal.js';
5
+ import { generateLoopLabel } from '../utils/loop-lowering.js';
6
+ /**
7
+ * Lowers `switch` to an `if` chain or, when cases fall through, a labeled block
8
+ * with a fallthrough flag. Case tests keep source order and evaluation count.
9
+ * Cases with lexical or function declarations stay unchanged because separate
10
+ * `if` blocks cannot preserve the shared switch scope.
11
+ *
12
+ * @example
13
+ * // ◀️ before
14
+ * switch (x) {
15
+ * case 1: a(); break;
16
+ * case 2: b();
17
+ * case 3: c(); break;
18
+ * default: d();
19
+ * }
20
+ *
21
+ * // ▶️ after
22
+ * _switch: {
23
+ * var _switchValue = x;
24
+ * var _switchFall = false;
25
+ * if (_switchFall || _switchValue === 1) { _switchFall = true; a(); break _switch; }
26
+ * if (_switchFall || _switchValue === 2) { _switchFall = true; b(); }
27
+ * if (_switchFall || _switchValue === 3) { _switchFall = true; c(); break _switch; }
28
+ * d();
29
+ * }
30
+ */
31
+ export function switchToIf(ast) {
32
+ return traverseForChanges(ast, visitor);
33
+ }
34
+ const visitor = {
35
+ SwitchStatement(path, state) {
36
+ if (transformSwitch(path)) {
37
+ state.changed = true;
38
+ }
39
+ },
40
+ };
41
+ function transformSwitch(path) {
42
+ const { node } = path;
43
+ // Separate `if` blocks cannot preserve cross-case lexical scope or Annex B
44
+ // function hoisting.
45
+ if (hasBlockScopedDeclaration(node)) {
46
+ return false;
47
+ }
48
+ if (canLowerToIfElseChain(node)) {
49
+ lowerToIfElseChain(path);
50
+ return true;
51
+ }
52
+ if (!labeledLoweringIsSafe(node, path.scope, path)) {
53
+ return false;
54
+ }
55
+ lowerToLabeledBlock(path);
56
+ return true;
57
+ }
58
+ function hasBlockScopedDeclaration(node) {
59
+ for (const caseClause of node.cases) {
60
+ for (const stmt of caseClause.consequent) {
61
+ if ((t.isVariableDeclaration(stmt) && stmt.kind !== 'var') ||
62
+ t.isClassDeclaration(stmt) ||
63
+ t.isFunctionDeclaration(stmt) ||
64
+ isLabeledFunctionDeclaration(stmt)) {
65
+ return true;
66
+ }
67
+ }
68
+ }
69
+ return false;
70
+ }
71
+ // Babel hides an Annex B.3.4 labeled function under LabeledStatement wrappers.
72
+ function isLabeledFunctionDeclaration(stmt) {
73
+ let current = stmt;
74
+ while (t.isLabeledStatement(current)) {
75
+ current = current.body;
76
+ }
77
+ return t.isFunctionDeclaration(current);
78
+ }
79
+ // A non-final default needs match results from later cases. Precomputing that
80
+ // result rereads tests, so every test must be pure in this shape.
81
+ function labeledLoweringIsSafe(node, scope, referencePath) {
82
+ const defaultIndex = node.cases.findIndex((caseClause) => caseClause.test === null);
83
+ if (defaultIndex === -1 || defaultIndex === node.cases.length - 1) {
84
+ return true;
85
+ }
86
+ return node.cases.every((caseClause) => caseClause.test == null || isPure(caseClause.test, scope, referencePath));
87
+ }
88
+ function canLowerToIfElseChain(node) {
89
+ for (let i = 0; i < node.cases.length; i++) {
90
+ if (!caseEligibleForIfElseChain(node.cases[i], i === node.cases.length - 1)) {
91
+ return false;
92
+ }
93
+ }
94
+ return true;
95
+ }
96
+ function caseEligibleForIfElseChain(caseClause, isLast) {
97
+ const { consequent } = caseClause;
98
+ if (consequent.length === 0) {
99
+ return isLast;
100
+ }
101
+ const last = consequent.at(-1);
102
+ const terminates = isCaseTerminator(last);
103
+ if (!terminates && !isLast) {
104
+ return false;
105
+ }
106
+ for (let i = 0; i < consequent.length - 1; i++) {
107
+ if (containsTopLevelUnlabeledBreak(consequent[i])) {
108
+ return false;
109
+ }
110
+ }
111
+ if (!(t.isBreakStatement(last) && !last.label) && containsTopLevelUnlabeledBreak(last)) {
112
+ return false;
113
+ }
114
+ return true;
115
+ }
116
+ function isCaseTerminator(stmt) {
117
+ if (t.isReturnStatement(stmt) || t.isThrowStatement(stmt)) {
118
+ return true;
119
+ }
120
+ if (t.isBreakStatement(stmt) || t.isContinueStatement(stmt)) {
121
+ return true;
122
+ }
123
+ return false;
124
+ }
125
+ function containsTopLevelUnlabeledBreak(node) {
126
+ if (t.isBreakStatement(node) && !node.label) {
127
+ return true;
128
+ }
129
+ if (t.isFunction(node) || t.isLoop(node) || t.isSwitchStatement(node)) {
130
+ return false;
131
+ }
132
+ const keys = t.VISITOR_KEYS[node.type];
133
+ if (!keys) {
134
+ return false;
135
+ }
136
+ for (const key of keys) {
137
+ const child = node[key];
138
+ if (Array.isArray(child)) {
139
+ for (const entry of child) {
140
+ if (entry &&
141
+ typeof entry.type === 'string' &&
142
+ containsTopLevelUnlabeledBreak(entry)) {
143
+ return true;
144
+ }
145
+ }
146
+ }
147
+ else if (child &&
148
+ typeof child.type === 'string' &&
149
+ containsTopLevelUnlabeledBreak(child)) {
150
+ return true;
151
+ }
152
+ }
153
+ return false;
154
+ }
155
+ // Declaration-bearing cases were refused, leaving only a trailing break to drop.
156
+ function buildBody(consequent) {
157
+ const body = [...consequent];
158
+ const last = body.at(-1);
159
+ if (last && t.isBreakStatement(last) && !last.label) {
160
+ body.pop();
161
+ }
162
+ return t.blockStatement(body);
163
+ }
164
+ function lowerToIfElseChain(path) {
165
+ const { node } = path;
166
+ const { scope } = path;
167
+ let discriminantExpr;
168
+ const preStmts = [];
169
+ if (isPrimitiveLiteral(node.discriminant)) {
170
+ discriminantExpr = node.discriminant;
171
+ }
172
+ else {
173
+ const valueName = scope.generateUid('switchValue');
174
+ discriminantExpr = t.identifier(valueName);
175
+ preStmts.push(t.variableDeclaration('var', [
176
+ t.variableDeclarator(t.identifier(valueName), node.discriminant),
177
+ ]));
178
+ }
179
+ const nonDefaultCases = node.cases.filter((caseClause) => caseClause.test !== null);
180
+ const defaultCase = node.cases.find((caseClause) => caseClause.test === null);
181
+ let chain = null;
182
+ if (defaultCase) {
183
+ const defaultBody = buildBody(defaultCase.consequent);
184
+ if (defaultBody.body.length > 0) {
185
+ chain = defaultBody;
186
+ }
187
+ }
188
+ for (let i = nonDefaultCases.length - 1; i >= 0; i--) {
189
+ const caseClause = nonDefaultCases[i];
190
+ const test = t.binaryExpression('===', t.cloneNode(discriminantExpr), caseClause.test);
191
+ chain = t.ifStatement(test, buildBody(caseClause.consequent), chain ?? undefined);
192
+ }
193
+ const replacement = [...preStmts];
194
+ if (chain) {
195
+ replacement.push(chain);
196
+ }
197
+ if (replacement.length === 0) {
198
+ path.remove();
199
+ return;
200
+ }
201
+ if (replacement.length === 1) {
202
+ path.replaceWith(replacement[0]);
203
+ return;
204
+ }
205
+ // Wrap single-statement slots so replacement cannot drop an enclosing label.
206
+ if (typeof path.listKey === 'string') {
207
+ path.replaceWithMultiple(replacement);
208
+ return;
209
+ }
210
+ path.replaceWith(t.blockStatement(replacement));
211
+ }
212
+ function lowerToLabeledBlock(path) {
213
+ const { node } = path;
214
+ const { scope } = path;
215
+ // `scope.generateUid` alone can collide with enclosing or nested labels.
216
+ const labelName = generateLoopLabel(path, 'switch');
217
+ const valueName = scope.generateUid('switchValue');
218
+ const fallName = scope.generateUid('switchFall');
219
+ const defaultIndex = node.cases.findIndex((caseClause) => caseClause.test === null);
220
+ const defaultIsLast = defaultIndex === node.cases.length - 1;
221
+ const statements = [
222
+ t.variableDeclaration('var', [
223
+ t.variableDeclarator(t.identifier(valueName), node.discriminant),
224
+ ]),
225
+ t.variableDeclaration('var', [
226
+ t.variableDeclarator(t.identifier(fallName), t.booleanLiteral(false)),
227
+ ]),
228
+ ];
229
+ // `_switchDefault` records whether any case matches while the default body
230
+ // remains in source order. Safety checks already proved rereads pure.
231
+ let defaultName = null;
232
+ if (defaultIndex !== -1 && !defaultIsLast) {
233
+ defaultName = scope.generateUid('switchDefault');
234
+ const nonDefaultTests = node.cases
235
+ .map((caseClause) => caseClause.test)
236
+ .filter((test) => test !== null);
237
+ const anyMatch = nonDefaultTests
238
+ .map((test) => t.binaryExpression('===', t.identifier(valueName), t.cloneNode(test)))
239
+ .reduce((acc, expr, i) => (i === 0 ? expr : t.logicalExpression('||', acc, expr)), t.booleanLiteral(false));
240
+ statements.push(t.variableDeclaration('var', [
241
+ t.variableDeclarator(t.identifier(defaultName), t.unaryExpression('!', anyMatch)),
242
+ ]));
243
+ }
244
+ for (const caseClause of node.cases) {
245
+ const isDefault = caseClause.test === null;
246
+ // A final default always runs once control reaches it, with nothing after it.
247
+ if (isDefault && defaultIsLast) {
248
+ statements.push(...caseClause.consequent);
249
+ continue;
250
+ }
251
+ const condition = isDefault
252
+ ? t.logicalExpression('||', t.identifier(fallName), t.identifier(defaultName))
253
+ : t.logicalExpression('||', t.identifier(fallName), t.binaryExpression('===', t.identifier(valueName), caseClause.test));
254
+ const body = [
255
+ t.expressionStatement(t.assignmentExpression('=', t.identifier(fallName), t.booleanLiteral(true))),
256
+ ...caseClause.consequent,
257
+ ];
258
+ statements.push(t.ifStatement(condition, t.blockStatement(body)));
259
+ }
260
+ const labeledBlock = t.labeledStatement(t.identifier(labelName), t.blockStatement(statements));
261
+ const [labeledPath] = path.replaceWith(labeledBlock);
262
+ rewriteUnlabeledBreaks(labeledPath, labelName);
263
+ }
264
+ function rewriteUnlabeledBreaks(path, labelName) {
265
+ path.traverse(rewriteBreaksVisitor, { labelName });
266
+ }
267
+ const rewriteBreaksVisitor = {
268
+ BreakStatement(path, state) {
269
+ if (path.node.label) {
270
+ return;
271
+ }
272
+ path.node.label = t.identifier(state.labelName);
273
+ },
274
+ 'Function|Loop|SwitchStatement'(path) {
275
+ ;
276
+ path.skip();
277
+ },
278
+ };
279
+ //# sourceMappingURL=switch-to-if.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switch-to-if.js","sourceRoot":"","sources":["../../src/transforms/switch-to-if.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,cAAc,CAAA;AAGjC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAE9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,UAAU,CAAC,GAAS;IAClC,OAAO,kBAAkB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;AACzC,CAAC;AAED,MAAM,OAAO,GAAyB;IACpC,eAAe,CAAC,IAAI,EAAE,KAAK;QACzB,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,KAAK,CAAC,OAAO,GAAG,IAAI,CAAA;QACtB,CAAC;IACH,CAAC;CACF,CAAA;AAED,SAAS,eAAe,CAAC,IAAiC;IACxD,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAA;IACrB,2EAA2E;IAC3E,qBAAqB;IACrB,IAAI,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,kBAAkB,CAAC,IAAI,CAAC,CAAA;QACxB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,KAAK,CAAA;IACd,CAAC;IACD,mBAAmB,CAAC,IAAI,CAAC,CAAA;IACzB,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,yBAAyB,CAAC,IAAuB;IACxD,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACpC,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;YACzC,IACE,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC;gBACtD,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC;gBAC1B,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC;gBAC7B,4BAA4B,CAAC,IAAI,CAAC,EAClC,CAAC;gBACD,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,+EAA+E;AAC/E,SAAS,4BAA4B,CAAC,IAAiB;IACrD,IAAI,OAAO,GAAgB,IAAI,CAAA;IAC/B,OAAO,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAA;IACxB,CAAC;IACD,OAAO,CAAC,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAA;AACzC,CAAC;AAED,8EAA8E;AAC9E,kEAAkE;AAClE,SAAS,qBAAqB,CAC5B,IAAuB,EACvB,KAAY,EACZ,aAAuB;IAEvB,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;IACnF,IAAI,YAAY,KAAK,CAAC,CAAC,IAAI,YAAY,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClE,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CACrB,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,aAAa,CAAC,CACzF,CAAA;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAuB;IACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;YAC7E,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,0BAA0B,CAAC,UAAwB,EAAE,MAAe;IAC3E,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,CAAA;IACjC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAA;IACf,CAAC;IACD,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAA;IAC/B,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACzC,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,IAAI,8BAA8B,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;YACnD,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IACD,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,8BAA8B,CAAC,IAAI,CAAC,EAAE,CAAC;QACvF,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAiB;IACzC,IAAI,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1D,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5D,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,8BAA8B,CAAC,IAAY;IAClD,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;QACtE,OAAO,KAAK,CAAA;IACd,CAAC;IACD,MAAM,IAAI,GAAI,CAAC,CAAC,YAAyC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACpE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,KAAK,CAAA;IACd,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAI,IAA2C,CAAC,GAAG,CAAC,CAAA;QAC/D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;gBAC1B,IACE,KAAK;oBACL,OAAQ,KAAgB,CAAC,IAAI,KAAK,QAAQ;oBAC1C,8BAA8B,CAAC,KAAe,CAAC,EAC/C,CAAC;oBACD,OAAO,IAAI,CAAA;gBACb,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IACL,KAAK;YACL,OAAQ,KAAgB,CAAC,IAAI,KAAK,QAAQ;YAC1C,8BAA8B,CAAC,KAAe,CAAC,EAC/C,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,iFAAiF;AACjF,SAAS,SAAS,CAAC,UAAyB;IAC1C,MAAM,IAAI,GAAG,CAAC,GAAG,UAAU,CAAC,CAAA;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACxB,IAAI,IAAI,IAAI,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACpD,IAAI,CAAC,GAAG,EAAE,CAAA;IACZ,CAAC;IACD,OAAO,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;AAC/B,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAiC;IAC3D,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;IAEtB,IAAI,gBAA8B,CAAA;IAClC,MAAM,QAAQ,GAAkB,EAAE,CAAA;IAClC,IAAI,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1C,gBAAgB,GAAG,IAAI,CAAC,YAAY,CAAA;IACtC,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,CAAA;QAClD,gBAAgB,GAAG,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;QAC1C,QAAQ,CAAC,IAAI,CACX,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE;YAC3B,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC;SACjE,CAAC,CACH,CAAA;IACH,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;IACnF,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;IAE7E,IAAI,KAAK,GAAuB,IAAI,CAAA;IACpC,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC,UAAU,CAAC,CAAA;QACrD,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,KAAK,GAAG,WAAW,CAAA;QACrB,CAAC;IACH,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACrD,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAE,CAAA;QACtC,MAAM,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAAE,UAAU,CAAC,IAAK,CAAC,CAAA;QACvF,KAAK,GAAG,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,KAAK,IAAI,SAAS,CAAC,CAAA;IACnF,CAAC;IAED,MAAM,WAAW,GAAkB,CAAC,GAAG,QAAQ,CAAC,CAAA;IAChD,IAAI,KAAK,EAAE,CAAC;QACV,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACzB,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,EAAE,CAAA;QACb,OAAM;IACR,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,CAAA;QACjC,OAAM;IACR,CAAC;IACD,6EAA6E;IAC7E,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACrC,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAA;QACrC,OAAM;IACR,CAAC;IACD,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAA;AACjD,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAiC;IAC5D,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;IAEtB,yEAAyE;IACzE,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IACnD,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,CAAA;IAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,CAAA;IAEhD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;IACnF,MAAM,aAAa,GAAG,YAAY,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;IAE5D,MAAM,UAAU,GAAkB;QAChC,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE;YAC3B,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC;SACjE,CAAC;QACF,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE;YAC3B,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;SACtE,CAAC;KACH,CAAA;IAED,2EAA2E;IAC3E,sEAAsE;IACtE,IAAI,WAAW,GAAkB,IAAI,CAAA;IACrC,IAAI,YAAY,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC1C,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,eAAe,CAAC,CAAA;QAChD,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK;aAC/B,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;aACpC,MAAM,CAAC,CAAC,IAAI,EAAwB,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;QACxD,MAAM,QAAQ,GAAiB,eAAe;aAC3C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;aACpF,MAAM,CACL,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,EACzE,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CACxB,CAAA;QACH,UAAU,CAAC,IAAI,CACb,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE;YAC3B,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;SAClF,CAAC,CACH,CAAA;IACH,CAAC;IAED,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,KAAK,IAAI,CAAA;QAE1C,8EAA8E;QAC9E,IAAI,SAAS,IAAI,aAAa,EAAE,CAAC;YAC/B,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;YACzC,SAAQ;QACV,CAAC;QAED,MAAM,SAAS,GAAiB,SAAS;YACvC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,WAAY,CAAC,CAAC;YAC/E,CAAC,CAAC,CAAC,CAAC,iBAAiB,CACjB,IAAI,EACJ,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EACtB,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,IAAoB,CAAC,CACpF,CAAA;QAEL,MAAM,IAAI,GAAkB;YAC1B,CAAC,CAAC,mBAAmB,CACnB,CAAC,CAAC,oBAAoB,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAC5E;YACD,GAAG,UAAU,CAAC,UAAU;SACzB,CAAA;QAED,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnE,CAAC;IAED,MAAM,YAAY,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAA;IAE9F,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAA;IACpD,sBAAsB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;AAChD,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAsB,EAAE,SAAiB;IACvE,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;AACpD,CAAC;AAMD,MAAM,oBAAoB,GAAgC;IACxD,cAAc,CAAC,IAAI,EAAE,KAAK;QACxB,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACjD,CAAC;IACD,+BAA+B,CAAC,IAAI;QAClC,CAAC;QAAC,IAAiB,CAAC,IAAI,EAAE,CAAA;IAC5B,CAAC;CACF,CAAA"}
@@ -0,0 +1,20 @@
1
+ import type { File } from '@babel/types';
2
+ /**
3
+ * Lowers conditional expressions to `if` statements. Expression values use a
4
+ * temporary. Parameter defaults and repeating loop tests stay unchanged because
5
+ * hoisting would change when they run.
6
+ *
7
+ * @example
8
+ * // ◀️ before
9
+ * var y = a ? b : c;
10
+ * log(d ? e : f);
11
+ *
12
+ * // ▶️ after
13
+ * var y;
14
+ * if (a) { y = b; } else { y = c; }
15
+ * var _ternaryResult;
16
+ * if (d) { _ternaryResult = e; } else { _ternaryResult = f; }
17
+ * log(_ternaryResult);
18
+ */
19
+ export declare function ternaryToIf(ast: File): boolean;
20
+ //# sourceMappingURL=ternary-to-if.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ternary-to-if.d.ts","sourceRoot":"","sources":["../../src/transforms/ternary-to-if.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAQxC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAM9C"}