js-confuser 1.2.1 → 1.4.1

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 (94) hide show
  1. package/CHANGELOG.md +171 -0
  2. package/README.md +7 -6
  3. package/dist/options.js +5 -1
  4. package/dist/parser.js +1 -2
  5. package/dist/presets.js +2 -2
  6. package/dist/transforms/calculator.js +48 -60
  7. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +482 -95
  8. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -0
  9. package/dist/transforms/controlFlowFlattening/{switchCaseObfucation.js → switchCaseObfuscation.js} +2 -2
  10. package/dist/transforms/deadCode.js +1 -1
  11. package/dist/transforms/dispatcher.js +14 -13
  12. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +5 -10
  13. package/dist/transforms/flatten.js +5 -1
  14. package/dist/transforms/hideInitializingCode.js +17 -2
  15. package/dist/transforms/identifier/globalConcealing.js +46 -25
  16. package/dist/transforms/identifier/movedDeclarations.js +69 -68
  17. package/dist/transforms/identifier/renameVariables.js +22 -98
  18. package/dist/transforms/identifier/variableAnalysis.js +133 -0
  19. package/dist/transforms/label.js +11 -2
  20. package/dist/transforms/lock/antiDebug.js +32 -13
  21. package/dist/transforms/lock/lock.js +13 -2
  22. package/dist/transforms/minify.js +117 -120
  23. package/dist/transforms/opaquePredicates.js +4 -2
  24. package/dist/transforms/preparation/preparation.js +8 -0
  25. package/dist/transforms/renameLabels.js +17 -3
  26. package/dist/transforms/rgf.js +8 -3
  27. package/dist/transforms/shuffle.js +25 -9
  28. package/dist/transforms/stack.js +5 -9
  29. package/dist/transforms/string/encoding.js +209 -0
  30. package/dist/transforms/string/stringCompression.js +10 -10
  31. package/dist/transforms/string/stringConcealing.js +94 -65
  32. package/dist/transforms/string/stringSplitting.js +7 -7
  33. package/dist/transforms/transform.js +10 -0
  34. package/dist/traverse.js +1 -35
  35. package/dist/util/gen.js +3 -1
  36. package/dist/util/identifiers.js +9 -19
  37. package/dist/util/insert.js +6 -40
  38. package/dist/util/scope.js +17 -0
  39. package/package.json +2 -2
  40. package/src/options.ts +19 -3
  41. package/src/parser.ts +1 -2
  42. package/src/presets.ts +2 -2
  43. package/src/transforms/calculator.ts +87 -91
  44. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +742 -142
  45. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +6 -0
  46. package/src/transforms/controlFlowFlattening/{switchCaseObfucation.ts → switchCaseObfuscation.ts} +6 -2
  47. package/src/transforms/deadCode.ts +8 -0
  48. package/src/transforms/dispatcher.ts +29 -14
  49. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +43 -19
  50. package/src/transforms/flatten.ts +15 -2
  51. package/src/transforms/hideInitializingCode.ts +432 -406
  52. package/src/transforms/identifier/globalConcealing.ts +148 -46
  53. package/src/transforms/identifier/movedDeclarations.ts +78 -101
  54. package/src/transforms/identifier/renameVariables.ts +21 -96
  55. package/src/transforms/identifier/variableAnalysis.ts +124 -0
  56. package/src/transforms/label.ts +20 -2
  57. package/src/transforms/lock/antiDebug.ts +69 -26
  58. package/src/transforms/lock/lock.ts +37 -3
  59. package/src/transforms/minify.ts +154 -130
  60. package/src/transforms/opaquePredicates.ts +25 -3
  61. package/src/transforms/preparation/preparation.ts +8 -1
  62. package/src/transforms/renameLabels.ts +26 -3
  63. package/src/transforms/rgf.ts +6 -1
  64. package/src/transforms/shuffle.ts +87 -29
  65. package/src/transforms/stack.ts +6 -8
  66. package/src/transforms/string/encoding.ts +310 -0
  67. package/src/transforms/string/stringCompression.ts +37 -24
  68. package/src/transforms/string/stringConcealing.ts +157 -160
  69. package/src/transforms/string/stringSplitting.ts +12 -8
  70. package/src/transforms/transform.ts +15 -2
  71. package/src/traverse.ts +1 -31
  72. package/src/util/gen.ts +5 -3
  73. package/src/util/identifiers.ts +20 -20
  74. package/src/util/insert.ts +12 -78
  75. package/src/util/scope.ts +9 -0
  76. package/test/{transforms/compare.test.ts → compare.test.ts} +2 -2
  77. package/test/index.test.ts +109 -1
  78. package/test/templates/template.test.ts +14 -0
  79. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +392 -10
  80. package/test/transforms/dispatcher.test.ts +30 -0
  81. package/test/transforms/flatten.test.ts +28 -0
  82. package/test/transforms/hideInitializingCode.test.ts +336 -336
  83. package/test/transforms/identifier/globalConcealing.test.ts +1 -2
  84. package/test/transforms/identifier/movedDeclarations.test.ts +137 -112
  85. package/test/transforms/identifier/renameVariables.test.ts +124 -13
  86. package/test/transforms/lock/antiDebug.test.ts +43 -0
  87. package/test/transforms/lock/selfDefending.test.ts +68 -0
  88. package/test/transforms/minify.test.ts +137 -0
  89. package/test/transforms/renameLabels.test.ts +33 -0
  90. package/test/transforms/rgf.test.ts +29 -0
  91. package/test/transforms/string/stringSplitting.test.ts +33 -0
  92. package/test/util/identifiers.test.ts +105 -17
  93. package/dist/util/expr.js +0 -60
  94. package/src/util/expr.ts +0 -56
