Skip to content

Commit d576495

Browse files
authored
support #__PURE__ in ESTree (#4879)
1 parent a06e203 commit d576495

File tree

7 files changed

+88
-19
lines changed

7 files changed

+88
-19
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ jobs:
1212
- '-mb braces'
1313
- '--ie8 -c'
1414
- '-mc'
15+
- '-p acorn --toplevel -mco spidermonkey'
1516
- '--toplevel -mc passes=3,pure_getters,unsafe'
1617
script:
1718
- acorn.sh

bin/uglifyjs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,16 +314,43 @@ function run() {
314314
try {
315315
if (options.parse) {
316316
if (options.parse.acorn) {
317+
var annotations = Object.create(null);
317318
files = convert_ast(function(toplevel, name) {
318-
return require("acorn").parse(files[name], {
319+
var content = files[name];
320+
var list = annotations[name] = [];
321+
var prev = -1;
322+
return require("acorn").parse(content, {
319323
allowHashBang: true,
320324
ecmaVersion: "latest",
321325
locations: true,
326+
onComment: function(block, text, start, end) {
327+
var match = /[@#]__PURE__/.exec(text);
328+
if (!match) {
329+
if (start != prev) return;
330+
match = [ list[prev] ];
331+
}
332+
while (/\s/.test(content[end])) end++;
333+
list[end] = match[0];
334+
prev = end;
335+
},
336+
preserveParens: true,
322337
program: toplevel,
323338
sourceFile: name,
324339
sourceType: "module",
325340
});
326341
});
342+
files.walk(new UglifyJS.TreeWalker(function(node) {
343+
if (!(node instanceof UglifyJS.AST_Call)) return;
344+
var list = annotations[node.start.file];
345+
var pure = list[node.start.pos];
346+
if (!pure) {
347+
var pos = node.start.parens;
348+
if (pos) for (var i = 0; !pure && i < pos.length; i++) {
349+
pure = list[pos[i]];
350+
}
351+
}
352+
if (pure) node.pure = pure;
353+
}));
327354
} else if (options.parse.spidermonkey) {
328355
files = convert_ast(function(toplevel, name) {
329356
var obj = JSON.parse(files[name]);

lib/mozilla-ast.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,22 @@
446446
args.value = val;
447447
return new AST_String(args);
448448
case "number":
449-
args.value = val;
450-
return new AST_Number(args);
449+
if (isNaN(val)) return new AST_NaN(args);
450+
var negate, node;
451+
if (isFinite(val)) {
452+
negate = 1 / val < 0;
453+
args.value = negate ? -val : val;
454+
node = new AST_Number(args);
455+
} else {
456+
negate = val < 0;
457+
node = new AST_Infinity(args);
458+
}
459+
return negate ? new AST_UnaryPrefix({
460+
start: args.start,
461+
end: args.end,
462+
operator: "-",
463+
expression: node,
464+
}) : node;
451465
case "boolean":
452466
return new (val ? AST_True : AST_False)(args);
453467
}
@@ -532,6 +546,14 @@
532546
name: "this",
533547
});
534548
},
549+
ParenthesizedExpression: function(M) {
550+
var node = from_moz(M.expression);
551+
if (!node.start.parens) node.start.parens = [];
552+
node.start.parens.push(my_start_token(M));
553+
if (!node.end.parens) node.end.parens = [];
554+
node.end.parens.push(my_end_token(M));
555+
return node;
556+
},
535557
};
536558

537559
MOZ_TO_ME.UpdateExpression =
@@ -570,8 +592,8 @@
570592
map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
571593
map("AssignmentPattern", AST_DefaultValue, "left>name, right>value");
572594
map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
573-
map("NewExpression", AST_New, "callee>expression, arguments@args");
574-
map("CallExpression", AST_Call, "callee>expression, arguments@args");
595+
map("NewExpression", AST_New, "callee>expression, arguments@args, pure=pure");
596+
map("CallExpression", AST_Call, "callee>expression, arguments@args, pure=pure");
575597
map("SequenceExpression", AST_Sequence, "expressions@expressions");
576598
map("SpreadElement", AST_Spread, "argument>expression");
577599
map("ObjectExpression", AST_Object, "properties@properties");

lib/output.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1456,7 +1456,7 @@ function OutputStream(options) {
14561456
parent = output.parent(level++);
14571457
if (parent instanceof AST_Call && parent.expression === node) return;
14581458
} while (parent instanceof AST_PropAccess && parent.expression === node);
1459-
output.print("/*" + self.pure + "*/");
1459+
output.print(typeof self.pure == "string" ? "/*" + self.pure + "*/" : "/*@__PURE__*/");
14601460
}
14611461
function print_call_args(self, output) {
14621462
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {

test/release/rollup-ts.sh

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@ UGLIFY_OPTIONS=$@
66
minify_in_situ() {
77
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
88
DIRS="$1"
9+
echo '> esbuild' $DIRS
10+
for i in `find $DIRS -type f -name '*.ts' | grep -v '\.d\.ts'`
11+
do
12+
echo "$i"
13+
CODE=`cat "$i"`
14+
node_modules/.bin/esbuild --loader=ts --target=es2019 > "$i" <<EOF
15+
$CODE
16+
EOF
17+
ARGS="$ARGS $i"
18+
done
919
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
1020
for i in `find $DIRS -type f -name '*.js'`
1121
do
1222
ARGS="$ARGS $i"
1323
done
1424
uglify-js $ARGS
15-
for i in `find $DIRS -type f -name '*.ts' | grep -v '\.d\.ts'`
16-
do
17-
echo "$i"
18-
node_modules/.bin/esbuild --loader=ts --target=es2019 < "$i" \
19-
| uglify-js $UGLIFY_OPTIONS -o "$i"
20-
done
2125
}
2226

2327
rm -rf tmp/rollup \

test/release/sucrase.sh

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ UGLIFY_OPTIONS=$@
66
minify_in_situ() {
77
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
88
DIRS="$1"
9+
echo '> esbuild' $DIRS
10+
for i in `find $DIRS -type f -name '*.ts' | grep -v '\.d\.ts'`
11+
do
12+
echo "$i"
13+
CODE=`cat "$i"`
14+
node_modules/.bin/esbuild --loader=ts --target=es2019 > "$i" <<EOF
15+
$CODE
16+
EOF
17+
ARGS="$ARGS $i"
18+
done
919
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
1020
for i in `find $DIRS -type f -name '*.js'`
1121
do
@@ -16,12 +26,6 @@ minify_in_situ() {
1626
ARGS="$ARGS $i"
1727
done
1828
uglify-js $ARGS
19-
for i in `find $DIRS -type f -name '*.ts' | grep -v '\.d\.ts'`
20-
do
21-
echo "$i"
22-
node_modules/.bin/esbuild --loader=ts --target=es2019 < "$i" \
23-
| uglify-js $UGLIFY_OPTIONS -o "$i"
24-
done
2529
}
2630

2731
rm -rf tmp/sucrase \

test/release/web-tooling-benchmark.sh

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/sh
22

3-
alias uglify-js="node --max-old-space-size=4096 $PWD/bin/uglifyjs"
3+
alias uglify-js="node --max-old-space-size=8192 $PWD/bin/uglifyjs"
44
UGLIFY_OPTIONS=$@
55

66
minify_in_situ() {
@@ -23,6 +23,17 @@ rm -rf tmp/web-tooling-benchmark \
2323
+++ b/package.json
2424
@@ -12 +11,0 @@
2525
- "postinstall": "npm run build:terser-bundled && npm run build:uglify-js-bundled && npm run build",
26+
--- a/src/bootstrap.js
27+
+++ b/src/bootstrap.js
28+
@@ -6 +6 @@ const gmean = require("compute-gmean");
29+
-const package = require("../package.json");
30+
+const package_json = require("../package.json");
31+
@@ -65 +65 @@ function initialize() {
32+
- document.title = \`Web Tooling Benchmark v\${package.version}\`;
33+
+ document.title = \`Web Tooling Benchmark v\${package_json.version}\`;
34+
@@ -68 +68 @@ function initialize() {
35+
- versionDiv.innerHTML = \`v\${package.version}\`;
36+
+ versionDiv.innerHTML = \`v\${package_json.version}\`;
2637
--- a/src/cli-flags-helper.js
2738
+++ b/src/cli-flags-helper.js
2839
@@ -7 +6,0 @@ const targetList = new Set([

0 commit comments

Comments
 (0)