js-confuser 1.5.8 → 1.6.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/workflows/node.js.yml +2 -2
- package/CHANGELOG.md +69 -0
- package/README.md +143 -7
- package/dist/index.js +33 -4
- package/dist/obfuscator.js +30 -31
- package/dist/options.js +4 -5
- package/dist/order.js +4 -6
- package/dist/probability.js +2 -4
- package/dist/templates/bufferToString.js +13 -0
- package/dist/templates/crash.js +2 -2
- package/dist/templates/es5.js +18 -0
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/calculator.js +77 -21
- package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +8 -3
- package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
- package/dist/transforms/deadCode.js +33 -25
- package/dist/transforms/dispatcher.js +7 -6
- package/dist/transforms/es5/antiClass.js +6 -2
- package/dist/transforms/es5/antiDestructuring.js +3 -1
- package/dist/transforms/es5/es5.js +31 -34
- package/dist/transforms/eval.js +11 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +8 -5
- package/dist/transforms/extraction/objectExtraction.js +6 -1
- package/dist/transforms/finalizer.js +82 -0
- package/dist/transforms/flatten.js +82 -55
- package/dist/transforms/hexadecimalNumbers.js +34 -9
- package/dist/transforms/identifier/globalAnalysis.js +88 -0
- package/dist/transforms/identifier/globalConcealing.js +10 -83
- package/dist/transforms/identifier/movedDeclarations.js +2 -8
- package/dist/transforms/identifier/renameVariables.js +39 -27
- package/dist/transforms/identifier/variableAnalysis.js +58 -62
- package/dist/transforms/minify.js +80 -61
- package/dist/transforms/opaquePredicates.js +1 -1
- package/dist/transforms/preparation/preparation.js +2 -2
- package/dist/transforms/preparation.js +231 -0
- package/dist/transforms/renameLabels.js +1 -1
- package/dist/transforms/rgf.js +4 -5
- package/dist/transforms/stack.js +87 -26
- package/dist/transforms/string/encoding.js +150 -179
- package/dist/transforms/string/stringCompression.js +14 -15
- package/dist/transforms/string/stringConcealing.js +25 -8
- package/dist/transforms/string/stringEncoding.js +13 -24
- package/dist/transforms/transform.js +11 -18
- package/dist/traverse.js +24 -18
- package/dist/util/compare.js +2 -2
- package/dist/util/gen.js +15 -0
- package/dist/util/insert.js +31 -7
- package/dist/util/random.js +15 -0
- package/package.json +5 -5
- package/src/index.ts +57 -19
- package/src/obfuscator.ts +26 -29
- package/src/options.ts +17 -21
- package/src/order.ts +4 -8
- package/src/probability.ts +2 -3
- package/src/templates/bufferToString.ts +68 -0
- package/src/templates/crash.ts +5 -9
- package/src/templates/es5.ts +131 -0
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/calculator.ts +122 -59
- package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +18 -3
- package/src/transforms/deadCode.ts +383 -26
- package/src/transforms/dispatcher.ts +8 -6
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/es5/antiDestructuring.ts +3 -1
- package/src/transforms/es5/es5.ts +32 -77
- package/src/transforms/eval.ts +18 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -6
- package/src/transforms/extraction/objectExtraction.ts +12 -5
- package/src/transforms/finalizer.ts +75 -0
- package/src/transforms/flatten.ts +194 -151
- package/src/transforms/identifier/globalAnalysis.ts +85 -0
- package/src/transforms/identifier/globalConcealing.ts +14 -103
- package/src/transforms/identifier/movedDeclarations.ts +4 -11
- package/src/transforms/identifier/renameVariables.ts +37 -30
- package/src/transforms/identifier/variableAnalysis.ts +66 -73
- package/src/transforms/minify.ts +116 -77
- package/src/transforms/opaquePredicates.ts +2 -2
- package/src/transforms/preparation.ts +238 -0
- package/src/transforms/renameLabels.ts +2 -2
- package/src/transforms/rgf.ts +6 -7
- package/src/transforms/stack.ts +97 -37
- package/src/transforms/string/encoding.ts +115 -212
- package/src/transforms/string/stringCompression.ts +27 -18
- package/src/transforms/string/stringConcealing.ts +41 -11
- package/src/transforms/string/stringEncoding.ts +18 -18
- package/src/transforms/transform.ts +15 -21
- package/src/traverse.ts +24 -12
- package/src/types.ts +11 -2
- package/src/util/compare.ts +2 -2
- package/src/util/gen.ts +21 -1
- package/src/util/insert.ts +49 -9
- package/src/util/random.ts +13 -0
- package/test/code/Cash.test.ts +1 -1
- package/test/code/Dynamic.test.ts +12 -10
- package/test/code/ES6.src.js +136 -0
- package/test/code/ES6.test.ts +28 -2
- package/test/code/NewFeatures.test.ts +19 -0
- package/test/index.test.ts +15 -2
- package/test/probability.test.ts +44 -0
- package/test/templates/template.test.ts +1 -1
- package/test/transforms/antiTooling.test.ts +52 -0
- package/test/transforms/calculator.test.ts +40 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +713 -149
- package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
- package/test/transforms/deadCode.test.ts +66 -15
- package/test/transforms/dispatcher.test.ts +44 -1
- package/test/transforms/es5/antiClass.test.ts +33 -0
- package/test/transforms/es5/antiDestructuring.test.ts +16 -0
- package/test/transforms/eval.test.ts +53 -0
- package/test/transforms/extraction/objectExtraction.test.ts +21 -0
- package/test/transforms/flatten.test.ts +195 -3
- package/test/transforms/identifier/movedDeclarations.test.ts +27 -0
- package/test/transforms/identifier/renameVariables.test.ts +108 -0
- package/test/transforms/lock/antiDebug.test.ts +2 -2
- package/test/transforms/minify.test.ts +151 -0
- package/test/transforms/preparation.test.ts +157 -0
- package/test/transforms/rgf.test.ts +56 -29
- package/test/transforms/stack.test.ts +91 -21
- package/test/transforms/string/stringCompression.test.ts +39 -0
- package/test/transforms/string/stringConcealing.test.ts +115 -0
- package/test/transforms/string/stringEncoding.test.ts +53 -2
- package/test/transforms/transform.test.ts +66 -0
- package/test/traverse.test.ts +139 -0
- package/test/util/compare.test.ts +23 -1
- package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
- package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
- package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
- package/src/transforms/hexadecimalNumbers.ts +0 -31
- package/src/transforms/hideInitializingCode.ts +0 -432
- package/src/transforms/label.ts +0 -64
- package/src/transforms/preparation/nameConflicts.ts +0 -102
- package/src/transforms/preparation/preparation.ts +0 -176
- package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
- package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
- package/test/transforms/hideInitializingCode.test.ts +0 -336
- package/test/transforms/preparation/nameConflicts.test.ts +0 -52
- package/test/transforms/preparation/preparation.test.ts +0 -62
|
@@ -30,28 +30,29 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
30
30
|
/**
|
|
31
31
|
* Rename variables to randomly generated names.
|
|
32
32
|
*
|
|
33
|
-
* -
|
|
33
|
+
* - 1. First collect data on identifiers in all scope using 'VariableAnalysis'
|
|
34
|
+
* - 2. After 'VariableAnalysis' is finished start applying to each scope (top-down)
|
|
35
|
+
* - 3. Each scope, find the all names used here and exclude those names from being re-named
|
|
36
|
+
* - 4. Now loop through all the defined names in this scope and set it to a random name (or re-use previously generated name)
|
|
37
|
+
* - 5. Update all the Identifiers node's 'name' property to reflect this change
|
|
34
38
|
*/
|
|
35
39
|
class RenameVariables extends _transform.default {
|
|
36
|
-
// Generator object
|
|
37
40
|
// Names already used
|
|
38
41
|
// Map of Context->Object of changes
|
|
39
42
|
// Ref to VariableAnalysis data
|
|
40
43
|
constructor(o) {
|
|
41
44
|
super(o, _order.ObfuscateOrder.RenameVariables);
|
|
42
45
|
|
|
43
|
-
_defineProperty(this, "gen", void 0);
|
|
44
|
-
|
|
45
46
|
_defineProperty(this, "generated", void 0);
|
|
46
47
|
|
|
47
48
|
_defineProperty(this, "changed", void 0);
|
|
48
49
|
|
|
49
50
|
_defineProperty(this, "variableAnalysis", void 0);
|
|
50
51
|
|
|
51
|
-
this.changed = new Map();
|
|
52
|
+
this.changed = new Map(); // 1.
|
|
53
|
+
|
|
52
54
|
this.variableAnalysis = new _variableAnalysis.default(o);
|
|
53
55
|
this.before.push(this.variableAnalysis);
|
|
54
|
-
this.gen = this.getGenerator();
|
|
55
56
|
this.generated = [];
|
|
56
57
|
}
|
|
57
58
|
|
|
@@ -60,22 +61,24 @@ class RenameVariables extends _transform.default {
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
transform(object, parents) {
|
|
64
|
+
// 2. Notice this is on 'onEnter' (top-down)
|
|
63
65
|
var isGlobal = object.type == "Program";
|
|
64
66
|
var type = isGlobal ? "root" : (0, _insert.isVarContext)(object) ? "var" : (0, _insert.isLexContext)(object) ? "lex" : undefined;
|
|
65
67
|
(0, _assert.ok)(type);
|
|
66
68
|
var newNames = Object.create(null);
|
|
67
69
|
var defined = this.variableAnalysis.defined.get(object) || new Set();
|
|
68
|
-
var references = this.variableAnalysis.references.get(object) || new Set();
|
|
70
|
+
var references = this.variableAnalysis.references.get(object) || new Set(); // No changes needed here
|
|
69
71
|
|
|
70
72
|
if (!defined && !this.changed.has(object)) {
|
|
71
73
|
this.changed.set(object, Object.create(null));
|
|
72
74
|
return;
|
|
73
|
-
}
|
|
75
|
+
} // Names possible to be re-used here
|
|
76
|
+
|
|
74
77
|
|
|
75
|
-
var possible = new Set();
|
|
78
|
+
var possible = new Set(); // 3. Try to re-use names when possible
|
|
76
79
|
|
|
77
80
|
if (this.generated.length && !isGlobal) {
|
|
78
|
-
var allReferences = new Set(
|
|
81
|
+
var allReferences = new Set();
|
|
79
82
|
var nope = new Set(defined);
|
|
80
83
|
(0, _traverse.walk)(object, [], (o, p) => {
|
|
81
84
|
var ref = this.variableAnalysis.references.get(o);
|
|
@@ -98,7 +101,7 @@ class RenameVariables extends _transform.default {
|
|
|
98
101
|
Object.keys(changes).forEach(x => {
|
|
99
102
|
var name = changes[x];
|
|
100
103
|
|
|
101
|
-
if (!allReferences.has(x)) {
|
|
104
|
+
if (!allReferences.has(x) && !references.has(x)) {
|
|
102
105
|
passed.add(name);
|
|
103
106
|
} else {
|
|
104
107
|
nope.add(name);
|
|
@@ -108,38 +111,51 @@ class RenameVariables extends _transform.default {
|
|
|
108
111
|
});
|
|
109
112
|
nope.forEach(x => passed.delete(x));
|
|
110
113
|
possible = passed;
|
|
111
|
-
}
|
|
114
|
+
} // 4. Defined names to new names
|
|
115
|
+
|
|
112
116
|
|
|
113
|
-
|
|
114
|
-
if (
|
|
115
|
-
|
|
117
|
+
for (var name of defined) {
|
|
118
|
+
if (!name.startsWith("__NO_JS_CONFUSER_RENAME__") && ( // Variables prefixed with '__NO_JS_CONFUSER_RENAME__' are never renamed
|
|
119
|
+
isGlobal && !name.startsWith("__p_") // Variables prefixed with '__p_' are created by the obfuscator, always renamed
|
|
120
|
+
? (0, _probability.ComputeProbabilityMap)(this.options.renameGlobals, x => x, name) : true) && (0, _probability.ComputeProbabilityMap)( // Check the user's option for renaming variables
|
|
121
|
+
this.options.renameVariables, x => x, name, isGlobal)) {
|
|
122
|
+
// Create a new name from (1) or (2) methods
|
|
116
123
|
var newName;
|
|
117
124
|
|
|
118
125
|
do {
|
|
119
126
|
if (possible.size) {
|
|
127
|
+
// (1) Re-use previously generated name
|
|
120
128
|
var first = possible.values().next().value;
|
|
121
129
|
possible.delete(first);
|
|
122
130
|
newName = first;
|
|
123
131
|
} else {
|
|
124
|
-
//
|
|
125
|
-
var
|
|
126
|
-
newName =
|
|
127
|
-
this.generated.push(
|
|
132
|
+
// (2) Create a new name with `generateIdentifier` function
|
|
133
|
+
var generatedName = this.generateIdentifier();
|
|
134
|
+
newName = generatedName;
|
|
135
|
+
this.generated.push(generatedName);
|
|
128
136
|
}
|
|
129
|
-
} while (this.variableAnalysis.globals.has(newName));
|
|
137
|
+
} while (this.variableAnalysis.globals.has(newName)); // Ensure global names aren't overridden
|
|
138
|
+
|
|
130
139
|
|
|
131
140
|
newNames[name] = newName;
|
|
132
141
|
} else {
|
|
142
|
+
// This variable name was deemed not to be renamed.
|
|
133
143
|
newNames[name] = name;
|
|
134
144
|
}
|
|
135
|
-
}
|
|
136
|
-
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
this.changed.set(object, newNames); // 5. Update Identifier node's 'name' property
|
|
148
|
+
|
|
137
149
|
(0, _traverse.walk)(object, parents, (o, p) => {
|
|
138
150
|
if (o.type == "Identifier") {
|
|
139
151
|
if (_constants.reservedIdentifiers.has(o.name) || this.options.globalVariables.has(o.name)) {
|
|
140
152
|
return;
|
|
141
153
|
}
|
|
142
154
|
|
|
155
|
+
if (o.$renamed) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
143
159
|
var info = (0, _identifiers.getIdentifierInfo)(o, p);
|
|
144
160
|
|
|
145
161
|
if (info.spec.isExported) {
|
|
@@ -163,11 +179,7 @@ class RenameVariables extends _transform.default {
|
|
|
163
179
|
}
|
|
164
180
|
|
|
165
181
|
if (newName && typeof newName === "string") {
|
|
166
|
-
|
|
167
|
-
return;
|
|
168
|
-
} // Strange behavior where the `local` and `imported` objects are the same
|
|
169
|
-
|
|
170
|
-
|
|
182
|
+
// Strange behavior where the `local` and `imported` objects are the same
|
|
171
183
|
if (info.isImportSpecifier) {
|
|
172
184
|
var importSpecifierIndex = p.findIndex(x => x.type === "ImportSpecifier");
|
|
173
185
|
|
|
@@ -9,8 +9,6 @@ var _assert = require("assert");
|
|
|
9
9
|
|
|
10
10
|
var _constants = require("../../constants");
|
|
11
11
|
|
|
12
|
-
var _traverse = require("../../traverse");
|
|
13
|
-
|
|
14
12
|
var _compare = require("../../util/compare");
|
|
15
13
|
|
|
16
14
|
var _identifiers = require("../../util/identifiers");
|
|
@@ -37,10 +35,12 @@ class VariableAnalysis extends _transform.default {
|
|
|
37
35
|
|
|
38
36
|
/**
|
|
39
37
|
* Set of global identifiers to never be redefined
|
|
38
|
+
*
|
|
39
|
+
* - Used to not accidentally block access to a global variable
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
|
-
* Set of
|
|
43
|
+
* Set of identifiers that are defined within the program
|
|
44
44
|
*/
|
|
45
45
|
constructor(o) {
|
|
46
46
|
super(o);
|
|
@@ -60,72 +60,68 @@ class VariableAnalysis extends _transform.default {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
match(object, parents) {
|
|
63
|
-
return
|
|
63
|
+
return object.type === "Identifier";
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
transform(object, parents) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
67
|
+
var name = object.name;
|
|
68
|
+
(0, _assert.ok)(typeof name === "string");
|
|
69
|
+
|
|
70
|
+
if (!(0, _compare.isValidIdentifier)(name)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (_constants.reservedIdentifiers.has(name)) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (this.options.globalVariables.has(name)) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var info = (0, _identifiers.getIdentifierInfo)(object, parents);
|
|
83
|
+
|
|
84
|
+
if (!info.spec.isReferenced) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (info.spec.isExported) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
var isDefined = info.spec.isDefined; // Keep track of defined names within the program
|
|
93
|
+
|
|
94
|
+
if (isDefined) {
|
|
95
|
+
this.notGlobals.add(object.name);
|
|
96
|
+
this.globals.delete(object.name);
|
|
97
|
+
} else if (!this.notGlobals.has(object.name)) {
|
|
98
|
+
this.globals.add(object.name);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
var definingContexts = info.spec.isDefined ? (0, _insert.getAllDefiningContexts)(object, parents) : (0, _insert.getReferencingContexts)(object, parents, info);
|
|
102
|
+
(0, _assert.ok)(definingContexts.length);
|
|
103
|
+
definingContexts.forEach(definingContext => {
|
|
104
|
+
// ok(
|
|
105
|
+
// isContext(definingContext),
|
|
106
|
+
// `${definingContext.type} is not a context`
|
|
107
|
+
// );
|
|
108
|
+
if (isDefined) {
|
|
109
|
+
// Add to defined Map
|
|
110
|
+
if (!this.defined.has(definingContext)) {
|
|
111
|
+
this.defined.set(definingContext, new Set());
|
|
92
112
|
}
|
|
93
113
|
|
|
94
|
-
|
|
114
|
+
this.defined.get(definingContext).add(name);
|
|
115
|
+
this.references.has(definingContext) && this.references.get(definingContext).delete(name);
|
|
116
|
+
} else {
|
|
117
|
+
// Add to references Map
|
|
118
|
+
if (!this.defined.has(definingContext) || !this.defined.get(definingContext).has(name)) {
|
|
119
|
+
if (!this.references.has(definingContext)) {
|
|
120
|
+
this.references.set(definingContext, new Set());
|
|
121
|
+
}
|
|
95
122
|
|
|
96
|
-
|
|
97
|
-
this.notGlobals.add(o.name);
|
|
98
|
-
this.globals.delete(o.name);
|
|
99
|
-
} else if (!this.notGlobals.has(o.name)) {
|
|
100
|
-
this.globals.add(o.name);
|
|
123
|
+
this.references.get(definingContext).add(name);
|
|
101
124
|
}
|
|
102
|
-
|
|
103
|
-
var definingContexts = info.spec.isDefined ? (0, _insert.getAllDefiningContexts)(o, p) : (0, _insert.getReferencingContexts)(o, p, info);
|
|
104
|
-
(0, _assert.ok)(definingContexts.length);
|
|
105
|
-
definingContexts.forEach(definingContext => {
|
|
106
|
-
// ok(
|
|
107
|
-
// isContext(definingContext),
|
|
108
|
-
// `${definingContext.type} is not a context`
|
|
109
|
-
// );
|
|
110
|
-
if (isDefined) {
|
|
111
|
-
// Add to defined Map
|
|
112
|
-
if (!this.defined.has(definingContext)) {
|
|
113
|
-
this.defined.set(definingContext, new Set());
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
this.defined.get(definingContext).add(name);
|
|
117
|
-
this.references.has(definingContext) && this.references.get(definingContext).delete(name);
|
|
118
|
-
} else {
|
|
119
|
-
// Add to references Map
|
|
120
|
-
if (!this.defined.has(definingContext) || !this.defined.get(definingContext).has(name)) {
|
|
121
|
-
if (!this.references.has(definingContext)) {
|
|
122
|
-
this.references.set(definingContext, new Set());
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
this.references.get(definingContext).add(name);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
125
|
}
|
|
130
126
|
});
|
|
131
127
|
}
|
|
@@ -21,6 +21,8 @@ var _assert = require("assert");
|
|
|
21
21
|
|
|
22
22
|
var _scope = require("../util/scope");
|
|
23
23
|
|
|
24
|
+
var _template = _interopRequireDefault(require("../templates/template"));
|
|
25
|
+
|
|
24
26
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
27
|
|
|
26
28
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
@@ -34,12 +36,13 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
34
36
|
* - `x['y']` **->** `x.y`
|
|
35
37
|
*/
|
|
36
38
|
class Minify extends _transform.default {
|
|
39
|
+
/**
|
|
40
|
+
* A helper function that is introduced preserve function semantics
|
|
41
|
+
*/
|
|
37
42
|
constructor(o) {
|
|
38
43
|
super(o, _order.ObfuscateOrder.Minify);
|
|
39
44
|
|
|
40
|
-
_defineProperty(this, "
|
|
41
|
-
|
|
42
|
-
this.variables = new Map();
|
|
45
|
+
_defineProperty(this, "arrowFunctionName", void 0);
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
match(object, parents) {
|
|
@@ -75,7 +78,7 @@ class Minify extends _transform.default {
|
|
|
75
78
|
var startIndex = -1;
|
|
76
79
|
var sequences = [];
|
|
77
80
|
body.forEach((stmt, i) => {
|
|
78
|
-
if (stmt.type == "ExpressionStatement") {
|
|
81
|
+
if (stmt.type == "ExpressionStatement" && !stmt.directive) {
|
|
79
82
|
exprs.push(stmt.expression);
|
|
80
83
|
|
|
81
84
|
if (startIndex == -1) {
|
|
@@ -105,48 +108,44 @@ class Minify extends _transform.default {
|
|
|
105
108
|
(0, _assert.ok)(seq.index != -1);
|
|
106
109
|
body.splice(seq.index, seq.exprs.length, (0, _gen.ExpressionStatement)(seq.exprs.length == 1 ? seq.exprs[0] : (0, _gen.SequenceExpression)(seq.exprs)));
|
|
107
110
|
});
|
|
108
|
-
}
|
|
111
|
+
} // Unnecessary return
|
|
109
112
|
|
|
110
|
-
if (object.type != "SwitchCase") {
|
|
111
|
-
// Unnecessary return
|
|
112
|
-
if (body.length && body[body.length - 1]) {
|
|
113
|
-
var last = body[body.length - 1];
|
|
114
113
|
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
if (parents[0] && (0, _insert.isVarContext)(parents[0]) && body.length && body[body.length - 1]) {
|
|
115
|
+
var last = body[body.length - 1];
|
|
117
116
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
117
|
+
if (last.type == "ReturnStatement") {
|
|
118
|
+
var isUndefined = last.argument == null;
|
|
119
|
+
|
|
120
|
+
if (isUndefined) {
|
|
121
|
+
body.pop();
|
|
123
122
|
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
lastDec.declarations.push(...(0, _insert.clone)(x.declarations));
|
|
140
|
-
remove.unshift(i);
|
|
141
|
-
}
|
|
123
|
+
}
|
|
124
|
+
} // Variable declaration grouping
|
|
125
|
+
// var a = 1;
|
|
126
|
+
// var b = 1;
|
|
127
|
+
// var c = 1;
|
|
128
|
+
//
|
|
129
|
+
// var a=1,b=1,c=1;
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
var lastDec = null;
|
|
133
|
+
var remove = [];
|
|
134
|
+
body.forEach((x, i) => {
|
|
135
|
+
if (x.type === "VariableDeclaration") {
|
|
136
|
+
if (!lastDec || lastDec.kind !== x.kind || !lastDec.declarations.length) {
|
|
137
|
+
lastDec = x;
|
|
142
138
|
} else {
|
|
143
|
-
lastDec
|
|
139
|
+
lastDec.declarations.push(...(0, _insert.clone)(x.declarations));
|
|
140
|
+
remove.unshift(i);
|
|
144
141
|
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
142
|
+
} else {
|
|
143
|
+
lastDec = null;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
remove.forEach(x => {
|
|
147
|
+
body.splice(x, 1);
|
|
148
|
+
});
|
|
150
149
|
};
|
|
151
150
|
}
|
|
152
151
|
/**
|
|
@@ -169,29 +168,30 @@ class Minify extends _transform.default {
|
|
|
169
168
|
}
|
|
170
169
|
}
|
|
171
170
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
if (blockIndex !== -1) {
|
|
175
|
-
var block = parents[blockIndex];
|
|
176
|
-
var body = block.body;
|
|
171
|
+
if (object.type === "FunctionDeclaration") {
|
|
172
|
+
var body = parents[0];
|
|
177
173
|
|
|
178
174
|
if (!Array.isArray(body)) {
|
|
179
175
|
return;
|
|
180
176
|
}
|
|
181
177
|
|
|
182
|
-
var
|
|
183
|
-
var index = body.indexOf(stmt);
|
|
178
|
+
var index = body.indexOf(object);
|
|
184
179
|
|
|
185
180
|
if (index == -1) {
|
|
186
181
|
return;
|
|
187
182
|
}
|
|
188
183
|
|
|
189
184
|
var before = body.slice(0, index);
|
|
190
|
-
(0, _assert.ok)(!before.includes(
|
|
191
|
-
var
|
|
192
|
-
|
|
185
|
+
(0, _assert.ok)(!before.includes(object));
|
|
186
|
+
var beforeTypes = new Set(before.map(x => x.type));
|
|
187
|
+
beforeTypes.delete("FunctionDeclaration");
|
|
188
|
+
|
|
189
|
+
if (beforeTypes.size > 0) {
|
|
190
|
+
return;
|
|
191
|
+
} // Test Variant #25: Don't break redefined function declaration
|
|
193
192
|
|
|
194
|
-
|
|
193
|
+
|
|
194
|
+
if (object.id && body.find(x => x.type === "FunctionDeclaration" && x !== object && x.id && x.id.name === object.id.name)) {
|
|
195
195
|
return;
|
|
196
196
|
}
|
|
197
197
|
}
|
|
@@ -212,15 +212,28 @@ class Minify extends _transform.default {
|
|
|
212
212
|
});
|
|
213
213
|
|
|
214
214
|
if (canTransform) {
|
|
215
|
+
if (!this.arrowFunctionName) {
|
|
216
|
+
this.arrowFunctionName = this.getPlaceholder();
|
|
217
|
+
(0, _insert.append)(parents[parents.length - 1] || object, (0, _template.default)("\n function ".concat(this.arrowFunctionName, "(arrowFn){\n return function(){ return arrowFn(...arguments) }\n }\n ")).single());
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const wrap = object => {
|
|
221
|
+
return (0, _gen.CallExpression)((0, _gen.Identifier)(this.arrowFunctionName), [(0, _insert.clone)(object)]);
|
|
222
|
+
};
|
|
223
|
+
|
|
215
224
|
if (object.type == "FunctionExpression") {
|
|
216
225
|
object.type = "ArrowFunctionExpression";
|
|
226
|
+
this.replace(object, wrap((0, _insert.clone)(object)));
|
|
217
227
|
} else {
|
|
218
228
|
var arrow = { ...(0, _insert.clone)(object),
|
|
219
229
|
type: "ArrowFunctionExpression"
|
|
220
230
|
};
|
|
221
|
-
this.replace(object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(object.id.name, arrow)));
|
|
231
|
+
this.replace(object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(object.id.name, wrap(arrow))));
|
|
222
232
|
var x = this.transform(arrow, []);
|
|
223
|
-
|
|
233
|
+
|
|
234
|
+
if (typeof x === "function") {
|
|
235
|
+
x();
|
|
236
|
+
}
|
|
224
237
|
}
|
|
225
238
|
}
|
|
226
239
|
};
|
|
@@ -237,7 +250,7 @@ class Minify extends _transform.default {
|
|
|
237
250
|
|
|
238
251
|
if (body.length == 1 && stmt1.type == "ReturnStatement") {
|
|
239
252
|
// x=>{a: 1} // Invalid syntax
|
|
240
|
-
if (stmt1.argument.type != "ObjectExpression") {
|
|
253
|
+
if (stmt1.argument && stmt1.argument.type != "ObjectExpression") {
|
|
241
254
|
object.body = stmt1.argument;
|
|
242
255
|
object.expression = true;
|
|
243
256
|
}
|
|
@@ -372,7 +385,7 @@ class Minify extends _transform.default {
|
|
|
372
385
|
object.alternate = null;
|
|
373
386
|
}
|
|
374
387
|
|
|
375
|
-
if (object.consequent.body.length == 1 && object.alternate && object.alternate.body.length == 1) {
|
|
388
|
+
if (object.consequent && object.consequent.body && object.consequent.body.length == 1 && object.alternate && object.alternate.body.length == 1) {
|
|
376
389
|
var stmt1 = (0, _insert.clone)(object.consequent.body[0]);
|
|
377
390
|
var stmt2 = (0, _insert.clone)(object.alternate.body[0]); // if (a) {return b;} else {return c;} -> return a ? b : c;
|
|
378
391
|
|
|
@@ -405,8 +418,16 @@ class Minify extends _transform.default {
|
|
|
405
418
|
if (property.type == "Literal" && (0, _compare.isValidIdentifier)(property.value)) {
|
|
406
419
|
object.computed = false;
|
|
407
420
|
object.property.type = "Identifier";
|
|
408
|
-
object.property.name = (0, _insert.clone)(object.property.value);
|
|
409
|
-
|
|
421
|
+
object.property.name = (0, _insert.clone)(object.property.value); // obj.name &&
|
|
422
|
+
// this.log(
|
|
423
|
+
// obj.name +
|
|
424
|
+
// "['" +
|
|
425
|
+
// object.property.name +
|
|
426
|
+
// "'] -> " +
|
|
427
|
+
// obj.name +
|
|
428
|
+
// "." +
|
|
429
|
+
// object.property.name
|
|
430
|
+
// );
|
|
410
431
|
}
|
|
411
432
|
}
|
|
412
433
|
|
|
@@ -421,18 +442,16 @@ class Minify extends _transform.default {
|
|
|
421
442
|
} // { "x": 1 } -> {x: 1}
|
|
422
443
|
|
|
423
444
|
|
|
424
|
-
if (object.type
|
|
445
|
+
if (object.type === "Property" || object.type === "MethodDefinition") {
|
|
425
446
|
if (object.key.type == "SequenceExpression" && object.key.expressions.length == 1) {
|
|
426
447
|
object.key = object.key.expressions[0];
|
|
427
448
|
object.computed = true;
|
|
428
449
|
}
|
|
429
450
|
|
|
430
|
-
if (object.key.type == "Literal" && (0, _compare.isValidIdentifier)(object.key.value)) {
|
|
451
|
+
if (object.key.type == "Literal" && typeof object.key.value === "string" && (0, _compare.isValidIdentifier)(object.key.value)) {
|
|
431
452
|
object.key.type = "Identifier";
|
|
432
453
|
object.key.name = object.key.value;
|
|
433
454
|
object.computed = false;
|
|
434
|
-
} else if (object.key.type == "Identifier" && !(0, _compare.isValidIdentifier)(object.key.name)) {
|
|
435
|
-
object.key = (0, _gen.Literal)(object.key.name);
|
|
436
455
|
}
|
|
437
456
|
}
|
|
438
457
|
|
|
@@ -66,7 +66,7 @@ class OpaquePredicates extends _transform.default {
|
|
|
66
66
|
_defineProperty(this, "made", void 0);
|
|
67
67
|
|
|
68
68
|
this.predicates = Object.create(null);
|
|
69
|
-
this.gen = this.getGenerator(
|
|
69
|
+
this.gen = this.getGenerator();
|
|
70
70
|
this.made = 0;
|
|
71
71
|
}
|
|
72
72
|
|
|
@@ -103,9 +103,9 @@ class ExplicitIdentifiers extends _transform.default {
|
|
|
103
103
|
if (parents[propIndex].type == "MethodDefinition" && parents[propIndex].kind == "constructor") {
|
|
104
104
|
return;
|
|
105
105
|
}
|
|
106
|
-
}
|
|
106
|
+
} // this.log(object.name, "->", `'${object.name}'`);
|
|
107
|
+
|
|
107
108
|
|
|
108
|
-
this.log(object.name, "->", "'".concat(object.name, "'"));
|
|
109
109
|
this.replace(object, (0, _gen.Literal)(object.name));
|
|
110
110
|
parents[0].computed = true;
|
|
111
111
|
parents[0].shorthand = false;
|