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
@@ -16,88 +16,15 @@ import {
16
16
  VariableDeclarator,
17
17
  FunctionExpression,
18
18
  ExpressionStatement,
19
- SequenceExpression,
20
19
  AssignmentExpression,
21
20
  VariableDeclaration,
22
21
  BreakStatement,
23
22
  } from "../../util/gen";
24
23
  import { append, prepend } from "../../util/insert";
25
- import { getIdentifierInfo } from "../../util/identifiers";
26
- import { getRandomInteger } from "../../util/random";
27
- import { reservedIdentifiers, reservedKeywords } from "../../constants";
24
+ import { chance, getRandomInteger } from "../../util/random";
25
+ import { reservedIdentifiers } from "../../constants";
28
26
  import { ComputeProbabilityMap } from "../../probability";
29
-
30
- class GlobalAnalysis extends Transform {
31
- notGlobals: Set<string>;
32
- globals: { [name: string]: Location[] };
33
-
34
- constructor(o) {
35
- super(o);
36
-
37
- this.globals = Object.create(null);
38
- this.notGlobals = new Set();
39
- }
40
-
41
- match(object: Node, parents: Node[]) {
42
- return object.type == "Identifier" && !reservedKeywords.has(object.name);
43
- }
44
-
45
- transform(object: Node, parents: Node[]) {
46
- // no touching `import()` or `import x from ...`
47
- var importIndex = parents.findIndex(
48
- (x) => x.type == "ImportExpression" || x.type == "ImportDeclaration"
49
- );
50
- if (importIndex !== -1) {
51
- if (
52
- parents[importIndex].source === (parents[importIndex - 1] || object)
53
- ) {
54
- return;
55
- }
56
- }
57
-
58
- var info = getIdentifierInfo(object, parents);
59
- if (!info.spec.isReferenced) {
60
- return;
61
- }
62
-
63
- // Add to globals
64
- if (!this.notGlobals.has(object.name)) {
65
- if (!this.globals[object.name]) {
66
- this.globals[object.name] = [];
67
- }
68
-
69
- this.globals[object.name].push([object, parents]);
70
- }
71
-
72
- if (info.spec.isDefined || info.spec.isModified) {
73
- delete this.globals[object.name];
74
-
75
- this.notGlobals.add(object.name);
76
- }
77
-
78
- var assignmentIndex = parents.findIndex(
79
- (x) => x.type == "AssignmentExpression"
80
- );
81
- var updateIndex = parents.findIndex((x) => x.type == "UpdateExpression");
82
-
83
- if (
84
- (assignmentIndex != -1 &&
85
- parents[assignmentIndex].left ===
86
- (parents[assignmentIndex - 1] || object)) ||
87
- updateIndex != -1
88
- ) {
89
- var memberIndex = parents.findIndex((x) => x.type == "MemberExpression");
90
- if (
91
- memberIndex == -1 ||
92
- memberIndex > (assignmentIndex == -1 ? assignmentIndex : updateIndex)
93
- ) {
94
- delete this.globals[object.name];
95
-
96
- this.notGlobals.add(object.name);
97
- }
98
- }
99
- }
100
- }
27
+ import GlobalAnalysis from "./globalAnalysis";
101
28
 
