Skip to content

Commit fb01a07

Browse files
authored
Merge branch 'master' into github/fix-365
2 parents dbc97e8 + 7a48a21 commit fb01a07

17 files changed

+677
-38
lines changed

escodegen.js

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
1212
Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
1313
Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
14+
Copyright (C) 2020 Apple Inc. All rights reserved.
1415
1516
Redistribution and use in source and binary forms, with or without
1617
modification, are permitted provided that the following conditions are met:
@@ -85,29 +86,31 @@
8586
Assignment: 1,
8687
Conditional: 2,
8788
ArrowFunction: 2,
88-
LogicalOR: 3,
89-
LogicalAND: 4,
90-
BitwiseOR: 5,
91-
BitwiseXOR: 6,
92-
BitwiseAND: 7,
93-
Equality: 8,
94-
Relational: 9,
95-
BitwiseSHIFT: 10,
96-
Additive: 11,
97-
Multiplicative: 12,
98-
Exponentiation: 13,
99-
Await: 14,
100-
Unary: 14,
101-
Postfix: 15,
102-
OptionalChaining: 16,
103-
Call: 17,
104-
New: 18,
105-
TaggedTemplate: 19,
106-
Member: 20,
107-
Primary: 21
89+
Coalesce: 3,
90+
LogicalOR: 4,
91+
LogicalAND: 5,
92+
BitwiseOR: 6,
93+
BitwiseXOR: 7,
94+
BitwiseAND: 8,
95+
Equality: 9,
96+
Relational: 10,
97+
BitwiseSHIFT: 11,
98+
Additive: 12,
99+
Multiplicative: 13,
100+
Exponentiation: 14,
101+
Await: 15,
102+
Unary: 15,
103+
Postfix: 16,
104+
OptionalChaining: 17,
105+
Call: 18,
106+
New: 19,
107+
TaggedTemplate: 20,
108+
Member: 21,
109+
Primary: 22
108110
};
109111

110112
BinaryPrecedence = {
113+
'??': Precedence.Coalesce,
111114
'||': Precedence.LogicalOR,
112115
'&&': Precedence.LogicalAND,
113116
'|': Precedence.BitwiseOR,
@@ -142,7 +145,8 @@
142145
F_ALLOW_UNPARATH_NEW = 1 << 2,
143146
F_FUNC_BODY = 1 << 3,
144147
F_DIRECTIVE_CTX = 1 << 4,
145-
F_SEMICOLON_OPT = 1 << 5;
148+
F_SEMICOLON_OPT = 1 << 5,
149+
F_FOUND_COALESCE = 1 << 6;
146150

147151
//Expression flag sets
148152
//NOTE: Flag order:
@@ -1967,7 +1971,7 @@
19671971
}
19681972
return parenthesize(
19691973
[
1970-
this.generateExpression(expr.test, Precedence.LogicalOR, flags, path),
1974+
this.generateExpression(expr.test, Precedence.Coalesce, flags),
19711975
space + '?' + space,
19721976
this.generateExpression(expr.consequent, Precedence.Assignment, flags, path),
19731977
space + ':' + space,
@@ -1979,6 +1983,9 @@
19791983
},
19801984

19811985
LogicalExpression: function (expr, precedence, flags, path) {
1986+
if (expr.operator === '??') {
1987+
flags |= F_FOUND_COALESCE;
1988+
}
19821989
return this.BinaryExpression(expr, precedence, flags, path);
19831990
},
19841991

@@ -2016,6 +2023,9 @@
20162023
if (expr.operator === 'in' && !(flags & F_ALLOW_IN)) {
20172024
return ['(', result, ')'];
20182025
}
2026+
if ((expr.operator === '||' || expr.operator === '&&') && (flags & F_FOUND_COALESCE)) {
2027+
return ['(', result, ')'];
2028+
}
20192029
return parenthesize(result, currentPrecedence, precedence);
20202030
},
20212031

@@ -2498,6 +2508,16 @@
24982508
return '/' + expr.regex.pattern + '/' + expr.regex.flags;
24992509
}
25002510

