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,29 +4,21 @@ 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 _order = require("../order");
|
|
11
|
-
|
|
12
9
|
var _gen = require("../util/gen");
|
|
13
|
-
|
|
14
10
|
var _insert = require("../util/insert");
|
|
15
|
-
|
|
16
11
|
var _compare = require("../util/compare");
|
|
17
|
-
|
|
18
12
|
var _traverse = require("../traverse");
|
|
19
|
-
|
|
20
13
|
var _assert = require("assert");
|
|
21
|
-
|
|
22
14
|
var _scope = require("../util/scope");
|
|
23
|
-
|
|
24
15
|
var _template = _interopRequireDefault(require("../templates/template"));
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
function _defineProperty(
|
|
29
|
-
|
|
16
|
+
var _globals = require("../templates/globals");
|
|
17
|
+
var _identifiers = require("../util/identifiers");
|
|
18
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
|
+
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; }
|
|
20
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
21
|
+
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); }
|
|
30
22
|
/**
|
|
31
23
|
* Basic transformations to reduce code size.
|
|
32
24
|
*
|
|
@@ -36,19 +28,16 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
36
28
|
* - `x['y']` **->** `x.y`
|
|
37
29
|
*/
|
|
38
30
|
class Minify extends _transform.default {
|
|
39
|
-
/**
|
|
40
|
-
* A helper function that is introduced preserve function semantics
|
|
41
|
-
*/
|
|
42
31
|
constructor(o) {
|
|
43
32
|
super(o, _order.ObfuscateOrder.Minify);
|
|
44
|
-
|
|
33
|
+
/**
|
|
34
|
+
* A helper function that is introduced preserve function semantics
|
|
35
|
+
*/
|
|
45
36
|
_defineProperty(this, "arrowFunctionName", void 0);
|
|
46
37
|
}
|
|
47
|
-
|
|
48
38
|
match(object, parents) {
|
|
49
39
|
return object.hasOwnProperty("type");
|
|
50
40
|
}
|
|
51
|
-
|
|
52
41
|
transform(object, parents) {
|
|
53
42
|
if ((0, _scope.isLexicalScope)(object)) {
|
|
54
43
|
return () => {
|
|
@@ -61,17 +50,16 @@ class Minify extends _transform.default {
|
|
|
61
50
|
earlyReturn = i + 1;
|
|
62
51
|
}
|
|
63
52
|
}
|
|
64
|
-
|
|
65
53
|
if (stmt.type == "FunctionDeclaration") {
|
|
66
54
|
fnDecs.push([stmt, i]);
|
|
67
55
|
}
|
|
68
56
|
});
|
|
69
|
-
|
|
70
57
|
if (earlyReturn < body.length) {
|
|
71
58
|
body.length = earlyReturn;
|
|
72
59
|
body.push(...fnDecs.filter(x => x[1] >= earlyReturn).map(x => x[0]));
|
|
73
|
-
}
|
|
60
|
+
}
|
|
74
61
|
|
|
62
|
+
// Now combine ExpressionStatements
|
|
75
63
|
|
|
76
64
|
if (body.length > 1) {
|
|
77
65
|
var exprs = [];
|
|
@@ -80,7 +68,6 @@ class Minify extends _transform.default {
|
|
|
80
68
|
body.forEach((stmt, i) => {
|
|
81
69
|
if (stmt.type == "ExpressionStatement" && !stmt.directive) {
|
|
82
70
|
exprs.push(stmt.expression);
|
|
83
|
-
|
|
84
71
|
if (startIndex == -1) {
|
|
85
72
|
startIndex = i;
|
|
86
73
|
}
|
|
@@ -91,44 +78,39 @@ class Minify extends _transform.default {
|
|
|
91
78
|
index: startIndex
|
|
92
79
|
});
|
|
93
80
|
}
|
|
94
|
-
|
|
95
81
|
exprs = [];
|
|
96
82
|
startIndex = -1;
|
|
97
83
|
}
|
|
98
84
|
});
|
|
99
|
-
|
|
100
85
|
if (exprs.length) {
|
|
101
86
|
sequences.push({
|
|
102
87
|
exprs: exprs,
|
|
103
88
|
index: startIndex
|
|
104
89
|
});
|
|
105
90
|
}
|
|
106
|
-
|
|
107
91
|
sequences.reverse().forEach(seq => {
|
|
108
92
|
(0, _assert.ok)(seq.index != -1);
|
|
109
93
|
body.splice(seq.index, seq.exprs.length, (0, _gen.ExpressionStatement)(seq.exprs.length == 1 ? seq.exprs[0] : (0, _gen.SequenceExpression)(seq.exprs)));
|
|
110
94
|
});
|
|
111
|
-
}
|
|
112
|
-
|
|
95
|
+
}
|
|
113
96
|
|
|
97
|
+
// Unnecessary return
|
|
114
98
|
if (parents[0] && (0, _insert.isVarContext)(parents[0]) && body.length && body[body.length - 1]) {
|
|
115
99
|
var last = body[body.length - 1];
|
|
116
|
-
|
|
117
100
|
if (last.type == "ReturnStatement") {
|
|
118
101
|
var isUndefined = last.argument == null;
|
|
119
|
-
|
|
120
102
|
if (isUndefined) {
|
|
121
103
|
body.pop();
|
|
122
104
|
}
|
|
123
105
|
}
|
|
124
|
-
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Variable declaration grouping
|
|
125
109
|
// var a = 1;
|
|
126
110
|
// var b = 1;
|
|
127
111
|
// var c = 1;
|
|
128
112
|
//
|
|
129
113
|
// var a=1,b=1,c=1;
|
|
130
|
-
|
|
131
|
-
|
|
132
114
|
var lastDec = null;
|
|
133
115
|
var remove = [];
|
|
134
116
|
body.forEach((x, i) => {
|
|
@@ -148,18 +130,16 @@ class Minify extends _transform.default {
|
|
|
148
130
|
});
|
|
149
131
|
};
|
|
150
132
|
}
|
|
133
|
+
|
|
151
134
|
/**
|
|
152
135
|
* ES6 and higher only
|
|
153
136
|
* - `function(){}` -> `()=>{}`
|
|
154
137
|
* - `function abc(){}` -> `var abc = ()=>{}`
|
|
155
138
|
*/
|
|
156
|
-
|
|
157
|
-
|
|
158
139
|
if (!this.options.es5 && (object.type == "FunctionExpression" || object.type == "FunctionDeclaration")) {
|
|
159
140
|
return () => {
|
|
160
141
|
// Don't touch `{get key(){...}}`
|
|
161
142
|
var propIndex = parents.findIndex(x => x.type == "Property" || x.type == "MethodDefinition");
|
|
162
|
-
|
|
163
143
|
if (propIndex !== -1) {
|
|
164
144
|
if (parents[propIndex].value === (parents[propIndex - 1] || object)) {
|
|
165
145
|
if (parents[propIndex].kind !== "init" || parents[propIndex].method) {
|
|
@@ -167,35 +147,28 @@ class Minify extends _transform.default {
|
|
|
167
147
|
}
|
|
168
148
|
}
|
|
169
149
|
}
|
|
170
|
-
|
|
171
150
|
if (object.type === "FunctionDeclaration") {
|
|
172
151
|
var body = parents[0];
|
|
173
|
-
|
|
174
152
|
if (!Array.isArray(body)) {
|
|
175
153
|
return;
|
|
176
154
|
}
|
|
177
|
-
|
|
178
155
|
var index = body.indexOf(object);
|
|
179
|
-
|
|
180
156
|
if (index == -1) {
|
|
181
157
|
return;
|
|
182
158
|
}
|
|
183
|
-
|
|
184
159
|
var before = body.slice(0, index);
|
|
185
160
|
(0, _assert.ok)(!before.includes(object));
|
|
186
161
|
var beforeTypes = new Set(before.map(x => x.type));
|
|
187
162
|
beforeTypes.delete("FunctionDeclaration");
|
|
188
|
-
|
|
189
163
|
if (beforeTypes.size > 0) {
|
|
190
164
|
return;
|
|
191
|
-
}
|
|
192
|
-
|
|
165
|
+
}
|
|
193
166
|
|
|
167
|
+
// Test Variant #25: Don't break redefined function declaration
|
|
194
168
|
if (object.id && body.find(x => x.type === "FunctionDeclaration" && x !== object && x.id && x.id.name === object.id.name)) {
|
|
195
169
|
return;
|
|
196
170
|
}
|
|
197
171
|
}
|
|
198
|
-
|
|
199
172
|
var canTransform = true;
|
|
200
173
|
(0, _traverse.walk)(object.body, [], ($object, $parents) => {
|
|
201
174
|
if ($object.type == "ThisExpression") {
|
|
@@ -204,33 +177,46 @@ class Minify extends _transform.default {
|
|
|
204
177
|
if ($object.name == "arguments") {
|
|
205
178
|
canTransform = false;
|
|
206
179
|
}
|
|
207
|
-
|
|
208
180
|
if ($object.name == "this") {
|
|
209
181
|
this.error(new Error("Use ThisExpression instead"));
|
|
210
182
|
}
|
|
211
183
|
}
|
|
212
184
|
});
|
|
213
|
-
|
|
214
185
|
if (canTransform) {
|
|
215
186
|
if (!this.arrowFunctionName) {
|
|
216
187
|
this.arrowFunctionName = this.getPlaceholder();
|
|
217
|
-
(0, _insert.append)(parents[parents.length - 1] || object,
|
|
188
|
+
(0, _insert.append)(parents[parents.length - 1] || object, new _template.default(`
|
|
189
|
+
function ${this.arrowFunctionName}(arrowFn, functionLength = 0){
|
|
190
|
+
var functionObject = function(){ return arrowFn(...arguments) };
|
|
191
|
+
|
|
192
|
+
${this.options.preserveFunctionLength ? `return {ObjectDefineProperty}(functionObject, "length", {
|
|
193
|
+
"value": functionLength,
|
|
194
|
+
"configurable": true
|
|
195
|
+
});` : `return functionObject`}
|
|
196
|
+
|
|
197
|
+
}
|
|
198
|
+
`).single({
|
|
199
|
+
ObjectDefineProperty: this.options.preserveFunctionLength ? this.createInitVariable(_globals.ObjectDefineProperty, parents) : undefined
|
|
200
|
+
}));
|
|
218
201
|
}
|
|
219
|
-
|
|
220
202
|
const wrap = object => {
|
|
221
|
-
|
|
203
|
+
var args = [(0, _insert.clone)(object)];
|
|
204
|
+
var fnLength = (0, _insert.computeFunctionLength)(object.params);
|
|
205
|
+
if (this.options.preserveFunctionLength && fnLength != 0) {
|
|
206
|
+
args.push((0, _gen.Literal)(fnLength));
|
|
207
|
+
}
|
|
208
|
+
return (0, _gen.CallExpression)((0, _gen.Identifier)(this.arrowFunctionName), args);
|
|
222
209
|
};
|
|
223
|
-
|
|
224
210
|
if (object.type == "FunctionExpression") {
|
|
225
211
|
object.type = "ArrowFunctionExpression";
|
|
226
212
|
this.replace(object, wrap((0, _insert.clone)(object)));
|
|
227
213
|
} else {
|
|
228
|
-
var arrow = {
|
|
214
|
+
var arrow = {
|
|
215
|
+
...(0, _insert.clone)(object),
|
|
229
216
|
type: "ArrowFunctionExpression"
|
|
230
217
|
};
|
|
231
218
|
this.replace(object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(object.id.name, wrap(arrow))));
|
|
232
219
|
var x = this.transform(arrow, []);
|
|
233
|
-
|
|
234
220
|
if (typeof x === "function") {
|
|
235
221
|
x();
|
|
236
222
|
}
|
|
@@ -238,16 +224,14 @@ class Minify extends _transform.default {
|
|
|
238
224
|
}
|
|
239
225
|
};
|
|
240
226
|
}
|
|
227
|
+
|
|
241
228
|
/**
|
|
242
229
|
* ()=>{ expr } -> ()=>expr
|
|
243
230
|
*/
|
|
244
|
-
|
|
245
|
-
|
|
246
231
|
if (object.type == "ArrowFunctionExpression" && object.body.type == "BlockStatement") {
|
|
247
232
|
return () => {
|
|
248
233
|
var body = (0, _insert.getBlockBody)(object.body);
|
|
249
234
|
var stmt1 = body[0];
|
|
250
|
-
|
|
251
235
|
if (body.length == 1 && stmt1.type == "ReturnStatement") {
|
|
252
236
|
// x=>{a: 1} // Invalid syntax
|
|
253
237
|
if (stmt1.argument && stmt1.argument.type != "ObjectExpression") {
|
|
@@ -257,10 +241,8 @@ class Minify extends _transform.default {
|
|
|
257
241
|
} else {
|
|
258
242
|
// ()=>{exprStmt;exprStmt;} -> ()=>(expr, expr, expr, undefined)
|
|
259
243
|
var exprs = body.filter(x => x.type == "ExpressionStatement");
|
|
260
|
-
|
|
261
244
|
if (exprs.length == body.length) {
|
|
262
245
|
var array = [];
|
|
263
|
-
|
|
264
246
|
function flatten(expr) {
|
|
265
247
|
if (expr.type == "SequenceExpression") {
|
|
266
248
|
expr.expressions.forEach(flatten);
|
|
@@ -270,51 +252,51 @@ class Minify extends _transform.default {
|
|
|
270
252
|
array.push(expr);
|
|
271
253
|
}
|
|
272
254
|
}
|
|
273
|
-
|
|
274
255
|
body.forEach(flatten);
|
|
275
256
|
object.body = (0, _gen.SequenceExpression)([...(0, _insert.clone)(array), (0, _gen.UnaryExpression)("void", (0, _gen.Literal)(0))]);
|
|
276
257
|
}
|
|
277
258
|
}
|
|
278
259
|
};
|
|
279
|
-
}
|
|
280
|
-
|
|
260
|
+
}
|
|
281
261
|
|
|
262
|
+
// (a()) -> a()
|
|
282
263
|
if (object.type == "SequenceExpression") {
|
|
283
264
|
return () => {
|
|
284
265
|
if (object.expressions.length == 1) {
|
|
285
266
|
this.replace(object, (0, _insert.clone)(object.expressions[0]));
|
|
286
267
|
}
|
|
287
268
|
};
|
|
288
|
-
}
|
|
289
|
-
|
|
269
|
+
}
|
|
290
270
|
|
|
271
|
+
// a += -1 -> a -= 1
|
|
291
272
|
if (object.type == "AssignmentExpression") {
|
|
292
273
|
return () => {
|
|
293
274
|
if (object.operator == "+=" && object.right.type == "UnaryExpression" && object.right.operator == "-") {
|
|
294
275
|
object.operator = "-=";
|
|
295
276
|
object.right = object.right.argument;
|
|
296
|
-
} else if (
|
|
277
|
+
} else if (
|
|
278
|
+
// a -= -1 -> a += 1
|
|
297
279
|
object.operator == "-=" && object.right.type == "UnaryExpression" && object.right.operator == "-") {
|
|
298
280
|
object.operator = "+=";
|
|
299
281
|
object.right = object.right.argument;
|
|
300
282
|
}
|
|
301
283
|
};
|
|
302
|
-
}
|
|
303
|
-
|
|
284
|
+
}
|
|
304
285
|
|
|
286
|
+
// a + -b -> a - b
|
|
305
287
|
if (object.type == "BinaryExpression") {
|
|
306
288
|
return () => {
|
|
307
289
|
if (object.operator == "+" && object.right.type == "UnaryExpression" && object.right.operator == "-") {
|
|
308
290
|
object.operator = "-";
|
|
309
291
|
object.right = object.right.argument;
|
|
310
|
-
} else if (
|
|
292
|
+
} else if (
|
|
293
|
+
// a - -1 -> a + 1
|
|
311
294
|
object.operator == "-" && object.right.type == "UnaryExpression" && object.right.operator == "-") {
|
|
312
295
|
object.operator = "+";
|
|
313
296
|
object.right = object.right.argument;
|
|
314
297
|
}
|
|
315
298
|
};
|
|
316
299
|
}
|
|
317
|
-
|
|
318
300
|
if (object.type == "ForStatement" || object.type == "ForInStatement" || object.type == "ForOfStatement" || object.type == "WhileStatement") {
|
|
319
301
|
if (object.body.type == "BlockStatement") {
|
|
320
302
|
return () => {
|
|
@@ -323,15 +305,13 @@ class Minify extends _transform.default {
|
|
|
323
305
|
}
|
|
324
306
|
};
|
|
325
307
|
}
|
|
326
|
-
}
|
|
327
|
-
|
|
308
|
+
}
|
|
328
309
|
|
|
310
|
+
// Last switch case does not need break
|
|
329
311
|
if (object.type == "SwitchStatement") {
|
|
330
312
|
var last = object.cases[object.cases.length - 1];
|
|
331
|
-
|
|
332
313
|
if (last) {
|
|
333
314
|
var lastStatement = last.consequent[last.consequent.length - 1];
|
|
334
|
-
|
|
335
315
|
if (lastStatement && lastStatement.type == "BreakStatement" && lastStatement.label == null) {
|
|
336
316
|
last.consequent.pop();
|
|
337
317
|
}
|
|
@@ -348,21 +328,20 @@ class Minify extends _transform.default {
|
|
|
348
328
|
}
|
|
349
329
|
}
|
|
350
330
|
}
|
|
351
|
-
}
|
|
352
|
-
// Todo Make this shit readable
|
|
353
|
-
|
|
331
|
+
}
|
|
354
332
|
|
|
333
|
+
// if ( x ) { y() } -> x && y()
|
|
334
|
+
// Todo Make this shit readable
|
|
355
335
|
if (object.type == "IfStatement") {
|
|
356
336
|
if (object.consequent.type != "BlockStatement") {
|
|
357
337
|
this.replace(object.consequent, (0, _gen.BlockStatement)([(0, _insert.clone)(object.consequent)]));
|
|
358
338
|
}
|
|
359
|
-
|
|
360
339
|
if (object.alternate && object.alternate.type != "BlockStatement") {
|
|
361
340
|
this.replace(object.alternate, (0, _gen.BlockStatement)([(0, _insert.clone)(object.alternate)]));
|
|
362
341
|
}
|
|
342
|
+
var body = (0, _insert.getBlockBody)(object.consequent);
|
|
363
343
|
|
|
364
|
-
|
|
365
|
-
|
|
344
|
+
// Check for hard-coded if statements
|
|
366
345
|
if (object.test.type == "Literal") {
|
|
367
346
|
if (object.test.value || object.test.regex) {
|
|
368
347
|
// Why would anyone test just a regex literal
|
|
@@ -371,33 +350,29 @@ class Minify extends _transform.default {
|
|
|
371
350
|
object.consequent = (0, _gen.BlockStatement)([]);
|
|
372
351
|
}
|
|
373
352
|
}
|
|
374
|
-
|
|
375
353
|
return () => {
|
|
376
354
|
// if ( a ) { } else {b()} -> if ( !a ) b();
|
|
377
355
|
if (body.length == 0 && object.alternate) {
|
|
378
356
|
object.test = (0, _gen.UnaryExpression)("!", (0, _insert.clone)(object.test));
|
|
379
|
-
|
|
380
357
|
if (object.alternate.type == "BlockStatement" && object.alternate.body.length == 1) {
|
|
381
358
|
object.alternate = (0, _insert.clone)(object.alternate.body[0]);
|
|
382
359
|
}
|
|
383
|
-
|
|
384
360
|
object.consequent = object.alternate;
|
|
385
361
|
object.alternate = null;
|
|
386
362
|
}
|
|
387
|
-
|
|
388
363
|
if (object.consequent && object.consequent.body && object.consequent.body.length == 1 && object.alternate && object.alternate.body.length == 1) {
|
|
389
364
|
var stmt1 = (0, _insert.clone)(object.consequent.body[0]);
|
|
390
|
-
var stmt2 = (0, _insert.clone)(object.alternate.body[0]);
|
|
365
|
+
var stmt2 = (0, _insert.clone)(object.alternate.body[0]);
|
|
391
366
|
|
|
367
|
+
// if (a) {return b;} else {return c;} -> return a ? b : c;
|
|
392
368
|
if (stmt1.type == "ReturnStatement" && stmt2.type == "ReturnStatement") {
|
|
393
369
|
this.replace(object, (0, _gen.ReturnStatement)((0, _gen.ConditionalExpression)((0, _insert.clone)(object.test), stmt1.argument || (0, _gen.Identifier)("undefined"), stmt2.argument || (0, _gen.Identifier)("undefined"))));
|
|
394
|
-
}
|
|
395
|
-
|
|
370
|
+
}
|
|
396
371
|
|
|
372
|
+
// if (a) {b = 0} else {b = 1} -> b = a ? 0 : 1;
|
|
397
373
|
if (stmt1.type == "ExpressionStatement" && stmt2.type == "ExpressionStatement") {
|
|
398
374
|
var e1 = stmt1.expression;
|
|
399
375
|
var e2 = stmt2.expression;
|
|
400
|
-
|
|
401
376
|
if (e1.type == "AssignmentExpression" && e2.type == "AssignmentExpression") {
|
|
402
377
|
if (e1.operator === e2.operator && (0, _compare.isEquivalent)(e1.left, e2.left)) {
|
|
403
378
|
this.replace(object, (0, _gen.ExpressionStatement)((0, _gen.AssignmentExpression)(e1.operator, e1.left, (0, _gen.ConditionalExpression)((0, _insert.clone)(object.test), e1.right, e2.right))));
|
|
@@ -406,19 +381,20 @@ class Minify extends _transform.default {
|
|
|
406
381
|
}
|
|
407
382
|
}
|
|
408
383
|
};
|
|
409
|
-
}
|
|
410
|
-
|
|
384
|
+
}
|
|
411
385
|
|
|
386
|
+
// x["abc"] -> x.abc
|
|
412
387
|
if (object.type == "MemberExpression") {
|
|
413
388
|
var {
|
|
414
389
|
object: obj,
|
|
415
390
|
property
|
|
416
391
|
} = object;
|
|
417
|
-
|
|
418
392
|
if (property.type == "Literal" && (0, _compare.isValidIdentifier)(property.value)) {
|
|
419
393
|
object.computed = false;
|
|
420
394
|
object.property.type = "Identifier";
|
|
421
|
-
object.property.name = (0, _insert.clone)(object.property.value);
|
|
395
|
+
object.property.name = (0, _insert.clone)(object.property.value);
|
|
396
|
+
|
|
397
|
+
// obj.name &&
|
|
422
398
|
// this.log(
|
|
423
399
|
// obj.name +
|
|
424
400
|
// "['" +
|
|
@@ -430,31 +406,27 @@ class Minify extends _transform.default {
|
|
|
430
406
|
// );
|
|
431
407
|
}
|
|
432
408
|
}
|
|
433
|
-
|
|
434
409
|
if (object.type == "CallExpression") {
|
|
435
410
|
if (object.callee.type == "MemberExpression") {
|
|
436
411
|
var key = object.callee.computed ? object.callee.property.value : object.callee.property.name;
|
|
437
|
-
|
|
438
412
|
if (key == "toString" && object.arguments.length == 0) {
|
|
439
413
|
this.replace(object, (0, _gen.BinaryExpression)("+", (0, _gen.Literal)(""), (0, _insert.clone)(object.callee.object)));
|
|
440
414
|
}
|
|
441
415
|
}
|
|
442
|
-
}
|
|
443
|
-
|
|
416
|
+
}
|
|
444
417
|
|
|
418
|
+
// { "x": 1 } -> {x: 1}
|
|
445
419
|
if (object.type === "Property" || object.type === "MethodDefinition") {
|
|
446
420
|
if (object.key.type == "SequenceExpression" && object.key.expressions.length == 1) {
|
|
447
421
|
object.key = object.key.expressions[0];
|
|
448
422
|
object.computed = true;
|
|
449
423
|
}
|
|
450
|
-
|
|
451
424
|
if (object.key.type == "Literal" && typeof object.key.value === "string" && (0, _compare.isValidIdentifier)(object.key.value)) {
|
|
452
425
|
object.key.type = "Identifier";
|
|
453
426
|
object.key.name = object.key.value;
|
|
454
427
|
object.computed = false;
|
|
455
428
|
}
|
|
456
429
|
}
|
|
457
|
-
|
|
458
430
|
if (object.type == "VariableDeclarator") {
|
|
459
431
|
// undefined is not necessary
|
|
460
432
|
if (object.init && object.init.type == "Identifier") {
|
|
@@ -462,20 +434,21 @@ class Minify extends _transform.default {
|
|
|
462
434
|
object.init = null;
|
|
463
435
|
}
|
|
464
436
|
}
|
|
465
|
-
|
|
466
|
-
if (object.id.type == "ObjectPattern" && object.init.type == "ObjectExpression") {
|
|
437
|
+
if (object.id.type == "ObjectPattern" && object.init && object.init.type == "ObjectExpression") {
|
|
467
438
|
if (object.id.properties.length === 1 && object.init.properties.length === 1) {
|
|
468
439
|
var key1 = object.id.properties[0].computed ? object.id.properties[0].key.value : object.id.properties[0].key.name;
|
|
469
|
-
var key2 = object.init.properties[0].computed ? object.init.properties[0].key.value : object.init.properties[0].key.name;
|
|
440
|
+
var key2 = object.init.properties[0].computed ? object.init.properties[0].key.value : object.init.properties[0].key.name;
|
|
441
|
+
|
|
442
|
+
// console.log(key1, key2);
|
|
470
443
|
|
|
471
444
|
if (key1 && key2 && key1 === key2) {
|
|
472
445
|
object.id = object.id.properties[0].value;
|
|
473
446
|
object.init = object.init.properties[0].value;
|
|
474
447
|
}
|
|
475
448
|
}
|
|
476
|
-
}
|
|
477
|
-
|
|
449
|
+
}
|
|
478
450
|
|
|
451
|
+
// check for redundant patterns
|
|
479
452
|
if (object.id.type == "ArrayPattern" && object.init && typeof object.init === "object" && object.init.type == "ArrayExpression") {
|
|
480
453
|
if (object.id.elements.length == 1 && object.init.elements.length == 1) {
|
|
481
454
|
object.id = object.id.elements[0];
|
|
@@ -483,7 +456,6 @@ class Minify extends _transform.default {
|
|
|
483
456
|
}
|
|
484
457
|
}
|
|
485
458
|
}
|
|
486
|
-
|
|
487
459
|
if (object.type == "Literal") {
|
|
488
460
|
return () => {
|
|
489
461
|
switch (typeof object.value) {
|
|
@@ -493,9 +465,10 @@ class Minify extends _transform.default {
|
|
|
493
465
|
}
|
|
494
466
|
};
|
|
495
467
|
}
|
|
496
|
-
|
|
497
468
|
if (object.type == "Identifier") {
|
|
498
469
|
return () => {
|
|
470
|
+
var info = (0, _identifiers.getIdentifierInfo)(object, parents);
|
|
471
|
+
if (info.spec.isDefined || info.spec.isModified) return;
|
|
499
472
|
if (object.name == "undefined" && !(0, _insert.isForInitialize)(object, parents)) {
|
|
500
473
|
this.replaceIdentifierOrLiteral(object, (0, _gen.UnaryExpression)("void", (0, _gen.Literal)(0)), parents);
|
|
501
474
|
} else if (object.name == "Infinity") {
|
|
@@ -503,20 +476,16 @@ class Minify extends _transform.default {
|
|
|
503
476
|
}
|
|
504
477
|
};
|
|
505
478
|
}
|
|
506
|
-
|
|
507
479
|
if (object.type == "UnaryExpression" && object.operator == "!") {
|
|
508
480
|
if (object.argument.type == "Literal" && !object.argument.regex) {
|
|
509
481
|
this.replace(object, (0, _gen.Literal)(!object.argument.value));
|
|
510
482
|
}
|
|
511
483
|
}
|
|
512
|
-
|
|
513
484
|
if (object.type == "ConditionalExpression") {
|
|
514
485
|
if (object.test.type == "Literal" && !object.test.regex) {
|
|
515
486
|
this.replace(object, object.test.value ? object.consequent : object.alternate);
|
|
516
487
|
}
|
|
517
488
|
}
|
|
518
489
|
}
|
|
519
|
-
|
|
520
490
|
}
|
|
521
|
-
|
|
522
491
|
exports.default = Minify;
|