102
29
  /**
103
30
  * Global Concealing hides global variables being accessed.
@@ -141,12 +68,10 @@ export default class GlobalConcealing extends Transform {
141
68
  }
142
69
  });
143
70
 
144
- // this.log(Object.keys(globals).join(', '))
145
-
146
71
  if (Object.keys(globals).length > 0) {
147
72
  var used = new Set();
148
73
 
149
- // 1. Make getter function
74
+ // Make getter function
150
75
 
151
76
  // holds "window" or "global"
152
77
  var globalVar = this.getPlaceholder();
@@ -157,6 +82,8 @@ export default class GlobalConcealing extends Transform {
157
82
  // "window" or "global" in node
158
83
  var global =
159
84
  this.options.globalVariables.values().next().value || "window";
85
+ var alternateGlobal = global === "window" ? "global" : "window";
86
+
160
87
  var getGlobalVariableFnName = this.getPlaceholder();
161
88
  var getThisVariableFnName = this.getPlaceholder();
162
89
 
@@ -164,7 +91,7 @@ export default class GlobalConcealing extends Transform {
164
91
  var getGlobalVariableFn = Template(`
165
92
  var ${getGlobalVariableFnName} = function(){
166
93
  try {
167
- return ${global};
94
+ return ${global} || ${alternateGlobal} || (new Function("return this"))();
168
95
  } catch (e){
169
96
  return ${getThisVariableFnName}["call"](this);
170
97
  }
@@ -182,7 +109,7 @@ export default class GlobalConcealing extends Transform {
182
109
  // 2. Replace old accessors
183
110
  var globalFn = this.getPlaceholder();
184
111
 
185
- var newNames = Object.create(null);
112
+ var newNames: { [globalVarName: string]: number } = Object.create(null);
186
113
 
187
114
  Object.keys(globals).forEach((name) => {
188
115
  var locations: Location[] = globals[name];
@@ -195,26 +122,10 @@ export default class GlobalConcealing extends Transform {
195
122
  newNames[name] = state;
196
123
 
197
124
  locations.forEach(([node, parents]) => {
198
- if (!parents.find((x) => x.$dispatcherSkip)) {
199
- // Do not replace
200
- if (parents[0]) {
201
- if (
202
- parents[0].type == "ClassDeclaration" ||
203
- parents[0].type == "ClassExpression" ||
204
- parents[0].type == "FunctionExpression" ||
205
- parents[0].type == "FunctionDeclaration"
206
- ) {
207
- if (parents[0].id === node) {
208
- return;
209
- }
210
- }
211
- }
212
-
213
- this.replace(
214
- node,
215
- CallExpression(Identifier(globalFn), [Literal(state)])
216
- );
217
- }
125
+ this.replace(
126
+ node,
127
+ CallExpression(Identifier(globalFn), [Literal(state)])
128
+ );
218
129
  });
219
130
  });
220
131
 
@@ -224,7 +135,7 @@ export default class GlobalConcealing extends Transform {
224
135
  var state;
225
136
  do {
226
137
  state = getRandomInteger(
227
- -1000,
138
+ 0,
228
139
  1000 + used.size + this.options.globalVariables.size * 100
229
140
  );
230
141
  } while (used.has(state));
@@ -259,7 +170,7 @@ export default class GlobalConcealing extends Transform {
259
170
  )
260
171
  ),
261
172
  ];
262
- if (Math.random() > 0.5 && name) {
173
+ if (chance(50)) {
263
174
  body = [
264
175
  ExpressionStatement(
265
176
  AssignmentExpression(
@@ -1,21 +1,18 @@
1
1
  import Transform from "../transform";
2
- import { isBlock, getBlock, walk } from "../../traverse";
2
+ import { isBlock, walk } from "../../traverse";
3
3
  import {
4
4
  Location,
5
5
  ExpressionStatement,
6
- SequenceExpression,
7
6
  AssignmentExpression,
8
7
  Identifier,
9
8
  Node,
10
9
  VariableDeclarator,
11
10
  VariableDeclaration,
12
11
  } from "../../util/gen";
13
- import { clone, isForInitialize, isFunction, prepend } from "../../util/insert";
12
+ import { isForInitialize, prepend } from "../../util/insert";
14
13
  import { ok } from "assert";
15
14
  import { ObfuscateOrder } from "../../order";
16
15
  import { getIdentifierInfo } from "../../util/identifiers";
17
- import { isLoop } from "../../util/compare";
18
- import { reservedIdentifiers } from "../../constants";
19
16
  import { isLexicalScope, getLexicalScope } from "../../util/scope";
20
17
 
21
18
  /**
@@ -46,7 +43,7 @@ export default class MovedDeclarations extends Transform {
46
43
 
47
44
  walk(object, parents, (o, p) => {
48
45
  if (o.type == "Identifier") {
49
- if (getLexicalScope(o, p) !== object) {
46
+ if (o.hidden || getLexicalScope(o, p) !== object) {
50
47
  illegal.add(o.name);
51
48
  } else {
52
49
  var info = getIdentifierInfo(o, p);
@@ -125,11 +122,7 @@ export default class MovedDeclarations extends Transform {
125
122
  })
126
123
  );
127
124
 
128
- if (object.type == "Program") {
129
- prepend(object, variableDeclaration);
130
- } else {
131
- body.unshift(variableDeclaration);
132
- }
125
+ prepend(object, variableDeclaration);
133
126
 
134
127
  movingNames.forEach((name) => {
135
128
  var { location, replace } = variableDeclarations[name];
@@ -1,18 +1,14 @@
1
1
  import { ok } from "assert";
2
2
  import { ObfuscateOrder } from "../../order";
3
3
  import { walk } from "../../traverse";
4
- import { Location, Node } from "../../util/gen";
4
+ import { Node } from "../../util/gen";
5
5
  import { getIdentifierInfo } from "../../util/identifiers";
6
6
  import {
7
- getVarContext,
8
7
  isVarContext,
9
- getLexContext,
10
8
  isContext,
11
9
  isLexContext,
12
- getDefiningContext,
13
10
  clone,
14
11
  } from "../../util/insert";
15
- import { isValidIdentifier } from "../../util/compare";
16
12
  import Transform from "../transform";
17
13
  import { reservedIdentifiers } from "../../constants";
18
14
  import { ComputeProbabilityMap } from "../../probability";
@@ -21,12 +17,13 @@ import VariableAnalysis from "./variableAnalysis";
21
17
  /**
22
18
  * Rename variables to randomly generated names.
23
19
  *
24
- * - Attempts to re-use already generated names in nested scopes.
20
+ * - 1. First collect data on identifiers in all scope using 'VariableAnalysis'
21
+ * - 2. After 'VariableAnalysis' is finished start applying to each scope (top-down)
22
+ * - 3. Each scope, find the all names used here and exclude those names from being re-named
23
+ * - 4. Now loop through all the defined names in this scope and set it to a random name (or re-use previously generated name)
24
+ * - 5. Update all the Identifiers node's 'name' property to reflect this change
25
25
  */
