From 121f9a8598ff58b41a2714f7024a32092fe03290 Mon Sep 17 00:00:00 2001 From: sanex3339 Date: Fri, 12 Jun 2020 21:56:36 +0300 Subject: [PATCH 1/4] Nullish coalescing support --- escodegen.js | 32 +++++++++++++++++-- .../nullish-coalescing.expected.js | 12 +++++++ .../nullish-coalescing.expected.min.js | 1 + .../nullish-coalescing.js | 12 +++++++ 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 test/compare-acorn-es2020/nullish-coalescing.expected.js create mode 100644 test/compare-acorn-es2020/nullish-coalescing.expected.min.js create mode 100644 test/compare-acorn-es2020/nullish-coalescing.js diff --git a/escodegen.js b/escodegen.js index 847fc370..e6903856 100644 --- a/escodegen.js +++ b/escodegen.js @@ -85,6 +85,7 @@ Assignment: 1, Conditional: 2, ArrowFunction: 2, + NullishCoalescing: 3, LogicalOR: 3, LogicalAND: 4, BitwiseOR: 5, @@ -108,6 +109,7 @@ }; BinaryPrecedence = { + '??': Precedence.NullishCoalescing, '||': Precedence.LogicalOR, '&&': Precedence.LogicalAND, '|': Precedence.BitwiseOR, @@ -1836,8 +1838,34 @@ BinaryExpression: function (expr, precedence, flags) { var result, leftPrecedence, rightPrecedence, currentPrecedence, fragment, leftSource; currentPrecedence = BinaryPrecedence[expr.operator]; - leftPrecedence = expr.operator === '**' ? Precedence.Postfix : currentPrecedence; - rightPrecedence = expr.operator === '**' ? currentPrecedence : currentPrecedence + 1; + + leftPrecedence = currentPrecedence; + rightPrecedence = currentPrecedence + 1; + + switch (expr.operator) { + case '**': + leftPrecedence = Precedence.Postfix; + rightPrecedence = currentPrecedence; + break; + + case '??': + if (expr.left.operator === '||' || expr.left.operator === '&&') { + leftPrecedence = BinaryPrecedence[expr.left.operator] + 1; + } + + if (expr.right.operator === '||' || expr.right.operator === '&&') { + rightPrecedence = BinaryPrecedence[expr.right.operator] + 1; + } + + break; + + case '||': + if (expr.left.operator === '??') { + leftPrecedence = BinaryPrecedence[expr.left.operator] + 1; + } + + break; + } if (currentPrecedence < precedence) { flags |= F_ALLOW_IN; diff --git a/test/compare-acorn-es2020/nullish-coalescing.expected.js b/test/compare-acorn-es2020/nullish-coalescing.expected.js new file mode 100644 index 00000000..874393a1 --- /dev/null +++ b/test/compare-acorn-es2020/nullish-coalescing.expected.js @@ -0,0 +1,12 @@ +a ?? b; +a ?? b ?? c; +a | b ?? c | d; +a ?? b ? c : d; +(a || b) ?? c; +a || (b ?? c); +(a && b) ?? c; +a && (b ?? c); +(a ?? b) || c; +a ?? (b || c); +(a ?? b) && c; +a ?? (b && c); \ No newline at end of file diff --git a/test/compare-acorn-es2020/nullish-coalescing.expected.min.js b/test/compare-acorn-es2020/nullish-coalescing.expected.min.js new file mode 100644 index 00000000..ecb75537 --- /dev/null +++ b/test/compare-acorn-es2020/nullish-coalescing.expected.min.js @@ -0,0 +1 @@ +a??b;a??b??c;a|b??c|d;a??b?c:d;(a||b)??c;a||(b??c);(a&&b)??c;a&&(b??c);(a??b)||c;a??(b||c);(a??b)&&c;a??(b&&c) diff --git a/test/compare-acorn-es2020/nullish-coalescing.js b/test/compare-acorn-es2020/nullish-coalescing.js new file mode 100644 index 00000000..874393a1 --- /dev/null +++ b/test/compare-acorn-es2020/nullish-coalescing.js @@ -0,0 +1,12 @@ +a ?? b; +a ?? b ?? c; +a | b ?? c | d; +a ?? b ? c : d; +(a || b) ?? c; +a || (b ?? c); +(a && b) ?? c; +a && (b ?? c); +(a ?? b) || c; +a ?? (b || c); +(a ?? b) && c; +a ?? (b && c); \ No newline at end of file From 5646f113ae78eca9046da1b8e4ea20d4baec87ad Mon Sep 17 00:00:00 2001 From: sanex Date: Mon, 24 Aug 2020 08:09:21 +0300 Subject: [PATCH 2/4] Updated nullish coalescing logic, added more tests --- escodegen.js | 4 ++-- test/compare-acorn-es2020/nullish-coalescing.expected.js | 3 +++ test/compare-acorn-es2020/nullish-coalescing.expected.min.js | 2 +- test/compare-acorn-es2020/nullish-coalescing.js | 5 ++++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/escodegen.js b/escodegen.js index e6903856..419e7a37 100644 --- a/escodegen.js +++ b/escodegen.js @@ -1849,11 +1849,11 @@ break; case '??': - if (expr.left.operator === '||' || expr.left.operator === '&&') { + if (expr.left.type === Syntax.LogicalExpression && (expr.left.operator === '||' || expr.left.operator === '&&')) { leftPrecedence = BinaryPrecedence[expr.left.operator] + 1; } - if (expr.right.operator === '||' || expr.right.operator === '&&') { + if (expr.right.operator === '&&') { rightPrecedence = BinaryPrecedence[expr.right.operator] + 1; } diff --git a/test/compare-acorn-es2020/nullish-coalescing.expected.js b/test/compare-acorn-es2020/nullish-coalescing.expected.js index 874393a1..5bb15e1f 100644 --- a/test/compare-acorn-es2020/nullish-coalescing.expected.js +++ b/test/compare-acorn-es2020/nullish-coalescing.expected.js @@ -2,6 +2,9 @@ a ?? b; a ?? b ?? c; a | b ?? c | d; a ?? b ? c : d; +a ? b ?? c : d; +a ? b : c ?? d; +a => b ?? c; (a || b) ?? c; a || (b ?? c); (a && b) ?? c; diff --git a/test/compare-acorn-es2020/nullish-coalescing.expected.min.js b/test/compare-acorn-es2020/nullish-coalescing.expected.min.js index ecb75537..dfefb728 100644 --- a/test/compare-acorn-es2020/nullish-coalescing.expected.min.js +++ b/test/compare-acorn-es2020/nullish-coalescing.expected.min.js @@ -1 +1 @@ -a??b;a??b??c;a|b??c|d;a??b?c:d;(a||b)??c;a||(b??c);(a&&b)??c;a&&(b??c);(a??b)||c;a??(b||c);(a??b)&&c;a??(b&&c) +a??b;a??b??c;a|b??c|d;a??b?c:d;a?b??c:d;a?b:c??d;a=>b??c;(a||b)??c;a||(b??c);(a&&b)??c;a&&(b??c);(a??b)||c;a??(b||c);(a??b)&&c;a??(b&&c) diff --git a/test/compare-acorn-es2020/nullish-coalescing.js b/test/compare-acorn-es2020/nullish-coalescing.js index 874393a1..d49d4189 100644 --- a/test/compare-acorn-es2020/nullish-coalescing.js +++ b/test/compare-acorn-es2020/nullish-coalescing.js @@ -2,6 +2,9 @@ a ?? b; a ?? b ?? c; a | b ?? c | d; a ?? b ? c : d; +a ? b ?? c : d; +a ? b : c ?? d; +a => b ?? c; (a || b) ?? c; a || (b ?? c); (a && b) ?? c; @@ -9,4 +12,4 @@ a && (b ?? c); (a ?? b) || c; a ?? (b || c); (a ?? b) && c; -a ?? (b && c); \ No newline at end of file +a ?? (b && c); From 7f97bfaaf618b515b45f1c2725a0452c8849c1d0 Mon Sep 17 00:00:00 2001 From: sanex Date: Mon, 24 Aug 2020 08:20:28 +0300 Subject: [PATCH 3/4] Added additional check for right expression type --- escodegen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/escodegen.js b/escodegen.js index 419e7a37..a9b9f7cc 100644 --- a/escodegen.js +++ b/escodegen.js @@ -1853,7 +1853,7 @@ leftPrecedence = BinaryPrecedence[expr.left.operator] + 1; } - if (expr.right.operator === '&&') { + if (expr.right.type === Syntax.LogicalExpression && expr.right.operator === '&&') { rightPrecedence = BinaryPrecedence[expr.right.operator] + 1; } From 6c1bd9479f02fc37ccf28008ce7e95e2de58f93a Mon Sep 17 00:00:00 2001 From: sanex Date: Mon, 24 Aug 2020 08:48:03 +0300 Subject: [PATCH 4/4] Added additional check for left expression type --- escodegen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/escodegen.js b/escodegen.js index a9b9f7cc..96a5b694 100644 --- a/escodegen.js +++ b/escodegen.js @@ -1860,7 +1860,7 @@ break; case '||': - if (expr.left.operator === '??') { + if (expr.left.type === Syntax.LogicalExpression && expr.left.operator === '??') { leftPrecedence = BinaryPrecedence[expr.left.operator] + 1; }