js-confuser 1.7.3 → 2.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +6 -4
  2. package/CHANGELOG.md +70 -0
  3. package/Migration.md +57 -0
  4. package/README.md +23 -929
  5. package/dist/constants.js +65 -14
  6. package/dist/index.js +108 -160
  7. package/dist/obfuscator.js +316 -118
  8. package/dist/options.js +1 -119
  9. package/dist/order.js +30 -30
  10. package/dist/presets.js +47 -45
  11. package/dist/probability.js +25 -32
  12. package/dist/templates/bufferToStringTemplate.js +9 -0
  13. package/dist/templates/deadCodeTemplates.js +9 -0
  14. package/dist/templates/getGlobalTemplate.js +19 -0
  15. package/dist/templates/integrityTemplate.js +30 -0
  16. package/dist/templates/setFunctionLengthTemplate.js +9 -0
  17. package/dist/templates/stringCompressionTemplate.js +10 -0
  18. package/dist/templates/tamperProtectionTemplates.js +21 -0
  19. package/dist/templates/template.js +199 -184
  20. package/dist/transforms/astScrambler.js +100 -0
  21. package/dist/transforms/calculator.js +70 -127
  22. package/dist/transforms/controlFlowFlattening.js +1182 -0
  23. package/dist/transforms/deadCode.js +62 -587
  24. package/dist/transforms/dispatcher.js +300 -313
  25. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +88 -189
  26. package/dist/transforms/extraction/objectExtraction.js +131 -215
  27. package/dist/transforms/finalizer.js +56 -59
  28. package/dist/transforms/flatten.js +275 -276
  29. package/dist/transforms/functionOutlining.js +230 -0
  30. package/dist/transforms/identifier/globalConcealing.js +214 -135
  31. package/dist/transforms/identifier/movedDeclarations.js +167 -91
  32. package/dist/transforms/identifier/renameVariables.js +239 -193
  33. package/dist/transforms/lock/integrity.js +61 -184
  34. package/dist/transforms/lock/lock.js +261 -387
  35. package/dist/transforms/minify.js +431 -436
  36. package/dist/transforms/opaquePredicates.js +65 -118
  37. package/dist/transforms/pack.js +160 -0
  38. package/dist/transforms/plugin.js +179 -0
  39. package/dist/transforms/preparation.js +261 -173
  40. package/dist/transforms/renameLabels.js +132 -56
  41. package/dist/transforms/rgf.js +140 -267
  42. package/dist/transforms/shuffle.js +52 -145
  43. package/dist/transforms/string/encoding.js +44 -175
  44. package/dist/transforms/string/stringCompression.js +79 -155
  45. package/dist/transforms/string/stringConcealing.js +189 -225
  46. package/dist/transforms/string/stringEncoding.js +32 -40
  47. package/dist/transforms/string/stringSplitting.js +54 -55
  48. package/dist/transforms/variableMasking.js +232 -0
  49. package/dist/utils/ControlObject.js +125 -0
  50. package/dist/utils/IntGen.js +46 -0
  51. package/dist/utils/NameGen.js +106 -0
  52. package/dist/utils/ast-utils.js +560 -0
  53. package/dist/utils/function-utils.js +56 -0
  54. package/dist/utils/gen-utils.js +48 -0
  55. package/dist/utils/node.js +77 -0
  56. package/dist/utils/object-utils.js +21 -0
  57. package/dist/utils/random-utils.js +91 -0
  58. package/dist/utils/static-utils.js +64 -0
  59. package/dist/validateOptions.js +122 -0
  60. package/index.d.ts +1 -17
  61. package/package.json +27 -22
  62. package/src/constants.ts +139 -82
  63. package/src/index.ts +70 -165
  64. package/src/obfuscationResult.ts +43 -0
  65. package/src/obfuscator.ts +328 -135
  66. package/src/options.ts +149 -658
  67. package/src/order.ts +14 -14
  68. package/src/presets.ts +39 -34
  69. package/src/probability.ts +21 -36
  70. package/src/templates/bufferToStringTemplate.ts +57 -0
  71. package/src/templates/deadCodeTemplates.ts +1185 -0
  72. package/src/templates/getGlobalTemplate.ts +72 -0
  73. package/src/templates/integrityTemplate.ts +69 -0
  74. package/src/templates/setFunctionLengthTemplate.ts +11 -0
  75. package/src/templates/stringCompressionTemplate.ts +42 -0
  76. package/src/templates/tamperProtectionTemplates.ts +116 -0
  77. package/src/templates/template.ts +149 -157
  78. package/src/transforms/astScrambler.ts +99 -0
  79. package/src/transforms/calculator.ts +96 -226
  80. package/src/transforms/controlFlowFlattening.ts +1594 -0
  81. package/src/transforms/deadCode.ts +85 -676
  82. package/src/transforms/dispatcher.ts +431 -640
  83. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +147 -295
  84. package/src/transforms/extraction/objectExtraction.ts +160 -333
  85. package/src/transforms/finalizer.ts +63 -64
  86. package/src/transforms/flatten.ts +439 -557
  87. package/src/transforms/functionOutlining.ts +225 -0
  88. package/src/transforms/identifier/globalConcealing.ts +255 -266
  89. package/src/transforms/identifier/movedDeclarations.ts +228 -142
  90. package/src/transforms/identifier/renameVariables.ts +250 -271
  91. package/src/transforms/lock/integrity.ts +85 -263
  92. package/src/transforms/lock/lock.ts +338 -579
  93. package/src/transforms/minify.ts +523 -663
  94. package/src/transforms/opaquePredicates.ts +90 -229
  95. package/src/transforms/pack.ts +195 -0
  96. package/src/transforms/plugin.ts +185 -0
  97. package/src/transforms/preparation.ts +337 -231
  98. package/src/transforms/renameLabels.ts +176 -77
  99. package/src/transforms/rgf.ts +293 -424
  100. package/src/transforms/shuffle.ts +80 -254
  101. package/src/transforms/string/encoding.ts +20 -126
  102. package/src/transforms/string/stringCompression.ts +117 -307
  103. package/src/transforms/string/stringConcealing.ts +254 -342
  104. package/src/transforms/string/stringEncoding.ts +28 -47
  105. package/src/transforms/string/stringSplitting.ts +61 -75
  106. package/src/transforms/variableMasking.ts +257 -0
  107. package/src/utils/ControlObject.ts +141 -0
  108. package/src/utils/IntGen.ts +33 -0
  109. package/src/utils/NameGen.ts +106 -0
  110. package/src/utils/ast-utils.ts +667 -0
  111. package/src/utils/function-utils.ts +50 -0
  112. package/src/utils/gen-utils.ts +48 -0
  113. package/src/utils/node.ts +78 -0
  114. package/src/utils/object-utils.ts +21 -0
  115. package/src/utils/random-utils.ts +79 -0
  116. package/src/utils/static-utils.ts +66 -0
  117. package/src/validateOptions.ts +256 -0
  118. package/tsconfig.json +13 -8
  119. package/babel.config.js +0 -12
  120. package/dev.js +0 -8
  121. package/dist/compiler.js +0 -34
  122. package/dist/parser.js +0 -59
  123. package/dist/precedence.js +0 -66
  124. package/dist/templates/bufferToString.js +0 -129
  125. package/dist/templates/core.js +0 -35
  126. package/dist/templates/crash.js +0 -28
  127. package/dist/templates/es5.js +0 -137
  128. package/dist/templates/functionLength.js +0 -34
  129. package/dist/templates/globals.js +0 -9
  130. package/dist/transforms/antiTooling.js +0 -88
  131. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +0 -1287
  132. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +0 -131
  133. package/dist/transforms/es5/antiClass.js +0 -164
  134. package/dist/transforms/es5/antiDestructuring.js +0 -193
  135. package/dist/transforms/es5/antiES6Object.js +0 -185
  136. package/dist/transforms/es5/antiSpreadOperator.js +0 -35
  137. package/dist/transforms/es5/antiTemplate.js +0 -66
  138. package/dist/transforms/es5/es5.js +0 -123
  139. package/dist/transforms/extraction/classExtraction.js +0 -83
  140. package/dist/transforms/identifier/globalAnalysis.js +0 -83
  141. package/dist/transforms/identifier/variableAnalysis.js +0 -104
  142. package/dist/transforms/lock/antiDebug.js +0 -76
  143. package/dist/transforms/stack.js +0 -349
  144. package/dist/transforms/transform.js +0 -372
  145. package/dist/traverse.js +0 -110
  146. package/dist/util/compare.js +0 -145
  147. package/dist/util/gen.js +0 -564
  148. package/dist/util/guard.js +0 -14
  149. package/dist/util/identifiers.js +0 -355
  150. package/dist/util/insert.js +0 -362
  151. package/dist/util/math.js +0 -19
  152. package/dist/util/object.js +0 -40
  153. package/dist/util/random.js +0 -156
  154. package/dist/util/scope.js +0 -20
  155. package/docs/ControlFlowFlattening.md +0 -595
  156. package/docs/Countermeasures.md +0 -70
  157. package/docs/ES5.md +0 -197
  158. package/docs/Integrity.md +0 -82
  159. package/docs/RGF.md +0 -424
  160. package/docs/RenameVariables.md +0 -116
  161. package/docs/TamperProtection.md +0 -100
  162. package/docs/Template.md +0 -117
  163. package/samples/example.js +0 -15
  164. package/samples/high.js +0 -1
  165. package/samples/input.js +0 -3
  166. package/samples/javascriptobfuscator.com.js +0 -8
  167. package/samples/jscrambler_advanced.js +0 -1894
  168. package/samples/jscrambler_light.js +0 -1134
  169. package/samples/low.js +0 -1
  170. package/samples/medium.js +0 -1
  171. package/samples/obfuscator.io.js +0 -1686
  172. package/samples/preemptive.com.js +0 -16
  173. package/src/compiler.ts +0 -35
  174. package/src/parser.ts +0 -49
  175. package/src/precedence.ts +0 -61
  176. package/src/templates/bufferToString.ts +0 -136
  177. package/src/templates/core.ts +0 -29
  178. package/src/templates/crash.ts +0 -23
  179. package/src/templates/es5.ts +0 -131
  180. package/src/templates/functionLength.ts +0 -32
  181. package/src/templates/globals.ts +0 -3
  182. package/src/transforms/antiTooling.ts +0 -102
  183. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +0 -2153
  184. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +0 -179
  185. package/src/transforms/es5/antiClass.ts +0 -276
  186. package/src/transforms/es5/antiDestructuring.ts +0 -294
  187. package/src/transforms/es5/antiES6Object.ts +0 -267
  188. package/src/transforms/es5/antiSpreadOperator.ts +0 -56
  189. package/src/transforms/es5/antiTemplate.ts +0 -98
  190. package/src/transforms/es5/es5.ts +0 -149
  191. package/src/transforms/extraction/classExtraction.ts +0 -168
  192. package/src/transforms/identifier/globalAnalysis.ts +0 -102
  193. package/src/transforms/identifier/variableAnalysis.ts +0 -118
  194. package/src/transforms/lock/antiDebug.ts +0 -112
  195. package/src/transforms/stack.ts +0 -557
  196. package/src/transforms/transform.ts +0 -441
  197. package/src/traverse.ts +0 -120
  198. package/src/types.ts +0 -133
  199. package/src/util/compare.ts +0 -181
  200. package/src/util/gen.ts +0 -651
  201. package/src/util/guard.ts +0 -17
  202. package/src/util/identifiers.ts +0 -494
  203. package/src/util/insert.ts +0 -419
  204. package/src/util/math.ts +0 -15
  205. package/src/util/object.ts +0 -39
  206. package/src/util/random.ts +0 -221
  207. package/src/util/scope.ts +0 -21
  208. package/test/code/Cash.src.js +0 -1011
  209. package/test/code/Cash.test.ts +0 -132
  210. package/test/code/Dynamic.src.js +0 -118
  211. package/test/code/Dynamic.test.ts +0 -49
  212. package/test/code/ES6.src.js +0 -235
  213. package/test/code/ES6.test.ts +0 -42
  214. package/test/code/NewFeatures.test.ts +0 -19
  215. package/test/code/StrictMode.src.js +0 -65
  216. package/test/code/StrictMode.test.js +0 -37
  217. package/test/compare.test.ts +0 -104
  218. package/test/index.test.ts +0 -249
  219. package/test/options.test.ts +0 -150
  220. package/test/presets.test.ts +0 -22
  221. package/test/probability.test.ts +0 -44
  222. package/test/templates/template.test.ts +0 -224
  223. package/test/transforms/antiTooling.test.ts +0 -52
  224. package/test/transforms/calculator.test.ts +0 -78
  225. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +0 -1274
  226. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +0 -192
  227. package/test/transforms/deadCode.test.ts +0 -85
  228. package/test/transforms/dispatcher.test.ts +0 -457
  229. package/test/transforms/es5/antiClass.test.ts +0 -427
  230. package/test/transforms/es5/antiDestructuring.test.ts +0 -157
  231. package/test/transforms/es5/antiES6Object.test.ts +0 -245
  232. package/test/transforms/es5/antiTemplate.test.ts +0 -116
  233. package/test/transforms/es5/es5.test.ts +0 -110
  234. package/test/transforms/extraction/classExtraction.test.ts +0 -86
  235. package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +0 -200
  236. package/test/transforms/extraction/objectExtraction.test.ts +0 -491
  237. package/test/transforms/flatten.test.ts +0 -721
  238. package/test/transforms/hexadecimalNumbers.test.ts +0 -62
  239. package/test/transforms/identifier/globalConcealing.test.ts +0 -142
  240. package/test/transforms/identifier/movedDeclarations.test.ts +0 -275
  241. package/test/transforms/identifier/renameVariables.test.ts +0 -695
  242. package/test/transforms/lock/antiDebug.test.ts +0 -66
  243. package/test/transforms/lock/browserLock.test.ts +0 -129
  244. package/test/transforms/lock/countermeasures.test.ts +0 -100
  245. package/test/transforms/lock/integrity.test.ts +0 -161
  246. package/test/transforms/lock/lock.test.ts +0 -204
  247. package/test/transforms/lock/osLock.test.ts +0 -312
  248. package/test/transforms/lock/selfDefending.test.ts +0 -68
  249. package/test/transforms/lock/tamperProtection.test.ts +0 -336
  250. package/test/transforms/minify.test.ts +0 -575
  251. package/test/transforms/opaquePredicates.test.ts +0 -43
  252. package/test/transforms/preparation.test.ts +0 -157
  253. package/test/transforms/renameLabels.test.ts +0 -95
  254. package/test/transforms/rgf.test.ts +0 -378
  255. package/test/transforms/shuffle.test.ts +0 -135
  256. package/test/transforms/stack.test.ts +0 -573
  257. package/test/transforms/string/stringCompression.test.ts +0 -120
  258. package/test/transforms/string/stringConcealing.test.ts +0 -299
  259. package/test/transforms/string/stringEncoding.test.ts +0 -95
  260. package/test/transforms/string/stringSplitting.test.ts +0 -135
  261. package/test/transforms/transform.test.ts +0 -66
  262. package/test/traverse.test.ts +0 -139
  263. package/test/util/compare.test.ts +0 -34
  264. package/test/util/gen.test.ts +0 -121
  265. package/test/util/identifiers.test.ts +0 -253
  266. package/test/util/insert.test.ts +0 -142
  267. package/test/util/math.test.ts +0 -5
  268. package/test/util/random.test.ts +0 -71
  269. /package/dist/{types.js → obfuscationResult.js} +0 -0