26
26
  export default class RenameVariables extends Transform {
27
- // Generator object
28
- gen: any;
29
-
30
27
  // Names already used
31
28
  generated: string[];
32
29
 
@@ -41,17 +38,18 @@ export default class RenameVariables extends Transform {
41
38
 
42
39
  this.changed = new Map();
43
40
 
41
+ // 1.
44
42
  this.variableAnalysis = new VariableAnalysis(o);
45
43
  this.before.push(this.variableAnalysis);
46
- this.gen = this.getGenerator();
47
44
  this.generated = [];
48
45
  }
49
46
 
50
- match(object, parents) {
47
+ match(object: Node, parents: Node[]) {
51
48
  return isContext(object);
52
49
  }
53
50
 
54
- transform(object, parents) {
51
+ transform(object: Node, parents: Node[]) {
52
+ // 2. Notice this is on 'onEnter' (top-down)
55
53
  var isGlobal = object.type == "Program";
56
54
  var type = isGlobal
57
55
  ? "root"
@@ -68,15 +66,18 @@ export default class RenameVariables extends Transform {
68
66
  var defined = this.variableAnalysis.defined.get(object) || new Set();
69
67
  var references = this.variableAnalysis.references.get(object) || new Set();
70
68
 
69
+ // No changes needed here
71
70
  if (!defined && !this.changed.has(object)) {
72
71
  this.changed.set(object, Object.create(null));
73
72
  return;
74
73
  }
75
74
 
76
- var possible = new Set();
75
+ // Names possible to be re-used here
76
+ var possible = new Set<string>();
77
77
 
78
+ // 3. Try to re-use names when possible
78
79
  if (this.generated.length && !isGlobal) {
79
- var allReferences = new Set(references || []);
80
+ var allReferences = new Set<string>();
80
81
  var nope = new Set(defined);
81
82
  walk(object, [], (o, p) => {
82
83
  var ref = this.variableAnalysis.references.get(o);
@@ -90,14 +91,14 @@ export default class RenameVariables extends Transform {
90
91
  }
91
92
  });
92
93
 
93
- var passed = new Set();
94
+ var passed = new Set<string>();
94
95
  parents.forEach((p) => {
95
96
  var changes = this.changed.get(p);
96
97
  if (changes) {
97
98
  Object.keys(changes).forEach((x) => {
98
99
  var name = changes[x];
99
100
 
100
- if (!allReferences.has(x)) {
101
+ if (!allReferences.has(x) && !references.has(x)) {
101
102
  passed.add(name);
102
103
  } else {
103
104
  nope.add(name);
@@ -111,42 +112,48 @@ export default class RenameVariables extends Transform {
111
112
  possible = passed;
112
113
  }
113
114
 
114
- defined.forEach((name) => {
115
+ // 4. Defined names to new names
116
+ for (var name of defined) {
115
117
  if (
116
- (isGlobal && !name.startsWith("__p_")
118
+ !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
117
120
  ? ComputeProbabilityMap(this.options.renameGlobals, (x) => x, name)
118
121
  : true) &&
119
122
  ComputeProbabilityMap(
123
+ // Check the user's option for renaming variables
120
124
  this.options.renameVariables,
121
125
  (x) => x,
122
126
  name,
123
127
  isGlobal
124
128
  )
125
129
  ) {
126
- // Fix 2. Ensure global names aren't overridden
127
- var newName;
130
+ // Create a new name from (1) or (2) methods
131
+ var newName: string;
128
132
  do {
129
133
  if (possible.size) {
134
+ // (1) Re-use previously generated name
130
135
  var first = possible.values().next().value;
131
136
  possible.delete(first);
132
137
  newName = first;
133
138
  } else {
134
- // Fix 1. Use `generateIdentifier` over `gen.generate()` so Integrity can get unique variable names
135
- var g = this.generateIdentifier();
139
+ // (2) Create a new name with `generateIdentifier` function
140
+ var generatedName = this.generateIdentifier();
136
141
 
137
- newName = g;
138
- this.generated.push(g);
142
+ newName = generatedName;
143
+ this.generated.push(generatedName);
139
144
  }
140
- } while (this.variableAnalysis.globals.has(newName));
145
+ } while (this.variableAnalysis.globals.has(newName)); // Ensure global names aren't overridden
141
146
 
142
147
  newNames[name] = newName;
143
148
  } else {
149
+ // This variable name was deemed not to be renamed.
144
150
  newNames[name] = name;
145
151
  }
146
- });
152
+ }
147
153
 
148
154
  this.changed.set(object, newNames);
149
155
 
156
+ // 5. Update Identifier node's 'name' property
150
157
  walk(object, parents, (o, p) => {
151
158
  if (o.type == "Identifier") {
152
159
  if (
@@ -156,6 +163,10 @@ export default class RenameVariables extends Transform {
156
163
  return;
157
164
  }
158
165
 
166
+ if (o.$renamed) {
167
+ return;
168
+ }
169
+
159
170
  var info = getIdentifierInfo(o, p);
160
171
 
161
172
  if (info.spec.isExported) {
@@ -182,10 +193,6 @@ export default class RenameVariables extends Transform {
182
193
  }
183
194
 
184
195
  if (newName && typeof newName === "string") {
185
- if (o.$renamed) {
186
- return;
187
- }
188
-
189
196
  // Strange behavior where the `local` and `imported` objects are the same
190
197
  if (info.isImportSpecifier) {
191
198
  var importSpecifierIndex = p.findIndex(
@@ -1,14 +1,9 @@
1
1
  import { ok } from "assert";
2
2
  import { reservedIdentifiers } from "../../constants";
3
- import { walk } from "../../traverse";
4
3
  import { isValidIdentifier } from "../../util/compare";
5
4
  import { Node } from "../../util/gen";
6
5
  import { getIdentifierInfo } from "../../util/identifiers";
7
6
  import {
8
- getDefiningContext,
9
- getVarContext,
10
- getLexContext,
11
- isContext,
12
7
  getReferencingContexts,
13
8
  getAllDefiningContexts,
14
9
  } from "../../util/insert";
@@ -30,11 +25,13 @@ export default class VariableAnalysis extends Transform {
30
25
 
31
26
  /**
32
27
  * Set of global identifiers to never be redefined
28
+ *
29
+ * - Used to not accidentally block access to a global variable
33
30
  */
34
31
  globals: Set<string>;
35
32
 
36
33
  /**
37
- * Set of identifers that are defined within the program
34
+ * Set of identifiers that are defined within the program
38
35
  */
39
36
  notGlobals: Set<string>;
40
37
 
@@ -48,77 +45,73 @@ export default class VariableAnalysis extends Transform {
48
45
  }
49
46
 
50
47
  match(object, parents) {
51
- return isContext(object);
48
+ return object.type === "Identifier";
52
49
  }
53
50
 
54
- transform(object, parents) {
55
- walk(object, parents, (o, p) => {
56
- if (o.type == "Identifier") {
57
- var name = o.name;
58
- ok(typeof name === "string");
59
- if (!isValidIdentifier(name)) {
60
- return;
51
+ transform(object: Node, parents: Node[]) {
52
+ var name = object.name;
53
+ ok(typeof name === "string");
54
+ if (!isValidIdentifier(name)) {
55
+ return;
56
+ }
57
+
58
+ if (reservedIdentifiers.has(name)) {
59
+ return;
60
+ }
61
+ if (this.options.globalVariables.has(name)) {
62
+ return;
63
+ }
64
+
65
+ var info = getIdentifierInfo(object, parents);
66
+ if (!info.spec.isReferenced) {
67
+ return;
68
+ }
69
+
70
+ if (info.spec.isExported) {
71
+ return;
72
+ }
73
+
74
+ var isDefined = info.spec.isDefined;
75
+
76
+ // Keep track of defined names within the program
77
+ if (isDefined) {
78
+ this.notGlobals.add(object.name);
79
+ this.globals.delete(object.name);
80
+ } else if (!this.notGlobals.has(object.name)) {
81
+ this.globals.add(object.name);
82
+ }
83
+
84
+ var definingContexts = info.spec.isDefined
85
+ ? getAllDefiningContexts(object, parents)
86
+ : getReferencingContexts(object, parents, info);
87
+
88
+ ok(definingContexts.length);
89
+
90
+ definingContexts.forEach((definingContext) => {
91
+ // ok(
92
+ // isContext(definingContext),
93
+ // `${definingContext.type} is not a context`
94
+ // );
95
+
96
+ if (isDefined) {
97
+ // Add to defined Map
98
+ if (!this.defined.has(definingContext)) {
99
+ this.defined.set(definingContext, new Set());
61
100
  }
62
-
63
- if (reservedIdentifiers.has(name)) {
64
- return;
65
- }
66
- if (this.options.globalVariables.has(name)) {
67
- return;
68
- }
69
-
70
- var info = getIdentifierInfo(o, p);
71
- if (!info.spec.isReferenced) {
72
- return;
73
- }
74
-
75
- if (info.spec.isExported) {
76
- return;
77
- }
78
-
79
- var isDefined = info.spec.isDefined;
80
-
81
- // Keep track of defined names within the program
82
- if (isDefined) {
83
- this.notGlobals.add(o.name);
84
- this.globals.delete(o.name);
85
- } else if (!this.notGlobals.has(o.name)) {
86
- this.globals.add(o.name);
87
- }
88
-
89
- var definingContexts = info.spec.isDefined
90
- ? getAllDefiningContexts(o, p)
91
- : getReferencingContexts(o, p, info);
92
-
93
- ok(definingContexts.length);
94
-
95
- definingContexts.forEach((definingContext) => {
96
- // ok(
97
- // isContext(definingContext),
98
- // `${definingContext.type} is not a context`
99
- // );
100
-
101
- if (isDefined) {
102
- // Add to defined Map
103
- if (!this.defined.has(definingContext)) {
104
- this.defined.set(definingContext, new Set());
105
- }
106
- this.defined.get(definingContext).add(name);
107
- this.references.has(definingContext) &&
108
- this.references.get(definingContext).delete(name);
109
- } else {
110
- // Add to references Map
111
- if (
112
- !this.defined.has(definingContext) ||
113
- !this.defined.get(definingContext).has(name)
114
- ) {
115
- if (!this.references.has(definingContext)) {
116
- this.references.set(definingContext, new Set());
117
- }
118
- this.references.get(definingContext).add(name);
119
- }
101
+ this.defined.get(definingContext).add(name);
102
+ this.references.has(definingContext) &&
103
+ this.references.get(definingContext).delete(name);
104
+ } else {
105
+ // Add to references Map
106
+ if (
107
+ !this.defined.has(definingContext) ||
108
+ !this.defined.get(definingContext).has(name)
109
+ ) {
110
+ if (!this.references.has(definingContext)) {
111
+ this.references.set(definingContext, new Set());
120
112
  }
121
- });
113
+ this.references.get(definingContext).add(name);
114
+ }
122
115
  }
123
116
  });
124
117
  }