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,839 @@
1
+ import traverse from '@babel/traverse';
2
+ import * as t from '@babel/types';
3
+ import { evaluateConstant, isOpaque } from '../analysis/constant.js';
4
+ import { enclosingScopeHasDirectEval, isInDirectivePrologue, isInsideWith } from '../utils/ast.js';
5
+ import { valueToLiteral } from '../utils/literal.js';
6
+ /**
7
+ * Replaces built-in calls and reads with smaller syntax or host-computed
8
+ * constants. Host evaluation requires known arguments and receivers. Shadowed
9
+ * names, optional forms, and regexp methods stay unchanged.
10
+ *
11
+ * @example
12
+ * // ◀️ before
13
+ * Math.pow(2, 3);
14
+ * Array.of(1, 2, 3);
15
+ * "abc".toUpperCase();
16
+ * Math.PI;
17
+ * parseInt("0x1F", 16);
18
+ *
19
+ * // ▶️ after
20
+ * 8;
21
+ * [1, 2, 3];
22
+ * "ABC";
23
+ * 3.141592653589793;
24
+ * 31;
25
+ */
26
+ export function foldBuiltinMethods(ast) {
27
+ const state = { changed: false, patchedRoots: collectPatchedIntrinsics(ast) };
28
+ traverse(ast, visitor, undefined, state);
29
+ return state.changed;
30
+ }
31
+ // A written intrinsic root may no longer match the host used for folding.
32
+ const INTRINSIC_ROOTS = new Set([
33
+ 'Math',
34
+ 'String',
35
+ 'Number',
36
+ 'Array',
37
+ 'Boolean',
38
+ 'BigInt',
39
+ 'Object',
40
+ 'Reflect',
41
+ 'parseInt',
42
+ 'parseFloat',
43
+ 'isNaN',
44
+ 'isFinite',
45
+ 'atob',
46
+ 'btoa',
47
+ 'encodeURI',
48
+ 'decodeURI',
49
+ 'encodeURIComponent',
50
+ 'decodeURIComponent',
51
+ ]);
52
+ // These global objects expose intrinsic roots as writable properties.
53
+ const GLOBAL_OBJECT_NAMES = new Set(['globalThis', 'window', 'self', 'global']);
54
+ function collectPatchedIntrinsics(ast) {
55
+ const poisoned = new Set();
56
+ const poison = (roots) => {
57
+ for (const root of roots) {
58
+ poisoned.add(root);
59
+ }
60
+ };
61
+ traverse(ast, {
62
+ // An alias can patch its intrinsic later, after further aliasing or calls.
63
+ VariableDeclarator(path) {
64
+ if (path.node.init && t.isIdentifier(path.node.id)) {
65
+ poison(aliasSourceRoots(path.node.init, path.scope));
66
+ }
67
+ },
68
+ AssignmentExpression(path) {
69
+ markWriteTarget(path.node.left, path.scope, poison);
70
+ if (path.node.operator === '=' && t.isIdentifier(path.node.left)) {
71
+ poison(aliasSourceRoots(path.node.right, path.scope));
72
+ }
73
+ },
74
+ UpdateExpression(path) {
75
+ markWriteTarget(path.node.argument, path.scope, poison);
76
+ },
77
+ UnaryExpression(path) {
78
+ // Deletion patches an intrinsic as surely as assignment.
79
+ if (path.node.operator === 'delete') {
80
+ markWriteTarget(path.node.argument, path.scope, poison);
81
+ }
82
+ },
83
+ ForInStatement(path) {
84
+ markWriteTarget(path.node.left, path.scope, poison);
85
+ },
86
+ ForOfStatement(path) {
87
+ markWriteTarget(path.node.left, path.scope, poison);
88
+ },
89
+ CallExpression(path) {
90
+ markMutationCall(path, poison);
91
+ },
92
+ Identifier(path) {
93
+ // Global eval and Function can patch any intrinsic outside this scan.
94
+ const { name } = path.node;
95
+ if (name !== 'eval' && name !== 'Function') {
96
+ return;
97
+ }
98
+ if (!path.isReferencedIdentifier() || path.scope.getBinding(name)) {
99
+ return;
100
+ }
101
+ if (name === 'eval') {
102
+ poison(INTRINSIC_ROOTS);
103
+ return;
104
+ }
105
+ const parent = path.parentPath;
106
+ if (parent &&
107
+ (parent.isCallExpression() || parent.isNewExpression()) &&
108
+ parent.node.callee === path.node) {
109
+ poison(INTRINSIC_ROOTS);
110
+ }
111
+ },
112
+ });
113
+ return poisoned;
114
+ }
115
+ // A global-object handle reaches every root. A local binding reaches none.
116
+ const NO_ROOTS = [];
117
+ // Destructuring writes recurse to each leaf target.
118
+ function markWriteTarget(target, scope, poison) {
119
+ if (t.isArrayPattern(target)) {
120
+ for (const element of target.elements) {
121
+ if (element) {
122
+ markWriteTarget(element, scope, poison);
123
+ }
124
+ }
125
+ return;
126
+ }
127
+ if (t.isObjectPattern(target)) {
128
+ for (const prop of target.properties) {
129
+ markWriteTarget(t.isObjectProperty(prop) ? prop.value : prop, scope, poison);
130
+ }
131
+ return;
132
+ }
133
+ if (t.isRestElement(target)) {
134
+ markWriteTarget(target.argument, scope, poison);
135
+ return;
136
+ }
137
+ if (t.isAssignmentPattern(target)) {
138
+ markWriteTarget(target.left, scope, poison);
139
+ return;
140
+ }
141
+ poison(writeTargetRoots(target, scope));
142
+ }
143
+ // Only genuine Object and Reflect bulk mutation methods count as patches.
144
+ function markMutationCall(path, poison) {
145
+ const { callee } = path.node;
146
+ // Preparation may already have changed the method to bracket syntax.
147
+ if (!t.isMemberExpression(callee) || !t.isIdentifier(callee.object)) {
148
+ return;
149
+ }
150
+ const method = staticPropertyName(callee);
151
+ if (method === null || path.scope.getBinding(callee.object.name)) {
152
+ return;
153
+ }
154
+ if (!isMutatingIntrinsicMethod(callee.object.name, method)) {
155
+ return;
156
+ }
157
+ const [firstArg] = path.node.arguments;
158
+ if (!firstArg || !t.isExpression(firstArg)) {
159
+ return;
160
+ }
161
+ poison(mutationTargetRoots(firstArg, path.scope));
162
+ }
163
+ function isMutatingIntrinsicMethod(receiver, method) {
164
+ if (receiver === 'Object') {
165
+ return (method === 'assign' ||
166
+ method === 'defineProperty' ||
167
+ method === 'defineProperties' ||
168
+ method === 'setPrototypeOf');
169
+ }
170
+ if (receiver === 'Reflect') {
171
+ return (method === 'set' ||
172
+ method === 'defineProperty' ||
173
+ method === 'deleteProperty' ||
174
+ method === 'setPrototypeOf');
175
+ }
176
+ return false;
177
+ }
178
+ // A bare write reaches an intrinsic only through a genuine global reference.
179
+ function writeTargetRoots(target, scope) {
180
+ if (t.isIdentifier(target)) {
181
+ if (scope.getBinding(target.name)) {
182
+ return NO_ROOTS;
183
+ }
184
+ return INTRINSIC_ROOTS.has(target.name) ? [target.name] : NO_ROOTS;
185
+ }
186
+ if (t.isMemberExpression(target)) {
187
+ return memberTargetRoots(target, scope);
188
+ }
189
+ return NO_ROOTS;
190
+ }
191
+ // Mutating the global object can reach every intrinsic root.
192
+ function mutationTargetRoots(target, scope) {
193
+ if (t.isIdentifier(target)) {
194
+ if (scope.getBinding(target.name)) {
195
+ return NO_ROOTS;
196
+ }
197
+ if (INTRINSIC_ROOTS.has(target.name)) {
198
+ return [target.name];
199
+ }
200
+ return GLOBAL_OBJECT_NAMES.has(target.name) ? INTRINSIC_ROOTS : NO_ROOTS;
201
+ }
202
+ if (t.isMemberExpression(target)) {
203
+ return memberTargetRoots(target, scope);
204
+ }
205
+ return NO_ROOTS;
206
+ }
207
+ function memberTargetRoots(member, scope) {
208
+ const root = memberRoot(member);
209
+ if (!root || scope.getBinding(root.name)) {
210
+ return NO_ROOTS;
211
+ }
212
+ if (INTRINSIC_ROOTS.has(root.name)) {
213
+ return [root.name];
214
+ }
215
+ if (GLOBAL_OBJECT_NAMES.has(root.name)) {
216
+ const name = staticPropertyName(innermostMember(member));
217
+ if (name === null) {
218
+ return INTRINSIC_ROOTS;
219
+ }
220
+ return INTRINSIC_ROOTS.has(name) ? [name] : NO_ROOTS;
221
+ }
222
+ return NO_ROOTS;
223
+ }
224
+ // Namespace and prototype aliases can patch roots. Method aliases cannot.
225
+ function aliasSourceRoots(value, scope) {
226
+ if (t.isIdentifier(value)) {
227
+ if (scope.getBinding(value.name)) {
228
+ return NO_ROOTS;
229
+ }
230
+ if (INTRINSIC_ROOTS.has(value.name)) {
231
+ return [value.name];
232
+ }
233
+ return GLOBAL_OBJECT_NAMES.has(value.name) ? INTRINSIC_ROOTS : NO_ROOTS;
234
+ }
235
+ if (t.isMemberExpression(value)) {
236
+ const root = memberRoot(value);
237
+ if (!root || scope.getBinding(root.name)) {
238
+ return NO_ROOTS;
239
+ }
240
+ if (INTRINSIC_ROOTS.has(root.name)) {
241
+ return staticPropertyName(value) === 'prototype' ? [root.name] : NO_ROOTS;
242
+ }
243
+ if (GLOBAL_OBJECT_NAMES.has(root.name)) {
244
+ const name = staticPropertyName(innermostMember(value));
245
+ if (name !== null && INTRINSIC_ROOTS.has(name)) {
246
+ return [name];
247
+ }
248
+ }
249
+ }
250
+ return NO_ROOTS;
251
+ }
252
+ function memberRoot(node) {
253
+ let current = node;
254
+ while (t.isMemberExpression(current)) {
255
+ current = current.object;
256
+ }
257
+ return t.isIdentifier(current) ? current : null;
258
+ }
259
+ // For `a.b.c`, `a.b` holds the property reached directly from the chain root.
260
+ function innermostMember(node) {
261
+ let current = node;
262
+ while (t.isMemberExpression(current.object)) {
263
+ current = current.object;
264
+ }
265
+ return current;
266
+ }
267
+ const visitor = {
268
+ CallExpression: {
269
+ exit(path, state) {
270
+ if (tryFoldBuiltinCall(path, state.patchedRoots)) {
271
+ state.changed = true;
272
+ }
273
+ },
274
+ },
275
+ MemberExpression: {
276
+ exit(path, state) {
277
+ if (tryFoldBuiltinMember(path, state.patchedRoots)) {
278
+ state.changed = true;
279
+ }
280
+ },
281
+ },
282
+ };
283
+ function tryFoldBuiltinCall(path, patchedRoots) {
284
+ const before = path.node;
285
+ handleCall(path, patchedRoots);
286
+ return path.node !== before || path.removed;
287
+ }
288
+ function tryFoldBuiltinMember(path, patchedRoots) {
289
+ const before = path.node;
290
+ handleMember(path, patchedRoots);
291
+ return path.node !== before || path.removed;
292
+ }
293
+ const MATH_CONSTANTS = new Map([
294
+ ['PI', Math.PI],
295
+ ['E', Math.E],
296
+ ['LN2', Math.LN2],
297
+ ['LN10', Math.LN10],
298
+ ['LOG2E', Math.LOG2E],
299
+ ['LOG10E', Math.LOG10E],
300
+ ['SQRT2', Math.SQRT2],
301
+ ['SQRT1_2', Math.SQRT1_2],
302
+ ]);
303
+ const NUMBER_CONSTANTS = new Map([
304
+ ['MAX_SAFE_INTEGER', Number.MAX_SAFE_INTEGER],
305
+ ['MIN_SAFE_INTEGER', Number.MIN_SAFE_INTEGER],
306
+ ['MAX_VALUE', Number.MAX_VALUE],
307
+ ['MIN_VALUE', Number.MIN_VALUE],
308
+ ['EPSILON', Number.EPSILON],
309
+ ]);
310
+ const MATH_FUNCTIONS = new Set([
311
+ 'abs',
312
+ 'acos',
313
+ 'acosh',
314
+ 'asin',
315
+ 'asinh',
316
+ 'atan',
317
+ 'atan2',
318
+ 'atanh',
319
+ 'cbrt',
320
+ 'ceil',
321
+ 'clz32',
322
+ 'cos',
323
+ 'cosh',
324
+ 'exp',
325
+ 'expm1',
326
+ 'floor',
327
+ 'fround',
328
+ 'hypot',
329
+ 'imul',
330
+ 'log',
331
+ 'log10',
332
+ 'log1p',
333
+ 'log2',
334
+ 'max',
335
+ 'min',
336
+ 'round',
337
+ 'sign',
338
+ 'sin',
339
+ 'sinh',
340
+ 'sqrt',
341
+ 'tan',
342
+ 'tanh',
343
+ 'trunc',
344
+ ]);
345
+ const NUMBER_NS_FUNCTIONS = new Set([
346
+ 'isNaN',
347
+ 'isFinite',
348
+ 'isInteger',
349
+ 'isSafeInteger',
350
+ 'parseInt',
351
+ 'parseFloat',
352
+ ]);
353
+ const STRING_NS_FUNCTIONS = new Set(['fromCharCode', 'fromCodePoint']);
354
+ const GLOBAL_FUNCTIONS = new Set([
355
+ 'parseInt',
356
+ 'parseFloat',
357
+ 'isNaN',
358
+ 'isFinite',
359
+ 'atob',
360
+ 'btoa',
361
+ 'encodeURI',
362
+ 'decodeURI',
363
+ 'encodeURIComponent',
364
+ 'decodeURIComponent',
365
+ ]);
366
+ const STRING_PROTOTYPE_METHODS = new Set([
367
+ 'charAt',
368
+ 'charCodeAt',
369
+ 'codePointAt',
370
+ 'toUpperCase',
371
+ 'toLowerCase',
372
+ 'slice',
373
+ 'substring',
374
+ 'substr',
375
+ 'trim',
376
+ 'trimStart',
377
+ 'trimEnd',
378
+ 'trimLeft',
379
+ 'trimRight',
380
+ 'indexOf',
381
+ 'lastIndexOf',
382
+ 'includes',
383
+ 'startsWith',
384
+ 'endsWith',
385
+ 'padStart',
386
+ 'padEnd',
387
+ 'at',
388
+ 'normalize',
389
+ 'repeat',
390
+ 'concat',
391
+ ]);
392
+ const NUMBER_PROTOTYPE_METHODS = new Set(['toString', 'toFixed', 'toExponential', 'toPrecision']);
393
+ const BOOLEAN_PROTOTYPE_METHODS = new Set(['toString']);
394
+ const BIGINT_PROTOTYPE_METHODS = new Set(['toString']);
395
+ function staticPropertyName(node) {
396
+ const prop = node.property;
397
+ if (!node.computed) {
398
+ if (t.isIdentifier(prop)) {
399
+ return prop.name;
400
+ }
401
+ return null;
402
+ }
403
+ if (t.isStringLiteral(prop)) {
404
+ return prop.value;
405
+ }
406
+ if (t.isNumericLiteral(prop)) {
407
+ return String(prop.value);
408
+ }
409
+ return null;
410
+ }
411
+ // Write targets require references. A folded literal would be invalid syntax,
412
+ // including when the member sits inside a destructuring target.
413
+ function isReferenceRequiredPosition(path) {
414
+ const { parentPath } = path;
415
+ if (!parentPath) {
416
+ return false;
417
+ }
418
+ const parent = parentPath.node;
419
+ const { node } = path;
420
+ if (t.isAssignmentExpression(parent) && parent.left === node) {
421
+ return true;
422
+ }
423
+ if (t.isUpdateExpression(parent) && parent.argument === node) {
424
+ return true;
425
+ }
426
+ if (t.isUnaryExpression(parent) && parent.operator === 'delete') {
427
+ return true;
428
+ }
429
+ if ((t.isForInStatement(parent) || t.isForOfStatement(parent)) && parent.left === node) {
430
+ return true;
431
+ }
432
+ if (t.isArrayPattern(parent)) {
433
+ return true;
434
+ }
435
+ if (t.isRestElement(parent) && parent.argument === node) {
436
+ return true;
437
+ }
438
+ if (t.isAssignmentPattern(parent) && parent.left === node) {
439
+ return true;
440
+ }
441
+ if (t.isObjectProperty(parent) && parent.value === node) {
442
+ const grandparent = parentPath.parentPath;
443
+ return grandparent != null && grandparent.isObjectPattern();
444
+ }
445
+ return false;
446
+ }
447
+ // Folding a leading call to a string can create a directive and change strictness.
448
+ function foldsIntoDirective(path, replacement) {
449
+ if (!t.isStringLiteral(replacement)) {
450
+ return false;
451
+ }
452
+ const { parentPath } = path;
453
+ return (parentPath != null && parentPath.isExpressionStatement() && isInDirectivePrologue(parentPath));
454
+ }
455
+ function handleCall(path, patchedRoots) {
456
+ // `with` and direct eval can shadow names outside Babel's scope table.
457
+ if (isInsideWith(path) || enclosingScopeHasDirectEval(path)) {
458
+ return;
459
+ }
460
+ const { callee } = path.node;
461
+ if (t.isIdentifier(callee)) {
462
+ foldGlobalCall(path, callee.name, patchedRoots);
463
+ return;
464
+ }
465
+ if (!t.isMemberExpression(callee)) {
466
+ return;
467
+ }
468
+ const propName = staticPropertyName(callee);
469
+ if (propName === null) {
470
+ return;
471
+ }
472
+ const obj = callee.object;
473
+ if (t.isSuper(obj)) {
474
+ return;
475
+ }
476
+ if (t.isIdentifier(obj)) {
477
+ foldNamespaceCall(path, obj.name, propName, patchedRoots);
478
+ if (!t.isCallExpression(path.node)) {
479
+ return;
480
+ }
481
+ }
482
+ foldReceiverCall(path, obj, propName, patchedRoots);
483
+ }
484
+ function handleMember(path, patchedRoots) {
485
+ const propName = staticPropertyName(path.node);
486
+ if (propName === null) {
487
+ return;
488
+ }
489
+ const { parent } = path;
490
+ // Calls use their own folding path.
491
+ if ((t.isCallExpression(parent) ||
492
+ t.isOptionalCallExpression(parent) ||
493
+ t.isNewExpression(parent)) &&
494
+ parent.callee === path.node) {
495
+ return;
496
+ }
497
+ if (isReferenceRequiredPosition(path)) {
498
+ return;
499
+ }
500
+ // Delay the ancestor walk until cheap shape checks pass.
501
+ if (isInsideWith(path) || enclosingScopeHasDirectEval(path)) {
502
+ return;
503
+ }
504
+ const obj = path.node.object;
505
+ if (t.isIdentifier(obj) && !path.scope.getBinding(obj.name) && !patchedRoots.has(obj.name)) {
506
+ if (obj.name === 'Math') {
507
+ const value = MATH_CONSTANTS.get(propName);
508
+ if (value !== undefined) {
509
+ const lit = valueToLiteral(value);
510
+ if (lit) {
511
+ path.replaceWith(lit);
512
+ }
513
+ }
514
+ return;
515
+ }
516
+ if (obj.name === 'Number') {
517
+ const value = NUMBER_CONSTANTS.get(propName);
518
+ if (value !== undefined) {
519
+ const lit = valueToLiteral(value);
520
+ if (lit) {
521
+ path.replaceWith(lit);
522
+ }
523
+ }
524
+ return;
525
+ }
526
+ }
527
+ if (propName === 'length') {
528
+ const recv = evaluateConstant(obj, path.scope, path);
529
+ if (recv.known && typeof recv.value === 'string') {
530
+ path.replaceWith(t.numericLiteral(recv.value.length));
531
+ }
532
+ }
533
+ }
534
+ function foldGlobalCall(path, name, patchedRoots) {
535
+ if (patchedRoots.has(name)) {
536
+ return;
537
+ }
538
+ if (name === 'Boolean') {
539
+ if (path.scope.getBinding('Boolean')) {
540
+ return;
541
+ }
542
+ foldBooleanCtor(path);
543
+ return;
544
+ }
545
+ if (name === 'String') {
546
+ if (path.scope.getBinding('String')) {
547
+ return;
548
+ }
549
+ foldStringCtor(path);
550
+ return;
551
+ }
552
+ if (name === 'Number') {
553
+ if (path.scope.getBinding('Number')) {
554
+ return;
555
+ }
556
+ foldNumberCtor(path);
557
+ return;
558
+ }
559
+ if (GLOBAL_FUNCTIONS.has(name)) {
560
+ if (path.scope.getBinding(name)) {
561
+ return;
562
+ }
563
+ const fn = globalThis[name];
564
+ if (typeof fn !== 'function') {
565
+ return;
566
+ }
567
+ foldByReflection(path, fn);
568
+ }
569
+ }
570
+ function foldNamespaceCall(path, ns, member, patchedRoots) {
571
+ if (path.scope.getBinding(ns) || patchedRoots.has(ns)) {
572
+ return;
573
+ }
574
+ if (ns === 'Math') {
575
+ if (member === 'pow') {
576
+ foldMathPow(path);
577
+ return;
578
+ }
579
+ if (MATH_FUNCTIONS.has(member)) {
580
+ foldByReflection(path, Math[member]);
581
+ }
582
+ return;
583
+ }
584
+ if (ns === 'String') {
585
+ if (STRING_NS_FUNCTIONS.has(member)) {
586
+ foldByReflection(path, String[member]);
587
+ }
588
+ return;
589
+ }
590
+ if (ns === 'Number') {
591
+ if (NUMBER_NS_FUNCTIONS.has(member)) {
592
+ foldByReflection(path, Number[member]);
593
+ }
594
+ return;
595
+ }
596
+ if (ns === 'Array') {
597
+ if (member === 'of') {
598
+ foldArrayOf(path);
599
+ return;
600
+ }
601
+ if (member === 'isArray') {
602
+ foldArrayIsArray(path);
603
+ }
604
+ }
605
+ }
606
+ function foldReceiverCall(path, receiverNode, method, patchedRoots) {
607
+ const recv = evaluateConstant(receiverNode, path.scope, path);
608
+ if (!recv.known) {
609
+ return;
610
+ }
611
+ const { value } = recv;
612
+ if (typeof value === 'string') {
613
+ if (!STRING_PROTOTYPE_METHODS.has(method) || patchedRoots.has('String')) {
614
+ return;
615
+ }
616
+ foldPrototypeCall(path, value, method);
617
+ return;
618
+ }
619
+ if (typeof value === 'number') {
620
+ if (!NUMBER_PROTOTYPE_METHODS.has(method) || patchedRoots.has('Number')) {
621
+ return;
622
+ }
623
+ foldPrototypeCall(path, value, method);
624
+ return;
625
+ }
626
+ if (typeof value === 'boolean') {
627
+ if (!BOOLEAN_PROTOTYPE_METHODS.has(method) || patchedRoots.has('Boolean')) {
628
+ return;
629
+ }
630
+ foldPrototypeCall(path, value, method);
631
+ return;
632
+ }
633
+ if (typeof value === 'bigint') {
634
+ if (!BIGINT_PROTOTYPE_METHODS.has(method) || patchedRoots.has('BigInt')) {
635
+ return;
636
+ }
637
+ foldPrototypeCall(path, value, method);
638
+ }
639
+ }
640
+ function foldMathPow(path) {
641
+ const args = path.node.arguments;
642
+ if (args.length !== 2) {
643
+ return;
644
+ }
645
+ const [left, right] = args;
646
+ if (!t.isExpression(left) || !t.isExpression(right)) {
647
+ return;
648
+ }
649
+ // `Math.pow` rejects two BigInt operands while `**` returns a BigInt. A known
650
+ // Number operand makes mixed BigInt input throw in both forms.
651
+ if (!operandIsNumber(left, path) && !operandIsNumber(right, path)) {
652
+ return;
653
+ }
654
+ path.replaceWith(t.binaryExpression('**', left, right));
655
+ }
656
+ function operandIsNumber(node, path) {
657
+ if (t.isNumericLiteral(node)) {
658
+ return true;
659
+ }
660
+ // Unary plus produces a Number or throws before exponentiation.
661
+ if (t.isUnaryExpression(node) && node.operator === '+') {
662
+ return true;
663
+ }
664
+ const evaluated = evaluateConstant(node, path.scope, path);
665
+ return evaluated.known && typeof evaluated.value === 'number';
666
+ }
667
+ function foldArrayOf(path) {
668
+ const args = path.node.arguments;
669
+ const elements = [];
670
+ for (const arg of args) {
671
+ if (t.isExpression(arg) || t.isSpreadElement(arg)) {
672
+ elements.push(arg);
673
+ continue;
674
+ }
675
+ return;
676
+ }
677
+ path.replaceWith(t.arrayExpression(elements));
678
+ }
679
+ function foldArrayIsArray(path) {
680
+ const args = path.node.arguments;
681
+ if (args.length !== 1) {
682
+ return;
683
+ }
684
+ const [arg] = args;
685
+ if (!t.isExpression(arg)) {
686
+ return;
687
+ }
688
+ // A known scalar cannot be an array.
689
+ const evaluated = evaluateConstant(arg, path.scope, path);
690
+ if (!evaluated.known) {
691
+ return;
692
+ }
693
+ const { value } = evaluated;
694
+ if (typeof value === 'string' ||
695
+ typeof value === 'number' ||
696
+ typeof value === 'boolean' ||
697
+ typeof value === 'bigint' ||
698
+ value === null ||
699
+ value === undefined) {
700
+ path.replaceWith(t.booleanLiteral(false));
701
+ }
702
+ }
703
+ function foldBooleanCtor(path) {
704
+ const args = path.node.arguments;
705
+ if (args.length === 0) {
706
+ path.replaceWith(t.booleanLiteral(false));
707
+ return;
708
+ }
709
+ if (args.length !== 1) {
710
+ return;
711
+ }
712
+ const [arg] = args;
713
+ if (!t.isExpression(arg)) {
714
+ return;
715
+ }
716
+ path.replaceWith(t.unaryExpression('!', t.unaryExpression('!', arg)));
717
+ }
718
+ function foldStringCtor(path) {
719
+ const args = path.node.arguments;
720
+ if (args.length === 0) {
721
+ const empty = t.stringLiteral('');
722
+ if (!foldsIntoDirective(path, empty)) {
723
+ path.replaceWith(empty);
724
+ }
725
+ return;
726
+ }
727
+ if (args.length !== 1) {
728
+ return;
729
+ }
730
+ const [arg] = args;
731
+ if (!t.isExpression(arg)) {
732
+ return;
733
+ }
734
+ const evaluated = evaluateConstant(arg, path.scope, path);
735
+ if (!evaluated.known || isOpaque(evaluated.value)) {
736
+ return;
737
+ }
738
+ let result;
739
+ try {
740
+ result = String(evaluated.value);
741
+ }
742
+ catch {
743
+ return;
744
+ }
745
+ const lit = valueToLiteral(result);
746
+ if (!lit || foldsIntoDirective(path, lit)) {
747
+ return;
748
+ }
749
+ path.replaceWith(lit);
750
+ }
751
+ function foldNumberCtor(path) {
752
+ const args = path.node.arguments;
753
+ if (args.length === 0) {
754
+ path.replaceWith(t.numericLiteral(0));
755
+ return;
756
+ }
757
+ if (args.length !== 1) {
758
+ return;
759
+ }
760
+ const [arg] = args;
761
+ if (!t.isExpression(arg)) {
762
+ return;
763
+ }
764
+ const evaluated = evaluateConstant(arg, path.scope, path);
765
+ if (!evaluated.known || isOpaque(evaluated.value)) {
766
+ return;
767
+ }
768
+ let result;
769
+ try {
770
+ // BigInt conversion throws outside the safe-integer range.
771
+ result = Number(evaluated.value);
772
+ }
773
+ catch {
774
+ return;
775
+ }
776
+ const lit = valueToLiteral(result);
777
+ if (!lit) {
778
+ return;
779
+ }
780
+ path.replaceWith(lit);
781
+ }
782
+ function foldByReflection(path, fn) {
783
+ if (typeof fn !== 'function') {
784
+ return;
785
+ }
786
+ const args = tryEvaluateArgs(path.node.arguments, path);
787
+ if (args === null) {
788
+ return;
789
+ }
790
+ let result;
791
+ try {
792
+ result = fn(...args);
793
+ }
794
+ catch {
795
+ return;
796
+ }
797
+ const lit = valueToLiteral(result);
798
+ if (!lit || foldsIntoDirective(path, lit)) {
799
+ return;
800
+ }
801
+ path.replaceWith(lit);
802
+ }
803
+ function foldPrototypeCall(path, receiver, method) {
804
+ const args = tryEvaluateArgs(path.node.arguments, path);
805
+ if (args === null) {
806
+ return;
807
+ }
808
+ let result;
809
+ try {
810
+ const fn = receiver[method];
811
+ if (typeof fn !== 'function') {
812
+ return;
813
+ }
814
+ result = fn.apply(receiver, args);
815
+ }
816
+ catch {
817
+ return;
818
+ }
819
+ const lit = valueToLiteral(result);
820
+ if (!lit || foldsIntoDirective(path, lit)) {
821
+ return;
822
+ }
823
+ path.replaceWith(lit);
824
+ }
825
+ function tryEvaluateArgs(args, path) {
826
+ const result = [];
827
+ for (const arg of args) {
828
+ if (!t.isExpression(arg)) {
829
+ return null;
830
+ }
831
+ const evaluated = evaluateConstant(arg, path.scope, path);
832
+ if (!evaluated.known || isOpaque(evaluated.value)) {
833
+ return null;
834
+ }
835
+ result.push(evaluated.value);
836
+ }
837
+ return result;
838
+ }
839
+ //# sourceMappingURL=fold-builtin-methods.js.map