storm-lua-minify 0.1.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.
@@ -0,0 +1,669 @@
1
+ "use strict";
2
+ // based on "luamin": Copyright Mathias Bynens <https://mathiasbynens.be/>
3
+ // SPDX-License-Identifier: MIT
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.Minifier = void 0;
6
+ const source_map_1 = require("source-map");
7
+ const PRECEDENCE = {
8
+ or: 1,
9
+ and: 2,
10
+ "<": 3,
11
+ ">": 3,
12
+ "<=": 3,
13
+ ">=": 3,
14
+ "~=": 3,
15
+ "==": 3,
16
+ "..": 5,
17
+ "+": 6,
18
+ "-": 6, // binary -
19
+ "*": 7,
20
+ "/": 7,
21
+ "%": 7,
22
+ unarynot: 8,
23
+ "unary#": 8,
24
+ "unary-": 8, // unary -
25
+ "^": 10,
26
+ };
27
+ const IDENTIFIER_PARTS = [
28
+ "0",
29
+ "1",
30
+ "2",
31
+ "3",
32
+ "4",
33
+ "5",
34
+ "6",
35
+ "7",
36
+ "8",
37
+ "9",
38
+ "a",
39
+ "b",
40
+ "c",
41
+ "d",
42
+ "e",
43
+ "f",
44
+ "g",
45
+ "h",
46
+ "i",
47
+ "j",
48
+ "k",
49
+ "l",
50
+ "m",
51
+ "n",
52
+ "o",
53
+ "p",
54
+ "q",
55
+ "r",
56
+ "s",
57
+ "t",
58
+ "u",
59
+ "v",
60
+ "w",
61
+ "x",
62
+ "y",
63
+ "z",
64
+ "A",
65
+ "B",
66
+ "C",
67
+ "D",
68
+ "E",
69
+ "F",
70
+ "G",
71
+ "H",
72
+ "I",
73
+ "J",
74
+ "K",
75
+ "L",
76
+ "M",
77
+ "N",
78
+ "O",
79
+ "P",
80
+ "Q",
81
+ "R",
82
+ "S",
83
+ "T",
84
+ "U",
85
+ "V",
86
+ "W",
87
+ "X",
88
+ "Y",
89
+ "Z",
90
+ "_",
91
+ ];
92
+ const identifierMap = new Map();
93
+ const identifiersInUse = new Set();
94
+ function wrapArray(obj) {
95
+ if (Array.isArray(obj)) {
96
+ return obj;
97
+ }
98
+ return [obj];
99
+ }
100
+ function generateZeroes(length) {
101
+ let zero = "0";
102
+ let result = "";
103
+ if (length < 1) {
104
+ return result;
105
+ }
106
+ if (length == 1) {
107
+ return zero;
108
+ }
109
+ while (length) {
110
+ if (length & 1) {
111
+ result += zero;
112
+ }
113
+ // eslint-disable-next-line no-cond-assign
114
+ if ((length >>= 1)) {
115
+ zero += zero;
116
+ }
117
+ }
118
+ return result;
119
+ }
120
+ function isKeyword(id) {
121
+ switch (id.length) {
122
+ case 2:
123
+ return "do" == id || "if" == id || "in" == id || "or" == id;
124
+ case 3:
125
+ return ("and" == id || "end" == id || "for" == id || "nil" == id || "not" == id);
126
+ case 4:
127
+ return "else" == id || "goto" == id || "then" == id || "true" == id;
128
+ case 5:
129
+ return ("break" == id ||
130
+ "false" == id ||
131
+ "local" == id ||
132
+ "until" == id ||
133
+ "while" == id);
134
+ case 6:
135
+ return "elseif" == id || "repeat" == id || "return" == id;
136
+ case 8:
137
+ return "function" == id;
138
+ }
139
+ return false;
140
+ }
141
+ function isNeedSeparator(a, b) {
142
+ const lastCharA = a.slice(-1);
143
+ const firstCharB = b.charAt(0);
144
+ const regexAlphaUnderscore = /[a-zA-Z_]/;
145
+ const regexAlphaNumUnderscore = /[a-zA-Z0-9_]/;
146
+ const regexDigits = /[0-9]/;
147
+ if (lastCharA == "" || firstCharB == "") {
148
+ return false;
149
+ }
150
+ if (regexAlphaUnderscore.test(lastCharA)) {
151
+ if (regexAlphaNumUnderscore.test(firstCharB)) {
152
+ // e.g. `while` + `1`
153
+ // e.g. `local a` + `local b`
154
+ return true;
155
+ }
156
+ else {
157
+ // e.g. `not` + `(2>3 or 3<2)`
158
+ // e.g. `x` + `^`
159
+ return false;
160
+ }
161
+ }
162
+ if (regexDigits.test(lastCharA)) {
163
+ if (firstCharB == "(" ||
164
+ !(firstCharB == "." || regexAlphaUnderscore.test(firstCharB))) {
165
+ // e.g. `1` + `+`
166
+ // e.g. `1` + `==`
167
+ return false;
168
+ }
169
+ else {
170
+ // e.g. `1` + `..`
171
+ // e.g. `1` + `and`
172
+ return true;
173
+ }
174
+ }
175
+ if (lastCharA == firstCharB && lastCharA == "-") {
176
+ // e.g. `1-` + `-2`
177
+ return true;
178
+ }
179
+ const secondLastCharA = a.slice(-2, -1);
180
+ if (lastCharA == "." &&
181
+ secondLastCharA != "." &&
182
+ regexAlphaNumUnderscore.test(firstCharB)) {
183
+ // e.g. `1.` + `print`
184
+ return true;
185
+ }
186
+ return false;
187
+ }
188
+ function addWithSeparator(val, adding, separator = " ") {
189
+ if (isNeedSeparator(val.toString(), wrapArray(adding)
190
+ .map((p) => p.toString())
191
+ .join())) {
192
+ val.add(separator);
193
+ }
194
+ val.add(adding);
195
+ return val;
196
+ }
197
+ function prependWithSeparator(val, prepending, separator = " ") {
198
+ if (isNeedSeparator(wrapArray(prepending)
199
+ .map((p) => p.toString())
200
+ .join(), val.toString())) {
201
+ val.prepend(separator);
202
+ }
203
+ val.prepend(prepending);
204
+ return val;
205
+ }
206
+ function insertSeparator(a, b, separator = " ") {
207
+ return isNeedSeparator(a.toString(), b.toString()) ? separator : undefined;
208
+ }
209
+ class Minifier {
210
+ fileName;
211
+ ast;
212
+ requireHelper;
213
+ constructor(fileName, ast, requireHelper) {
214
+ this.fileName = fileName;
215
+ this.ast = ast;
216
+ this.requireHelper = requireHelper;
217
+ ast.globals?.map((v) => identifiersInUse.add(v.name));
218
+ }
219
+ parse() {
220
+ const body = this.formatStatementList(this.ast.body);
221
+ /*if (this.ast.comments) {
222
+ const comments = this.ast.comments as Comment[];
223
+ comments.reverse().filter(v => v.raw.includes("--#") || v.raw.includes("[[#")).forEach(comment => {
224
+ body.prepend(this.sourceNodeHelper(comment, comment.raw));
225
+ })
226
+ return body;
227
+ } else*/ {
228
+ return body;
229
+ }
230
+ }
231
+ sourceNodeHelper(node, chuncks, name) {
232
+ const line = node?.loc?.start.line;
233
+ const column = node?.loc?.start.column;
234
+ return new source_map_1.SourceNode(line == undefined ? null : line, column == undefined ? null : column, this.fileName, // 本当に自分のファイル名でよいかは要検討
235
+ chuncks, name);
236
+ }
237
+ formatStatementList(body) {
238
+ const result = this.sourceNodeHelper(undefined, []);
239
+ wrapArray(body).forEach((statement) => {
240
+ addWithSeparator(result, this.formatStatement(statement), "\n");
241
+ });
242
+ return result;
243
+ }
244
+ formatStatement(statement) {
245
+ if (statement.type == "AssignmentStatement") {
246
+ // left-hand side
247
+ const variables = statement.variables
248
+ .map((variable) => [this.formatExpression(variable), ","])
249
+ .flat();
250
+ const inits = statement.init
251
+ .map((init) => [this.formatExpression(init), ","])
252
+ .flat();
253
+ const result = this.sourceNodeHelper(statement, this.sourceNodeHelper(undefined, variables.slice(0, -1)));
254
+ addWithSeparator(result, "=");
255
+ addWithSeparator(result, this.sourceNodeHelper(undefined, inits.slice(0, -1)));
256
+ return result;
257
+ }
258
+ else if (statement.type == "LocalStatement") {
259
+ const variables = statement.variables
260
+ .map((variable) => [this.formatExpression(variable), ","])
261
+ .flat();
262
+ const result = this.sourceNodeHelper(statement, [
263
+ "local ",
264
+ this.sourceNodeHelper(undefined, variables.slice(0, -1)),
265
+ ]);
266
+ if (statement.init.length) {
267
+ const inits = statement.init
268
+ .map((init) => [this.formatExpression(init), ","])
269
+ .flat();
270
+ addWithSeparator(result, "=");
271
+ addWithSeparator(result, this.sourceNodeHelper(undefined, inits.slice(0, -1)));
272
+ }
273
+ return result;
274
+ }
275
+ else if (statement.type == "CallStatement") {
276
+ return this.formatExpression(statement.expression); // NOTE: もう一度囲んでもいい
277
+ }
278
+ else if (statement.type == "IfStatement") {
279
+ const result = this.sourceNodeHelper(statement, []);
280
+ statement.clauses.forEach((clause) => {
281
+ const clauseMap = this.sourceNodeHelper(clause, []);
282
+ if (clause.type == "IfClause") {
283
+ addWithSeparator(clauseMap, "if");
284
+ addWithSeparator(clauseMap, this.formatExpression(clause.condition));
285
+ addWithSeparator(clauseMap, "then");
286
+ }
287
+ else if (clause.type == "ElseifClause") {
288
+ addWithSeparator(clauseMap, "elseif");
289
+ addWithSeparator(clauseMap, this.formatExpression(clause.condition));
290
+ addWithSeparator(clauseMap, "then");
291
+ }
292
+ else {
293
+ addWithSeparator(clauseMap, "else");
294
+ }
295
+ addWithSeparator(clauseMap, this.formatStatementList(clause.body));
296
+ addWithSeparator(result, clauseMap);
297
+ });
298
+ addWithSeparator(result, "end");
299
+ return result;
300
+ }
301
+ else if (statement.type == "WhileStatement") {
302
+ const result = this.sourceNodeHelper(statement, "while");
303
+ addWithSeparator(result, this.formatExpression(statement.condition));
304
+ addWithSeparator(result, "do");
305
+ addWithSeparator(result, this.formatStatementList(statement.body));
306
+ addWithSeparator(result, "end");
307
+ return result;
308
+ }
309
+ else if (statement.type == "DoStatement") {
310
+ const result = this.sourceNodeHelper(statement, "do");
311
+ addWithSeparator(result, this.formatStatementList(statement.body));
312
+ addWithSeparator(result, "end");
313
+ return result;
314
+ }
315
+ else if (statement.type == "ReturnStatement") {
316
+ const result = this.sourceNodeHelper(statement, "return");
317
+ if (statement.arguments.length) {
318
+ const returns = statement.arguments
319
+ .map((argument) => [this.formatExpression(argument), ","])
320
+ .flat();
321
+ addWithSeparator(result, returns.slice(0, -1));
322
+ }
323
+ return result;
324
+ }
325
+ else if (statement.type == "BreakStatement") {
326
+ return this.sourceNodeHelper(statement, "break");
327
+ }
328
+ else if (statement.type == "RepeatStatement") {
329
+ const result = this.sourceNodeHelper(statement, "repeat");
330
+ addWithSeparator(result, this.formatStatementList(statement.body));
331
+ addWithSeparator(result, "until");
332
+ addWithSeparator(result, this.formatExpression(statement.condition));
333
+ return result;
334
+ }
335
+ else if (statement.type == "FunctionDeclaration") {
336
+ const result = this.sourceNodeHelper(statement, (statement.isLocal ? "local " : "") + "function ");
337
+ if (statement.identifier) {
338
+ addWithSeparator(result, this.formatExpression(statement.identifier));
339
+ }
340
+ addWithSeparator(result, "(");
341
+ if (statement.parameters.length) {
342
+ const parameters = statement.parameters
343
+ .map((parameter) => {
344
+ return [
345
+ parameter.type == "Identifier"
346
+ ? this.generateIdentifier(parameter)
347
+ : parameter.value,
348
+ ",",
349
+ ];
350
+ })
351
+ .flat();
352
+ addWithSeparator(result, parameters.slice(0, -1));
353
+ }
354
+ addWithSeparator(result, ")");
355
+ addWithSeparator(result, this.formatStatementList(statement.body));
356
+ addWithSeparator(result, "end");
357
+ return result;
358
+ }
359
+ else if (statement.type == "ForGenericStatement") {
360
+ // see also `ForNumericStatement`
361
+ const result = this.sourceNodeHelper(statement, "for");
362
+ const variables = statement.variables
363
+ .map((variable) => [this.generateIdentifier(variable), ","])
364
+ .flat();
365
+ const iterators = statement.iterators
366
+ .map((iterator) => [this.formatExpression(iterator), ","])
367
+ .flat();
368
+ addWithSeparator(result, variables.slice(0, -1));
369
+ addWithSeparator(result, "in");
370
+ addWithSeparator(result, iterators.slice(0, -1));
371
+ addWithSeparator(result, "do");
372
+ addWithSeparator(result, this.formatStatementList(statement.body));
373
+ addWithSeparator(result, "end");
374
+ return result;
375
+ }
376
+ else if (statement.type == "ForNumericStatement") {
377
+ // The variables in a `ForNumericStatement` are always local
378
+ const result = this.sourceNodeHelper(statement, "for");
379
+ addWithSeparator(result, this.generateIdentifier(statement.variable));
380
+ addWithSeparator(result, "=");
381
+ addWithSeparator(result, this.formatExpression(statement.start));
382
+ addWithSeparator(result, ",");
383
+ addWithSeparator(result, this.formatExpression(statement.end));
384
+ if (statement.step) {
385
+ addWithSeparator(result, ",");
386
+ addWithSeparator(result, this.formatExpression(statement.step));
387
+ }
388
+ addWithSeparator(result, "do");
389
+ addWithSeparator(result, this.formatStatementList(statement.body));
390
+ addWithSeparator(result, "end");
391
+ return result;
392
+ }
393
+ else if (statement.type == "LabelStatement") {
394
+ // The identifier names in a `LabelStatement` can safely be renamed
395
+ return this.sourceNodeHelper(statement, [
396
+ "::",
397
+ this.generateIdentifier(statement.label),
398
+ "::",
399
+ ]);
400
+ }
401
+ else if (statement.type == "GotoStatement") {
402
+ // The identifier names in a `GotoStatement` can safely be renamed
403
+ return this.sourceNodeHelper(statement, [
404
+ "goto ",
405
+ this.generateIdentifier(statement.label),
406
+ ]);
407
+ }
408
+ else {
409
+ throw TypeError("Unknown statement type: `" + JSON.stringify(statement) + "`");
410
+ }
411
+ }
412
+ /*function joinStatements(a: string | SourceNode, b: string | SourceNode, separator = " ") {
413
+ return isNeedSeparator(a.toString(), b.toString()) ? a.toString() + separator + b.toString() : a.toString() + b.toString();
414
+ }*/
415
+ formatExpression(expression, argOptions) {
416
+ if (expression.type == "Identifier") {
417
+ return this.sourceNodeHelper(expression,
418
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error
419
+ //@ts-ignore
420
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
421
+ expression.isLocal
422
+ ? this.generateIdentifier(expression, true)
423
+ : expression.name, expression.name);
424
+ }
425
+ else if (expression.type == "StringLiteral" ||
426
+ expression.type == "NumericLiteral" ||
427
+ expression.type == "BooleanLiteral" ||
428
+ expression.type == "NilLiteral" ||
429
+ expression.type == "VarargLiteral") {
430
+ return this.sourceNodeHelper(expression, expression.raw);
431
+ }
432
+ else if (expression.type == "LogicalExpression" ||
433
+ expression.type == "BinaryExpression") {
434
+ const operator = expression.operator;
435
+ const currentPrecedence = PRECEDENCE[operator];
436
+ let associativity = "left";
437
+ const options = {
438
+ precedence: 0,
439
+ preserveIdentifiers: false,
440
+ ...argOptions,
441
+ };
442
+ const leftHand = this.formatExpression(expression.left, {
443
+ precedence: currentPrecedence,
444
+ direction: "left",
445
+ parent: operator,
446
+ });
447
+ const rightHand = this.formatExpression(expression.right, {
448
+ precedence: currentPrecedence,
449
+ direction: "right",
450
+ parent: operator,
451
+ });
452
+ if (operator == "^" || operator == "..") {
453
+ associativity = "right";
454
+ }
455
+ else if (currentPrecedence < options.precedence ||
456
+ (currentPrecedence == options.precedence &&
457
+ associativity != options.direction &&
458
+ options.parent != "+" &&
459
+ !(options.parent == "*" && (operator == "/" || operator == "*")))) {
460
+ return this.sourceNodeHelper(expression, [
461
+ "(",
462
+ leftHand,
463
+ insertSeparator(leftHand, operator),
464
+ operator,
465
+ insertSeparator(operator, rightHand),
466
+ rightHand,
467
+ ")",
468
+ ].filter((p) => p !== undefined));
469
+ }
470
+ return this.sourceNodeHelper(expression, [
471
+ leftHand,
472
+ insertSeparator(leftHand, operator),
473
+ operator,
474
+ insertSeparator(operator, rightHand),
475
+ rightHand,
476
+ ].filter((p) => p !== undefined));
477
+ }
478
+ else if (expression.type == "UnaryExpression") {
479
+ const operator = expression.operator;
480
+ const currentPrecedence = PRECEDENCE["unary" + operator];
481
+ const options = {
482
+ precedence: 0,
483
+ ...argOptions,
484
+ };
485
+ const p2 = this.formatExpression(expression.argument, {
486
+ precedence: currentPrecedence,
487
+ });
488
+ const result = this.sourceNodeHelper(expression, [operator, insertSeparator(operator, p2), p2].filter((p) => p !== undefined));
489
+ if (currentPrecedence < options.precedence &&
490
+ // In principle, we should parenthesize the RHS of an
491
+ // expression like `3^-2`, because `^` has higher precedence
492
+ // than unary `-` according to the manual. But that is
493
+ // misleading on the RHS of `^`, since the parser will
494
+ // always try to find a unary operator regardless of
495
+ // precedence.
496
+ !(options.parent == "^" && options.direction == "right")) {
497
+ result.prepend("(");
498
+ result.add(")");
499
+ }
500
+ return result;
501
+ }
502
+ else if (expression.type == "CallExpression") {
503
+ // requireの展開モードは2種類: SLモード-その場に読み込み, FLモード-require相当の関数で呼び出し
504
+ if (this.formatBase(expression.base).toString() == "require" &&
505
+ expression?.arguments[0].type === "StringLiteral") {
506
+ const res = this.requireHelper(expression.arguments[0].raw.replaceAll('"', ""));
507
+ if (res != undefined) {
508
+ return res;
509
+ }
510
+ }
511
+ const args = expression.arguments
512
+ .map((arg) => [this.formatExpression(arg), ","])
513
+ .flat();
514
+ return this.sourceNodeHelper(expression, [
515
+ this.formatBase(expression.base),
516
+ "(",
517
+ this.sourceNodeHelper(undefined, args.slice(0, -1)),
518
+ ")",
519
+ ]);
520
+ }
521
+ else if (expression.type == "TableCallExpression") {
522
+ return this.sourceNodeHelper(expression, [
523
+ this.formatExpression(expression.base),
524
+ this.formatExpression(expression.arguments),
525
+ ]);
526
+ }
527
+ else if (expression.type == "StringCallExpression") {
528
+ return this.sourceNodeHelper(expression, [
529
+ this.formatExpression(expression.base),
530
+ this.formatExpression(expression.argument),
531
+ ]);
532
+ }
533
+ else if (expression.type == "IndexExpression") {
534
+ return this.sourceNodeHelper(expression, [
535
+ this.formatBase(expression.base),
536
+ "[",
537
+ this.formatExpression(expression.index),
538
+ "]",
539
+ ]);
540
+ }
541
+ else if (expression.type == "MemberExpression") {
542
+ return this.sourceNodeHelper(expression, [
543
+ this.formatBase(expression.base),
544
+ expression.indexer,
545
+ this.formatExpression(expression.identifier, {
546
+ preserveIdentifiers: true,
547
+ }),
548
+ ]);
549
+ }
550
+ else if (expression.type == "FunctionDeclaration") {
551
+ const result = this.sourceNodeHelper(expression, ["function", "("]);
552
+ if (expression.parameters.length) {
553
+ const parameters = expression.parameters
554
+ .map((parameter) => {
555
+ return [
556
+ this.sourceNodeHelper(parameter, parameter.type === "Identifier"
557
+ ? this.generateIdentifier(parameter)
558
+ : parameter.value),
559
+ ",",
560
+ ];
561
+ })
562
+ .flat();
563
+ addWithSeparator(result, parameters.slice(0, -1));
564
+ }
565
+ result.add(")");
566
+ const body = this.formatStatementList(expression.body);
567
+ addWithSeparator(result, body);
568
+ addWithSeparator(result, "end");
569
+ return result;
570
+ }
571
+ else if (expression.type == "TableConstructorExpression") {
572
+ const result = this.sourceNodeHelper(expression, "{");
573
+ const fields = expression.fields
574
+ .map((field, ix, ar) => {
575
+ // Stormworks "propert" Trailing Comma: https://nona-takahara.github.io/blog/entry11.html
576
+ const comma = ix !== ar.length - 1 ||
577
+ this.formatExpression(field.value).toString().includes("property")
578
+ ? ","
579
+ : undefined;
580
+ if (field.type == "TableKey") {
581
+ return this.sourceNodeHelper(field, [
582
+ this.sourceNodeHelper(undefined, [
583
+ "[",
584
+ this.formatExpression(field.key),
585
+ "]",
586
+ ]),
587
+ "=",
588
+ this.formatExpression(field.value),
589
+ comma,
590
+ ].filter((p) => p !== undefined));
591
+ }
592
+ else if (field.type == "TableValue") {
593
+ return [this.formatExpression(field.value), comma].filter((p) => p !== undefined);
594
+ }
595
+ else {
596
+ // at this point, `field.type == 'TableKeyString'`
597
+ // TODO: keep track of nested scopes (#18)
598
+ return this.sourceNodeHelper(field, [
599
+ this.formatExpression(field.key, { preserveIdentifiers: true }),
600
+ "=",
601
+ this.formatExpression(field.value),
602
+ comma,
603
+ ].filter((p) => p !== undefined));
604
+ }
605
+ })
606
+ .flat();
607
+ addWithSeparator(result, fields);
608
+ addWithSeparator(result, "}");
609
+ return result;
610
+ }
611
+ else {
612
+ throw TypeError("Unknown expression type: `" + JSON.stringify(expression) + "`");
613
+ }
614
+ }
615
+ formatBase(base) {
616
+ const type = base.type;
617
+ const needsParens = type == "CallExpression" ||
618
+ type == "BinaryExpression" ||
619
+ type == "FunctionDeclaration" ||
620
+ type == "TableConstructorExpression" ||
621
+ type == "LogicalExpression" ||
622
+ type == "StringLiteral";
623
+ const result = this.sourceNodeHelper(base, this.formatExpression(base));
624
+ if (needsParens) {
625
+ prependWithSeparator(result, "(");
626
+ addWithSeparator(result, ")");
627
+ }
628
+ return result;
629
+ }
630
+ currentIdentifier = "";
631
+ generateIdentifier(nameItem, nested = false) {
632
+ if (nameItem.name === "self") {
633
+ return this.sourceNodeHelper(nameItem, "self", "self");
634
+ }
635
+ const defined = identifierMap.get(nameItem.name);
636
+ if (defined) {
637
+ return this.sourceNodeHelper(nameItem, defined, nameItem.name); // 第3引数は要調査
638
+ }
639
+ const length = this.currentIdentifier.length;
640
+ let position = length - 1;
641
+ let character;
642
+ let index;
643
+ while (position >= 0) {
644
+ character = this.currentIdentifier.charAt(position);
645
+ index = IDENTIFIER_PARTS.indexOf(character);
646
+ if (index != IDENTIFIER_PARTS.length - 1) {
647
+ this.currentIdentifier =
648
+ this.currentIdentifier.substring(0, position) +
649
+ IDENTIFIER_PARTS[index + 1] +
650
+ generateZeroes(length - (position + 1));
651
+ if (isKeyword(this.currentIdentifier) ||
652
+ identifiersInUse.has(this.currentIdentifier)) {
653
+ return this.generateIdentifier(nameItem, nested);
654
+ }
655
+ identifierMap.set(nameItem.name, this.currentIdentifier);
656
+ return this.generateIdentifier(nameItem, nested);
657
+ }
658
+ --position;
659
+ }
660
+ this.currentIdentifier = "a" + generateZeroes(length);
661
+ if (identifiersInUse.has(this.currentIdentifier)) {
662
+ return this.generateIdentifier(nameItem, nested);
663
+ }
664
+ identifierMap.set(nameItem.name, this.currentIdentifier);
665
+ return this.generateIdentifier(nameItem, nested);
666
+ // return this.sourceNodeHelper(nameItem, nameItem.name, nested ? nameItem.name : undefined);
667
+ }
668
+ }
669
+ exports.Minifier = Minifier;