2511+
if (typeof expr.value === 'bigint') {
2512+
return expr.value.toString() + 'n';
2513+
}
2514+
2515+
// `expr.value` can be null if `expr.bigint` exists. We need to check
2516+
// `expr.bigint` first.
2517+
if (expr.bigint) {
2518+
return expr.bigint + 'n';
2519+
}
2520+
25012521
if (expr.value === null) {
25022522
return 'null';
25032523
}

gulpfile.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
Copyright (C) 2014 Yusuke Suzuki <utatane.tea@gmail.com>
3+
Copyright (C) 2019-2020 Apple Inc. All rights reserved.
34
45
Redistribution and use in source and binary forms, with or without
56
modification, are permitted provided that the following conditions are met:
@@ -64,20 +65,20 @@ var ESLINT_OPTION = {
6465
}
6566
};
6667

67-
gulp.task('test', function () {
68+
gulp.task('test', gulp.series(function () {
6869
return gulp.src(TEST)
6970
.pipe(mocha({
7071
reporter: 'spec',
7172
timeout: 100000 // 100s
7273
}));
73-
});
74+
}));
7475

75-
gulp.task('lint', function () {
76+
gulp.task('lint', gulp.series(function () {
7677
return gulp.src(LINT)
7778
.pipe(eslint(ESLINT_OPTION))
7879
.pipe(eslint.formatEach('stylish', process.stderr))
7980
.pipe(eslint.failOnError());
80-
});
81+
}));
8182

82-
gulp.task('travis', [ 'lint', 'test' ]);
83-
gulp.task('default', [ 'travis' ]);
83+
gulp.task('travis', gulp.series([ 'lint', 'test' ]));
84+
gulp.task('default', gulp.series([ 'travis' ]));

