js-confuser 1.7.1 → 1.7.3
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/workflows/node.js.yml +1 -1
- package/CHANGELOG.md +73 -0
- package/README.md +32 -31
- package/dist/compiler.js +2 -8
- package/dist/constants.js +22 -10
- package/dist/index.js +15 -30
- package/dist/obfuscator.js +15 -62
- package/dist/options.js +33 -40
- package/dist/order.js +4 -7
- package/dist/parser.js +5 -13
- package/dist/precedence.js +6 -8
- package/dist/presets.js +4 -6
- package/dist/probability.js +13 -24
- package/dist/templates/bufferToString.js +121 -5
- package/dist/templates/core.js +35 -0
- package/dist/templates/crash.js +22 -11
- package/dist/templates/es5.js +125 -6
- package/dist/templates/functionLength.js +24 -6
- package/dist/templates/globals.js +9 -0
- package/dist/templates/template.js +189 -43
- package/dist/transforms/antiTooling.js +26 -22
- package/dist/transforms/calculator.js +19 -55
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +242 -333
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +46 -25
- package/dist/transforms/deadCode.js +542 -31
- package/dist/transforms/dispatcher.js +112 -112
- package/dist/transforms/es5/antiClass.js +70 -44
- package/dist/transforms/es5/antiDestructuring.js +14 -38
- package/dist/transforms/es5/antiES6Object.js +39 -48
- package/dist/transforms/es5/antiSpreadOperator.js +5 -14
- package/dist/transforms/es5/antiTemplate.js +10 -19
- package/dist/transforms/es5/es5.js +7 -40
- package/dist/transforms/extraction/classExtraction.js +83 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +41 -80
- package/dist/transforms/extraction/objectExtraction.js +24 -56
- package/dist/transforms/finalizer.js +6 -20
- package/dist/transforms/flatten.js +51 -99
- package/dist/transforms/identifier/globalAnalysis.js +21 -26
- package/dist/transforms/identifier/globalConcealing.js +72 -56
- package/dist/transforms/identifier/movedDeclarations.js +66 -38
- package/dist/transforms/identifier/renameVariables.js +36 -68
- package/dist/transforms/identifier/variableAnalysis.js +21 -48
- package/dist/transforms/lock/antiDebug.js +20 -25
- package/dist/transforms/lock/integrity.js +53 -52
- package/dist/transforms/lock/lock.js +161 -126
- package/dist/transforms/minify.js +77 -108
- package/dist/transforms/opaquePredicates.js +12 -49
- package/dist/transforms/preparation.js +28 -49
- package/dist/transforms/renameLabels.js +5 -22
- package/dist/transforms/rgf.js +125 -72
- package/dist/transforms/shuffle.js +42 -47
- package/dist/transforms/stack.js +41 -98
- package/dist/transforms/string/encoding.js +76 -27
- package/dist/transforms/string/stringCompression.js +75 -68
- package/dist/transforms/string/stringConcealing.js +127 -135
- package/dist/transforms/string/stringEncoding.js +6 -26
- package/dist/transforms/string/stringSplitting.js +5 -30
- package/dist/transforms/transform.js +76 -104
- package/dist/traverse.js +11 -18
- package/dist/util/compare.js +27 -29
- package/dist/util/gen.js +32 -86
- package/dist/util/guard.js +5 -1
- package/dist/util/identifiers.js +9 -72
- package/dist/util/insert.js +27 -77
- package/dist/util/math.js +0 -3
- package/dist/util/object.js +3 -7
- package/dist/util/random.js +31 -36
- package/dist/util/scope.js +6 -3
- package/docs/Countermeasures.md +13 -6
- package/docs/Integrity.md +35 -28
- package/docs/RGF.md +6 -1
- package/docs/RenameVariables.md +116 -0
- package/docs/TamperProtection.md +100 -0
- package/docs/Template.md +117 -0
- package/package.json +3 -3
- package/src/constants.ts +17 -0
- package/src/index.ts +7 -5
- package/src/options.ts +60 -7
- package/src/order.ts +2 -2
- package/src/templates/bufferToString.ts +79 -11
- package/src/templates/core.ts +29 -0
- package/src/templates/crash.ts +6 -38
- package/src/templates/es5.ts +1 -1
- package/src/templates/functionLength.ts +21 -3
- package/src/templates/globals.ts +3 -0
- package/src/templates/template.ts +205 -46
- package/src/transforms/antiTooling.ts +33 -11
- package/src/transforms/calculator.ts +4 -2
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +12 -5
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +46 -10
- package/src/transforms/deadCode.ts +74 -42
- package/src/transforms/dispatcher.ts +99 -73
- package/src/transforms/es5/antiClass.ts +25 -12
- package/src/transforms/es5/antiDestructuring.ts +1 -1
- package/src/transforms/es5/antiES6Object.ts +2 -2
- package/src/transforms/es5/antiTemplate.ts +1 -1
- package/src/transforms/extraction/classExtraction.ts +168 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +11 -16
- package/src/transforms/extraction/objectExtraction.ts +4 -15
- package/src/transforms/flatten.ts +20 -5
- package/src/transforms/identifier/globalAnalysis.ts +18 -1
- package/src/transforms/identifier/globalConcealing.ts +119 -72
- package/src/transforms/identifier/movedDeclarations.ts +90 -24
- package/src/transforms/identifier/renameVariables.ts +16 -1
- package/src/transforms/lock/antiDebug.ts +2 -2
- package/src/transforms/lock/integrity.ts +13 -11
- package/src/transforms/lock/lock.ts +122 -30
- package/src/transforms/minify.ts +28 -13
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +16 -0
- package/src/transforms/rgf.ts +139 -12
- package/src/transforms/shuffle.ts +3 -3
- package/src/transforms/stack.ts +19 -4
- package/src/transforms/string/encoding.ts +88 -51
- package/src/transforms/string/stringCompression.ts +86 -17
- package/src/transforms/string/stringConcealing.ts +148 -118
- package/src/transforms/string/stringEncoding.ts +1 -2
- package/src/transforms/string/stringSplitting.ts +1 -2
- package/src/transforms/transform.ts +63 -46
- package/src/types.ts +2 -0
- package/src/util/compare.ts +39 -5
- package/src/util/gen.ts +10 -3
- package/src/util/guard.ts +10 -0
- package/src/util/insert.ts +17 -0
- package/src/util/random.ts +81 -1
- package/src/util/scope.ts +14 -2
- package/test/code/Cash.test.ts +94 -5
- package/test/code/StrictMode.src.js +65 -0
- package/test/code/StrictMode.test.js +37 -0
- package/test/compare.test.ts +62 -2
- package/test/options.test.ts +129 -55
- package/test/templates/template.test.ts +211 -1
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +37 -18
- package/test/transforms/dispatcher.test.ts +55 -0
- package/test/transforms/extraction/classExtraction.test.ts +86 -0
- package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +8 -0
- package/test/transforms/extraction/objectExtraction.test.ts +2 -0
- package/test/transforms/identifier/globalConcealing.test.ts +89 -0
- package/test/transforms/identifier/movedDeclarations.test.ts +61 -0
- package/test/transforms/identifier/renameVariables.test.ts +75 -1
- package/test/transforms/lock/tamperProtection.test.ts +336 -0
- package/test/transforms/minify.test.ts +37 -0
- package/test/transforms/rgf.test.ts +50 -0
- package/dist/transforms/controlFlowFlattening/choiceFlowObfuscation.js +0 -62
- package/dist/transforms/controlFlowFlattening/controlFlowObfuscation.js +0 -159
- package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +0 -106
- package/dist/transforms/eval.js +0 -84
- package/dist/transforms/hexadecimalNumbers.js +0 -63
- package/dist/transforms/hideInitializingCode.js +0 -270
- package/dist/transforms/identifier/nameRecycling.js +0 -218
- package/dist/transforms/label.js +0 -67
- package/dist/transforms/preparation/nameConflicts.js +0 -116
- package/dist/transforms/preparation/preparation.js +0 -188
|
@@ -4,33 +4,25 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _traverse = require("../traverse");
|
|
9
|
-
|
|
10
8
|
var _gen = require("../util/gen");
|
|
11
|
-
|
|
12
9
|
var _identifiers = require("../util/identifiers");
|
|
13
|
-
|
|
14
10
|
var _insert = require("../util/insert");
|
|
15
|
-
|
|
16
11
|
var _transform = _interopRequireDefault(require("./transform"));
|
|
17
|
-
|
|
18
12
|
var _compare = require("../util/compare");
|
|
19
|
-
|
|
20
13
|
var _random = require("../util/random");
|
|
21
|
-
|
|
22
14
|
var _probability = require("../probability");
|
|
23
|
-
|
|
24
15
|
var _constants = require("../constants");
|
|
25
|
-
|
|
26
16
|
var _order = require("../order");
|
|
27
|
-
|
|
28
17
|
var _template = _interopRequireDefault(require("../templates/template"));
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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); }
|
|
34
26
|
/**
|
|
35
27
|
* A Dispatcher processes function calls. All the function declarations are brought into a dictionary.
|
|
36
28
|
*
|
|
@@ -56,76 +48,87 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
56
48
|
* 3. using `this`
|
|
57
49
|
*/
|
|
58
50
|
class Dispatcher extends _transform.default {
|
|
59
|
-
// Debug mode preserves function names
|
|
60
51
|
constructor(o) {
|
|
61
52
|
super(o, _order.ObfuscateOrder.Dispatcher);
|
|
62
|
-
|
|
53
|
+
// Debug mode preserves function names
|
|
63
54
|
_defineProperty(this, "isDebug", false);
|
|
64
|
-
|
|
65
55
|
_defineProperty(this, "count", void 0);
|
|
66
|
-
|
|
56
|
+
_defineProperty(this, "functionLengthName", void 0);
|
|
67
57
|
this.count = 0;
|
|
68
58
|
}
|
|
69
|
-
|
|
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
|
+
}
|
|
70
68
|
match(object, parents) {
|
|
71
69
|
if ((0, _compare.isInsideType)("AwaitExpression", object, parents)) {
|
|
72
70
|
return false;
|
|
73
71
|
}
|
|
74
|
-
|
|
75
|
-
return (0, _insert.isVarContext)(object) && object.type !== "ArrowFunctionExpression" && !object.$dispatcherSkip && !parents.find(x => x.$dispatcherSkip);
|
|
72
|
+
return (0, _insert.isVarContext)(object) && object.type !== "ArrowFunctionExpression" && !object.$multiTransformSkip && !parents.find(x => x.$multiTransformSkip);
|
|
76
73
|
}
|
|
77
|
-
|
|
78
74
|
transform(object, parents) {
|
|
79
75
|
return () => {
|
|
80
76
|
if ((0, _probability.ComputeProbabilityMap)(this.options.dispatcher, mode => mode)) {
|
|
81
77
|
if (object.type != "Program" && object.body.type != "BlockStatement") {
|
|
82
78
|
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
79
|
+
}
|
|
85
80
|
|
|
86
|
-
|
|
81
|
+
// Map of FunctionDeclarations
|
|
82
|
+
var functionDeclarations = Object.create(null);
|
|
87
83
|
|
|
84
|
+
// Array of Identifier nodes
|
|
88
85
|
var identifiers = [];
|
|
89
|
-
var illegalFnNames = new Set();
|
|
86
|
+
var illegalFnNames = new Set();
|
|
90
87
|
|
|
88
|
+
// New Names for Functions
|
|
91
89
|
var newFnNames = Object.create(null); // [old name]: randomized name
|
|
92
90
|
|
|
93
91
|
var context = (0, _insert.isVarContext)(object) ? object : (0, _insert.getVarContext)(object, parents);
|
|
92
|
+
var lexicalScope = (0, _insert.isFunction)(context) ? context.body : context;
|
|
94
93
|
(0, _traverse.walk)(object, parents, (o, p) => {
|
|
95
94
|
if (object == o) {
|
|
96
95
|
// Fix 1
|
|
97
96
|
return;
|
|
98
97
|
}
|
|
99
|
-
|
|
100
98
|
var c = (0, _insert.getVarContext)(o, p);
|
|
101
|
-
|
|
102
99
|
if (o.type == "FunctionDeclaration") {
|
|
103
100
|
c = (0, _insert.getVarContext)(p[0], p.slice(1));
|
|
104
101
|
}
|
|
105
|
-
|
|
106
102
|
if (context === c) {
|
|
107
103
|
if (o.type == "FunctionDeclaration" && o.id.name) {
|
|
108
104
|
var name = o.id.name;
|
|
109
|
-
|
|
110
|
-
if (o.$requiresEval || o.async || o.generator || p.find(x => x.$dispatcherSkip || x.type == "MethodDefinition") || o.body.type != "BlockStatement") {
|
|
105
|
+
if (o.$requiresEval || o.async || o.generator || p.find(x => x.$multiTransformSkip || x.type == "MethodDefinition") || o.body.type != "BlockStatement") {
|
|
111
106
|
illegalFnNames.add(name);
|
|
112
|
-
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
113
109
|
|
|
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
|
+
}
|
|
114
117
|
|
|
118
|
+
// If dupe, no routing
|
|
115
119
|
if (functionDeclarations[name]) {
|
|
116
120
|
illegalFnNames.add(name);
|
|
117
121
|
return;
|
|
118
122
|
}
|
|
119
|
-
|
|
120
123
|
(0, _traverse.walk)(o, p, (oo, pp) => {
|
|
121
124
|
if (oo.type == "Identifier" && oo.name == "arguments" || oo.type == "ThisExpression" || oo.type == "Super") {
|
|
122
125
|
if ((0, _insert.getVarContext)(oo, pp) === o) {
|
|
123
126
|
illegalFnNames.add(name);
|
|
124
127
|
return "EXIT";
|
|
125
128
|
}
|
|
126
|
-
}
|
|
127
|
-
|
|
129
|
+
}
|
|
128
130
|
|
|
131
|
+
// Avoid functions with function expressions as they have a different scope
|
|
129
132
|
if ((oo.type === "FunctionExpression" || oo.type === "ArrowFunctionExpression") && pp.find(x => x == o.params)) {
|
|
130
133
|
illegalFnNames.add(name);
|
|
131
134
|
return "EXIT";
|
|
@@ -134,18 +137,17 @@ class Dispatcher extends _transform.default {
|
|
|
134
137
|
functionDeclarations[name] = [o, p];
|
|
135
138
|
}
|
|
136
139
|
}
|
|
137
|
-
|
|
138
140
|
if (o.type == "Identifier") {
|
|
139
141
|
if (_constants.reservedIdentifiers.has(o.name)) {
|
|
140
142
|
return;
|
|
141
143
|
}
|
|
142
|
-
|
|
143
144
|
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
144
|
-
|
|
145
145
|
if (!info.spec.isReferenced) {
|
|
146
146
|
return;
|
|
147
147
|
}
|
|
148
|
-
|
|
148
|
+
if ((0, _guard.isJSConfuserVar)(p)) {
|
|
149
|
+
illegalFnNames.add(o.name);
|
|
150
|
+
}
|
|
149
151
|
if (info.spec.isDefined) {
|
|
150
152
|
if (info.isFunctionDeclaration) {
|
|
151
153
|
if (p[0].id && (!functionDeclarations[p[0].id.name] || functionDeclarations[p[0].id.name][0] !== p[0])) {
|
|
@@ -163,18 +165,23 @@ class Dispatcher extends _transform.default {
|
|
|
163
165
|
});
|
|
164
166
|
illegalFnNames.forEach(name => {
|
|
165
167
|
delete functionDeclarations[name];
|
|
166
|
-
});
|
|
168
|
+
});
|
|
167
169
|
|
|
170
|
+
// map original name->new game
|
|
168
171
|
var gen = this.getGenerator();
|
|
169
172
|
Object.keys(functionDeclarations).forEach(name => {
|
|
170
173
|
newFnNames[name] = this.isDebug ? "_dispatcher_" + this.count + "_" + name : gen.generate();
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
var set = new Set(Object.keys(newFnNames));
|
|
174
|
+
});
|
|
175
|
+
// set containing new name
|
|
176
|
+
var set = new Set(Object.keys(newFnNames));
|
|
174
177
|
|
|
178
|
+
// Only make a dispatcher function if it caught any functions
|
|
175
179
|
if (set.size > 0) {
|
|
180
|
+
if (!this.functionLengthName) {
|
|
181
|
+
this.functionLengthName = this.getPlaceholder();
|
|
182
|
+
}
|
|
176
183
|
var payloadArg = this.getPlaceholder() + "_dispatcher_" + this.count + "_payload";
|
|
177
|
-
var dispatcherFnName = this.getPlaceholder() + "_dispatcher_" + this.count;
|
|
184
|
+
var dispatcherFnName = this.getPlaceholder() + "_dispatcher_" + this.count + _constants.predictableFunctionTag;
|
|
178
185
|
this.log(dispatcherFnName, set);
|
|
179
186
|
this.count++;
|
|
180
187
|
var expectedGet = gen.generate();
|
|
@@ -184,56 +191,41 @@ class Dispatcher extends _transform.default {
|
|
|
184
191
|
var newReturnMemberName = gen.generate();
|
|
185
192
|
var shuffledKeys = (0, _random.shuffle)(Object.keys(functionDeclarations));
|
|
186
193
|
var mapName = this.getPlaceholder();
|
|
187
|
-
var cacheName = this.getPlaceholder();
|
|
188
|
-
// 1. create function map
|
|
194
|
+
var cacheName = this.getPlaceholder();
|
|
189
195
|
|
|
196
|
+
// creating the dispatcher function
|
|
197
|
+
// 1. create function map
|
|
190
198
|
var map = (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(mapName, (0, _gen.ObjectExpression)(shuffledKeys.map(name => {
|
|
191
199
|
var [def, defParents] = functionDeclarations[name];
|
|
192
200
|
var body = (0, _insert.getBlockBody)(def.body);
|
|
193
|
-
var functionExpression = {
|
|
201
|
+
var functionExpression = {
|
|
202
|
+
...def,
|
|
194
203
|
expression: false,
|
|
195
204
|
type: "FunctionExpression",
|
|
196
|
-
id: null
|
|
205
|
+
id: null,
|
|
206
|
+
params: [],
|
|
207
|
+
[_constants.predictableFunctionTag]: true
|
|
197
208
|
};
|
|
198
209
|
this.addComment(functionExpression, name);
|
|
199
|
-
|
|
200
210
|
if (def.params.length > 0) {
|
|
201
211
|
const fixParam = param => {
|
|
202
212
|
return param;
|
|
203
213
|
};
|
|
204
|
-
|
|
205
214
|
var variableDeclaration = (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)({
|
|
206
215
|
type: "ArrayPattern",
|
|
207
216
|
elements: def.params.map(fixParam)
|
|
208
217
|
}, (0, _gen.Identifier)(payloadArg)));
|
|
209
|
-
(0, _insert.prepend)(def.body, variableDeclaration);
|
|
210
|
-
|
|
211
|
-
var args = [0, 1, 2].map(x => this.getPlaceholder());
|
|
212
|
-
functionExpression.params = args.map(x => (0, _gen.Identifier)(x));
|
|
213
|
-
var deadCode = (0, _random.choice)(["fakeReturn", "ifStatement"]);
|
|
214
|
-
|
|
215
|
-
switch (deadCode) {
|
|
216
|
-
case "fakeReturn":
|
|
217
|
-
// Dead code...
|
|
218
|
-
var ifStatement = (0, _gen.IfStatement)((0, _gen.UnaryExpression)("!", (0, _gen.Identifier)(args[0])), [(0, _gen.ReturnStatement)((0, _gen.CallExpression)((0, _gen.Identifier)(args[1]), [(0, _gen.ThisExpression)(), (0, _gen.Identifier)(args[2])]))], null);
|
|
219
|
-
body.unshift(ifStatement);
|
|
220
|
-
break;
|
|
221
|
-
|
|
222
|
-
case "ifStatement":
|
|
223
|
-
var test = (0, _gen.LogicalExpression)("||", (0, _gen.Identifier)(args[0]), (0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(args[1]), (0, _gen.CallExpression)((0, _gen.Identifier)(args[2]), [])));
|
|
224
|
-
def.body = (0, _gen.BlockStatement)([(0, _gen.IfStatement)(test, [...body], null), (0, _gen.ReturnStatement)((0, _gen.Identifier)(args[1]))]);
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
227
|
-
} // For logging purposes
|
|
228
|
-
|
|
218
|
+
(0, _insert.prepend)(def.body, variableDeclaration);
|
|
219
|
+
}
|
|
229
220
|
|
|
221
|
+
// For logging purposes
|
|
230
222
|
var signature = name + "(" + def.params.map(x => x.name || "<>").join(",") + ")";
|
|
231
|
-
this.log("Added", signature);
|
|
223
|
+
this.log("Added", signature);
|
|
232
224
|
|
|
225
|
+
// delete ref in block
|
|
233
226
|
if (defParents.length) {
|
|
234
227
|
(0, _insert.deleteDirect)(def, defParents[0]);
|
|
235
228
|
}
|
|
236
|
-
|
|
237
229
|
this.addComment(functionExpression, signature);
|
|
238
230
|
return (0, _gen.Property)((0, _gen.Literal)(newFnNames[name]), functionExpression, false);
|
|
239
231
|
}))));
|
|
@@ -241,113 +233,121 @@ class Dispatcher extends _transform.default {
|
|
|
241
233
|
var x = this.getPlaceholder();
|
|
242
234
|
var y = this.getPlaceholder();
|
|
243
235
|
var z = this.getPlaceholder();
|
|
244
|
-
|
|
245
236
|
function getAccessor() {
|
|
246
237
|
return (0, _gen.MemberExpression)((0, _gen.Identifier)(mapName), (0, _gen.Identifier)(x), true);
|
|
247
|
-
}
|
|
248
|
-
|
|
238
|
+
}
|
|
249
239
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
(0, _gen.
|
|
256
|
-
|
|
257
|
-
(0, _gen.
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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}]
|
|
259
|
+
|
|
260
|
+
${this.options.preserveFunctionLength ? `if(a){
|
|
261
|
+
return ${this.functionLengthName}(fn, a)
|
|
262
|
+
}` : ""}
|
|
263
|
+
|
|
264
|
+
return fn
|
|
265
|
+
}
|
|
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
|
|
261
278
|
(0, _gen.ReturnStatement)((0, _gen.Identifier)(returnProp))])]);
|
|
262
279
|
(0, _insert.append)(object, fn);
|
|
263
|
-
|
|
264
280
|
if (payloadArg) {
|
|
265
281
|
(0, _insert.prepend)(object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(payloadArg, (0, _gen.ArrayExpression)([]))));
|
|
266
282
|
}
|
|
267
|
-
|
|
268
283
|
identifiers.forEach(_ref => {
|
|
269
284
|
let [o, p] = _ref;
|
|
270
|
-
|
|
271
285
|
if (o.type != "Identifier") {
|
|
272
286
|
return;
|
|
273
287
|
}
|
|
274
|
-
|
|
275
288
|
var newName = newFnNames[o.name];
|
|
276
|
-
|
|
277
289
|
if (!newName || typeof newName !== "string") {
|
|
278
290
|
return;
|
|
279
291
|
}
|
|
280
|
-
|
|
281
292
|
if (!functionDeclarations[o.name]) {
|
|
282
293
|
this.error(new Error("newName, missing function declaration"));
|
|
283
294
|
}
|
|
284
|
-
|
|
285
295
|
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
286
|
-
|
|
287
296
|
if (info.isFunctionCall && p[0].type == "CallExpression" && p[0].callee === o) {
|
|
288
297
|
// Invoking call expression: `a();`
|
|
298
|
+
|
|
289
299
|
if (o.name == dispatcherFnName) {
|
|
290
300
|
return;
|
|
291
301
|
}
|
|
292
|
-
|
|
293
|
-
this.log("".concat(o.name, "(").concat(p[0].arguments.map(_ => "<>").join(","), ") -> ").concat(dispatcherFnName, "('").concat(newName, "')"));
|
|
302
|
+
this.log(`${o.name}(${p[0].arguments.map(_ => "<>").join(",")}) -> ${dispatcherFnName}('${newName}')`);
|
|
294
303
|
var assignmentExpressions = [];
|
|
295
304
|
var dispatcherArgs = [(0, _gen.Literal)(newName)];
|
|
296
|
-
|
|
297
305
|
if (p[0].arguments.length) {
|
|
298
306
|
assignmentExpressions = [(0, _gen.AssignmentExpression)("=", (0, _gen.Identifier)(payloadArg), (0, _gen.ArrayExpression)(p[0].arguments))];
|
|
299
307
|
} else {
|
|
300
308
|
dispatcherArgs.push((0, _gen.Literal)(expectedClearArgs));
|
|
301
309
|
}
|
|
302
|
-
|
|
303
310
|
var type = (0, _random.choice)(["CallExpression", "NewExpression"]);
|
|
304
311
|
var callExpression = null;
|
|
305
|
-
|
|
306
312
|
switch (type) {
|
|
307
313
|
case "CallExpression":
|
|
308
314
|
callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(dispatcherFnName), dispatcherArgs);
|
|
309
315
|
break;
|
|
310
|
-
|
|
311
316
|
case "NewExpression":
|
|
312
317
|
if (dispatcherArgs.length == 1) {
|
|
313
318
|
dispatcherArgs.push((0, _gen.Identifier)("undefined"));
|
|
314
319
|
}
|
|
315
|
-
|
|
316
320
|
callExpression = (0, _gen.MemberExpression)((0, _gen.NewExpression)((0, _gen.Identifier)(dispatcherFnName), [...dispatcherArgs, (0, _gen.Literal)(expectedNew)]), (0, _gen.Identifier)(newReturnMemberName), false);
|
|
317
321
|
break;
|
|
318
322
|
}
|
|
319
|
-
|
|
320
323
|
this.addComment(callExpression, "Calling " + o.name + "(" + p[0].arguments.map(x => x.name).join(", ") + ")");
|
|
321
|
-
var expr = assignmentExpressions.length ? (0, _gen.SequenceExpression)([...assignmentExpressions, callExpression]) : callExpression;
|
|
324
|
+
var expr = assignmentExpressions.length ? (0, _gen.SequenceExpression)([...assignmentExpressions, callExpression]) : callExpression;
|
|
322
325
|
|
|
326
|
+
// Replace the parent call expression
|
|
323
327
|
this.replace(p[0], expr);
|
|
324
328
|
} else {
|
|
325
329
|
// Non-invoking reference: `a`
|
|
330
|
+
|
|
326
331
|
if (info.spec.isDefined) {
|
|
327
332
|
if (info.isFunctionDeclaration) {
|
|
328
333
|
this.log("Skipped getter " + o.name + " (function declaration)");
|
|
329
334
|
} else {
|
|
330
335
|
this.log("Skipped getter " + o.name + " (defined)");
|
|
331
336
|
}
|
|
332
|
-
|
|
333
337
|
return;
|
|
334
338
|
}
|
|
335
|
-
|
|
336
339
|
if (info.spec.isModified) {
|
|
337
340
|
this.log("Skipped getter " + o.name + " (modified)");
|
|
338
341
|
return;
|
|
339
342
|
}
|
|
340
|
-
|
|
341
|
-
this.log("(getter) ".concat(o.name, " -> ").concat(dispatcherFnName, "('").concat(newName, "')"));
|
|
343
|
+
this.log(`(getter) ${o.name} -> ${dispatcherFnName}('${newName}')`);
|
|
342
344
|
this.replace(o, (0, _gen.CallExpression)((0, _gen.Identifier)(dispatcherFnName), [(0, _gen.Literal)(newName), (0, _gen.Literal)(expectedGet)]));
|
|
343
345
|
}
|
|
344
346
|
});
|
|
345
|
-
(0, _insert.prepend)(object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)((0, _gen.Identifier)(cacheName),
|
|
347
|
+
(0, _insert.prepend)(object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)((0, _gen.Identifier)(cacheName), new _template.default(`Object.create(null)`).single().expression)));
|
|
346
348
|
}
|
|
347
349
|
}
|
|
348
350
|
};
|
|
349
351
|
}
|
|
350
|
-
|
|
351
352
|
}
|
|
352
|
-
|
|
353
353
|
exports.default = Dispatcher;
|
|
@@ -4,90 +4,81 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _transform = _interopRequireDefault(require("../transform"));
|
|
9
|
-
|
|
10
8
|
var _template = _interopRequireDefault(require("../../templates/template"));
|
|
11
|
-
|
|
12
9
|
var _traverse = require("../../traverse");
|
|
13
|
-
|
|
14
10
|
var _gen = require("../../util/gen");
|
|
15
|
-
|
|
16
11
|
var _assert = require("assert");
|
|
17
|
-
|
|
18
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
-
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
13
|
class AntiClass extends _transform.default {
|
|
21
14
|
constructor(o) {
|
|
22
15
|
super(o);
|
|
23
16
|
}
|
|
24
|
-
|
|
25
17
|
match(o, p) {
|
|
26
18
|
return o.type == "ClassDeclaration" || o.type == "ClassExpression";
|
|
27
19
|
}
|
|
28
|
-
|
|
29
20
|
transform(object, parents) {
|
|
30
21
|
return () => {
|
|
31
22
|
var body = object.body;
|
|
32
|
-
|
|
33
23
|
if (body.type !== "ClassBody") {
|
|
34
24
|
return;
|
|
35
25
|
}
|
|
36
|
-
|
|
37
26
|
if (!Array.isArray(body.body)) {
|
|
38
27
|
return;
|
|
39
28
|
}
|
|
40
|
-
|
|
41
29
|
var isDeclaration = object.type == "ClassDeclaration";
|
|
42
30
|
var virtualName = "virtual" + this.getPlaceholder();
|
|
43
31
|
var staticBody = [];
|
|
44
32
|
var virtualBody = [];
|
|
45
33
|
var superName;
|
|
46
|
-
var thisName = "this" + this.getPlaceholder();
|
|
34
|
+
var thisName = "this" + this.getPlaceholder();
|
|
47
35
|
|
|
48
|
-
|
|
49
|
-
virtualBody.push(
|
|
36
|
+
// self this
|
|
37
|
+
virtualBody.push(new _template.default(`var ${thisName} = this;`).single());
|
|
38
|
+
virtualBody.push(new _template.default(`${thisName}["constructor"] = null;`).single());
|
|
50
39
|
var superArguments;
|
|
51
40
|
var superBody = [];
|
|
52
|
-
|
|
53
41
|
if (object.superClass) {
|
|
54
42
|
superName = "super" + this.getPlaceholder();
|
|
55
43
|
}
|
|
56
|
-
|
|
57
44
|
var virtualDescriptorsName = this.getPlaceholder();
|
|
58
|
-
var staticDescriptorsName = this.getPlaceholder();
|
|
45
|
+
var staticDescriptorsName = this.getPlaceholder();
|
|
59
46
|
|
|
60
|
-
|
|
47
|
+
// getters/setters
|
|
48
|
+
virtualBody.push(new _template.default(`var ${virtualDescriptorsName} = {getters: {}, setters: {}}`).single());
|
|
61
49
|
|
|
62
|
-
|
|
50
|
+
// getters/setters
|
|
51
|
+
staticBody.push(new _template.default(`var ${staticDescriptorsName} = {getters: {}, setters: {}}`).single());
|
|
63
52
|
body.body.forEach(methodDefinition => {
|
|
64
53
|
if (!methodDefinition.key) {
|
|
65
54
|
return;
|
|
66
55
|
}
|
|
67
|
-
|
|
68
56
|
var isStatic = methodDefinition.static;
|
|
69
57
|
var key = (0, _gen.MemberExpression)(isStatic ? (0, _gen.Identifier)(virtualName) : (0, _gen.ThisExpression)(), methodDefinition.key, methodDefinition.computed);
|
|
70
58
|
var value = methodDefinition.value;
|
|
71
59
|
var pushingTo = isStatic ? staticBody : virtualBody;
|
|
72
|
-
|
|
73
60
|
if (superName && value.type == "FunctionExpression") {
|
|
74
61
|
var first = value.body.body[0];
|
|
75
|
-
|
|
76
62
|
if (first.type == "ExpressionStatement" && first.expression.type == "CallExpression") {
|
|
77
63
|
if (first.expression.callee.type == "Super") {
|
|
64
|
+
/// super(...args)
|
|
78
65
|
superArguments = first.expression.arguments;
|
|
79
66
|
value.body.body.shift();
|
|
67
|
+
} else if (
|
|
68
|
+
// F(super(...args))
|
|
69
|
+
first.expression.arguments[0] && first.expression.arguments[0].type === "CallExpression" && first.expression.arguments[0].callee.type === "Super") {
|
|
70
|
+
superArguments = first.expression.arguments[0].arguments;
|
|
71
|
+
first.expression.arguments[0] = (0, _gen.Identifier)("undefined");
|
|
80
72
|
}
|
|
81
73
|
}
|
|
82
|
-
|
|
83
74
|
(0, _traverse.walk)(value.body, [value, methodDefinition, body.body, body, object, ...parents], (o, p) => {
|
|
84
75
|
if (o.type == "Super") {
|
|
85
76
|
this.replace(o, (0, _gen.Identifier)(superName));
|
|
86
77
|
}
|
|
87
78
|
});
|
|
88
|
-
}
|
|
89
|
-
|
|
79
|
+
}
|
|
90
80
|
|
|
81
|
+
// Support class fields
|
|
91
82
|
if (methodDefinition.type === "PropertyDefinition") {
|
|
92
83
|
var assignmentExpression = (0, _gen.AssignmentExpression)("=", key, value || (0, _gen.Identifier)("undefined"));
|
|
93
84
|
pushingTo.push((0, _gen.ExpressionStatement)(assignmentExpression));
|
|
@@ -103,36 +94,71 @@ class AntiClass extends _transform.default {
|
|
|
103
94
|
throw new Error("Unsupported method definition");
|
|
104
95
|
}
|
|
105
96
|
});
|
|
106
|
-
virtualBody.push(
|
|
107
|
-
|
|
108
|
-
|
|
97
|
+
virtualBody.push(new _template.default(`
|
|
98
|
+
[...Object.keys(${virtualDescriptorsName}.getters), ...Object.keys(${virtualDescriptorsName}.setters)].forEach(key=>{
|
|
99
|
+
|
|
100
|
+
if( !${thisName}.hasOwnProperty(key) ) {
|
|
101
|
+
var getter = ${virtualDescriptorsName}.getters[key];
|
|
102
|
+
var setter = ${virtualDescriptorsName}.setters[key];
|
|
103
|
+
Object.defineProperty(${thisName}, key, {
|
|
104
|
+
get: getter,
|
|
105
|
+
set: setter,
|
|
106
|
+
configurable: true
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
`).single());
|
|
113
|
+
staticBody.push(new _template.default(`
|
|
114
|
+
[...Object.keys(${staticDescriptorsName}.getters), ...Object.keys(${staticDescriptorsName}.setters)].forEach(key=>{
|
|
115
|
+
|
|
116
|
+
if( !${virtualName}.hasOwnProperty(key) ) {
|
|
117
|
+
var getter = ${staticDescriptorsName}.getters[key];
|
|
118
|
+
var setter = ${staticDescriptorsName}.setters[key];
|
|
119
|
+
Object.defineProperty(${virtualName}, key, {
|
|
120
|
+
get: getter,
|
|
121
|
+
set: setter,
|
|
122
|
+
configurable: true
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
`).single());
|
|
109
129
|
if (superName) {
|
|
110
|
-
(0, _assert.ok)(superArguments, "
|
|
111
|
-
|
|
112
|
-
|
|
130
|
+
(0, _assert.ok)(superArguments, "Failed to find super() arguments");
|
|
131
|
+
|
|
132
|
+
// save the super state
|
|
133
|
+
virtualBody.unshift(new _template.default(`
|
|
134
|
+
Object.keys(this).forEach(key=>{
|
|
135
|
+
var descriptor = Object.getOwnPropertyDescriptor(this, key);
|
|
136
|
+
if ( descriptor) {
|
|
137
|
+
Object.defineProperty(${superName}, key, descriptor)
|
|
138
|
+
} else {
|
|
139
|
+
${superName}[key] = this[key];
|
|
140
|
+
}
|
|
141
|
+
})`).single());
|
|
113
142
|
virtualBody.unshift((0, _gen.ExpressionStatement)((0, _gen.CallExpression)((0, _gen.MemberExpression)(object.superClass, (0, _gen.Identifier)("call"), false), [(0, _gen.ThisExpression)(), ...superArguments])));
|
|
114
|
-
virtualBody.unshift(
|
|
143
|
+
virtualBody.unshift(new _template.default(`var ${superName} = {}`).single());
|
|
115
144
|
}
|
|
116
|
-
|
|
117
|
-
virtualBody.push((0, _template.default)("if(!this[\"constructor\"]){this[\"constructor\"] = ()=>{}};").single());
|
|
118
|
-
|
|
145
|
+
virtualBody.push(new _template.default(`if(!this["constructor"]){this["constructor"] = ()=>{}};`).single());
|
|
119
146
|
if (object.id && object.id.name) {
|
|
120
|
-
virtualBody.push(
|
|
147
|
+
virtualBody.push(new _template.default(`Object.defineProperty(this["constructor"], 'name', {
|
|
148
|
+
writable: true,
|
|
149
|
+
configurable: true,
|
|
150
|
+
value: '${object.id.name}'
|
|
151
|
+
});`).single());
|
|
121
152
|
}
|
|
122
|
-
|
|
123
|
-
virtualBody.push((0, _template.default)("this[\"constructor\"](...arguments)").single());
|
|
153
|
+
virtualBody.push(new _template.default(`this["constructor"](...arguments)`).single());
|
|
124
154
|
var virtualFunction = (0, _gen.FunctionExpression)([], virtualBody);
|
|
125
155
|
var completeBody = [(0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(virtualName, virtualFunction)), ...staticBody, (0, _gen.ReturnStatement)((0, _gen.Identifier)(virtualName))];
|
|
126
156
|
var expr = (0, _gen.CallExpression)((0, _gen.FunctionExpression)([], completeBody), []);
|
|
127
|
-
|
|
128
157
|
if (isDeclaration) {
|
|
129
158
|
expr = (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(object.id, expr));
|
|
130
159
|
}
|
|
131
|
-
|
|
132
160
|
this.replace(object, expr);
|
|
133
161
|
};
|
|
134
162
|
}
|
|
135
|
-
|
|
136
163
|
}
|
|
137
|
-
|
|
138
164
|
exports.default = AntiClass;
|