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.
Files changed (139) hide show
  1. package/.github/workflows/node.js.yml +2 -2
  2. package/CHANGELOG.md +69 -0
  3. package/README.md +143 -7
  4. package/dist/index.js +33 -4
  5. package/dist/obfuscator.js +30 -31
  6. package/dist/options.js +4 -5
  7. package/dist/order.js +4 -6
  8. package/dist/probability.js +2 -4
  9. package/dist/templates/bufferToString.js +13 -0
  10. package/dist/templates/crash.js +2 -2
  11. package/dist/templates/es5.js +18 -0
  12. package/dist/transforms/antiTooling.js +1 -1
  13. package/dist/transforms/calculator.js +77 -21
  14. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +980 -367
  15. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +8 -3
  16. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +25 -26
  17. package/dist/transforms/deadCode.js +33 -25
  18. package/dist/transforms/dispatcher.js +7 -6
  19. package/dist/transforms/es5/antiClass.js +6 -2
  20. package/dist/transforms/es5/antiDestructuring.js +3 -1
  21. package/dist/transforms/es5/es5.js +31 -34
  22. package/dist/transforms/eval.js +11 -0
  23. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +8 -5
  24. package/dist/transforms/extraction/objectExtraction.js +6 -1
  25. package/dist/transforms/finalizer.js +82 -0
  26. package/dist/transforms/flatten.js +82 -55
  27. package/dist/transforms/hexadecimalNumbers.js +34 -9
  28. package/dist/transforms/identifier/globalAnalysis.js +88 -0
  29. package/dist/transforms/identifier/globalConcealing.js +10 -83
  30. package/dist/transforms/identifier/movedDeclarations.js +2 -8
  31. package/dist/transforms/identifier/renameVariables.js +39 -27
  32. package/dist/transforms/identifier/variableAnalysis.js +58 -62
  33. package/dist/transforms/minify.js +80 -61
  34. package/dist/transforms/opaquePredicates.js +1 -1
  35. package/dist/transforms/preparation/preparation.js +2 -2
  36. package/dist/transforms/preparation.js +231 -0
  37. package/dist/transforms/renameLabels.js +1 -1
  38. package/dist/transforms/rgf.js +4 -5
  39. package/dist/transforms/stack.js +87 -26
  40. package/dist/transforms/string/encoding.js +150 -179
  41. package/dist/transforms/string/stringCompression.js +14 -15
  42. package/dist/transforms/string/stringConcealing.js +25 -8
  43. package/dist/transforms/string/stringEncoding.js +13 -24
  44. package/dist/transforms/transform.js +11 -18
  45. package/dist/traverse.js +24 -18
  46. package/dist/util/compare.js +2 -2
  47. package/dist/util/gen.js +15 -0
  48. package/dist/util/insert.js +31 -7
  49. package/dist/util/random.js +15 -0
  50. package/package.json +5 -5
  51. package/src/index.ts +57 -19
  52. package/src/obfuscator.ts +26 -29
  53. package/src/options.ts +17 -21
  54. package/src/order.ts +4 -8
  55. package/src/probability.ts +2 -3
  56. package/src/templates/bufferToString.ts +68 -0
  57. package/src/templates/crash.ts +5 -9
  58. package/src/templates/es5.ts +131 -0
  59. package/src/transforms/antiTooling.ts +1 -1
  60. package/src/transforms/calculator.ts +122 -59
  61. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +1583 -571
  62. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +18 -3
  63. package/src/transforms/deadCode.ts +383 -26
  64. package/src/transforms/dispatcher.ts +8 -6
  65. package/src/transforms/es5/antiClass.ts +10 -1
  66. package/src/transforms/es5/antiDestructuring.ts +3 -1
  67. package/src/transforms/es5/es5.ts +32 -77
  68. package/src/transforms/eval.ts +18 -0
  69. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +9 -6
  70. package/src/transforms/extraction/objectExtraction.ts +12 -5
  71. package/src/transforms/finalizer.ts +75 -0
  72. package/src/transforms/flatten.ts +194 -151
  73. package/src/transforms/identifier/globalAnalysis.ts +85 -0
  74. package/src/transforms/identifier/globalConcealing.ts +14 -103
  75. package/src/transforms/identifier/movedDeclarations.ts +4 -11
  76. package/src/transforms/identifier/renameVariables.ts +37 -30
  77. package/src/transforms/identifier/variableAnalysis.ts +66 -73
  78. package/src/transforms/minify.ts +116 -77
  79. package/src/transforms/opaquePredicates.ts +2 -2
  80. package/src/transforms/preparation.ts +238 -0
  81. package/src/transforms/renameLabels.ts +2 -2
  82. package/src/transforms/rgf.ts +6 -7
  83. package/src/transforms/stack.ts +97 -37
  84. package/src/transforms/string/encoding.ts +115 -212
  85. package/src/transforms/string/stringCompression.ts +27 -18
  86. package/src/transforms/string/stringConcealing.ts +41 -11
  87. package/src/transforms/string/stringEncoding.ts +18 -18
  88. package/src/transforms/transform.ts +15 -21
  89. package/src/traverse.ts +24 -12
  90. package/src/types.ts +11 -2
  91. package/src/util/compare.ts +2 -2
  92. package/src/util/gen.ts +21 -1
  93. package/src/util/insert.ts +49 -9
  94. package/src/util/random.ts +13 -0
  95. package/test/code/Cash.test.ts +1 -1
  96. package/test/code/Dynamic.test.ts +12 -10
  97. package/test/code/ES6.src.js +136 -0
  98. package/test/code/ES6.test.ts +28 -2
  99. package/test/code/NewFeatures.test.ts +19 -0
  100. package/test/index.test.ts +15 -2
  101. package/test/probability.test.ts +44 -0
  102. package/test/templates/template.test.ts +1 -1
  103. package/test/transforms/antiTooling.test.ts +52 -0
  104. package/test/transforms/calculator.test.ts +40 -0
  105. package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +713 -149
  106. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +173 -0
  107. package/test/transforms/deadCode.test.ts +66 -15
  108. package/test/transforms/dispatcher.test.ts +44 -1
  109. package/test/transforms/es5/antiClass.test.ts +33 -0
  110. package/test/transforms/es5/antiDestructuring.test.ts +16 -0
  111. package/test/transforms/eval.test.ts +53 -0
  112. package/test/transforms/extraction/objectExtraction.test.ts +21 -0
  113. package/test/transforms/flatten.test.ts +195 -3
  114. package/test/transforms/identifier/movedDeclarations.test.ts +27 -0
  115. package/test/transforms/identifier/renameVariables.test.ts +108 -0
  116. package/test/transforms/lock/antiDebug.test.ts +2 -2
  117. package/test/transforms/minify.test.ts +151 -0
  118. package/test/transforms/preparation.test.ts +157 -0
  119. package/test/transforms/rgf.test.ts +56 -29
  120. package/test/transforms/stack.test.ts +91 -21
  121. package/test/transforms/string/stringCompression.test.ts +39 -0
  122. package/test/transforms/string/stringConcealing.test.ts +115 -0
  123. package/test/transforms/string/stringEncoding.test.ts +53 -2
  124. package/test/transforms/transform.test.ts +66 -0
  125. package/test/traverse.test.ts +139 -0
  126. package/test/util/compare.test.ts +23 -1
  127. package/src/transforms/controlFlowFlattening/choiceFlowObfuscation.ts +0 -87
  128. package/src/transforms/controlFlowFlattening/controlFlowObfuscation.ts +0 -203
  129. package/src/transforms/controlFlowFlattening/switchCaseObfuscation.ts +0 -130
  130. package/src/transforms/hexadecimalNumbers.ts +0 -31
  131. package/src/transforms/hideInitializingCode.ts +0 -432
  132. package/src/transforms/label.ts +0 -64
  133. package/src/transforms/preparation/nameConflicts.ts +0 -102
  134. package/src/transforms/preparation/preparation.ts +0 -176
  135. package/test/transforms/controlFlowFlattening/controlFlowObfuscation.test.ts +0 -101
  136. package/test/transforms/controlFlowFlattening/switchCaseObfuscation.test.ts +0 -120
  137. package/test/transforms/hideInitializingCode.test.ts +0 -336
  138. package/test/transforms/preparation/nameConflicts.test.ts +0 -52
  139. package/test/transforms/preparation/preparation.test.ts +0 -62