package.json

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,24 @@
3232
"dependencies": {
3333
"estraverse": "^5.2.0",
3434
"esutils": "^2.0.2",
35-
"esprima": "^4.0.1",
36-
"optionator": "^0.8.1"
35+
"esprima": "^4.0.1"
3736
},
3837
"optionalDependencies": {
3938
"source-map": "~0.6.1"
4039
},
4140
"devDependencies": {
42-
"acorn": "^7.3.1",
41+
"acorn": "^8.0.4",
4342
"bluebird": "^3.4.7",
4443
"bower-registry-client": "^1.0.0",
4544
"chai": "^4.2.0",
4645
"chai-exclude": "^2.0.2",
4746
"commonjs-everywhere": "^0.9.7",
48-
"gulp": "^3.8.10",
49-
"gulp-eslint": "^3.0.1",
50-
"gulp-mocha": "^3.0.1",
51-
"semver": "^5.1.0"
47+
"gulp": "^4.0.2",
48+
"gulp-eslint": "^6.0.0",
49+
"gulp-mocha": "^7.0.2",
50+
"minimist": "^1.2.5",
51+
"optionator": "^0.9.1",
52+
"semver": "^7.3.4"
5253
},
5354
"license": "BSD-2-Clause",
5455
"scripts": {

test/compare-acorn-es2020.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function test(code, expected) {
4949
actualTree = acorn.parse(actual, options);
5050

5151
expect(actual).to.be.equal(expected);
52-
expect(tree).excludingEvery(['start', 'end']).to.deep.equal(actualTree);
52+
expect(tree).excludingEvery(['start', 'end', 'raw']).to.deep.equal(actualTree);
5353
}
5454

5555
function testMin(code, expected) {
@@ -71,7 +71,7 @@ function testMin(code, expected) {
7171
actualTree = acorn.parse(actual, options);
7272

7373
expect(actual).to.be.equal(expected);
74-
expect(tree).excludingEvery(['start', 'end']).to.deep.equal(actualTree);
74+
expect(tree).excludingEvery(['start', 'end', 'raw']).to.deep.equal(actualTree);
7575
}
7676

7777
describe('compare acorn es2020 test', function () {
@@ -92,4 +92,4 @@ describe('compare acorn es2020 test', function () {
9292
}
9393
});
9494
});
95-
/* vim: set sw=4 ts=4 et tw=80 : */
95+
/* vim: set sw=4 ts=4 et tw=80 : */
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2000n + 30;
2+
20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n + 30;
3+
-20000000000000000000000000000n;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2000n+30;20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n+30;-20000000000000000000000000000n

test/compare-acorn-es2020/bigint.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (C) 2020 Apple Inc.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
* THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
2000n + 30;
27+
20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n + 30;
28+
-20000000000000000000000000000n;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
function testBasicCases() {
2+
shouldBe(undefined ?? 3, 3);
3+
shouldBe(null ?? 3, 3);
4+
shouldBe(true ?? 3, true);
5+
shouldBe(false ?? 3, false);
6+
shouldBe(0 ?? 3, 0);
7+
shouldBe(1 ?? 3, 1);
8+
shouldBe('' ?? 3, '');
9+
shouldBe('hi' ?? 3, 'hi');
10+
shouldBe(({} ?? 3) instanceof Object, true);
11+
shouldBe(({ x: 'hi' } ?? 3).x, 'hi');
12+
shouldBe(([] ?? 3) instanceof Array, true);
13+
shouldBe((['hi'] ?? 3)[0], 'hi');
14+
shouldBe((makeMasquerader() ?? 3) == null, true);
15+
}
16+
noInline(testBasicCases);
17+
for (let i = 0; i < 100000; i++)
18+
testBasicCases();
19+
shouldBe(1 | null ?? 3, 1);
20+
shouldBe(1 ^ null ?? 3, 1);
21+
shouldBe(1 & null ?? 3, 0);
22+
shouldBe(3 == null ?? 3, false);
23+
shouldBe(3 != null ?? 3, true);
24+
shouldBe(3 === null ?? 3, false);
25+
shouldBe(3 !== null ?? 3, true);
26+
shouldBe(1 < null ?? 3, false);
27+
shouldBe(1 > null ?? 3, true);
28+
shouldBe(1 <= null ?? 3, false);
29+
shouldBe(1 >= null ?? 3, true);
30+
shouldBe(1 << null ?? 3, 1);
31+
shouldBe(1 >> null ?? 3, 1);
32+
shouldBe(1 >>> null ?? 3, 1);
33+
shouldBe(1 + null ?? 3, 1);
34+
shouldBe(1 - null ?? 3, 1);
35+
shouldBe(1 * null ?? 3, 0);
36+
shouldBe(1 / null ?? 3, Infinity);
37+
shouldBe(isNaN(1 % null ?? 3), true);
38+
shouldBe(1 ** null ?? 3, 1);
39+
const obj = {
40+
count: 0,
41+
get x() {
42+
this.count++;
43+
return 'x';
44+
}
45+
};
46+
false ?? obj.x;
47+
shouldBe(obj.count, 0);
48+
null ?? obj.x;
49+
shouldBe(obj.count, 1);
50+
obj.x ?? obj.x;
51+
shouldBe(obj.count, 2);
52+
(0 || 1) ?? 2;
53+
0 || (1 ?? 2);
54+
(0 && 1) ?? 2;
55+
0 && (1 ?? 2);
56+
(0 ?? 1) || 2;
57+
0 ?? (1 || 2);
58+
(0 ?? 1) && 2;
59+
0 ?? (1 && 2);
60+
0 || 1 && 2 | 3 ^ 4 & 5 == 6 != 7 === 8 !== 9 < 0 > 1 <= 2 >= 3 << 4 >> 5 >>> 6 + 7 - 8 * 9 / 0 % 1 ** 2;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
function testBasicCases(){shouldBe(undefined??3,3);shouldBe(null??3,3);shouldBe(true??3,true);shouldBe(false??3,false);shouldBe(0??3,0);shouldBe(1??3,1);shouldBe(''??3,'');shouldBe('hi'??3,'hi');shouldBe(({}??3)instanceof Object,true);shouldBe(({x:'hi'}??3).x,'hi');shouldBe(([]??3)instanceof Array,true);shouldBe((['hi']??3)[0],'hi');shouldBe((makeMasquerader()??3)==null,true)}noInline(testBasicCases);for(let i=0;i<1e5;i++)testBasicCases();shouldBe(1|null??3,1);shouldBe(1^null??3,1);shouldBe(1&null??3,0);shouldBe(3==null??3,false);shouldBe(3!=null??3,true);shouldBe(3===null??3,false);shouldBe(3!==null??3,true);shouldBe(1<null??3,false);shouldBe(1>null??3,true);shouldBe(1<=null??3,false);shouldBe(1>=null??3,true);shouldBe(1<<null??3,1);shouldBe(1>>null??3,1);shouldBe(1>>>null??3,1);shouldBe(1+null??3,1);shouldBe(1-null??3,1);shouldBe(1*null??3,0);shouldBe(1/null??3,Infinity);shouldBe(isNaN(1%null??3),true);shouldBe(1**null??3,1);const obj={count:0,get x(){this.count++;return'x'}};false??obj.x;shouldBe(obj.count,0);null??obj.x;shouldBe(obj.count,1);obj.x??obj.x;shouldBe(obj.count,2);(0||1)??2;0||(1??2);(0&&1)??2;0&&(1??2);(0??1)||2;0??(1||2);(0??1)&&2;0??(1&&2);0||1&&2|3^4&5==6!=7===8!==9<0>1<=2>=3<<4>>5>>>6+7-8*9/0%1**2
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (C) 2020 Sony Interactive Entertainment Inc.
3+
* Copyright (C) 2020 Apple Inc.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
* 1. Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* 2. Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in the
12+
* documentation and/or other materials provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24+
* THE POSSIBILITY OF SUCH DAMAGE.
25+
*/
26+
27+
function testBasicCases() {
28+
shouldBe(undefined ?? 3, 3);
29+
shouldBe(null ?? 3, 3);
30+
shouldBe(true ?? 3, true);
31+
shouldBe(false ?? 3, false);
32+
shouldBe(0 ?? 3, 0);
33+
shouldBe(1 ?? 3, 1);
34+
shouldBe('' ?? 3, '');
35+
shouldBe('hi' ?? 3, 'hi');
36+
shouldBe(({} ?? 3) instanceof Object, true);
37+
shouldBe(({ x: 'hi' } ?? 3).x, 'hi');
38+
shouldBe(([] ?? 3) instanceof Array, true);
39+
shouldBe((['hi'] ?? 3)[0], 'hi');
40+
shouldBe((makeMasquerader() ?? 3) == null, true);
41+
}
42+
noInline(testBasicCases);
43+
44+
for (let i = 0; i < 1e5; i++)
45+
testBasicCases();
46+
47+
shouldBe(1 | null ?? 3, 1);
48+
shouldBe(1 ^ null ?? 3, 1);
49+
shouldBe(1 & null ?? 3, 0);
50+
shouldBe(3 == null ?? 3, false);
51+
shouldBe(3 != null ?? 3, true);
52+
shouldBe(3 === null ?? 3, false);
53+
shouldBe(3 !== null ?? 3, true);
54+
shouldBe(1 < null ?? 3, false);
55+
shouldBe(1 > null ?? 3, true);
56+
shouldBe(1 <= null ?? 3, false);
57+
shouldBe(1 >= null ?? 3, true);
58+
shouldBe(1 << null ?? 3, 1);
59+
shouldBe(1 >> null ?? 3, 1);
60+
shouldBe(1 >>> null ?? 3, 1);
61+
shouldBe(1 + null ?? 3, 1);
62+
shouldBe(1 - null ?? 3, 1);
63+
shouldBe(1 * null ?? 3, 0);
64+
shouldBe(1 / null ?? 3, Infinity);
65+
shouldBe(isNaN(1 % null ?? 3), true);
66+
shouldBe(1 ** null ?? 3, 1);
67+
68+
const obj = {
69+
count: 0,
70+
get x() { this.count++; return 'x'; }
71+
};
72+
false ?? obj.x;
73+
shouldBe(obj.count, 0);
74+
null ?? obj.x;
75+
shouldBe(obj.count, 1);
76+
obj.x ?? obj.x;
77+
shouldBe(obj.count, 2);
78+
79+
(0 || 1) ?? 2;
80+
0 || (1 ?? 2);
81+
(0 && 1) ?? 2;
82+
0 && (1 ?? 2);
83+
(0 ?? 1) || 2;
84+
0 ?? (1 || 2);
85+
(0 ?? 1) && 2;
86+
0 ?? (1 && 2);
87+
88+
0 || 1 && 2 | 3 ^ 4 & 5 == 6 != 7 === 8 !== 9 < 0 > 1 <= 2 >= 3 << 4 >> 5 >>> 6 + 7 - 8 * 9 / 0 % 1 ** 2

0 commit comments

Comments
 (0)