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.
Files changed (153) hide show
  1. package/.github/workflows/node.js.yml +1 -1
  2. package/CHANGELOG.md +73 -0
  3. package/README.md +32 -31
  4. package/dist/compiler.js +2 -8
  5. package/dist/constants.js +22 -10
  6. package/dist/index.js +15 -30
  7. package/dist/obfuscator.js +15 -62
  8. package/dist/options.js +33 -40
  9. package/dist/order.js +4 -7
  10. package/dist/parser.js +5 -13
  11. package/dist/precedence.js +6 -8
  12. package/dist/presets.js +4 -6
  13. package/dist/probability.js +13 -24
  14. package/dist/templates/bufferToString.js +121 -5
  15. package/dist/templates/core.js +35 -0
  16. package/dist/templates/crash.js +22 -11
  17. package/dist/templates/es5.js +125 -6
  18. package/dist/templates/functionLength.js +24 -6
  19. package/dist/templates/globals.js +9 -0
  20. package/dist/templates/template.js +189 -43
  21. package/dist/transforms/antiTooling.js +26 -22
  22. package/dist/transforms/calculator.js +19 -55
  23. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +242 -333
  24. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +46 -25
  25. package/dist/transforms/deadCode.js +542 -31
  26. package/dist/transforms/dispatcher.js +112 -112
  27. package/dist/transforms/es5/antiClass.js +70 -44
  28. package/dist/transforms/es5/antiDestructuring.js +14 -38
  29. package/dist/transforms/es5/antiES6Object.js +39 -48
  30. package/dist/transforms/es5/antiSpreadOperator.js +5 -14
  31. package/dist/transforms/es5/antiTemplate.js +10 -19
  32. package/dist/transforms/es5/es5.js +7 -40
  33. package/dist/transforms/extraction/classExtraction.js +83 -0
  34. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +41 -80
  35. package/dist/transforms/extraction/objectExtraction.js +24 -56
  36. package/dist/transforms/finalizer.js +6 -20
  37. package/dist/transforms/flatten.js +51 -99
  38. package/dist/transforms/identifier/globalAnalysis.js +21 -26
  39. package/dist/transforms/identifier/globalConcealing.js +72 -56
  40. package/dist/transforms/identifier/movedDeclarations.js +66 -38
  41. package/dist/transforms/identifier/renameVariables.js +36 -68
  42. package/dist/transforms/identifier/variableAnalysis.js +21 -48
  43. package/dist/transforms/lock/antiDebug.js +20 -25
  44. package/dist/transforms/lock/integrity.js +53 -52
  45. package/dist/transforms/lock/lock.js +161 -126
  46. package/dist/transforms/minify.js +77 -108
  47. package/dist/transforms/opaquePredicates.js +12 -49
  48. package/dist/transforms/preparation.js +28 -49
  49. package/dist/transforms/renameLabels.js +5 -22
  50. package/dist/transforms/rgf.js +125 -72
  51. package/dist/transforms/shuffle.js +42 -47
  52. package/dist/transforms/stack.js +41 -98
  53. package/dist/transforms/string/encoding.js +76 -27
  54. package/dist/transforms/string/stringCompression.js +75 -68
  55. package/dist/transforms/string/stringConcealing.js +127 -135
  56. package/dist/transforms/string/stringEncoding.js +6 -26
  57. package/dist/transforms/string/stringSplitting.js +5 -30
  58. package/dist/transforms/transform.js +76 -104
  59. package/dist/traverse.js +11 -18
  60. package/dist/util/compare.js +27 -29
  61. package/dist/util/gen.js +32 -86
  62. package/dist/util/guard.js +5 -1
  63. package/dist/util/identifiers.js +9 -72
  64. package/dist/util/insert.js +27 -77
  65. package/dist/util/math.js +0 -3
  66. package/dist/util/object.js +3 -7
  67. package/dist/util/random.js +31 -36
  68. package/dist/util/scope.js +6 -3
  69. package/docs/Countermeasures.md +13 -6
  70. package/docs/Integrity.md +35 -28
  71. package/docs/RGF.md +6 -1
  72. package/docs/RenameVariables.md +116 -0
  73. package/docs/TamperProtection.md +100 -0
  74. package/docs/Template.md +117 -0
  75. package/package.json +3 -3
  76. package/src/constants.ts +17 -0
  77. package/src/index.ts +7 -5
  78. package/src/options.ts +60 -7
  79. package/src/order.ts +2 -2
  80. package/src/templates/bufferToString.ts +79 -11
  81. package/src/templates/core.ts +29 -0
  82. package/src/templates/crash.ts +6 -38
  83. package/src/templates/es5.ts +1 -1
  84. package/src/templates/functionLength.ts +21 -3
  85. package/src/templates/globals.ts +3 -0
  86. package/src/templates/template.ts +205 -46
  87. package/src/transforms/antiTooling.ts +33 -11
  88. package/src/transforms/calculator.ts +4 -2
  89. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +12 -5
  90. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +46 -10
  91. package/src/transforms/deadCode.ts +74 -42
  92. package/src/transforms/dispatcher.ts +99 -73
  93. package/src/transforms/es5/antiClass.ts +25 -12
  94. package/src/transforms/es5/antiDestructuring.ts +1 -1
  95. package/src/transforms/es5/antiES6Object.ts +2 -2
  96. package/src/transforms/es5/antiTemplate.ts +1 -1
  97. package/src/transforms/extraction/classExtraction.ts +168 -0
  98. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +11 -16
  99. package/src/transforms/extraction/objectExtraction.ts +4 -15
  100. package/src/transforms/flatten.ts +20 -5
  101. package/src/transforms/identifier/globalAnalysis.ts +18 -1
  102. package/src/transforms/identifier/globalConcealing.ts +119 -72
  103. package/src/transforms/identifier/movedDeclarations.ts +90 -24
  104. package/src/transforms/identifier/renameVariables.ts +16 -1
  105. package/src/transforms/lock/antiDebug.ts +2 -2
  106. package/src/transforms/lock/integrity.ts +13 -11
  107. package/src/transforms/lock/lock.ts +122 -30
  108. package/src/transforms/minify.ts +28 -13
  109. package/src/transforms/opaquePredicates.ts +2 -2
  110. package/src/transforms/preparation.ts +16 -0
  111. package/src/transforms/rgf.ts +139 -12
  112. package/src/transforms/shuffle.ts +3 -3
  113. package/src/transforms/stack.ts +19 -4
  114. package/src/transforms/string/encoding.ts +88 -51
  115. package/src/transforms/string/stringCompression.ts +86 -17
  116. package/src/transforms/string/stringConcealing.ts +148 -118
  117. package/src/transforms/string/stringEncoding.ts +1 -2
  118. package/src/transforms/string/stringSplitting.ts +1 -2
  119. package/src/transforms/transform.ts +63 -46
  120. package/src/types.ts +2 -0
  121. package/src/util/compare.ts +39 -5
  122. package/src/util/gen.ts +10 -3
  123. package/src/util/guard.ts +10 -0
  124. package/src/util/insert.ts +17 -0
  125. package/src/util/random.ts +81 -1
  126. package/src/util/scope.ts +14 -2
  127. package/test/code/Cash.test.ts +94 -5
  128. package/test/code/StrictMode.src.js +65 -0
  129. package/test/code/StrictMode.test.js +37 -0
  130. package/test/compare.test.ts +62 -2
  131. package/test/options.test.ts +129 -55
  132. package/test/templates/template.test.ts +211 -1
  133. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +37 -18
  134. package/test/transforms/dispatcher.test.ts +55 -0
  135. package/test/transforms/extraction/classExtraction.test.ts +86 -0
  136. package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +8 -0
  137. package/test/transforms/extraction/objectExtraction.test.ts +2 -0
  138. package/test/transforms/identifier/globalConcealing.test.ts +89 -0
  139. package/test/transforms/identifier/movedDeclarations.test.ts +61 -0
  140. package/test/transforms/identifier/renameVariables.test.ts +75 -1
  141. package/test/transforms/lock/tamperProtection.test.ts +336 -0
  142. package/test/transforms/minify.test.ts +37 -0
  143. package/test/transforms/rgf.test.ts +50 -0
  144. package/dist/transforms/controlFlowFlattening/choiceFlowObfuscation.js +0 -62
  145. package/dist/transforms/controlFlowFlattening/controlFlowObfuscation.js +0 -159
  146. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +0 -106
  147. package/dist/transforms/eval.js +0 -84
  148. package/dist/transforms/hexadecimalNumbers.js +0 -63
  149. package/dist/transforms/hideInitializingCode.js +0 -270
  150. package/dist/transforms/identifier/nameRecycling.js +0 -218
  151. package/dist/transforms/label.js +0 -67
  152. package/dist/transforms/preparation/nameConflicts.js +0 -116
  153. 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
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
-
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; }
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
- } // Now combine ExpressionStatements
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
- } // Unnecessary return
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
- } // Variable declaration grouping
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
- } // Test Variant #25: Don't break redefined function declaration
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, (0, _template.default)("\n function ".concat(this.arrowFunctionName, "(arrowFn, functionLength){\n var functionObject = function(){ return arrowFn(...arguments) };\n\n Object[\"defineProperty\"](functionObject, \"length\", {\n \"value\": functionLength,\n \"configurable\": true\n });\n\n return functionObject;\n }\n ")).single());
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
- return (0, _gen.CallExpression)((0, _gen.Identifier)(this.arrowFunctionName), [(0, _insert.clone)(object), (0, _gen.Literal)((0, _insert.computeFunctionLength)(object.params))]);
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 = { ...(0, _insert.clone)(object),
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
- } // (a()) -> a()
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
- } // a += -1 -> a -= 1
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 ( // a -= -1 -> a += 1
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
- } // a + -b -> a - b
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 ( // a - -1 -> a + 1
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
- } // Last switch case does not need break
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
- } // if ( x ) { y() } -> x && y()
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
- var body = (0, _insert.getBlockBody)(object.consequent); // Check for hard-coded if statements
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]); // if (a) {return b;} else {return c;} -> return a ? b : c;
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
- } // if (a) {b = 0} else {b = 1} -> b = a ? 0 : 1;
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
- } // x["abc"] -> x.abc
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); // obj.name &&
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
- } // { "x": 1 } -> {x: 1}
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; // console.log(key1, key2);
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
- } // check for redundant patterns
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;