@@ -1,432 +0,0 @@
1
- import { reservedIdentifiers } from "../constants";
2
- import { ObfuscateOrder } from "../order";
3
- import { walk } from "../traverse";
4
- import {
5
- AssignmentExpression,
6
- BinaryExpression,
7
- BreakStatement,
8
- CallExpression,
9
- ConditionalExpression,
10
- ExpressionStatement,
11
- FunctionDeclaration,
12
- FunctionExpression,
13
- Identifier,
14
- Literal,
15
- MemberExpression,
16
- ReturnStatement,
17
- SequenceExpression,
18
- SwitchCase,
19
- SwitchStatement,
20
- ThisExpression,
21
- UnaryExpression,
22
- VariableDeclaration,
23
- VariableDeclarator,
24
- } from "../util/gen";
25
- import { getIdentifierInfo, validateChain } from "../util/identifiers";
26
- import { getVarContext, isForInitialize, isFunction } from "../util/insert";
27
- import { choice, getRandomInteger, shuffle } from "../util/random";
28
- import Transform from "./transform";
29
-
30
- export default class HideInitializingCode extends Transform {
31
- constructor(o) {
32
- super(o, ObfuscateOrder.HideInitializingCode);
33
- }
34
-
35
- match(object, parents) {
36
- return object.type == "Program";
37
- }
38
-
39
- transform(object, parents) {
40
- return () => {
41
- var body = object.body;
42
- var hasExport = false;
43
-
44
- var stmts = [];
45
- var functions = [];
46
- var exportTypes = new Set([
47
- "ExportNamedDeclaration",
48
- "ExportSpecifier",
49
- "ExportDefaultDeclaration",
50
- "ExportAllDeclaration",
51
- ]);
52
-
53
- var sampledNames = new Set<string>();
54
-
55
- body.forEach((stmt) => {
56
- if (stmt.type == "FunctionDeclaration") {
57
- functions.push(stmt);
58
- if (stmt.id) {
59
- sampledNames.add(stmt.id.name);
60
- }
61
- } else if (exportTypes.has(stmt.type)) {
62
- hasExport = true;
63
- } else {
64
- stmts.push(stmt);
65
- }
66
- });
67
-
68
- if (hasExport) {
69
- return;
70
- }
71
-
72
- var definedNames = new Set<string>();
73
-
74
- const findNames = (o, p) => {
75
- validateChain(o, p);
76
- var context = getVarContext(o, p);
77
- walk(o, p, (oo, pp) => {
78
- if (
79
- oo.type == "Identifier" &&
80
- !reservedIdentifiers.has(oo.name) &&
81
- !this.options.globalVariables.has(oo.name)
82
- ) {
83
- var info = getIdentifierInfo(oo, pp);
84
- if (
85
- info.spec.isReferenced &&
86
- info.spec.isDefined &&
87
- getVarContext(oo, pp) === context
88
- ) {
89
- definedNames.add(oo.name);
90
- }
91
- }
92
- });
93
- };
94
-
95
- walk(object, [], (o, p) => {
96
- if (o.type == "VariableDeclaration" || o.type == "ClassDeclaration") {
97
- if (p.find((x) => isFunction(x))) {
98
- return;
99
- }
100
- if (o.type == "VariableDeclaration") {
101
- return () => {
102
- var exprs = [];
103
- var fi = isForInitialize(o, p);
104
- o.declarations.forEach((declarator) => {
105
- findNames(declarator.id, [declarator, o.declarations, o, ...p]);
106
- if (fi === "left-hand") {
107
- exprs.push({ ...declarator.id });
108
- } else {
109
- exprs.push(
110
- AssignmentExpression(
111
- "=",
112
- declarator.id,
113
- declarator.init || Identifier("undefined")
114
- )
115
- );
116
- }
117
- });
118
-
119
- if (fi) {
120
- this.replace(
121
- o,
122
- exprs.length > 1 ? SequenceExpression(exprs) : exprs[0]
123
- );
124
- } else {
125
- this.replace(o, ExpressionStatement(SequenceExpression(exprs)));
126
- }
127
- };
128
- } else if (o.type == "ClassDeclaration") {
129
- if (o.id.name) {
130
- definedNames.add(o.id.name);
131
-
132
- this.replace(
133
- o,
134
- ExpressionStatement(
135
- AssignmentExpression("=", Identifier(o.id.name), {
136
- ...o,
137
- type: "ClassExpression",
138
- })
139
- )
140
- );
141
- }
142
- }
143
- }
144
- });
145
-
146
- var addNodes = [];
147
- if (definedNames.size) {
148
- addNodes.push(
149
- VariableDeclaration(
150
- Array.from(definedNames).map((name) => {
151
- return VariableDeclarator(name);
152
- })
153
- )
154
- );
155
- }
156
-
157
- var deadValues: { [name: string]: number } = Object.create(null);
158
- Array(getRandomInteger(1, 20))
159
- .fill(0)
160
- .forEach(() => {
161
- var name = this.getPlaceholder();
162
- var value = getRandomInteger(-250, 250);
163
- addNodes.push(
164
- VariableDeclaration(VariableDeclarator(name, Literal(value)))
165
- );
166
-
167
- deadValues[name] = value;
168
- sampledNames.add(name);
169
- });
170
-
171
- var map = new Map<string, { [input: number]: number }>();
172
- var fnsToMake = getRandomInteger(1, 5);
173
-
174
- var numberLiteralsMade = 1;
175
- function numberLiteral(num: number, depth = 1) {
176
- if (
177
- depth > 6 ||
178
- Math.random() > 0.8 / depth ||
179
- Math.random() > 80 / numberLiteralsMade
180
- ) {
181
- return Literal(num);
182
- }
183
-
184
- numberLiteralsMade++;
185
-
186
- function ternaryCall(
187
- name: string,
188
- param: number = getRandomInteger(-250, 250)
189
- ) {
190
- return ConditionalExpression(
191
- BinaryExpression(
192
- "==",
193
- UnaryExpression("typeof", Identifier(name)),
194
- Literal("function")
195
- ),
196
- CallExpression(Identifier(name), [numberLiteral(param, depth + 1)]),
197
- Identifier(name)
198
- );
199
- }
200
-
201
- if (Math.random() > 0.5) {
202
- var fnName = choice(Array.from(map.keys()));
203
- if (fnName) {
204
- var inputOutputs = map.get(fnName);
205
- var randomInput = choice(Object.keys(inputOutputs));
206
- var outputValue = inputOutputs[randomInput];
207
- var parsed = parseFloat(randomInput);
208
-
209
- return BinaryExpression(
210
- "-",
211
-
212
- ternaryCall(fnName, parsed),
213
- numberLiteral(outputValue - num, depth + 1)
214
- );
215
- }
216
- }
217
-
218
- var deadValueName = choice(Object.keys(deadValues));
219
- var actualValue = deadValues[deadValueName];
220
-
221
- if (Math.random() > 0.5) {
222
- return BinaryExpression(
223
- "+",
224
- numberLiteral(num - actualValue, depth + 1),
225
- ternaryCall(deadValueName)
226
- );
227
- }
228
-
229
- return BinaryExpression(
230
- "-",
231
- ternaryCall(deadValueName),
232
- numberLiteral(actualValue - num, depth + 1)
233
- );
234
- }
235
-
236
- for (var i = 0; i < fnsToMake; i++) {
237
- var name = this.getPlaceholder();
238
- var testShift = getRandomInteger(-250, 250);
239
- var returnShift = getRandomInteger(-250, 250);
240
-
241
- var inputs = getRandomInteger(2, 5);
242
- var used = new Set<number>();
243
- var uniqueNumbersNeeded = inputs * 2;
244
- for (var j = 0; j < uniqueNumbersNeeded; j++) {
245
- var num;
246
- var k = 0;
247
- do {
248
- num = getRandomInteger(-250, 250 + k * 100);
249
- k++;
250
- } while (used.has(num));
251
-
252
- used.add(num);
253
- }
254
-
255
- var inputOutput = Object.create(null);
256
- var array: number[] = Array.from(used);
257
- for (var j = 0; j < array.length; j += 2) {
258
- inputOutput[array[j]] = array[j + 1];
259
- }
260
-
261
- var cases = Object.keys(inputOutput).map((input) => {
262
- var parsed = parseFloat(input);
263
-
264
- return SwitchCase(numberLiteral(parsed + testShift), [
265
- ExpressionStatement(
266
- AssignmentExpression(
267
- "=",
268
- Identifier("input"),
269
- numberLiteral(inputOutput[input] - returnShift)
270
- )
271
- ),
272
- BreakStatement(),
273
- ]);
274
- });
275
-
276
- var functionExpression = FunctionExpression(
277
- [Identifier("testShift"), Identifier("returnShift")],
278
- [
279
- ReturnStatement(
280
- FunctionExpression(
281
- [Identifier("input")],
282
- [
283
- SwitchStatement(
284
- BinaryExpression(
285
- "+",
286
- Identifier("input"),
287
- Identifier("testShift")
288
- ),
289
- cases
290
- ),
291
-
292
- ReturnStatement(
293
- BinaryExpression(
294
- "+",
295
- Identifier("input"),
296
- Identifier("returnShift")
297
- )
298
- ),
299
- ]
300
- )
301
- ),
302
- ]
303
- );
304
-
305
- var variableDeclaration = VariableDeclaration(
306
- VariableDeclarator(
307
- name,
308
- CallExpression(functionExpression, [
309
- numberLiteral(testShift),
310
- numberLiteral(returnShift),
311
- ])
312
- )
313
- );
314
- addNodes.push(variableDeclaration);
315
-
316
- map.set(name, inputOutput);
317
- sampledNames.add(name);
318
- }
319
-
320
- var deadNameArray = Object.keys(deadValues);
321
- var sampledArray = Array.from(sampledNames);
322
-
323
- var check = getRandomInteger(-250, 250);
324
-
325
- var initName = "init" + this.getPlaceholder();
326
-
327
- // Entangle number literals
328
- var made = 1; // Limit frequency
329
- walk(stmts, [], (o, p) => {
330
- if (
331
- o.type == "Literal" &&
332
- typeof o.value === "number" &&
333
- Math.floor(o.value) === o.value &&
334
- Math.abs(o.value) < 100_000 &&
335
- Math.random() < 4 / made
336
- ) {
337
- made++;
338
- return () => {
339
- this.replaceIdentifierOrLiteral(o, numberLiteral(o.value), p);
340
- };
341
- }
342
- });
343
-
344
- // Create the new function
345
- addNodes.push(FunctionDeclaration(initName, [], [...stmts]));
346
-
347
- function truePredicate() {
348
- return BinaryExpression(
349
- ">",
350
- Literal(600 + getRandomInteger(200, 800)),
351
- Literal(400 - getRandomInteger(0, 600))
352
- );
353
- }
354
- function falsePredicate() {
355
- return BinaryExpression(
356
- ">",
357
- Literal(400 - getRandomInteger(0, 600)),
358
- Literal(600 + getRandomInteger(200, 800))
359
- );
360
- }
361
-
362
- function safeCallExpression(name, param: number) {
363
- return ConditionalExpression(
364
- BinaryExpression(
365
- "==",
366
- UnaryExpression("typeof", Identifier(name)),
367
- Literal("function")
368
- ),
369
- CallExpression(
370
- MemberExpression(Identifier(name), Identifier("call"), false),
371
- [ThisExpression(), numberLiteral(param)]
372
- ),
373
- Identifier(name)
374
- );
375
- }
376
-
377
- function ternaryHell(expr, depth = 1) {
378
- if (!depth || depth > 5 || Math.random() > 0.99 / (depth / 2)) {
379
- return expr;
380
- }
381
-
382
- var deadCode = safeCallExpression(
383
- choice(sampledArray),
384
- getRandomInteger(-250, 250)
385
- );
386
-
387
- if (Math.random() > 0.5) {
388
- return ConditionalExpression(
389
- truePredicate(),
390
- ternaryHell(expr, depth + 1),
391
- ternaryHell(deadCode, depth + 1)
392
- );
393
- }
394
-
395
- return ConditionalExpression(
396
- falsePredicate(),
397
- ternaryHell(deadCode, depth + 1),
398
- ternaryHell(expr, depth + 1)
399
- );
400
- }
401
-
402
- // Array of random ternary expressions
403
- var concealedCall = [];
404
-
405
- // Add 'dead calls', these expression don't call anything
406
- Array(getRandomInteger(2, 8))
407
- .fill(0)
408
- .forEach(() => {
409
- concealedCall.push(
410
- ExpressionStatement(
411
- ternaryHell(
412
- safeCallExpression(
413
- choice(deadNameArray),
414
- getRandomInteger(-250, 250)
415
- )
416
- )
417
- )
418
- );
419
- });
420
-
421
- // The real call to the 'init' function
422
- concealedCall.push(
423
- ExpressionStatement(ternaryHell(safeCallExpression(initName, check)))
424
- );
425
-
426
- shuffle(concealedCall);
427
- shuffle(functions);
428
-
429
- object.body = [...addNodes, ...functions, ...concealedCall];
430
- };
431
- }
432
- }
@@ -1,64 +0,0 @@
1
- import Transform from "./transform";
2
- import { Identifier, LabeledStatement } from "../util/gen";
3
- import { walk } from "../traverse";
4
- import { clone } from "../util/insert";
5
- import { isLoop } from "../util/compare";
6
-
7
- /**
8
- * Ensures every break; statement has a label to point to.
9
- *
10
- * This is because Control Flow Flattening adds For Loops which label-less break statements point to the nearest,
11
- * when they actually need to point to the original statement.
12
- */
13
- export default class Label extends Transform {
14
- constructor(o) {
15
- super(o);
16
- }
17
-
18
- match(object, parents) {
19
- return (
20
- isLoop(object) ||
21
- (object.type == "BlockStatement" &&
22
- parents[0] &&
23
- parents[0].type == "LabeledStatement" &&
24
- parents[0].body === object)
25
- );
26
- }
27
-
28
- transform(object, parents) {
29
- return () => {
30
- var currentLabel =
31
- parents[0].type == "LabeledStatement" && parents[0].label.name;
32
-
33
- var label = currentLabel || this.getPlaceholder();
34
-
35
- walk(object, parents, (o, p) => {
36
- if (o.type == "BreakStatement" || o.type == "ContinueStatement") {
37
- function isContinuableStatement(x) {
38
- return isLoop(x) && x.type !== "SwitchStatement";
39
- }
40
- function isBreakableStatement(x) {
41
- return isLoop(x) || (o.label && x.type == "BlockStatement");
42
- }
43
-
44
- var fn =
45
- o.type == "ContinueStatement"
46
- ? isContinuableStatement
47
- : isBreakableStatement;
48
-
49
- var loop = p.find(fn);
50
- if (object == loop) {
51
- if (!o.label) {
52
- o.label = Identifier(label);
53
- }
54
- }
55
- }
56
- });
57
-
58
- // Append label statement as this loop has none
59
- if (!currentLabel) {
60
- this.replace(object, LabeledStatement(label, { ...object }));
61
- }
62
- };
63
- }
64
- }
@@ -1,102 +0,0 @@
1
- import { reservedIdentifiers } from "../../constants";
2
- import { Node } from "../../util/gen";
3
- import {
4
- getDefiningIdentifier,
5
- getIdentifierInfo,
6
- } from "../../util/identifiers";
7
- import Transform from "../transform";
8
-
9
- export class NameMappingAnalysis extends Transform {
10
- names: Map<string, Set<Node>>;
11
-
12
- constructor(o) {
13
- super(o);
14
-
15
- this.names = new Map();
16
- }
17
-
18
- match(object, parents) {
19
- return object.type == "Identifier" && !reservedIdentifiers.has(object.name);
20
- }
21
-
22
- transform(object, parents) {
23
- var info = getIdentifierInfo(object, parents);
24
-
25
- if (info.spec.isReferenced && !info.spec.isDefined) {
26
- object.$definedAt = getDefiningIdentifier(object, parents);
27
- }
28
-
29
- if (info.spec.isDefined) {
30
- if (!this.names.has(object.name)) {
31
- this.names.set(object.name, new Set([object]));
32
- } else {
33
- this.names.get(object.name).add(object);
34
- }
35
- }
36
- }
37
- }
38
-
39
- /**
40
- * Renames variables & removes conflicts.
41
- *
42
- * - This helps transformations like `Dispatcher` not replace re-declared identifiers.
43
- */
44
- export default class NameConflicts extends Transform {
45
- nameMappingAnalysis: NameMappingAnalysis;
46
-
47
- changes: Map<Node, string>;
48
- references: Map<Node, Set<Node>>;
49
-
50
- constructor(o) {
51
- super(o);
52
-
53
- this.before.push((this.nameMappingAnalysis = new NameMappingAnalysis(o)));
54
- this.changes = new Map();
55
- this.references = new Map();
56
- }
57
-
58
- match(object, parents) {
59
- return (
60
- object.type == "Identifier" &&
61
- !reservedIdentifiers.has(object.name) &&
62
- !this.options.globalVariables.has(object.name)
63
- );
64
- }
65
-
66
- transform(object: Node, parents: Node[]) {
67
- var info = getIdentifierInfo(object, parents);
68
-
69
- if (info.isMethodDefinition) {
70
- return;
71
- }
72
-
73
- if (object.$definedAt) {
74
- object.name = this.changes.get(object.$definedAt[0]) || object.name;
75
-
76
- if (!this.references.has(object.$definedAt[0])) {
77
- this.references.set(object.$definedAt[0], new Set([object]));
78
- } else {
79
- this.references.get(object.$definedAt[0]).add(object);
80
- }
81
- } else if (info.spec.isDefined) {
82
- var set = this.nameMappingAnalysis.names.get(object.name);
83
- if (set && set.size > 1) {
84
- var index = Array.from(set).indexOf(object);
85
-
86
- var newName = "_".repeat(index) + object.name;
87
-
88
- if (index > 4 || this.nameMappingAnalysis.names.has(newName)) {
89
- newName = this.getPlaceholder() + "_" + object.name;
90
- }
91
-
92
- object.name = newName;
93
- this.changes.set(object, newName);
94
- if (this.references.has(object)) {
95
- this.references.get(object).forEach((ref) => {
96
- ref.name = newName;
97
- });
98
- }
99
- }
100
- }
101
- }
102
- }