terser 5.6.1 → 5.8.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.
- package/CHANGELOG.md +39 -0
- package/README.md +46 -21
- package/dist/bundle.min.js +4718 -3740
- package/lib/ast.js +13 -7
- package/lib/cli.js +0 -2
- package/lib/compress/common.js +296 -0
- package/lib/compress/compressor-flags.js +63 -0
- package/lib/compress/drop-side-effect-free.js +353 -0
- package/lib/compress/evaluate.js +458 -0
- package/lib/compress/index.js +483 -3608
- package/lib/compress/inference.js +934 -0
- package/lib/compress/native-objects.js +183 -0
- package/lib/compress/reduce-vars.js +675 -0
- package/lib/compress/tighten-body.js +1461 -0
- package/lib/equivalent-to.js +5 -0
- package/lib/minify.js +28 -11
- package/lib/output.js +20 -7
- package/lib/parse.js +76 -82
- package/lib/propmangle.js +54 -31
- package/lib/scope.js +49 -24
- package/lib/transform.js +2 -2
- package/lib/utils/index.js +3 -5
- package/package.json +13 -12
- package/tools/terser.d.ts +37 -0
package/lib/equivalent-to.js
CHANGED
@@ -18,6 +18,7 @@ import {
|
|
18
18
|
AST_Directive,
|
19
19
|
AST_Do,
|
20
20
|
AST_Dot,
|
21
|
+
AST_DotHash,
|
21
22
|
AST_EmptyStatement,
|
22
23
|
AST_Expansion,
|
23
24
|
AST_Export,
|
@@ -233,6 +234,10 @@ AST_Dot.prototype.shallow_cmp = mkshallow({
|
|
233
234
|
property: "eq"
|
234
235
|
});
|
235
236
|
|
237
|
+
AST_DotHash.prototype.shallow_cmp = mkshallow({
|
238
|
+
property: "eq"
|
239
|
+
});
|
240
|
+
|
236
241
|
AST_Unary.prototype.shallow_cmp = mkshallow({
|
237
242
|
operator: "eq"
|
238
243
|
});
|
package/lib/minify.js
CHANGED
@@ -7,14 +7,14 @@ import {
|
|
7
7
|
map_to_object,
|
8
8
|
HOP,
|
9
9
|
} from "./utils/index.js";
|
10
|
-
import { AST_Toplevel } from "./ast.js";
|
10
|
+
import { AST_Toplevel, AST_Node } from "./ast.js";
|
11
11
|
import { parse } from "./parse.js";
|
12
12
|
import { OutputStream } from "./output.js";
|
13
13
|
import { Compressor } from "./compress/index.js";
|
14
|
-
import { base54 } from "./scope.js";
|
15
14
|
import { SourceMap } from "./sourcemap.js";
|
16
15
|
import {
|
17
16
|
mangle_properties,
|
17
|
+
mangle_private_properties,
|
18
18
|
reserve_quoted_keys,
|
19
19
|
} from "./propmangle.js";
|
20
20
|
|
@@ -77,6 +77,7 @@ async function minify(files, options) {
|
|
77
77
|
rename: undefined,
|
78
78
|
safari10: false,
|
79
79
|
sourceMap: false,
|
80
|
+
spidermonkey: false,
|
80
81
|
timings: false,
|
81
82
|
toplevel: false,
|
82
83
|
warnings: false,
|
@@ -148,20 +149,32 @@ async function minify(files, options) {
|
|
148
149
|
if (files instanceof AST_Toplevel) {
|
149
150
|
toplevel = files;
|
150
151
|
} else {
|
151
|
-
if (typeof files == "string") {
|
152
|
+
if (typeof files == "string" || (options.parse.spidermonkey && !Array.isArray(files))) {
|
152
153
|
files = [ files ];
|
153
154
|
}
|
154
155
|
options.parse = options.parse || {};
|
155
156
|
options.parse.toplevel = null;
|
156
|
-
|
157
|
-
|
158
|
-
options.parse.toplevel =
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
157
|
+
|
158
|
+
if (options.parse.spidermonkey) {
|
159
|
+
options.parse.toplevel = AST_Node.from_mozilla_ast(Object.keys(files).reduce(function(toplevel, name) {
|
160
|
+
if (!toplevel) return files[name];
|
161
|
+
toplevel.body = toplevel.body.concat(files[name].body);
|
162
|
+
return toplevel;
|
163
|
+
}, null));
|
164
|
+
} else {
|
165
|
+
delete options.parse.spidermonkey;
|
166
|
+
|
167
|
+
for (var name in files) if (HOP(files, name)) {
|
168
|
+
options.parse.filename = name;
|
169
|
+
options.parse.toplevel = parse(files[name], options.parse);
|
170
|
+
if (options.sourceMap && options.sourceMap.content == "inline") {
|
171
|
+
if (Object.keys(files).length > 1)
|
172
|
+
throw new Error("inline source map only works with singular input");
|
173
|
+
options.sourceMap.content = read_source_map(files[name]);
|
174
|
+
}
|
163
175
|
}
|
164
176
|
}
|
177
|
+
|
165
178
|
toplevel = options.parse.toplevel;
|
166
179
|
}
|
167
180
|
if (quoted_props && options.mangle.properties.keep_quoted !== "strict") {
|
@@ -190,9 +203,9 @@ async function minify(files, options) {
|
|
190
203
|
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
191
204
|
if (timings) timings.mangle = Date.now();
|
192
205
|
if (options.mangle) {
|
193
|
-
base54.reset();
|
194
206
|
toplevel.compute_char_frequency(options.mangle);
|
195
207
|
toplevel.mangle_names(options.mangle);
|
208
|
+
toplevel = mangle_private_properties(toplevel, options.mangle);
|
196
209
|
}
|
197
210
|
if (timings) timings.properties = Date.now();
|
198
211
|
if (options.mangle && options.mangle.properties) {
|
@@ -203,6 +216,9 @@ async function minify(files, options) {
|
|
203
216
|
if (options.format.ast) {
|
204
217
|
result.ast = toplevel;
|
205
218
|
}
|
219
|
+
if (options.format.spidermonkey) {
|
220
|
+
result.ast = toplevel.to_mozilla_ast();
|
221
|
+
}
|
206
222
|
if (!HOP(options.format, "code") || options.format.code) {
|
207
223
|
if (options.sourceMap) {
|
208
224
|
options.format.source_map = await SourceMap({
|
@@ -220,6 +236,7 @@ async function minify(files, options) {
|
|
220
236
|
}
|
221
237
|
delete options.format.ast;
|
222
238
|
delete options.format.code;
|
239
|
+
delete options.format.spidermonkey;
|
223
240
|
var stream = OutputStream(options.format);
|
224
241
|
toplevel.print(stream);
|
225
242
|
result.code = stream.get();
|
package/lib/output.js
CHANGED
@@ -159,7 +159,7 @@ import {
|
|
159
159
|
is_basic_identifier_string,
|
160
160
|
is_identifier_string,
|
161
161
|
PRECEDENCE,
|
162
|
-
|
162
|
+
ALL_RESERVED_WORDS,
|
163
163
|
} from "./parse.js";
|
164
164
|
|
165
165
|
const EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/;
|
@@ -349,11 +349,17 @@ function OutputStream(options) {
|
|
349
349
|
var do_add_mapping = mappings ? function() {
|
350
350
|
mappings.forEach(function(mapping) {
|
351
351
|
try {
|
352
|
+
let { name, token } = mapping;
|
353
|
+
if (token.type == "name" || token.type === "privatename") {
|
354
|
+
name = token.value;
|
355
|
+
} else if (name instanceof AST_Symbol) {
|
356
|
+
name = token.type === "string" ? token.value : name.name;
|
357
|
+
}
|
352
358
|
options.source_map.add(
|
353
359
|
mapping.token.file,
|
354
360
|
mapping.line, mapping.col,
|
355
361
|
mapping.token.line, mapping.token.col,
|
356
|
-
|
362
|
+
is_basic_identifier_string(name) ? name : undefined
|
357
363
|
);
|
358
364
|
} catch(ex) {
|
359
365
|
// Ignore bad mapping
|
@@ -1713,7 +1719,11 @@ function OutputStream(options) {
|
|
1713
1719
|
// https://github.com/mishoo/UglifyJS2/issues/60
|
1714
1720
|
if (noin) {
|
1715
1721
|
parens = walk(node, node => {
|
1716
|
-
|
1722
|
+
// Don't go into scopes -- except arrow functions:
|
1723
|
+
// https://github.com/terser/terser/issues/1019#issuecomment-877642607
|
1724
|
+
if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) {
|
1725
|
+
return true;
|
1726
|
+
}
|
1717
1727
|
if (node instanceof AST_Binary && node.operator == "in") {
|
1718
1728
|
return walk_abort; // makes walk() return true
|
1719
1729
|
}
|
@@ -1783,7 +1793,7 @@ function OutputStream(options) {
|
|
1783
1793
|
var expr = self.expression;
|
1784
1794
|
expr.print(output);
|
1785
1795
|
var prop = self.property;
|
1786
|
-
var print_computed =
|
1796
|
+
var print_computed = ALL_RESERVED_WORDS.has(prop)
|
1787
1797
|
? output.option("ie8")
|
1788
1798
|
: !is_identifier_string(
|
1789
1799
|
prop,
|
@@ -1816,6 +1826,7 @@ function OutputStream(options) {
|
|
1816
1826
|
|
1817
1827
|
if (self.optional) output.print("?");
|
1818
1828
|
output.print(".#");
|
1829
|
+
output.add_mapping(self.end);
|
1819
1830
|
output.print_name(prop);
|
1820
1831
|
});
|
1821
1832
|
DEFPRINT(AST_Sub, function(self, output) {
|
@@ -1964,7 +1975,7 @@ function OutputStream(options) {
|
|
1964
1975
|
}
|
1965
1976
|
return output.print(make_num(key));
|
1966
1977
|
}
|
1967
|
-
var print_string =
|
1978
|
+
var print_string = ALL_RESERVED_WORDS.has(key)
|
1968
1979
|
? output.option("ie8")
|
1969
1980
|
: (
|
1970
1981
|
output.option("ecma") < 2015 || output.option("safari10")
|
@@ -1991,7 +2002,7 @@ function OutputStream(options) {
|
|
1991
2002
|
output.option("ecma") >= 2015 || output.option("safari10")
|
1992
2003
|
) &&
|
1993
2004
|
get_name(self.value) === self.key &&
|
1994
|
-
!
|
2005
|
+
!ALL_RESERVED_WORDS.has(self.key)
|
1995
2006
|
) {
|
1996
2007
|
print_property_name(self.key, self.quote, output);
|
1997
2008
|
|
@@ -2269,8 +2280,10 @@ function OutputStream(options) {
|
|
2269
2280
|
DEFMAP([
|
2270
2281
|
AST_ObjectGetter,
|
2271
2282
|
AST_ObjectSetter,
|
2283
|
+
AST_PrivateGetter,
|
2284
|
+
AST_PrivateSetter,
|
2272
2285
|
], function(output) {
|
2273
|
-
output.add_mapping(this.
|
2286
|
+
output.add_mapping(this.key.end, this.key.name);
|
2274
2287
|
});
|
2275
2288
|
|
2276
2289
|
DEFMAP([ AST_ObjectProperty ], function(output) {
|
package/lib/parse.js
CHANGED
@@ -102,7 +102,6 @@ import {
|
|
102
102
|
AST_Label,
|
103
103
|
AST_LabeledStatement,
|
104
104
|
AST_LabelRef,
|
105
|
-
AST_Lambda,
|
106
105
|
AST_Let,
|
107
106
|
AST_NameMapping,
|
108
107
|
AST_New,
|
@@ -167,13 +166,15 @@ var LATEST_TEMPLATE_END = true;
|
|
167
166
|
|
168
167
|
var KEYWORDS = "break case catch class const continue debugger default delete do else export extends finally for function if in instanceof let new return switch throw try typeof var void while with";
|
169
168
|
var KEYWORDS_ATOM = "false null true";
|
170
|
-
var RESERVED_WORDS = "enum
|
169
|
+
var RESERVED_WORDS = "enum import super this " + KEYWORDS_ATOM + " " + KEYWORDS;
|
170
|
+
var ALL_RESERVED_WORDS = "implements interface package private protected public static " + RESERVED_WORDS;
|
171
171
|
var KEYWORDS_BEFORE_EXPRESSION = "return new delete throw else case yield await";
|
172
172
|
|
173
173
|
KEYWORDS = makePredicate(KEYWORDS);
|
174
174
|
RESERVED_WORDS = makePredicate(RESERVED_WORDS);
|
175
175
|
KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION);
|
176
176
|
KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM);
|
177
|
+
ALL_RESERVED_WORDS = makePredicate(ALL_RESERVED_WORDS);
|
177
178
|
|
178
179
|
var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^"));
|
179
180
|
|
@@ -1293,7 +1294,7 @@ function parse($TEXT, options) {
|
|
1293
1294
|
if (is_if_body) {
|
1294
1295
|
croak("classes are not allowed as the body of an if");
|
1295
1296
|
}
|
1296
|
-
return class_(AST_DefClass);
|
1297
|
+
return class_(AST_DefClass, is_export_default);
|
1297
1298
|
|
1298
1299
|
case "function":
|
1299
1300
|
next();
|
@@ -2488,7 +2489,7 @@ function parse($TEXT, options) {
|
|
2488
2489
|
return new AST_Object({ properties: a });
|
2489
2490
|
});
|
2490
2491
|
|
2491
|
-
function class_(KindOfClass) {
|
2492
|
+
function class_(KindOfClass, is_export_default) {
|
2492
2493
|
var start, method, class_name, extends_, a = [];
|
2493
2494
|
|
2494
2495
|
S.input.push_directives_stack(); // Push directive stack, but not scope stack
|
@@ -2499,7 +2500,11 @@ function parse($TEXT, options) {
|
|
2499
2500
|
}
|
2500
2501
|
|
2501
2502
|
if (KindOfClass === AST_DefClass && !class_name) {
|
2502
|
-
|
2503
|
+
if (is_export_default) {
|
2504
|
+
KindOfClass = AST_ClassExpression;
|
2505
|
+
} else {
|
2506
|
+
unexpected();
|
2507
|
+
}
|
2503
2508
|
}
|
2504
2509
|
|
2505
2510
|
if (S.token.value == "extends") {
|
@@ -2532,9 +2537,9 @@ function parse($TEXT, options) {
|
|
2532
2537
|
}
|
2533
2538
|
|
2534
2539
|
function concise_method_or_getset(name, start, is_class) {
|
2535
|
-
|
2540
|
+
const get_symbol_ast = (name, SymbolClass = AST_SymbolMethod) => {
|
2536
2541
|
if (typeof name === "string" || typeof name === "number") {
|
2537
|
-
return new
|
2542
|
+
return new SymbolClass({
|
2538
2543
|
start,
|
2539
2544
|
name: "" + name,
|
2540
2545
|
end: prev()
|
@@ -2544,47 +2549,71 @@ function parse($TEXT, options) {
|
|
2544
2549
|
}
|
2545
2550
|
return name;
|
2546
2551
|
};
|
2547
|
-
|
2548
|
-
|
2549
|
-
|
2550
|
-
|
2551
|
-
end: property_token,
|
2552
|
-
name: "" + name
|
2553
|
-
});
|
2554
|
-
} else if (name === null) {
|
2555
|
-
unexpected();
|
2556
|
-
}
|
2557
|
-
return name;
|
2558
|
-
};
|
2559
|
-
var privatename = start.type == "privatename";
|
2552
|
+
|
2553
|
+
const is_not_method_start = () =>
|
2554
|
+
!is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("operator", "=");
|
2555
|
+
|
2560
2556
|
var is_async = false;
|
2561
2557
|
var is_static = false;
|
2562
2558
|
var is_generator = false;
|
2563
|
-
var
|
2564
|
-
|
2559
|
+
var is_private = false;
|
2560
|
+
var accessor_type = null;
|
2561
|
+
|
2562
|
+
if (is_class && name === "static" && is_not_method_start()) {
|
2565
2563
|
is_static = true;
|
2566
|
-
property_token = S.token;
|
2567
|
-
privatename = property_token.type == "privatename";
|
2568
2564
|
name = as_property_name();
|
2569
2565
|
}
|
2570
|
-
if (name === "async" &&
|
2566
|
+
if (name === "async" && is_not_method_start()) {
|
2571
2567
|
is_async = true;
|
2572
|
-
property_token = S.token;
|
2573
|
-
privatename = property_token.type == "privatename";
|
2574
2568
|
name = as_property_name();
|
2575
2569
|
}
|
2576
|
-
if (
|
2570
|
+
if (prev().type === "operator" && prev().value === "*") {
|
2577
2571
|
is_generator = true;
|
2578
|
-
property_token = S.token;
|
2579
|
-
privatename = property_token.type == "privatename";
|
2580
2572
|
name = as_property_name();
|
2581
|
-
|
2582
|
-
|
2573
|
+
}
|
2574
|
+
if ((name === "get" || name === "set") && is_not_method_start()) {
|
2575
|
+
accessor_type = name;
|
2576
|
+
name = as_property_name();
|
2577
|
+
}
|
2578
|
+
if (prev().type === "privatename") {
|
2579
|
+
is_private = true;
|
2580
|
+
}
|
2581
|
+
|
2582
|
+
const property_token = prev();
|
2583
|
+
|
2584
|
+
if (accessor_type != null) {
|
2585
|
+
if (!is_private) {
|
2586
|
+
const AccessorClass = accessor_type === "get"
|
2587
|
+
? AST_ObjectGetter
|
2588
|
+
: AST_ObjectSetter;
|
2589
|
+
|
2590
|
+
name = get_symbol_ast(name);
|
2591
|
+
return new AccessorClass({
|
2592
|
+
start,
|
2593
|
+
static: is_static,
|
2594
|
+
key: name,
|
2595
|
+
quote: name instanceof AST_SymbolMethod ? property_token.quote : undefined,
|
2596
|
+
value: create_accessor(),
|
2597
|
+
end: prev()
|
2598
|
+
});
|
2599
|
+
} else {
|
2600
|
+
const AccessorClass = accessor_type === "get"
|
2601
|
+
? AST_PrivateGetter
|
2602
|
+
: AST_PrivateSetter;
|
2603
|
+
|
2604
|
+
return new AccessorClass({
|
2605
|
+
start,
|
2606
|
+
static: is_static,
|
2607
|
+
key: get_symbol_ast(name),
|
2608
|
+
value: create_accessor(),
|
2609
|
+
end: prev(),
|
2610
|
+
});
|
2583
2611
|
}
|
2584
2612
|
}
|
2613
|
+
|
2585
2614
|
if (is("punc", "(")) {
|
2586
|
-
name =
|
2587
|
-
const AST_MethodVariant =
|
2615
|
+
name = get_symbol_ast(name);
|
2616
|
+
const AST_MethodVariant = is_private
|
2588
2617
|
? AST_PrivateMethod
|
2589
2618
|
: AST_ConciseMethod;
|
2590
2619
|
var node = new AST_MethodVariant({
|
@@ -2600,57 +2629,13 @@ function parse($TEXT, options) {
|
|
2600
2629
|
});
|
2601
2630
|
return node;
|
2602
2631
|
}
|
2603
|
-
const setter_token = S.token;
|
2604
|
-
if ((name === "get" || name === "set") && setter_token.type === "privatename") {
|
2605
|
-
next();
|
2606
|
-
|
2607
|
-
const AST_AccessorVariant =
|
2608
|
-
name === "get"
|
2609
|
-
? AST_PrivateGetter
|
2610
|
-
: AST_PrivateSetter;
|
2611
|
-
|
2612
|
-
return new AST_AccessorVariant({
|
2613
|
-
start,
|
2614
|
-
static: is_static,
|
2615
|
-
key: get_method_name_ast(setter_token.value, start),
|
2616
|
-
value: create_accessor(),
|
2617
|
-
end: prev(),
|
2618
|
-
});
|
2619
|
-
}
|
2620
2632
|
|
2621
|
-
if (name == "get") {
|
2622
|
-
if (!is("punc") || is("punc", "[")) {
|
2623
|
-
name = get_method_name_ast(as_property_name(), start);
|
2624
|
-
return new AST_ObjectGetter({
|
2625
|
-
start : start,
|
2626
|
-
static: is_static,
|
2627
|
-
key : name,
|
2628
|
-
quote : name instanceof AST_SymbolMethod ?
|
2629
|
-
setter_token.quote : undefined,
|
2630
|
-
value : create_accessor(),
|
2631
|
-
end : prev()
|
2632
|
-
});
|
2633
|
-
}
|
2634
|
-
} else if (name == "set") {
|
2635
|
-
if (!is("punc") || is("punc", "[")) {
|
2636
|
-
name = get_method_name_ast(as_property_name(), start);
|
2637
|
-
return new AST_ObjectSetter({
|
2638
|
-
start : start,
|
2639
|
-
static: is_static,
|
2640
|
-
key : name,
|
2641
|
-
quote : name instanceof AST_SymbolMethod ?
|
2642
|
-
setter_token.quote : undefined,
|
2643
|
-
value : create_accessor(),
|
2644
|
-
end : prev()
|
2645
|
-
});
|
2646
|
-
}
|
2647
|
-
}
|
2648
2633
|
if (is_class) {
|
2649
|
-
const key =
|
2634
|
+
const key = get_symbol_ast(name, AST_SymbolClassProperty);
|
2650
2635
|
const quote = key instanceof AST_SymbolClassProperty
|
2651
2636
|
? property_token.quote
|
2652
2637
|
: undefined;
|
2653
|
-
const AST_ClassPropertyVariant =
|
2638
|
+
const AST_ClassPropertyVariant = is_private
|
2654
2639
|
? AST_ClassPrivateProperty
|
2655
2640
|
: AST_ClassProperty;
|
2656
2641
|
if (is("operator", "=")) {
|
@@ -2872,8 +2857,17 @@ function parse($TEXT, options) {
|
|
2872
2857
|
semicolon();
|
2873
2858
|
} else if ((node = statement(is_default)) instanceof AST_Definitions && is_default) {
|
2874
2859
|
unexpected(node.start);
|
2875
|
-
} else if (
|
2860
|
+
} else if (
|
2861
|
+
node instanceof AST_Definitions
|
2862
|
+
|| node instanceof AST_Defun
|
2863
|
+
|| node instanceof AST_DefClass
|
2864
|
+
) {
|
2876
2865
|
exported_definition = node;
|
2866
|
+
} else if (
|
2867
|
+
node instanceof AST_ClassExpression
|
2868
|
+
|| node instanceof AST_Function
|
2869
|
+
) {
|
2870
|
+
exported_value = node;
|
2877
2871
|
} else if (node instanceof AST_SimpleStatement) {
|
2878
2872
|
exported_value = node.body;
|
2879
2873
|
} else {
|
@@ -3347,6 +3341,6 @@ export {
|
|
3347
3341
|
JS_Parse_Error,
|
3348
3342
|
parse,
|
3349
3343
|
PRECEDENCE,
|
3350
|
-
|
3344
|
+
ALL_RESERVED_WORDS,
|
3351
3345
|
tokenizer,
|
3352
3346
|
};
|
package/lib/propmangle.js
CHANGED
@@ -59,6 +59,8 @@ import {
|
|
59
59
|
AST_ObjectKeyVal,
|
60
60
|
AST_ObjectProperty,
|
61
61
|
AST_PrivateMethod,
|
62
|
+
AST_PrivateGetter,
|
63
|
+
AST_PrivateSetter,
|
62
64
|
AST_Sequence,
|
63
65
|
AST_String,
|
64
66
|
AST_Sub,
|
@@ -140,28 +142,59 @@ function addStrings(node, add) {
|
|
140
142
|
}));
|
141
143
|
}
|
142
144
|
|
145
|
+
function mangle_private_properties(ast, options) {
|
146
|
+
var cprivate = -1;
|
147
|
+
var private_cache = new Map();
|
148
|
+
var nth_identifier = options.nth_identifier || base54;
|
149
|
+
|
150
|
+
ast = ast.transform(new TreeTransformer(function(node) {
|
151
|
+
if (
|
152
|
+
node instanceof AST_ClassPrivateProperty
|
153
|
+
|| node instanceof AST_PrivateMethod
|
154
|
+
|| node instanceof AST_PrivateGetter
|
155
|
+
|| node instanceof AST_PrivateSetter
|
156
|
+
) {
|
157
|
+
node.key.name = mangle_private(node.key.name);
|
158
|
+
} else if (node instanceof AST_DotHash) {
|
159
|
+
node.property = mangle_private(node.property);
|
160
|
+
}
|
161
|
+
}));
|
162
|
+
return ast;
|
163
|
+
|
164
|
+
function mangle_private(name) {
|
165
|
+
let mangled = private_cache.get(name);
|
166
|
+
if (!mangled) {
|
167
|
+
mangled = nth_identifier.get(++cprivate);
|
168
|
+
private_cache.set(name, mangled);
|
169
|
+
}
|
170
|
+
|
171
|
+
return mangled;
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
143
175
|
function mangle_properties(ast, options) {
|
144
176
|
options = defaults(options, {
|
145
177
|
builtins: false,
|
146
178
|
cache: null,
|
147
179
|
debug: false,
|
148
180
|
keep_quoted: false,
|
181
|
+
nth_identifier: base54,
|
149
182
|
only_cache: false,
|
150
183
|
regex: null,
|
151
184
|
reserved: null,
|
152
185
|
undeclared: false,
|
153
186
|
}, true);
|
154
187
|
|
188
|
+
var nth_identifier = options.nth_identifier;
|
189
|
+
|
155
190
|
var reserved_option = options.reserved;
|
156
191
|
if (!Array.isArray(reserved_option)) reserved_option = [reserved_option];
|
157
192
|
var reserved = new Set(reserved_option);
|
158
193
|
if (!options.builtins) find_builtins(reserved);
|
159
194
|
|
160
195
|
var cname = -1;
|
161
|
-
var cprivate = -1;
|
162
196
|
|
163
197
|
var cache;
|
164
|
-
var private_cache = new Map();
|
165
198
|
if (options.cache) {
|
166
199
|
cache = options.cache.props;
|
167
200
|
cache.forEach(function(mangled_name) {
|
@@ -184,27 +217,26 @@ function mangle_properties(ast, options) {
|
|
184
217
|
|
185
218
|
var names_to_mangle = new Set();
|
186
219
|
var unmangleable = new Set();
|
187
|
-
var private_properties = new Set();
|
188
220
|
|
189
|
-
var
|
221
|
+
var keep_quoted = !!options.keep_quoted;
|
190
222
|
|
191
223
|
// step 1: find candidates to mangle
|
192
224
|
ast.walk(new TreeWalker(function(node) {
|
193
225
|
if (
|
194
226
|
node instanceof AST_ClassPrivateProperty
|
195
227
|
|| node instanceof AST_PrivateMethod
|
228
|
+
|| node instanceof AST_PrivateGetter
|
229
|
+
|| node instanceof AST_PrivateSetter
|
230
|
+
|| node instanceof AST_DotHash
|
196
231
|
) {
|
197
|
-
|
198
|
-
} else if (node instanceof AST_DotHash) {
|
199
|
-
private_properties.add(node.property);
|
232
|
+
// handled by mangle_private_properties
|
200
233
|
} else if (node instanceof AST_ObjectKeyVal) {
|
201
|
-
if (typeof node.key == "string" &&
|
202
|
-
(!keep_quoted_strict || !node.quote)) {
|
234
|
+
if (typeof node.key == "string" && (!keep_quoted || !node.quote)) {
|
203
235
|
add(node.key);
|
204
236
|
}
|
205
237
|
} else if (node instanceof AST_ObjectProperty) {
|
206
238
|
// setter or getter, since KeyVal is handled above
|
207
|
-
if (!
|
239
|
+
if (!keep_quoted || !node.quote) {
|
208
240
|
add(node.key.name);
|
209
241
|
}
|
210
242
|
} else if (node instanceof AST_Dot) {
|
@@ -217,11 +249,11 @@ function mangle_properties(ast, options) {
|
|
217
249
|
declared = !(root.thedef && root.thedef.undeclared);
|
218
250
|
}
|
219
251
|
if (declared &&
|
220
|
-
(!
|
252
|
+
(!keep_quoted || !node.quote)) {
|
221
253
|
add(node.property);
|
222
254
|
}
|
223
255
|
} else if (node instanceof AST_Sub) {
|
224
|
-
if (!
|
256
|
+
if (!keep_quoted) {
|
225
257
|
addStrings(node.property, add);
|
226
258
|
}
|
227
259
|
} else if (node instanceof AST_Call
|
@@ -237,25 +269,25 @@ function mangle_properties(ast, options) {
|
|
237
269
|
if (
|
238
270
|
node instanceof AST_ClassPrivateProperty
|
239
271
|
|| node instanceof AST_PrivateMethod
|
272
|
+
|| node instanceof AST_PrivateGetter
|
273
|
+
|| node instanceof AST_PrivateSetter
|
274
|
+
|| node instanceof AST_DotHash
|
240
275
|
) {
|
241
|
-
|
242
|
-
} else if (node instanceof AST_DotHash) {
|
243
|
-
node.property = mangle_private(node.property);
|
276
|
+
// handled by mangle_private_properties
|
244
277
|
} else if (node instanceof AST_ObjectKeyVal) {
|
245
|
-
if (typeof node.key == "string" &&
|
246
|
-
(!keep_quoted_strict || !node.quote)) {
|
278
|
+
if (typeof node.key == "string" && (!keep_quoted || !node.quote)) {
|
247
279
|
node.key = mangle(node.key);
|
248
280
|
}
|
249
281
|
} else if (node instanceof AST_ObjectProperty) {
|
250
282
|
// setter, getter, method or class field
|
251
|
-
if (!
|
283
|
+
if (!keep_quoted || !node.quote) {
|
252
284
|
node.key.name = mangle(node.key.name);
|
253
285
|
}
|
254
286
|
} else if (node instanceof AST_Dot) {
|
255
|
-
if (!
|
287
|
+
if (!keep_quoted || !node.quote) {
|
256
288
|
node.property = mangle(node.property);
|
257
289
|
}
|
258
|
-
} else if (!
|
290
|
+
} else if (!keep_quoted && node instanceof AST_Sub) {
|
259
291
|
node.property = mangleStrings(node.property);
|
260
292
|
} else if (node instanceof AST_Call
|
261
293
|
&& node.expression.print_to_string() == "Object.defineProperty") {
|
@@ -312,7 +344,7 @@ function mangle_properties(ast, options) {
|
|
312
344
|
// either debug mode is off, or it is on and we could not use the mangled name
|
313
345
|
if (!mangled) {
|
314
346
|
do {
|
315
|
-
mangled =
|
347
|
+
mangled = nth_identifier.get(++cname);
|
316
348
|
} while (!can_mangle(mangled));
|
317
349
|
}
|
318
350
|
|
@@ -321,16 +353,6 @@ function mangle_properties(ast, options) {
|
|
321
353
|
return mangled;
|
322
354
|
}
|
323
355
|
|
324
|
-
function mangle_private(name) {
|
325
|
-
let mangled = private_cache.get(name);
|
326
|
-
if (!mangled) {
|
327
|
-
mangled = base54(++cprivate);
|
328
|
-
private_cache.set(name, mangled);
|
329
|
-
}
|
330
|
-
|
331
|
-
return mangled;
|
332
|
-
}
|
333
|
-
|
334
356
|
function mangleStrings(node) {
|
335
357
|
return node.transform(new TreeTransformer(function(node) {
|
336
358
|
if (node instanceof AST_Sequence) {
|
@@ -350,4 +372,5 @@ function mangle_properties(ast, options) {
|
|
350
372
|
export {
|
351
373
|
reserve_quoted_keys,
|
352
374
|
mangle_properties,
|
375
|
+
mangle_private_properties,
|
353
376
|
};
|