js-confuser 1.7.2 → 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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +6 -4
- package/.github/workflows/node.js.yml +1 -1
- package/CHANGELOG.md +105 -0
- package/Migration.md +57 -0
- package/README.md +23 -913
- package/dist/constants.js +69 -13
- package/dist/index.js +108 -152
- package/dist/obfuscator.js +316 -118
- package/dist/options.js +1 -109
- package/dist/order.js +30 -30
- package/dist/presets.js +47 -45
- package/dist/probability.js +25 -32
- package/dist/templates/bufferToStringTemplate.js +9 -0
- package/dist/templates/deadCodeTemplates.js +9 -0
- package/dist/templates/getGlobalTemplate.js +19 -0
- package/dist/templates/integrityTemplate.js +30 -0
- package/dist/templates/setFunctionLengthTemplate.js +9 -0
- package/dist/templates/stringCompressionTemplate.js +10 -0
- package/dist/templates/tamperProtectionTemplates.js +21 -0
- package/dist/templates/template.js +213 -93
- package/dist/transforms/astScrambler.js +100 -0
- package/dist/transforms/calculator.js +70 -127
- package/dist/transforms/controlFlowFlattening.js +1182 -0
- package/dist/transforms/deadCode.js +62 -577
- package/dist/transforms/dispatcher.js +300 -309
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +88 -189
- package/dist/transforms/extraction/objectExtraction.js +131 -215
- package/dist/transforms/finalizer.js +56 -59
- package/dist/transforms/flatten.js +275 -276
- package/dist/transforms/functionOutlining.js +230 -0
- package/dist/transforms/identifier/globalConcealing.js +217 -103
- package/dist/transforms/identifier/movedDeclarations.js +167 -91
- package/dist/transforms/identifier/renameVariables.js +240 -187
- package/dist/transforms/lock/integrity.js +61 -184
- package/dist/transforms/lock/lock.js +263 -303
- package/dist/transforms/minify.js +431 -436
- package/dist/transforms/opaquePredicates.js +65 -118
- package/dist/transforms/pack.js +160 -0
- package/dist/transforms/plugin.js +179 -0
- package/dist/transforms/preparation.js +263 -163
- package/dist/transforms/renameLabels.js +132 -56
- package/dist/transforms/rgf.js +142 -240
- package/dist/transforms/shuffle.js +52 -145
- package/dist/transforms/string/encoding.js +45 -173
- package/dist/transforms/string/stringCompression.js +81 -126
- package/dist/transforms/string/stringConcealing.js +189 -224
- package/dist/transforms/string/stringEncoding.js +32 -40
- package/dist/transforms/string/stringSplitting.js +54 -55
- package/dist/transforms/variableMasking.js +232 -0
- package/dist/utils/ControlObject.js +125 -0
- package/dist/utils/IntGen.js +46 -0
- package/dist/utils/NameGen.js +106 -0
- package/dist/utils/ast-utils.js +560 -0
- package/dist/utils/function-utils.js +56 -0
- package/dist/utils/gen-utils.js +48 -0
- package/dist/utils/node.js +77 -0
- package/dist/utils/object-utils.js +21 -0
- package/dist/utils/random-utils.js +91 -0
- package/dist/utils/static-utils.js +64 -0
- package/dist/validateOptions.js +122 -0
- package/index.d.ts +1 -17
- package/package.json +27 -22
- package/src/constants.ts +139 -77
- package/src/index.ts +70 -163
- package/src/obfuscationResult.ts +43 -0
- package/src/obfuscator.ts +328 -135
- package/src/options.ts +154 -623
- package/src/order.ts +14 -14
- package/src/presets.ts +39 -34
- package/src/probability.ts +21 -36
- package/src/templates/{bufferToString.ts → bufferToStringTemplate.ts} +5 -54
- package/src/templates/deadCodeTemplates.ts +1185 -0
- package/src/templates/getGlobalTemplate.ts +72 -0
- package/src/templates/integrityTemplate.ts +69 -0
- package/src/templates/setFunctionLengthTemplate.ts +11 -0
- package/src/templates/stringCompressionTemplate.ts +42 -0
- package/src/templates/tamperProtectionTemplates.ts +116 -0
- package/src/templates/template.ts +183 -92
- package/src/transforms/astScrambler.ts +99 -0
- package/src/transforms/calculator.ts +96 -224
- package/src/transforms/controlFlowFlattening.ts +1594 -0
- package/src/transforms/deadCode.ts +85 -628
- package/src/transforms/dispatcher.ts +431 -636
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +147 -299
- package/src/transforms/extraction/objectExtraction.ts +160 -333
- package/src/transforms/finalizer.ts +63 -64
- package/src/transforms/flatten.ts +439 -557
- package/src/transforms/functionOutlining.ts +225 -0
- package/src/transforms/identifier/globalConcealing.ts +261 -189
- package/src/transforms/identifier/movedDeclarations.ts +228 -142
- package/src/transforms/identifier/renameVariables.ts +252 -258
- package/src/transforms/lock/integrity.ts +84 -260
- package/src/transforms/lock/lock.ts +342 -491
- package/src/transforms/minify.ts +523 -663
- package/src/transforms/opaquePredicates.ts +90 -229
- package/src/transforms/pack.ts +195 -0
- package/src/transforms/plugin.ts +185 -0
- package/src/transforms/preparation.ts +337 -215
- package/src/transforms/renameLabels.ts +176 -77
- package/src/transforms/rgf.ts +293 -386
- package/src/transforms/shuffle.ts +80 -254
- package/src/transforms/string/encoding.ts +26 -129
- package/src/transforms/string/stringCompression.ts +118 -236
- package/src/transforms/string/stringConcealing.ts +255 -339
- package/src/transforms/string/stringEncoding.ts +28 -47
- package/src/transforms/string/stringSplitting.ts +61 -75
- package/src/transforms/variableMasking.ts +257 -0
- package/src/utils/ControlObject.ts +141 -0
- package/src/utils/IntGen.ts +33 -0
- package/src/utils/NameGen.ts +106 -0
- package/src/utils/ast-utils.ts +667 -0
- package/src/utils/function-utils.ts +50 -0
- package/src/utils/gen-utils.ts +48 -0
- package/src/utils/node.ts +78 -0
- package/src/utils/object-utils.ts +21 -0
- package/src/utils/random-utils.ts +79 -0
- package/src/utils/static-utils.ts +66 -0
- package/src/validateOptions.ts +256 -0
- package/tsconfig.json +13 -8
- package/babel.config.js +0 -12
- package/dev.js +0 -8
- package/dist/compiler.js +0 -34
- package/dist/parser.js +0 -59
- package/dist/precedence.js +0 -66
- package/dist/templates/bufferToString.js +0 -108
- package/dist/templates/crash.js +0 -59
- package/dist/templates/es5.js +0 -137
- package/dist/templates/functionLength.js +0 -34
- package/dist/templates/globals.js +0 -9
- package/dist/transforms/antiTooling.js +0 -88
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +0 -1281
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +0 -131
- package/dist/transforms/es5/antiClass.js +0 -164
- package/dist/transforms/es5/antiDestructuring.js +0 -193
- package/dist/transforms/es5/antiES6Object.js +0 -185
- package/dist/transforms/es5/antiSpreadOperator.js +0 -35
- package/dist/transforms/es5/antiTemplate.js +0 -66
- package/dist/transforms/es5/es5.js +0 -123
- package/dist/transforms/extraction/classExtraction.js +0 -83
- package/dist/transforms/identifier/globalAnalysis.js +0 -70
- package/dist/transforms/identifier/variableAnalysis.js +0 -104
- package/dist/transforms/lock/antiDebug.js +0 -76
- package/dist/transforms/stack.js +0 -343
- package/dist/transforms/transform.js +0 -350
- package/dist/traverse.js +0 -110
- package/dist/util/compare.js +0 -145
- package/dist/util/gen.js +0 -564
- package/dist/util/guard.js +0 -9
- package/dist/util/identifiers.js +0 -355
- package/dist/util/insert.js +0 -362
- package/dist/util/math.js +0 -19
- package/dist/util/object.js +0 -40
- package/dist/util/random.js +0 -130
- package/dist/util/scope.js +0 -20
- package/docs/ControlFlowFlattening.md +0 -595
- package/docs/Countermeasures.md +0 -63
- package/docs/ES5.md +0 -197
- package/docs/Integrity.md +0 -75
- package/docs/RGF.md +0 -419
- package/samples/example.js +0 -15
- package/samples/high.js +0 -1
- package/samples/input.js +0 -3
- package/samples/javascriptobfuscator.com.js +0 -8
- package/samples/jscrambler_advanced.js +0 -1894
- package/samples/jscrambler_light.js +0 -1134
- package/samples/low.js +0 -1
- package/samples/medium.js +0 -1
- package/samples/obfuscator.io.js +0 -1686
- package/samples/preemptive.com.js +0 -16
- package/src/compiler.ts +0 -35
- package/src/parser.ts +0 -49
- package/src/precedence.ts +0 -61
- package/src/templates/crash.ts +0 -55
- package/src/templates/es5.ts +0 -131
- package/src/templates/functionLength.ts +0 -32
- package/src/templates/globals.ts +0 -3
- package/src/transforms/antiTooling.ts +0 -102
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +0 -2146
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +0 -179
- package/src/transforms/es5/antiClass.ts +0 -272
- package/src/transforms/es5/antiDestructuring.ts +0 -294
- package/src/transforms/es5/antiES6Object.ts +0 -267
- package/src/transforms/es5/antiSpreadOperator.ts +0 -56
- package/src/transforms/es5/antiTemplate.ts +0 -98
- package/src/transforms/es5/es5.ts +0 -149
- package/src/transforms/extraction/classExtraction.ts +0 -168
- package/src/transforms/identifier/globalAnalysis.ts +0 -85
- package/src/transforms/identifier/variableAnalysis.ts +0 -118
- package/src/transforms/lock/antiDebug.ts +0 -112
- package/src/transforms/stack.ts +0 -551
- package/src/transforms/transform.ts +0 -453
- package/src/traverse.ts +0 -120
- package/src/types.ts +0 -131
- package/src/util/compare.ts +0 -181
- package/src/util/gen.ts +0 -651
- package/src/util/guard.ts +0 -7
- package/src/util/identifiers.ts +0 -494
- package/src/util/insert.ts +0 -419
- package/src/util/math.ts +0 -15
- package/src/util/object.ts +0 -39
- package/src/util/random.ts +0 -141
- package/src/util/scope.ts +0 -21
- package/test/code/Cash.src.js +0 -1011
- package/test/code/Cash.test.ts +0 -49
- package/test/code/Dynamic.src.js +0 -118
- package/test/code/Dynamic.test.ts +0 -49
- package/test/code/ES6.src.js +0 -235
- package/test/code/ES6.test.ts +0 -42
- package/test/code/NewFeatures.test.ts +0 -19
- package/test/code/StrictMode.src.js +0 -65
- package/test/code/StrictMode.test.js +0 -37
- package/test/compare.test.ts +0 -104
- package/test/index.test.ts +0 -249
- package/test/options.test.ts +0 -132
- package/test/presets.test.ts +0 -22
- package/test/probability.test.ts +0 -44
- package/test/templates/template.test.ts +0 -14
- package/test/transforms/antiTooling.test.ts +0 -52
- package/test/transforms/calculator.test.ts +0 -78
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +0 -1274
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +0 -192
- package/test/transforms/deadCode.test.ts +0 -85
- package/test/transforms/dispatcher.test.ts +0 -457
- package/test/transforms/es5/antiClass.test.ts +0 -427
- package/test/transforms/es5/antiDestructuring.test.ts +0 -157
- package/test/transforms/es5/antiES6Object.test.ts +0 -245
- package/test/transforms/es5/antiTemplate.test.ts +0 -116
- package/test/transforms/es5/es5.test.ts +0 -110
- package/test/transforms/extraction/classExtraction.test.ts +0 -86
- package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +0 -200
- package/test/transforms/extraction/objectExtraction.test.ts +0 -491
- package/test/transforms/flatten.test.ts +0 -721
- package/test/transforms/hexadecimalNumbers.test.ts +0 -62
- package/test/transforms/identifier/globalConcealing.test.ts +0 -72
- package/test/transforms/identifier/movedDeclarations.test.ts +0 -275
- package/test/transforms/identifier/renameVariables.test.ts +0 -621
- package/test/transforms/lock/antiDebug.test.ts +0 -66
- package/test/transforms/lock/browserLock.test.ts +0 -129
- package/test/transforms/lock/countermeasures.test.ts +0 -100
- package/test/transforms/lock/integrity.test.ts +0 -161
- package/test/transforms/lock/lock.test.ts +0 -204
- package/test/transforms/lock/osLock.test.ts +0 -312
- package/test/transforms/lock/selfDefending.test.ts +0 -68
- package/test/transforms/minify.test.ts +0 -575
- package/test/transforms/opaquePredicates.test.ts +0 -43
- package/test/transforms/preparation.test.ts +0 -157
- package/test/transforms/renameLabels.test.ts +0 -95
- package/test/transforms/rgf.test.ts +0 -378
- package/test/transforms/shuffle.test.ts +0 -135
- package/test/transforms/stack.test.ts +0 -573
- package/test/transforms/string/stringCompression.test.ts +0 -120
- package/test/transforms/string/stringConcealing.test.ts +0 -299
- package/test/transforms/string/stringEncoding.test.ts +0 -95
- package/test/transforms/string/stringSplitting.test.ts +0 -135
- package/test/transforms/transform.test.ts +0 -66
- package/test/traverse.test.ts +0 -139
- package/test/util/compare.test.ts +0 -34
- package/test/util/gen.test.ts +0 -121
- package/test/util/identifiers.test.ts +0 -253
- package/test/util/insert.test.ts +0 -142
- package/test/util/math.test.ts +0 -5
- package/test/util/random.test.ts +0 -71
- /package/dist/{types.js → obfuscationResult.js} +0 -0
|
@@ -1,311 +1,310 @@
|
|
|
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
|
|
7
|
-
var
|
|
8
|
-
var
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var t = _interopRequireWildcard(require("@babel/types"));
|
|
9
|
+
var _astUtils = require("../utils/ast-utils");
|
|
10
|
+
var _probability = require("../probability");
|
|
9
11
|
var _order = require("../order");
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
var
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
function
|
|
19
|
-
function
|
|
20
|
-
function
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* modified = true;
|
|
33
|
-
* if(reference) {
|
|
34
|
-
*
|
|
35
|
-
* }
|
|
36
|
-
* ...
|
|
37
|
-
* console.log(myParam);
|
|
38
|
-
* }
|
|
39
|
-
*
|
|
40
|
-
* // Output
|
|
41
|
-
* function myFunction_flat([myParam], flatObject){
|
|
42
|
-
* flatObject["set_modified"] = true;
|
|
43
|
-
* if(flatObject["get_reference"]) {
|
|
44
|
-
*
|
|
45
|
-
* }
|
|
46
|
-
* ...
|
|
47
|
-
* console.log(myParam)
|
|
48
|
-
* }
|
|
49
|
-
*
|
|
50
|
-
* function myFunction(){
|
|
51
|
-
* var flatObject = {
|
|
52
|
-
* set set_modified(v) { modified = v }
|
|
53
|
-
* get get_reference() { return reference }
|
|
54
|
-
* }
|
|
55
|
-
* return myFunction_flat([...arguments], flatObject)
|
|
56
|
-
* }
|
|
57
|
-
* ```
|
|
58
|
-
*
|
|
59
|
-
* Flatten is used to make functions eligible for the RGF transformation.
|
|
60
|
-
*
|
|
61
|
-
* - `myFunction_flat` is now eligible because it does not rely on outside scoped variables
|
|
62
|
-
*/
|
|
63
|
-
class Flatten extends _transform.default {
|
|
64
|
-
constructor(o) {
|
|
65
|
-
super(o, _order.ObfuscateOrder.Flatten);
|
|
66
|
-
_defineProperty(this, "isDebug", false);
|
|
67
|
-
_defineProperty(this, "definedNames", void 0);
|
|
68
|
-
// Array of FunctionDeclaration nodes
|
|
69
|
-
_defineProperty(this, "flattenedFns", void 0);
|
|
70
|
-
_defineProperty(this, "gen", void 0);
|
|
71
|
-
_defineProperty(this, "functionLengthName", void 0);
|
|
72
|
-
this.definedNames = new Map();
|
|
73
|
-
this.flattenedFns = [];
|
|
74
|
-
this.gen = this.getGenerator("mangled");
|
|
75
|
-
if (this.isDebug) {
|
|
76
|
-
console.warn("Flatten debug mode");
|
|
12
|
+
var _constants = require("../constants");
|
|
13
|
+
var _functionUtils = require("../utils/function-utils");
|
|
14
|
+
var _assert = require("assert");
|
|
15
|
+
var _NameGen = require("../utils/NameGen");
|
|
16
|
+
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); }
|
|
17
|
+
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; }
|
|
18
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
19
|
+
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."); }
|
|
20
|
+
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; } }
|
|
21
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
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 _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; } } }; }
|
|
27
|
+
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; } }
|
|
28
|
+
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; }
|
|
29
|
+
var _default = exports["default"] = function _default(_ref) {
|
|
30
|
+
var Plugin = _ref.Plugin;
|
|
31
|
+
var me = Plugin(_order.Order.Flatten, {
|
|
32
|
+
changeData: {
|
|
33
|
+
functions: 0
|
|
77
34
|
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if
|
|
82
|
-
|
|
35
|
+
});
|
|
36
|
+
var isDebug = false;
|
|
37
|
+
function flattenFunction(fnPath) {
|
|
38
|
+
// Skip if already processed
|
|
39
|
+
if (me.isSkipped(fnPath)) return;
|
|
40
|
+
|
|
41
|
+
// Don't apply to generator functions
|
|
42
|
+
if (fnPath.node.generator) return;
|
|
43
|
+
|
|
44
|
+
// Skip getter/setter methods
|
|
45
|
+
if (fnPath.isObjectMethod() || fnPath.isClassMethod()) {
|
|
46
|
+
if (fnPath.node.kind !== "method") return;
|
|
83
47
|
}
|
|
84
|
-
}
|
|
85
|
-
match(object, parents) {
|
|
86
|
-
return (object.type == "FunctionDeclaration" || object.type === "FunctionExpression") && object.body.type == "BlockStatement" && !object.$requiresEval && !object.generator && !object.params.find(x => x.type !== "Identifier");
|
|
87
|
-
}
|
|
88
|
-
transform(object, parents) {
|
|
89
|
-
return () => {
|
|
90
|
-
var _object$id, _parents$, _parents$0$id, _parents$0$id2, _parents$2, _parents$3;
|
|
91
|
-
if (parents[0]) {
|
|
92
|
-
// Don't change class methods
|
|
93
|
-
if (parents[0].type === "MethodDefinition" && parents[0].value === object) {
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
48
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
(0, _assert.ok)(object.type === "FunctionDeclaration" || object.type === "FunctionExpression");
|
|
49
|
+
// Do not apply to arrow functions
|
|
50
|
+
if (t.isArrowFunctionExpression(fnPath.node)) return;
|
|
51
|
+
if (!t.isBlockStatement(fnPath.node.body)) return;
|
|
103
52
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
53
|
+
// Skip if marked as unsafe
|
|
54
|
+
if (fnPath.node[_constants.UNSAFE]) return;
|
|
55
|
+
var program = fnPath.findParent(function (p) {
|
|
56
|
+
return p.isProgram();
|
|
57
|
+
});
|
|
58
|
+
var functionName = (0, _astUtils.getFunctionName)(fnPath);
|
|
59
|
+
if (!t.isValidIdentifier(functionName, true)) {
|
|
60
|
+
functionName = "anonymous";
|
|
61
|
+
}
|
|
62
|
+
if (!(0, _probability.computeProbabilityMap)(me.options.flatten, functionName)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
var strictMode = fnPath.find(function (path) {
|
|
66
|
+
return (0, _astUtils.isStrictMode)(path);
|
|
67
|
+
});
|
|
68
|
+
if (strictMode === fnPath) return;
|
|
69
|
+
me.log("Transforming", functionName);
|
|
70
|
+
var flatObjectName = "".concat(me.getPlaceholder(), "_flat_object");
|
|
71
|
+
var newFnName = "".concat(me.getPlaceholder(), "_flat_").concat(functionName);
|
|
72
|
+
var nameGen = new _NameGen.NameGen(me.options.identifierGenerator);
|
|
73
|
+
function generateProp(originalName, type) {
|
|
74
|
+
var newPropertyName;
|
|
75
|
+
do {
|
|
76
|
+
newPropertyName = isDebug ? type + "_" + originalName : nameGen.generate();
|
|
77
|
+
} while (allPropertyNames.has(newPropertyName));
|
|
78
|
+
allPropertyNames.add(newPropertyName);
|
|
79
|
+
return newPropertyName;
|
|
80
|
+
}
|
|
81
|
+
var standardProps = new Map();
|
|
82
|
+
var setterPropsNeeded = new Set();
|
|
83
|
+
var typeofProps = new Map();
|
|
84
|
+
var functionCallProps = new Map();
|
|
85
|
+
var allPropertyNames = new Set();
|
|
86
|
+
var identifierPaths = [];
|
|
87
|
+
|
|
88
|
+
// Traverse function to identify variables to be replaced with flat object properties
|
|
89
|
+
fnPath.traverse({
|
|
90
|
+
Identifier: {
|
|
91
|
+
exit: function exit(identifierPath) {
|
|
92
|
+
if (!(0, _astUtils.isVariableIdentifier)(identifierPath)) return;
|
|
93
|
+
if (identifierPath.isBindingIdentifier() && (0, _astUtils.isDefiningIdentifier)(identifierPath)) return;
|
|
94
|
+
if ((0, _functionUtils.isVariableFunctionIdentifier)(identifierPath)) return;
|
|
95
|
+
if (identifierPath.node[_constants.UNSAFE]) return;
|
|
96
|
+
var identifierName = identifierPath.node.name;
|
|
97
|
+
if (identifierName === "arguments") return;
|
|
98
|
+
var binding = identifierPath.scope.getBinding(identifierName);
|
|
99
|
+
if (!binding) {
|
|
127
100
|
return;
|
|
128
101
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
102
|
+
var definedLocal = identifierPath.scope;
|
|
103
|
+
do {
|
|
104
|
+
if (definedLocal.hasOwnBinding(identifierName)) return;
|
|
105
|
+
if (definedLocal === fnPath.scope) break;
|
|
106
|
+
definedLocal = definedLocal.parent;
|
|
107
|
+
if (definedLocal === program.scope) (0, _assert.ok)(functionName + ":" + identifierName);
|
|
108
|
+
} while (definedLocal);
|
|
109
|
+
var cursor = fnPath.scope.parent;
|
|
110
|
+
var isOutsideVariable = false;
|
|
111
|
+
do {
|
|
112
|
+
if (cursor.hasBinding(identifierName)) {
|
|
113
|
+
isOutsideVariable = true;
|
|
114
|
+
break;
|
|
135
115
|
}
|
|
116
|
+
cursor = cursor.parent;
|
|
117
|
+
} while (cursor);
|
|
118
|
+
if (!isOutsideVariable) {
|
|
136
119
|
return;
|
|
137
120
|
}
|
|
138
|
-
|
|
139
|
-
if (!isDefined) {
|
|
140
|
-
identifierNodes.push([o, p, info]);
|
|
141
|
-
}
|
|
121
|
+
identifierPaths.push(identifierPath);
|
|
142
122
|
}
|
|
143
|
-
if (o.type == "TryStatement") {
|
|
144
|
-
isIllegal = true;
|
|
145
|
-
return "EXIT";
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
if (isIllegal) {
|
|
149
|
-
return;
|
|
150
123
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
var
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
var
|
|
163
|
-
|
|
164
|
-
var
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (p[0].type === "UpdateExpression") {
|
|
179
|
-
getterPropNames[identifierName] = setterPropName;
|
|
180
|
-
} else {
|
|
181
|
-
// If assignment on member expression, ensure a getter function is also available: Ex. myObject.property = ...
|
|
182
|
-
var assignmentIndex = p.findIndex(x => x.type === "AssignmentExpression");
|
|
183
|
-
if (assignmentIndex !== -1 && p[assignmentIndex].left.type !== "Identifier") {
|
|
184
|
-
getterPropNames[identifierName] = setterPropName;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// calls flatObject.set_identifier_value(newValue)
|
|
189
|
-
this.replace(o, getFlatObjectMember(setterPropName));
|
|
190
|
-
break;
|
|
191
|
-
case "getter":
|
|
192
|
-
var getterPropName = getterPropNames[identifierName];
|
|
193
|
-
if (typeof getterPropName === "undefined") {
|
|
194
|
-
// No getter function made yet, make it (Try to re-use setter name if available)
|
|
195
|
-
getterPropName = setterPropNames[identifierName] || (this.isDebug ? "get_" + identifierName : this.gen.generate());
|
|
196
|
-
getterPropNames[identifierName] = getterPropName;
|
|
197
|
-
}
|
|
124
|
+
});
|
|
125
|
+
me.log("Function ".concat(functionName), "requires", Array.from(new Set(identifierPaths.map(function (x) {
|
|
126
|
+
return x.node.name;
|
|
127
|
+
}))));
|
|
128
|
+
for (var _i = 0, _identifierPaths = identifierPaths; _i < _identifierPaths.length; _i++) {
|
|
129
|
+
var identifierPath = _identifierPaths[_i];
|
|
130
|
+
var identifierName = identifierPath.node.name;
|
|
131
|
+
if (typeof identifierName !== "string") continue;
|
|
132
|
+
var isTypeof = identifierPath.parentPath.isUnaryExpression({
|
|
133
|
+
operator: "typeof"
|
|
134
|
+
});
|
|
135
|
+
var isFunctionCall = identifierPath.parentPath.isCallExpression() && identifierPath.parentPath.node.callee === identifierPath.node;
|
|
136
|
+
if (isTypeof) {
|
|
137
|
+
var typeofProp = typeofProps.get(identifierName);
|
|
138
|
+
if (!typeofProp) {
|
|
139
|
+
typeofProp = generateProp(identifierName, "typeof");
|
|
140
|
+
typeofProps.set(identifierName, typeofProp);
|
|
141
|
+
}
|
|
142
|
+
(0, _astUtils.ensureComputedExpression)(identifierPath.parentPath);
|
|
143
|
+
identifierPath.parentPath.replaceWith(t.memberExpression(t.identifier(flatObjectName), t.stringLiteral(typeofProp), true))[0].skip();
|
|
144
|
+
} else if (isFunctionCall) {
|
|
145
|
+
var functionCallProp = functionCallProps.get(identifierName);
|
|
146
|
+
if (!functionCallProp) {
|
|
147
|
+
functionCallProp = generateProp(identifierName, "call");
|
|
148
|
+
functionCallProps.set(identifierName, functionCallProp);
|
|
149
|
+
}
|
|
150
|
+
(0, _astUtils.ensureComputedExpression)(identifierPath);
|
|
198
151
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
152
|
+
// Replace identifier with a reference to the flat object property
|
|
153
|
+
identifierPath.replaceWith(t.memberExpression(t.identifier(flatObjectName), t.stringLiteral(functionCallProp), true))[0].skip();
|
|
154
|
+
} else {
|
|
155
|
+
var standardProp = standardProps.get(identifierName);
|
|
156
|
+
if (!standardProp) {
|
|
157
|
+
standardProp = generateProp(identifierName, "standard");
|
|
158
|
+
standardProps.set(identifierName, standardProp);
|
|
159
|
+
}
|
|
160
|
+
if (!setterPropsNeeded.has(identifierName)) {
|
|
161
|
+
// Only provide 'set' method if the variable is modified
|
|
162
|
+
var isModification = (0, _astUtils.isModifiedIdentifier)(identifierPath);
|
|
163
|
+
if (isModification) {
|
|
164
|
+
setterPropsNeeded.add(identifierName);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
(0, _astUtils.ensureComputedExpression)(identifierPath);
|
|
207
168
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
169
|
+
// Replace identifier with a reference to the flat object property
|
|
170
|
+
identifierPath.replaceWith(t.memberExpression(t.identifier(flatObjectName), t.stringLiteral(standardProp), true))[0].skip();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
213
173
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
callPropNames[identifierName] = callPropName;
|
|
220
|
-
}
|
|
174
|
+
// for (const prop of [...typeofProps.keys(), ...functionCallProps.keys()]) {
|
|
175
|
+
// if (!standardProps.has(prop)) {
|
|
176
|
+
// standardProps.set(prop, generateProp());
|
|
177
|
+
// }
|
|
178
|
+
// }
|
|
221
179
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
180
|
+
var flatObjectProperties = [];
|
|
181
|
+
var _iterator = _createForOfIteratorHelper(standardProps),
|
|
182
|
+
_step;
|
|
183
|
+
try {
|
|
184
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
185
|
+
var entry = _step.value;
|
|
186
|
+
var _entry = entry,
|
|
187
|
+
_entry2 = _slicedToArray(_entry, 2),
|
|
188
|
+
_identifierName = _entry2[0],
|
|
189
|
+
objectProp = _entry2[1];
|
|
190
|
+
flatObjectProperties.push(me.skip(t.objectMethod("get", t.stringLiteral(objectProp), [], t.blockStatement([t.returnStatement(t.identifier(_identifierName))]), false, false, false)));
|
|
227
191
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
192
|
+
// Not all properties need a setter
|
|
193
|
+
if (setterPropsNeeded.has(_identifierName)) {
|
|
194
|
+
var valueArgName = me.getPlaceholder() + "_value";
|
|
195
|
+
flatObjectProperties.push(me.skip(t.objectMethod("set", t.stringLiteral(objectProp), [t.identifier(valueArgName)], t.blockStatement([t.expressionStatement(t.assignmentExpression("=", t.identifier(_identifierName), t.identifier(valueArgName)))]), false, false, false)));
|
|
231
196
|
}
|
|
232
197
|
}
|
|
198
|
+
} catch (err) {
|
|
199
|
+
_iterator.e(err);
|
|
200
|
+
} finally {
|
|
201
|
+
_iterator.f();
|
|
202
|
+
}
|
|
203
|
+
var _iterator2 = _createForOfIteratorHelper(typeofProps),
|
|
204
|
+
_step2;
|
|
205
|
+
try {
|
|
206
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
207
|
+
var _entry3 = _step2.value;
|
|
208
|
+
var _entry4 = _slicedToArray(_entry3, 2),
|
|
209
|
+
_identifierName2 = _entry4[0],
|
|
210
|
+
_objectProp = _entry4[1];
|
|
211
|
+
flatObjectProperties.push(me.skip(t.objectMethod("get", t.stringLiteral(_objectProp), [], t.blockStatement([t.returnStatement(t.unaryExpression("typeof", t.identifier(_identifierName2)))]), false, false, false)));
|
|
212
|
+
}
|
|
213
|
+
} catch (err) {
|
|
214
|
+
_iterator2.e(err);
|
|
215
|
+
} finally {
|
|
216
|
+
_iterator2.f();
|
|
217
|
+
}
|
|
218
|
+
var _iterator3 = _createForOfIteratorHelper(functionCallProps),
|
|
219
|
+
_step3;
|
|
220
|
+
try {
|
|
221
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
222
|
+
var _entry5 = _step3.value;
|
|
223
|
+
var _entry6 = _slicedToArray(_entry5, 2),
|
|
224
|
+
_identifierName3 = _entry6[0],
|
|
225
|
+
_objectProp2 = _entry6[1];
|
|
226
|
+
flatObjectProperties.push(me.skip(t.objectMethod("method", t.stringLiteral(_objectProp2), [t.restElement(t.identifier("args"))], t.blockStatement([t.returnStatement(t.callExpression(t.identifier(_identifierName3), [t.spreadElement(t.identifier("args"))]))]), false, false, false)));
|
|
227
|
+
}
|
|
233
228
|
|
|
234
|
-
// Create the
|
|
235
|
-
|
|
229
|
+
// Create the new flattened function
|
|
230
|
+
} catch (err) {
|
|
231
|
+
_iterator3.e(err);
|
|
232
|
+
} finally {
|
|
233
|
+
_iterator3.f();
|
|
234
|
+
}
|
|
235
|
+
var flattenedFunctionDeclaration = t.functionDeclaration(t.identifier(newFnName), [t.arrayPattern(_toConsumableArray(fnPath.node.params)), t.identifier(flatObjectName)], t.blockStatement(_toConsumableArray(fnPath.node.body.body).concat()), false, fnPath.node.async);
|
|
236
236
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
flatObjectProperties.push((0, _gen.Property)((0, _gen.Literal)(getterPropName), (0, _gen.FunctionExpression)([], [(0, _gen.ReturnStatement)((0, _gen.Identifier)(identifierName))]), true, "get"));
|
|
241
|
-
}
|
|
237
|
+
// Create the flat object variable declaration
|
|
238
|
+
var flatObjectDeclaration = t.variableDeclaration("var", [t.variableDeclarator(t.identifier(flatObjectName), t.objectExpression(flatObjectProperties))]);
|
|
239
|
+
var argName = me.getPlaceholder() + "_args";
|
|
242
240
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
241
|
+
// Replace original function body with a call to the flattened function
|
|
242
|
+
fnPath.node.body = t.blockStatement([flatObjectDeclaration, t.returnStatement(t.callExpression(t.identifier(newFnName), [t.identifier(argName), t.identifier(flatObjectName)]))]);
|
|
243
|
+
var originalLength = (0, _functionUtils.computeFunctionLength)(fnPath);
|
|
244
|
+
fnPath.node.params = [t.restElement(t.identifier(argName))];
|
|
248
245
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
var argumentsName = this.getPlaceholder();
|
|
253
|
-
flatObjectProperties.push((0, _gen.Property)((0, _gen.Literal)(callPropName), (0, _gen.FunctionExpression)([(0, _gen.RestElement)((0, _gen.Identifier)(argumentsName))], [(0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.Identifier)(identifierName), [(0, _gen.SpreadElement)((0, _gen.Identifier)(argumentsName))]))]), true));
|
|
254
|
-
}
|
|
246
|
+
// Ensure updated parameter gets registered in the function scope
|
|
247
|
+
fnPath.scope.crawl();
|
|
248
|
+
fnPath.skip();
|
|
255
249
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
var newValueParameterName = this.getPlaceholder();
|
|
260
|
-
flatObjectProperties.push((0, _gen.Property)((0, _gen.Literal)(setterPropName), (0, _gen.FunctionExpression)([(0, _gen.Identifier)(newValueParameterName)], [(0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(identifierName), (0, _gen.Identifier)(newValueParameterName)))]), true, "set"));
|
|
261
|
-
}
|
|
262
|
-
if (!this.isDebug) {
|
|
263
|
-
(0, _random.shuffle)(flatObjectProperties);
|
|
264
|
-
}
|
|
265
|
-
var newBody = (0, _insert.getBlockBody)(object.body);
|
|
250
|
+
// Add the new flattened function at the top level
|
|
251
|
+
var newPath = (0, _astUtils.prependProgram)(program, flattenedFunctionDeclaration)[0];
|
|
252
|
+
me.skip(newPath);
|
|
266
253
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
254
|
+
// Copy over all properties except the predictable flag
|
|
255
|
+
var _iterator4 = _createForOfIteratorHelper(Object.getOwnPropertySymbols(fnPath.node)),
|
|
256
|
+
_step4;
|
|
257
|
+
try {
|
|
258
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
259
|
+
var symbol = _step4.value;
|
|
260
|
+
if (symbol !== _constants.PREDICTABLE) {
|
|
261
|
+
newPath.node[symbol] = fnPath.node[symbol];
|
|
262
|
+
}
|
|
270
263
|
}
|
|
271
|
-
var newFunctionDeclaration = (0, _gen.FunctionDeclaration)(newFnName, [(0, _gen.ArrayPattern)((0, _insert.clone)(object.params)), (0, _gen.Identifier)(flatObjectName)], newBody);
|
|
272
|
-
newFunctionDeclaration.async = !!object.async;
|
|
273
|
-
newFunctionDeclaration.generator = false;
|
|
274
|
-
this.flattenedFns.push(newFunctionDeclaration);
|
|
275
|
-
var argumentsName = this.getPlaceholder();
|
|
276
264
|
|
|
277
|
-
//
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
265
|
+
// Old function is no longer predictable (rest element parameter)
|
|
266
|
+
} catch (err) {
|
|
267
|
+
_iterator4.e(err);
|
|
268
|
+
} finally {
|
|
269
|
+
_iterator4.f();
|
|
270
|
+
}
|
|
271
|
+
fnPath.node[_constants.PREDICTABLE] = false;
|
|
272
|
+
// Old function is unsafe (uses arguments, this)
|
|
273
|
+
fnPath.node[_constants.UNSAFE] = true;
|
|
274
|
+
newPath.node[_constants.PREDICTABLE] = true;
|
|
283
275
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
276
|
+
// Carry over 'use strict' directive if not already present
|
|
277
|
+
if (strictMode) {
|
|
278
|
+
newPath.node.body.directives.push(t.directive(t.directiveLiteral("use strict")));
|
|
279
|
+
|
|
280
|
+
// Non-simple parameter list conversion
|
|
281
|
+
(0, _astUtils.prepend)(newPath, t.variableDeclaration("var", [t.variableDeclarator(t.arrayPattern(newPath.node.params), t.identifier("arguments"))]));
|
|
282
|
+
newPath.node.params = [];
|
|
283
|
+
// Using 'arguments' is unsafe
|
|
284
|
+
newPath.node[_constants.UNSAFE] = true;
|
|
285
|
+
// Params changed and using 'arguments'
|
|
286
|
+
newPath.node[_constants.PREDICTABLE] = false;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Ensure parameters are registered in the new function scope
|
|
290
|
+
newPath.scope.crawl();
|
|
291
|
+
newPath.skip();
|
|
292
|
+
me.skip(newPath);
|
|
293
|
+
|
|
294
|
+
// Set function length
|
|
295
|
+
me.setFunctionLength(fnPath, originalLength);
|
|
296
|
+
me.changeData.functions++;
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
visitor: {
|
|
300
|
+
Function: {
|
|
301
|
+
exit: function exit(path) {
|
|
302
|
+
flattenFunction(path);
|
|
306
303
|
}
|
|
304
|
+
},
|
|
305
|
+
Program: function Program(path) {
|
|
306
|
+
path.scope.crawl();
|
|
307
307
|
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
exports.default = Flatten;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
};
|