@@ -4,8 +4,6 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.validateChain = validateChain;
7
- exports.isWithinClass = isWithinClass;
8
- exports.isWithin = isWithin;
9
7
  exports.getIdentifierInfo = getIdentifierInfo;
10
8
  exports.getDefiningIdentifier = getDefiningIdentifier;
11
9
  exports.isFunctionParameter = isFunctionParameter;
@@ -44,14 +42,6 @@ function validateChain(object, parents) {
44
42
  }
45
43
  }
46
44
  }
47
-
48
- function isWithinClass(object, parents) {
49
- return isWithin(object, parents, "ClassDeclaration") || isWithin(object, parents, "ClassExpression");
50
- }
51
-
52
- function isWithin(object, parents, type) {
53
- return [object, ...parents].some(x => x.type == type);
54
- }
55
45
  /**
56
46
  * Returns detailed information about the given Identifier node.
57
47
  * @param object
@@ -99,10 +89,11 @@ function getIdentifierInfo(object, parents) {
99
89
  var isImportSpecifier = (parent.type == "ImportDefaultSpecifier" || parent.type == "ImportSpecifier") && parent.local == object;
100
90
  var isFunctionCall = parent.callee == object; // NewExpression and CallExpression
101
91
 
102
- var isAssignmentLeft = parent.type == "AssignmentExpression" && parent.left == object;
103
- var isAssignmentValue = parent.type == "AssignmentExpression" && parent.right == object;
92
+ var assignmentIndex = parents.findIndex(p => p.type === "AssignmentExpression");
93
+ var isAssignmentLeft = assignmentIndex !== -1 && parents[assignmentIndex].left === (parents[assignmentIndex - 1] || object);
94
+ var isAssignmentValue = assignmentIndex !== -1 && parents[assignmentIndex].right === (parents[assignmentIndex - 1] || object);
104
95
  var isUpdateExpression = parent.type == "UpdateExpression";
105
- var isClassDeclaration = parent.type == "ClassDeclaration" && parent.id == object;
96
+ var isClassDeclaration = (parent.type == "ClassDeclaration" || parent.type == "ClassExpression") && parent.id == object;
106
97
  var isMethodDefinition = parent.type == "MethodDefinition" && parent.key == object && !parent.computed;
107
98
  var isMetaProperty = parent.type == "MetaProperty";
108
99
  var isLabel = parent.type == "LabeledStatement" && parent.label == object; // Fix 1: Labels are properly identified
@@ -300,7 +291,7 @@ function getDefiningIdentifier(object, parents) {
300
291
  }
301
292
  }
302
293
 
303
- function isFunctionParameter(o, p) {
294
+ function isFunctionParameter(o, p, c) {
304
295
  (0, _assert.ok)(o);
305
296
  (0, _assert.ok)(p);
306
297
  validateChain(o, p);
@@ -315,7 +306,7 @@ function isFunctionParameter(o, p) {
315
306
  return false;
316
307
  }
317
308
 
318
- var c = (0, _insert.getVarContext)(o, p);
309
+ c = c || (0, _insert.getVarContext)(o, p);
319
310
 
320
311
  if (c === object) {
321
312
  var pIndex = p.indexOf(object.params);
@@ -327,8 +318,7 @@ function isFunctionParameter(o, p) {
327
318
  var param = p[pIndex - 1] || o;
328
319
  var paramIndex = object.params.indexOf(param);
329
320
  (0, _assert.ok)(paramIndex !== -1);
330
- var sliced = p.slice(p.indexOf(paramIndex));
331
- (0, _assert.ok)(!sliced.includes(o));
321
+ var sliced = p.slice(0, pIndex);
332
322
  var isReferenced = true;
333
323
  var i = 0;
334
324
 
@@ -342,7 +332,7 @@ function isFunctionParameter(o, p) {
342
332
  break;
343
333
  }
344
334
 
345
- if (node.type == "ObjectPattern" && node.key === down) {
335
+ if (node.type == "Property" && node.key === down && sliced[i + 2] && sliced[i + 2].type == "ObjectPattern") {
346
336
  isReferenced = false;
347
337
  break;
348
338
  }
@@ -365,7 +355,7 @@ function getFunctionParameters(object, parents) {
365
355
  var locations = [];
366
356
  (0, _traverse.walk)(object.params, [object, ...parents], (o, p) => {
367
357
  if (o.type == "Identifier") {
368
- if (isFunctionParameter(o, p)) {
358
+ if (isFunctionParameter(o, p, object)) {
369
359
  locations.push([o, p]);
370
360
  }
371
361
  }
@@ -21,7 +21,6 @@ exports.prepend = prepend;
21
21
  exports.append = append;
22
22
  exports.clone = clone;
23
23
  exports.isForInitialize = isForInitialize;
24
- exports.isInBranch = isInBranch;
25
24
 
26
25
  var _assert = require("assert");
27
26
 
@@ -151,27 +150,15 @@ function getDefiningContext(o, p) {
151
150
  return getVarContext(o, p);
152
151
  }
153
152
 
154
- function getReferencingContexts(o, p) {
153
+ function getReferencingContexts(o, p, info) {
155
154
  (0, _identifiers.validateChain)(o, p);
156
155
  (0, _assert.ok)(o.type == "Identifier");
157
- var info = (0, _identifiers.getIdentifierInfo)(o, p);
158
- (0, _assert.ok)(info.spec.isReferenced);
159
- var assignmentPatternIndex = p.findIndex(x => x.type == "AssignmentPattern");
160
-
161
- if (assignmentPatternIndex != -1) {
162
- if (p[assignmentPatternIndex].right == (p[assignmentPatternIndex - 1] || o)) {
163
- var sliced = p.slice(assignmentPatternIndex);
164
- var fnIndex = sliced.findIndex(x => isFunction(x));
165
- var associatedFn = sliced[fnIndex];
166
156
 
167
- if (fnIndex !== -1 && sliced[fnIndex].params == (sliced[fnIndex - 1] || o)) {
168
- if (associatedFn == getVarContext(o, p)) {
169
- return isLexContext(associatedFn.body) ? [associatedFn, associatedFn.body] : [associatedFn];
170
- }
171
- }
172
- }
157
+ if (!info) {
158
+ info = (0, _identifiers.getIdentifierInfo)(o, p);
173
159
  }
174
160
 
161
+ (0, _assert.ok)(info.spec.isReferenced);
175
162
  return [getVarContext(o, p), getLexContext(o, p)];
176
163
  }
177
164
 
@@ -328,36 +315,15 @@ function isForInitialize(o, p) {
328
315
 
329
316
  if (forIndex !== -1) {
330
317
  if (p[forIndex].type == "ForStatement") {
331
- if (p[forIndex].init == p[forIndex - 1] || o) {
318
+ if (p[forIndex].init == (p[forIndex - 1] || o)) {
332
319
  return "initializer";
333
320
  }
334
321
  } else {
335
- if (p[forIndex].left == p[forIndex - 1] || o) {
322
+ if (p[forIndex].left == (p[forIndex - 1] || o)) {
336
323
  return "left-hand";
337
324
  }
338
325
  }
339
326
  }
340
327
 
341
328
  return false;
342
- }
343
-
344
- function isInBranch(object, parents, context) {
345
- (0, _assert.ok)(object);
346
- (0, _assert.ok)(parents);
347
- (0, _assert.ok)(context);
348
- (0, _assert.ok)(parents.includes(context));
349
- var definingContext = parents[0].type == "FunctionDeclaration" && parents[0].id == object ? getVarContext(parents[0], parents.slice(1)) : getVarContext(object, parents);
350
- var contextIndex = parents.findIndex(x => x === context);
351
- var slicedParents = parents.slice(0, contextIndex);
352
- (0, _assert.ok)(!slicedParents.includes(object), "slicedParents includes object");
353
- var slicedTypes = new Set(slicedParents.map(x => x.type));
354
- var isBranch = definingContext !== context;
355
-
356
- if (!isBranch) {
357
- if (["IfStatement", "ForStatement", "ForInStatement", "ForOfStatement", "WhileStatement", "DoWhileStatement", "SwitchStatement", "ConditionalExpression", "LogicalExpression", "TryStatement", "ChainExpression", "BinaryExpression", "FunctionExpression", "FunctionDeclaration", "ArrowFunctionExpression", "ClassExpression", "ClassDeclaration"].find(x => slicedTypes.has(x))) {
358
- isBranch = true;
359
- }
360
- }
361
-
362
- return isBranch;
363
329
  }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isLexicalScope = isLexicalScope;
7
+ exports.getLexicalScope = getLexicalScope;
8
+
9
+ var _traverse = require("../traverse");
10
+
11
+ function isLexicalScope(object) {
12
+ return (0, _traverse.isBlock)(object) || object.type == "SwitchCase";
13
+ }
14
+
15
+ function getLexicalScope(object, parents) {
16
+ return [object, ...parents].find(node => isLexicalScope(node));
17
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-confuser",
3
- "version": "1.2.1",
3
+ "version": "1.4.1",
4
4
  "description": "JavaScript Obfuscation Tool.",
5
5
  "main": "dist/index.js",
6
6
  "types": "index.d.ts",
@@ -22,7 +22,7 @@
22
22
  "author": "MichaelXF",
23
23
  "license": "MIT",
24
24
  "dependencies": {
25
- "acorn": "^8.4.0",
25
+ "acorn": "^8.5.0",
26
26
  "escodegen": "^2.0.0"
27
27
  },
28
28
  "devDependencies": {
package/src/options.ts CHANGED
@@ -224,7 +224,7 @@ export interface ObfuscateOptions {
224
224
  /**
225
225
  * ### `stringConcealing`
226
226
  *
227
- * [String Concealing](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-concealing) involves encoding strings to conceal plain-text values. (`true/false`)
227
+ * [String Concealing](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-concealing) involves encoding strings to conceal plain-text values. (`true/false/0-1`)
228
228
  *
229
229
  * `"console"` -> `decrypt('<~@rH7+Dert~>')`
230
230
  *
@@ -237,7 +237,7 @@ export interface ObfuscateOptions {
237
237
  /**
238
238
  * ### `stringEncoding`
239
239
  *
240
- * [String Encoding](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-encoding) transforms a string into an encoded representation. (`true/false`)
240
+ * [String Encoding](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-encoding) transforms a string into an encoded representation. (`true/false/0-1`)
241
241
  *
242
242
  * `"console"` -> `'\x63\x6f\x6e\x73\x6f\x6c\x65'`
243
243
  *
@@ -252,7 +252,7 @@ export interface ObfuscateOptions {
252
252
  /**
253
253
  * ### `stringSplitting`
254
254
  *
255
- * [String Splitting](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-splitting) splits your strings into multiple expressions. (`true/false`)
255
+ * [String Splitting](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-splitting) splits your strings into multiple expressions. (`true/false/0-1`)
256
256
  *
257
257
  * `"console"` -> `String.fromCharCode(99) + 'ons' + 'ole'`
258
258
  *
@@ -447,6 +447,17 @@ export interface ObfuscateOptions {
447
447
  calculator?: ProbabilityMap<boolean>;
448
448
 
449
449
  lock?: {
450
+ /**
451
+ * ### `lock.selfDefending`
452
+ *
453
+ * Prevents the use of code beautifiers or formatters against your code.
454
+ *
455
+ * [Identical to Obfuscator.io's Self Defending](https://github.com/javascript-obfuscator/javascript-obfuscator#selfdefending)
456
+ *
457
+ * [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
458
+ */
459
+ selfDefending?: boolean;
460
+
450
461
  /**
451
462
  * ### `lock.antiDebug`
452
463
  *
@@ -692,6 +703,7 @@ const validProperties = new Set([
692
703
  "shuffle",
693
704
  "stack",
694
705
  "verbose",
706
+ "globalVariables",
695
707
  "debugComments",
696
708
  ]);
697
709
 
@@ -837,6 +849,10 @@ export async function correctOptions(
837
849
  options.globalVariables = new Set(Object.keys(options.globalVariables));
838
850
  }
839
851
 
852
+ if (options.lock && options.lock.selfDefending) {
853
+ options.compact = true; // self defending forcibly enables this
854
+ }
855
+
840
856
  // options.globalVariables was never used.
841
857
  // GlobalConcealing implicitly determines a global to be a variable referenced but never defined or modified.
842
858
  if (!options.hasOwnProperty("globalVariables")) {
package/src/parser.ts CHANGED
@@ -18,8 +18,7 @@ export default async function parseJS(code: string): Promise<{
18
18
  var parsed = parseSync(code);
19
19
  return parsed as any;
20
20
  } catch (e) {
21
- console.error(e);
22
- throw new Error("Failed to parse code.");
21
+ throw e;
23
22
  }
24
23
  }
25
24
 
package/src/presets.ts CHANGED
@@ -43,11 +43,11 @@ const highPreset: ObfuscateOptions = {
43
43
  renameVariables: true,
44
44
  renameGlobals: true,
45
45
  shuffle: { hash: 0.5, true: 0.5 },
46
+ stack: true,
46
47
  stringConcealing: true,
47
48
  stringCompression: true,
48
49
  stringEncoding: true,
49
50
  stringSplitting: 0.75,
50
- stack: true,
51
51
 
52
52
  // Use at own risk
53
53
  eval: false,
@@ -68,7 +68,6 @@ const mediumPreset: ObfuscateOptions = {
68
68
  deadCode: 0.025,
69
69
  dispatcher: 0.75,
70
70
  duplicateLiteralsRemoval: 0.5,
71
- flatten: true,
72
71
  globalConcealing: true,
73
72
  identifierGenerator: "randomized",
74
73
  minify: true,
@@ -78,6 +77,7 @@ const mediumPreset: ObfuscateOptions = {
78
77
  renameVariables: true,
79
78
  renameGlobals: true,
80
79
  shuffle: true,
80
+ stack: 0.5,
81
81
  stringConcealing: true,
82
82
  stringSplitting: 0.25,
83
83
  };
@@ -34,104 +34,100 @@ export default class Calculator extends Transform {
34
34
  this.gen = this.getGenerator();
35
35
  }
36
36
 
37
+ apply(tree) {
38
+ super.apply(tree);
39
+
40
+ if (Object.keys(this.ops).length == 0) {
41
+ return;
42
+ }
43
+
44
+ var opArg = this.getPlaceholder();
45
+ var leftArg = this.getPlaceholder();
46
+ var rightArg = this.getPlaceholder();
47
+ var switchCases = [];
48
+
49
+ Object.keys(this.ops).forEach((operator) => {
50
+ var code = this.ops[operator];
51
+
52
+ var factory =
53
+ operator == "&&" || operator == "||"
54
+ ? LogicalExpression
55
+ : BinaryExpression;
56
+
57
+ var body = [
58
+ ReturnStatement(
59
+ factory(operator, Identifier(leftArg), Identifier(rightArg))
60
+ ),
61
+ ];
62
+
63
+ switchCases.push(SwitchCase(Literal(code), body));
64
+ });
65
+
66
+ var func = FunctionDeclaration(
67
+ this.calculatorFn,
68
+ [opArg, leftArg, rightArg].map((x) => Identifier(x)),
69
+ [SwitchStatement(Identifier(opArg), switchCases)]
70
+ );
71
+
72
+ prepend(tree, func);
73
+ }
74
+
37
75
  match(object: Node, parents: Node[]) {
38
- return object.type == "Program" || object.type == "BinaryExpression";
76
+ return object.type == "BinaryExpression";
39
77
  }
40
78
 
41
79
  transform(object: Node, parents: Node[]) {
42
- if (object.type == "Program") {
43
- return () => {
44
- var block = getBlock(object, parents);
45
-
46
- if (Object.keys(this.ops).length == 0) {
47
- return;
48
- }
49
-
50
- var opArg = this.getPlaceholder();
51
- var leftArg = this.getPlaceholder();
52
- var rightArg = this.getPlaceholder();
53
- var switchCases = [];
54
-
55
- Object.keys(this.ops).forEach((operator) => {
56
- var code = this.ops[operator];
57
-
58
- var factory =
59
- operator == "&&" || operator == "||"
60
- ? LogicalExpression
61
- : BinaryExpression;
62
-
63
- var body = [
64
- ReturnStatement(
65
- factory(operator, Identifier(leftArg), Identifier(rightArg))
66
- ),
67
- ];
68
-
69
- switchCases.push(SwitchCase(Literal(code), body));
70
- });
71
-
72
- var func = FunctionDeclaration(
73
- this.calculatorFn,
74
- [opArg, leftArg, rightArg].map((x) => Identifier(x)),
75
- [SwitchStatement(Identifier(opArg), switchCases)]
76
- );
77
-
78
- prepend(block, func);
79
- };
80
+ var operator = object.operator;
81
+ var allowedOperators = new Set(["+", "-", "*", "/"]);
82
+ if (!allowedOperators.has(operator)) {
83
+ return;
80
84
  }
81
85
 
82
- if (object.type == "BinaryExpression") {
83
- var operator = object.operator;
84
- if (!{ "+": 1, "-": 1, "*": 1, "/": 1 }[object.operator]) {
85
- return;
86
- }
86
+ var myPrecedence =
87
+ OPERATOR_PRECEDENCE[operator] +
88
+ Object.keys(OPERATOR_PRECEDENCE).indexOf(operator) / 100;
89
+ var precedences = parents.map(
90
+ (x) =>
91
+ x.type == "BinaryExpression" &&
92
+ OPERATOR_PRECEDENCE[x.operator] +
93
+ Object.keys(OPERATOR_PRECEDENCE).indexOf(x.operator) / 100
94
+ );
95
+
96
+ // corrupt AST
97
+ if (precedences.find((x) => x >= myPrecedence)) {
98
+ return;
99
+ }
100
+ if (
101
+ parents.find((x) => x.$dispatcherSkip || x.type == "BinaryExpression")
102
+ ) {
103
+ return;
104
+ }
87
105
 
88
- var myPrecedence =
89
- OPERATOR_PRECEDENCE[operator] +
90
- Object.keys(OPERATOR_PRECEDENCE).indexOf(operator) / 100;
91
- var maxParentPrecedence = parents
92
- .map(
93
- (x) =>
94
- x.type == "BinaryExpression" &&
95
- OPERATOR_PRECEDENCE[x.operator] +
96
- Object.keys(OPERATOR_PRECEDENCE).indexOf(x.operator) / 100
97
- )
98
- .sort()
99
- .pop();
100
-
101
- // corrupt AST
102
- if (maxParentPrecedence && maxParentPrecedence > myPrecedence) {
103
- return;
106
+ return () => {
107
+ if (typeof this.ops[operator] !== "number") {
108
+ var newState;
109
+ do {
110
+ newState = getRandomInteger(
111
+ -1000,
112
+ 1000 + Object.keys(this.ops).length * 5
113
+ );
114
+ } while (this.statesUsed.has(newState));
115
+
116
+ ok(!isNaN(newState));
117
+
118
+ this.statesUsed.add(newState);
119
+ this.ops[operator] = newState;
120
+ this.log(operator, `calc(${newState}, left, right)`);
104
121
  }
105
- return () => {
106
- if (parents.find((x) => x.$dispatcherSkip)) {
107
- return;
108
- }
109
-
110
- if (typeof this.ops[operator] !== "number") {
111
- var newState;
112
- do {
113
- newState = getRandomInteger(
114
- -1000,
115
- 1000 + Object.keys(this.ops).length * 5
116
- );
117
- } while (this.statesUsed.has(newState));
118
-
119
- ok(!isNaN(newState));
120
-
121
- this.statesUsed.add(newState);
122
- this.ops[operator] = newState;
123
- this.log(operator, `calc(${newState}, left, right)`);
124
- }
125
-
126
- this.replace(
127
- object,
128
- CallExpression(Identifier(this.calculatorFn), [
129
- Literal(this.ops[operator]),
130
- { ...object.left },
131
- { ...object.right },
132
- ])
133
- );
134
- };
135
- }
122
+
123
+ this.replace(
124
+ object,
125
+ CallExpression(Identifier(this.calculatorFn), [
126
+ Literal(this.ops[operator]),
127
+ object.left,
128
+ object.right,
129
+ ])
130
+ );
131
+ };
136
132
  }
137
133
  }