@@ -1,353 +1,340 @@
1
1
  "use strict";
2
2
 
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
- exports.default = void 0;
7
- var _traverse = require("../traverse");
8
- var _gen = require("../util/gen");
9
- var _identifiers = require("../util/identifiers");
10
- var _insert = require("../util/insert");
11
- var _transform = _interopRequireDefault(require("./transform"));
12
- var _compare = require("../util/compare");
13
- var _random = require("../util/random");
7
+ exports["default"] = void 0;
8
+ var t = _interopRequireWildcard(require("@babel/types"));
9
+ var _template = _interopRequireDefault(require("../templates/template"));
10
+ var _assert = require("assert");
11
+ var _randomUtils = require("../utils/random-utils");
14
12
  var _probability = require("../probability");
15
- var _constants = require("../constants");
16
13
  var _order = require("../order");
17
- var _template = _interopRequireDefault(require("../templates/template"));
18
- var _functionLength = require("../templates/functionLength");
19
- var _globals = require("../templates/globals");
20
- var _scope = require("../util/scope");
21
- var _guard = require("../util/guard");
22
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
23
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
24
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
25
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
26
- /**
27
- * A Dispatcher processes function calls. All the function declarations are brought into a dictionary.
28
- *
29
- * ```js
30
- * var param1;
31
- * function dispatcher(key){
32
- * var fns = {
33
- * 'fn1': function(){
34
- * var [arg1] = [param1];
35
- * console.log(arg1);
36
- * }
37
- * }
38
- * return fns[key]();
39
- * };
40
- * param1 = "Hello World";
41
- * dispatcher('fn1'); // > "Hello World"
42
- * ```
43
- *
44
- * Can break code with:
45
- *
46
- * 1. testing function equality,
47
- * 2. using `arguments.callee`,
48
- * 3. using `this`
49
- */
50
- class Dispatcher extends _transform.default {
51
- constructor(o) {
52
- super(o, _order.ObfuscateOrder.Dispatcher);
53
- // Debug mode preserves function names
54
- _defineProperty(this, "isDebug", false);
55
- _defineProperty(this, "count", void 0);
56
- _defineProperty(this, "functionLengthName", void 0);
57
- this.count = 0;
58
- }
59
- apply(tree) {
60
- super.apply(tree);
61
- if (this.options.preserveFunctionLength && this.functionLengthName) {
62
- (0, _insert.prepend)(tree, _functionLength.FunctionLengthTemplate.single({
63
- name: this.functionLengthName,
64
- ObjectDefineProperty: this.createInitVariable(_globals.ObjectDefineProperty, [tree])
65
- }));
66
- }
67
- }
68
- match(object, parents) {
69
- if ((0, _compare.isInsideType)("AwaitExpression", object, parents)) {
70
- return false;
14
+ var _constants = require("../constants");
15
+ var _functionUtils = require("../utils/function-utils");
16
+ var _setFunctionLengthTemplate = require("../templates/setFunctionLengthTemplate");
17
+ var _node = require("../utils/node");
18
+ var _astUtils = require("../utils/ast-utils");
19
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
20
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
21
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
22
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
23
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
24
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
25
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
26
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
27
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
28
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
29
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
30
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
31
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
32
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
33
+ var _default = exports["default"] = function _default(_ref) {
34
+ var Plugin = _ref.Plugin;
35
+ var me = Plugin(_order.Order.Dispatcher, {
36
+ changeData: {
37
+ functions: 0
71
38
  }
72
- return (0, _insert.isVarContext)(object) && object.type !== "ArrowFunctionExpression" && !object.$multiTransformSkip && !parents.find(x => x.$multiTransformSkip);
73
- }
74
- transform(object, parents) {
75
- return () => {
76
- if ((0, _probability.ComputeProbabilityMap)(this.options.dispatcher, mode => mode)) {
77
- if (object.type != "Program" && object.body.type != "BlockStatement") {
78
- return;
79
- }
39
+ });
40
+ var dispatcherCounter = 0;
41
+ var setFunctionLength = me.getPlaceholder("d_fnLength");
80
42
 
81
- // Map of FunctionDeclarations
82
- var functionDeclarations = Object.create(null);
43
+ // in Debug mode, function names are preserved
44
+ var isDebug = false;
45
+ return {
46
+ visitor: {
47
+ "Program|Function": {
48
+ exit: function exit(_path) {
49
+ var blockPath = _path;
50
+ if (blockPath.isProgram()) {
51
+ blockPath.scope.crawl();
83
52
 
84
- // Array of Identifier nodes
85
- var identifiers = [];
86
- var illegalFnNames = new Set();
53
+ // Don't insert function length code when disabled
54
+ // Instead insert empty function as the identifier is still referenced
55
+ var insertNode = t.functionDeclaration(t.identifier(setFunctionLength), [], t.blockStatement([]));
56
+ if (me.options.preserveFunctionLength) {
57
+ // Insert function length code
58
+ insertNode = _setFunctionLengthTemplate.SetFunctionLengthTemplate.single({
59
+ fnName: setFunctionLength
60
+ });
61
+ }
62
+ me.skip((0, _astUtils.prependProgram)(_path, insertNode));
63
+ }
64
+ if (blockPath.node[_constants.UNSAFE]) return;
87
65
 
88
- // New Names for Functions
89
- var newFnNames = Object.create(null); // [old name]: randomized name
66
+ // For testing
67
+ // if (!blockPath.isProgram()) return;
90
68
 
91
- var context = (0, _insert.isVarContext)(object) ? object : (0, _insert.getVarContext)(object, parents);
92
- var lexicalScope = (0, _insert.isFunction)(context) ? context.body : context;
93
- (0, _traverse.walk)(object, parents, (o, p) => {
94
- if (object == o) {
95
- // Fix 1
96
- return;
97
- }
98
- var c = (0, _insert.getVarContext)(o, p);
99
- if (o.type == "FunctionDeclaration") {
100
- c = (0, _insert.getVarContext)(p[0], p.slice(1));
101
- }
102
- if (context === c) {
103
- if (o.type == "FunctionDeclaration" && o.id.name) {
104
- var name = o.id.name;
105
- if (o.$requiresEval || o.async || o.generator || p.find(x => x.$multiTransformSkip || x.type == "MethodDefinition") || o.body.type != "BlockStatement") {
106
- illegalFnNames.add(name);
107
- return;
108
- }
69
+ var blockStatement = blockPath.isProgram() ? blockPath : blockPath.get("body");
109
70
 
110
- // Must defined in the same block as the current function being scanned
111
- // Solves 'let' and 'class' declaration issue
112
- var ls = (0, _scope.getLexicalScope)(o, p);
113
- if (ls !== lexicalScope) {
114
- illegalFnNames.add(name);
115
- return;
116
- }
71
+ // Track functions and illegal ones
72
+ // A function is illegal if:
73
+ // - the function is async or generator
74
+ // - the function is redefined
75
+ // - the function uses 'this', 'eval', or 'arguments'
76
+ var functionPaths = new Map();
77
+ var illegalNames = new Set();
117
78
 
118
- // If dupe, no routing
119
- if (functionDeclarations[name]) {
120
- illegalFnNames.add(name);
121
- return;
79
+ // Scan for function declarations
80
+ blockPath.traverse({
81
+ // Check for reassigned / redefined functions
82
+ BindingIdentifier: {
83
+ exit: function exit(path) {
84
+ var _path$parentPath;
85
+ if (!(0, _astUtils.isVariableIdentifier)(path)) return;
86
+ var name = path.node.name;
87
+ if (!((_path$parentPath = path.parentPath) !== null && _path$parentPath !== void 0 && _path$parentPath.isFunctionDeclaration())) {
88
+ illegalNames.add(name);
89
+ }
122
90
  }
123
- (0, _traverse.walk)(o, p, (oo, pp) => {
124
- if (oo.type == "Identifier" && oo.name == "arguments" || oo.type == "ThisExpression" || oo.type == "Super") {
125
- if ((0, _insert.getVarContext)(oo, pp) === o) {
126
- illegalFnNames.add(name);
127
- return "EXIT";
128
- }
91
+ },
92
+ // Find functions eligible for dispatching
93
+ FunctionDeclaration: {
94
+ exit: function exit(path) {
95
+ var name = path.node.id.name;
96
+ // If the function is not named, we can't dispatch it
97
+ if (!name) {
98
+ return;
129
99
  }
130
100
 
131
- // Avoid functions with function expressions as they have a different scope
132
- if ((oo.type === "FunctionExpression" || oo.type === "ArrowFunctionExpression") && pp.find(x => x == o.params)) {
133
- illegalFnNames.add(name);
134
- return "EXIT";
101
+ // Do not apply to async or generator functions
102
+ if (path.node.async || path.node.generator) {
103
+ return;
135
104
  }
136
- });
137
- functionDeclarations[name] = [o, p];
138
- }
139
- }
140
- if (o.type == "Identifier") {
141
- if (_constants.reservedIdentifiers.has(o.name)) {
142
- return;
143
- }
144
- var info = (0, _identifiers.getIdentifierInfo)(o, p);
145
- if (!info.spec.isReferenced) {
146
- return;
147
- }
148
- if ((0, _guard.isJSConfuserVar)(p)) {
149
- illegalFnNames.add(o.name);
150
- }
151
- if (info.spec.isDefined) {
152
- if (info.isFunctionDeclaration) {
153
- if (p[0].id && (!functionDeclarations[p[0].id.name] || functionDeclarations[p[0].id.name][0] !== p[0])) {
154
- illegalFnNames.add(o.name);
105
+
106
+ // Do not apply to functions in nested scopes
107
+ if (path.parentPath !== blockStatement || me.isSkipped(path)) {
108
+ illegalNames.add(name);
109
+ return;
110
+ }
111
+ if ((0, _astUtils.isStrictMode)(path)) {
112
+ illegalNames.add(name);
113
+ return;
114
+ }
115
+
116
+ // Do not apply to unsafe functions, redefined functions, or internal obfuscator functions
117
+ if (path.node[_constants.UNSAFE] || functionPaths.has(name) || me.obfuscator.isInternalVariable(name)) {
118
+ illegalNames.add(name);
119
+ return;
155
120
  }
156
- } else {
157
- illegalFnNames.add(o.name);
121
+
122
+ // Functions with default parameters are not fully supported
123
+ // (Could be a Function Expression referencing outer scope)
124
+ if (path.node.params.find(function (x) {
125
+ return x.type === "AssignmentPattern";
126
+ })) {
127
+ illegalNames.add(name);
128
+ return;
129
+ }
130
+ functionPaths.set(name, path);
158
131
  }
159
- } else if (info.spec.isModified) {
160
- illegalFnNames.add(o.name);
161
- } else {
162
- identifiers.push([o, p]);
163
132
  }
133
+ });
134
+ var _iterator = _createForOfIteratorHelper(illegalNames),
135
+ _step;
136
+ try {
137
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
138
+ var _name = _step.value;
139
+ functionPaths["delete"](_name);
140
+ }
141
+ } catch (err) {
142
+ _iterator.e(err);
143
+ } finally {
144
+ _iterator.f();
164
145
  }
165
- });
166
- illegalFnNames.forEach(name => {
167
- delete functionDeclarations[name];
168
- });
169
-
170
- // map original name->new game
171
- var gen = this.getGenerator();
172
- Object.keys(functionDeclarations).forEach(name => {
173
- newFnNames[name] = this.isDebug ? "_dispatcher_" + this.count + "_" + name : gen.generate();
174
- });
175
- // set containing new name
176
- var set = new Set(Object.keys(newFnNames));
146
+ var _iterator2 = _createForOfIteratorHelper(functionPaths.keys()),
147
+ _step2;
148
+ try {
149
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
150
+ var name = _step2.value;
151
+ if (!(0, _probability.computeProbabilityMap)(me.options.dispatcher, name)) {
152
+ functionPaths["delete"](name);
153
+ }
154
+ }
177
155
 
178
- // Only make a dispatcher function if it caught any functions
179
- if (set.size > 0) {
180
- if (!this.functionLengthName) {
181
- this.functionLengthName = this.getPlaceholder();
156
+ // No functions here to change
157
+ } catch (err) {
158
+ _iterator2.e(err);
159
+ } finally {
160
+ _iterator2.f();
182
161
  }
183
- var payloadArg = this.getPlaceholder() + "_dispatcher_" + this.count + "_payload";
184
- var dispatcherFnName = this.getPlaceholder() + "_dispatcher_" + this.count + _constants.predictableFunctionTag;
185
- this.log(dispatcherFnName, set);
186
- this.count++;
187
- var expectedGet = gen.generate();
188
- var expectedClearArgs = gen.generate();
189
- var expectedNew = gen.generate();
190
- var returnProp = gen.generate();
191
- var newReturnMemberName = gen.generate();
192
- var shuffledKeys = (0, _random.shuffle)(Object.keys(functionDeclarations));
193
- var mapName = this.getPlaceholder();
194
- var cacheName = this.getPlaceholder();
195
-
196
- // creating the dispatcher function
197
- // 1. create function map
198
- var map = (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(mapName, (0, _gen.ObjectExpression)(shuffledKeys.map(name => {
199
- var [def, defParents] = functionDeclarations[name];
200
- var body = (0, _insert.getBlockBody)(def.body);
201
- var functionExpression = {
202
- ...def,
203
- expression: false,
204
- type: "FunctionExpression",
205
- id: null,
206
- params: [],
207
- [_constants.predictableFunctionTag]: true
208
- };
209
- this.addComment(functionExpression, name);
210
- if (def.params.length > 0) {
211
- const fixParam = param => {
212
- return param;
213
- };
214
- var variableDeclaration = (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)({
215
- type: "ArrayPattern",
216
- elements: def.params.map(fixParam)
217
- }, (0, _gen.Identifier)(payloadArg)));
218
- (0, _insert.prepend)(def.body, variableDeclaration);
162
+ if (functionPaths.size === 0) {
163
+ return;
164
+ }
165
+ me.changeData.functions += functionPaths.size;
166
+ var dispatcherName = me.getPlaceholder() + "_dispatcher_" + dispatcherCounter++;
167
+ var payloadName = me.getPlaceholder() + "_payload";
168
+ var cacheName = me.getPlaceholder() + "_cache";
169
+ var newNameMapping = new Map();
170
+ var keys = {
171
+ placeholderNoMeaning: isDebug ? "noMeaning" : (0, _randomUtils.getRandomString)(10),
172
+ clearPayload: isDebug ? "clearPayload" : (0, _randomUtils.getRandomString)(10),
173
+ nonCall: isDebug ? "nonCall" : (0, _randomUtils.getRandomString)(10),
174
+ returnAsObject: isDebug ? "returnAsObject" : (0, _randomUtils.getRandomString)(10),
175
+ returnAsObjectProperty: isDebug ? "returnAsObjectProperty" : (0, _randomUtils.getRandomString)(10)
176
+ };
177
+ var _iterator3 = _createForOfIteratorHelper(functionPaths.keys()),
178
+ _step3;
179
+ try {
180
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
181
+ var name = _step3.value;
182
+ newNameMapping.set(name, isDebug ? "_" + name : (0, _randomUtils.getRandomString)(6) /** "_" + name */);
219
183
  }
220
184
 
221
- // For logging purposes
222
- var signature = name + "(" + def.params.map(x => x.name || "<>").join(",") + ")";
223
- this.log("Added", signature);
224
-
225
- // delete ref in block
226
- if (defParents.length) {
227
- (0, _insert.deleteDirect)(def, defParents[0]);
228
- }
229
- this.addComment(functionExpression, signature);
230
- return (0, _gen.Property)((0, _gen.Literal)(newFnNames[name]), functionExpression, false);
231
- }))));
232
- var getterArgName = this.getPlaceholder();
233
- var x = this.getPlaceholder();
234
- var y = this.getPlaceholder();
235
- var z = this.getPlaceholder();
236
- function getAccessor() {
237
- return (0, _gen.MemberExpression)((0, _gen.Identifier)(mapName), (0, _gen.Identifier)(x), true);
185
+ // Find identifiers calling/referencing the functions
186
+ } catch (err) {
187
+ _iterator3.e(err);
188
+ } finally {
189
+ _iterator3.f();
238
190
  }
191
+ blockPath.traverse({
192
+ ReferencedIdentifier: {
193
+ exit: function exit(path) {
194
+ if (path.isJSX()) return;
195
+ if ((0, _functionUtils.isVariableFunctionIdentifier)(path)) return;
196
+ var name = path.node.name;
197
+ var fnPath = functionPaths.get(name);
198
+ if (!fnPath) return;
199
+ var newName = newNameMapping.get(name);
239
200
 
240
- // 2. define it
241
- var fn = (0, _gen.FunctionDeclaration)(dispatcherFnName, [(0, _gen.Identifier)(x), (0, _gen.Identifier)(y), (0, _gen.Identifier)(z)], [
242
- // Define map of callable functions
243
- map,
244
- // Set returning variable to undefined
245
- (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(returnProp)),
246
- // Arg to clear the payload
247
- (0, _gen.IfStatement)((0, _gen.BinaryExpression)("==", (0, _gen.Identifier)(y), (0, _gen.Literal)(expectedClearArgs)), [(0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(payloadArg), (0, _gen.ArrayExpression)([])))], null), (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)((0, _gen.Identifier)("lengths"), (0, _gen.ObjectExpression)(!this.options.preserveFunctionLength ? [] : shuffledKeys.map(name => {
248
- var [def, defParents] = functionDeclarations[name];
249
- return {
250
- key: newFnNames[name],
251
- value: (0, _insert.computeFunctionLength)(def.params)
252
- };
253
- }).filter(item => item.value !== 0).map(item => (0, _gen.Property)((0, _gen.Literal)(item.key), (0, _gen.Literal)(item.value)))))), new _template.default(`
254
- function makeFn${_constants.predictableFunctionTag}(){
255
- var fn = function(...args){
256
- ${payloadArg} = args;
257
- return ${mapName}[${x}].call(this)
258
- }, a = lengths[${x}]
201
+ // Do not replace if not referencing the actual function
202
+ if (path.scope.getBinding(name).path !== fnPath) {
203
+ return;
204
+ }
205
+ var createDispatcherCall = function createDispatcherCall(name, flagArg) {
206
+ var dispatcherArgs = [t.stringLiteral(name)];
207
+ if (flagArg) {
208
+ dispatcherArgs.push(t.stringLiteral(flagArg));
209
+ }
210
+ var asObject = (0, _randomUtils.chance)(50);
211
+ if (asObject) {
212
+ if (dispatcherArgs.length < 2) {
213
+ dispatcherArgs.push(t.stringLiteral(keys.placeholderNoMeaning));
214
+ }
215
+ dispatcherArgs.push(t.stringLiteral(keys.returnAsObject));
216
+ }
217
+ var callExpression = t.callExpression(t.identifier(dispatcherName), dispatcherArgs);
218
+ if (!asObject) {
219
+ return callExpression;
220
+ }
221
+ if ((0, _randomUtils.chance)(50)) {
222
+ callExpression.type = "NewExpression";
223
+ }
224
+ return t.memberExpression(callExpression, t.stringLiteral(keys.returnAsObjectProperty), true);
225
+ };
259
226
 
260
- ${this.options.preserveFunctionLength ? `if(a){
261
- return ${this.functionLengthName}(fn, a)
262
- }` : ""}
263
-
264
- return fn
227
+ // Replace the identifier with a call to the function
228
+ var parentPath = path.parentPath;
229
+ if (path.key === "callee" && parentPath !== null && parentPath !== void 0 && parentPath.isCallExpression()) {
230
+ var expressions = [];
231
+ var callArguments = parentPath.node.arguments;
232
+ if (callArguments.length === 0) {
233
+ expressions.push(
234
+ // Call the function
235
+ createDispatcherCall(newName, keys.clearPayload));
236
+ } else {
237
+ expressions.push(
238
+ // Prepare the payload arguments
239
+ t.assignmentExpression("=", t.identifier(payloadName), t.arrayExpression(callArguments)),
240
+ // Call the function
241
+ createDispatcherCall(newName));
242
+ }
243
+ var output = expressions.length === 1 ? expressions[0] : t.sequenceExpression(expressions);
244
+ if (!parentPath.container) return;
245
+ parentPath.replaceWith(output);
246
+ } else {
247
+ if (!path.container) return;
248
+ // Replace non-invocation references with a 'cached' version of the function
249
+ path.replaceWith(createDispatcherCall(newName, keys.nonCall));
250
+ }
265
251
  }
266
- `).single(),
267
- // Arg to get a function reference
268
- (0, _gen.IfStatement)((0, _gen.BinaryExpression)("==", (0, _gen.Identifier)(y), (0, _gen.Literal)(expectedGet)), [
269
- // Getter flag: return the function object
270
- (0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(returnProp), (0, _gen.LogicalExpression)("||", (0, _gen.MemberExpression)((0, _gen.Identifier)(cacheName), (0, _gen.Identifier)(x), true), (0, _gen.AssignmentExpression)("=", (0, _gen.MemberExpression)((0, _gen.Identifier)(cacheName), (0, _gen.Identifier)(x), true), (0, _gen.CallExpression)((0, _gen.Identifier)(`makeFn${_constants.predictableFunctionTag}`), [])))))], [
271
- // Call the function, return result
272
- (0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(returnProp), (0, _gen.CallExpression)(getAccessor(), [])))]),
273
- // Check how the function was invoked (new () vs ())
274
- (0, _gen.IfStatement)((0, _gen.BinaryExpression)("==", (0, _gen.Identifier)(z), (0, _gen.Literal)(expectedNew)), [
275
- // Wrap in object
276
- (0, _gen.ReturnStatement)((0, _gen.ObjectExpression)([(0, _gen.Property)((0, _gen.Identifier)(newReturnMemberName), (0, _gen.Identifier)(returnProp), false)]))], [
277
- // Return raw result
278
- (0, _gen.ReturnStatement)((0, _gen.Identifier)(returnProp))])]);
279
- (0, _insert.append)(object, fn);
280
- if (payloadArg) {
281
- (0, _insert.prepend)(object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(payloadArg, (0, _gen.ArrayExpression)([]))));
282
- }
283
- identifiers.forEach(_ref => {
284
- let [o, p] = _ref;
285
- if (o.type != "Identifier") {
286
- return;
287
252
  }
288
- var newName = newFnNames[o.name];
289
- if (!newName || typeof newName !== "string") {
290
- return;
291
- }
292
- if (!functionDeclarations[o.name]) {
293
- this.error(new Error("newName, missing function declaration"));
294
- }
295
- var info = (0, _identifiers.getIdentifierInfo)(o, p);
296
- if (info.isFunctionCall && p[0].type == "CallExpression" && p[0].callee === o) {
297
- // Invoking call expression: `a();`
253
+ });
254
+ var fnLengthProperties = [];
298
255
 
299
- if (o.name == dispatcherFnName) {
300
- return;
301
- }
302
- this.log(`${o.name}(${p[0].arguments.map(_ => "<>").join(",")}) -> ${dispatcherFnName}('${newName}')`);
303
- var assignmentExpressions = [];
304
- var dispatcherArgs = [(0, _gen.Literal)(newName)];
305
- if (p[0].arguments.length) {
306
- assignmentExpressions = [(0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(payloadArg), (0, _gen.ArrayExpression)(p[0].arguments))];
307
- } else {
308
- dispatcherArgs.push((0, _gen.Literal)(expectedClearArgs));
256
+ // Create the dispatcher function
257
+ var objectExpression = t.objectExpression(Array.from(newNameMapping).map(function (_ref2) {
258
+ var _ref3 = _slicedToArray(_ref2, 2),
259
+ name = _ref3[0],
260
+ newName = _ref3[1];
261
+ var originalPath = functionPaths.get(name);
262
+ var originalFn = originalPath.node;
263
+ if (me.options.preserveFunctionLength) {
264
+ var fnLength = (0, _functionUtils.computeFunctionLength)(originalPath);
265
+ if (fnLength >= 1) {
266
+ // 0 is already the default
267
+ fnLengthProperties.push(t.objectProperty(t.stringLiteral(newName), (0, _node.numericLiteral)(fnLength)));
309
268
  }
310
- var type = (0, _random.choice)(["CallExpression", "NewExpression"]);
311
- var callExpression = null;
312
- switch (type) {
313
- case "CallExpression":
314
- callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(dispatcherFnName), dispatcherArgs);
315
- break;
316
- case "NewExpression":
317
- if (dispatcherArgs.length == 1) {
318
- dispatcherArgs.push((0, _gen.Identifier)("undefined"));
319
- }
320
- callExpression = (0, _gen.MemberExpression)((0, _gen.NewExpression)((0, _gen.Identifier)(dispatcherFnName), [...dispatcherArgs, (0, _gen.Literal)(expectedNew)]), (0, _gen.Identifier)(newReturnMemberName), false);
321
- break;
322
- }
323
- this.addComment(callExpression, "Calling " + o.name + "(" + p[0].arguments.map(x => x.name).join(", ") + ")");
324
- var expr = assignmentExpressions.length ? (0, _gen.SequenceExpression)([...assignmentExpressions, callExpression]) : callExpression;
269
+ }
270
+ var newBody = _toConsumableArray(originalFn.body.body);
271
+ (0, _assert.ok)(Array.isArray(newBody));
325
272
 
326
- // Replace the parent call expression
327
- this.replace(p[0], expr);
328
- } else {
329
- // Non-invoking reference: `a`
273
+ // Unpack parameters
274
+ if (originalFn.params.length > 0) {
275
+ newBody.unshift(t.variableDeclaration("var", [t.variableDeclarator(t.arrayPattern(_toConsumableArray(originalFn.params)), t.identifier(payloadName))]));
276
+ }
330
277
 
331
- if (info.spec.isDefined) {
332
- if (info.isFunctionDeclaration) {
333
- this.log("Skipped getter " + o.name + " (function declaration)");
334
- } else {
335
- this.log("Skipped getter " + o.name + " (defined)");
336
- }
337
- return;
338
- }
339
- if (info.spec.isModified) {
340
- this.log("Skipped getter " + o.name + " (modified)");
341
- return;
278
+ // Add debug label
279
+ if (isDebug) {
280
+ newBody.unshift(t.expressionStatement(t.stringLiteral("Dispatcher: ".concat(name, " -> ").concat(newName))));
281
+ }
282
+ var functionExpression = t.functionExpression(null, [], t.blockStatement(newBody));
283
+ var _iterator4 = _createForOfIteratorHelper(Object.getOwnPropertySymbols(originalFn)),
284
+ _step4;
285
+ try {
286
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
287
+ var symbol = _step4.value;
288
+ functionExpression[symbol] = originalFn[symbol];
342
289
  }
343
- this.log(`(getter) ${o.name} -> ${dispatcherFnName}('${newName}')`);
344
- this.replace(o, (0, _gen.CallExpression)((0, _gen.Identifier)(dispatcherFnName), [(0, _gen.Literal)(newName), (0, _gen.Literal)(expectedGet)]));
290
+ } catch (err) {
291
+ _iterator4.e(err);
292
+ } finally {
293
+ _iterator4.f();
345
294
  }
295
+ functionExpression[_constants.PREDICTABLE] = true;
296
+ return t.objectProperty(t.stringLiteral(newName), functionExpression);
297
+ }));
298
+ var fnLengths = t.objectExpression(fnLengthProperties);
299
+ var dispatcher = new _template["default"]("\n function ".concat(dispatcherName, "(name, flagArg, returnTypeArg, fnLengths = {fnLengthsObjectExpression}) {\n var output;\n var fns = {objectExpression};\n\n if(flagArg === \"").concat(keys.clearPayload, "\") {\n ").concat(payloadName, " = [];\n }\n if(flagArg === \"").concat(keys.nonCall, "\") {\n function createFunction(){\n var fn = function(...args){ \n ").concat(payloadName, " = args;\n return fns[name].apply(this);\n }\n\n var fnLength = fnLengths[name];\n if(fnLength) {\n ").concat(setFunctionLength, "(fn, fnLength);\n }\n\n return fn;\n }\n output = ").concat(cacheName, "[name] || (").concat(cacheName, "[name] = createFunction());\n } else {\n output = fns[name]();\n }\n\n if(returnTypeArg === \"").concat(keys.returnAsObject, "\") {\n return { \"").concat(keys.returnAsObjectProperty, "\": output };\n } else {\n return output;\n }\n }\n ")).single({
300
+ objectExpression: objectExpression,
301
+ fnLengthsObjectExpression: fnLengths
346
302
  });
347
- (0, _insert.prepend)(object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)((0, _gen.Identifier)(cacheName), new _template.default(`Object.create(null)`).single().expression)));
303
+ dispatcher[_constants.PREDICTABLE] = true;
304
+
305
+ /**
306
+ * Prepends the node into the block. (And registers the declaration)
307
+ * @param node
308
+ */
309
+ function prepend(node) {
310
+ var newPath = blockStatement.unshiftContainer("body", node)[0];
311
+ blockStatement.scope.registerDeclaration(newPath);
312
+ }
313
+
314
+ // Insert the dispatcher function
315
+ prepend(dispatcher);
316
+
317
+ // Insert the payload variable
318
+ prepend(t.variableDeclaration("var", [t.variableDeclarator(t.identifier(payloadName))]));
319
+
320
+ // Insert the cache variable
321
+ prepend(t.variableDeclaration("var", [t.variableDeclarator(t.identifier(cacheName), new _template["default"]("Object[\"create\"](null)").expression())]));
322
+
323
+ // Remove original functions
324
+ var _iterator5 = _createForOfIteratorHelper(functionPaths.values()),
325
+ _step5;
326
+ try {
327
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
328
+ var path = _step5.value;
329
+ path.remove();
330
+ }
331
+ } catch (err) {
332
+ _iterator5.e(err);
333
+ } finally {
334
+ _iterator5.f();
335
+ }
348
336
  }
349
337
  }
350
- };
351
- }
352
- }
353
- exports.default = Dispatcher;
338
+ }
339
+ };
340
+ };