Skip to content

Commit b36023f

Browse files
avpfacebook-github-bot
authored andcommitted
Test and fix more JS generation
Reviewed By: tmikov Differential Revision: D30438835 fbshipit-source-id: 27ad500f722088c9912b3f5995a1e36fbca1de99
1 parent 24f8451 commit b36023f

2 files changed

Lines changed: 91 additions & 4 deletions

File tree

unsupported/juno/src/gen_js.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2661,6 +2661,8 @@ impl<W: Write> GenJS<W> {
26612661
/// which is situated at `child_pos` position in relation to its `parent`.
26622662
fn need_parens(&self, parent: &Node, child: &Node, child_pos: ChildPos) -> NeedParens {
26632663
use NodeKind::*;
2664+
2665+
#[allow(clippy::if_same_then_else)]
26642666
if matches!(parent.kind, ArrowFunctionExpression { .. }) {
26652667
// (x) => ({x: 10}) needs parens to avoid confusing it with a block and a
26662668
// labelled statement.
@@ -2689,10 +2691,10 @@ impl<W: Write> GenJS<W> {
26892691
|| (is_unary_op(parent, UnaryExpressionOperator::Plus)
26902692
&& self.root_starts_with(child, check_plus))
26912693
|| (child_pos == ChildPos::Right
2692-
&& is_binary_op(parent, "-")
2694+
&& is_binary_op(parent, BinaryExpressionOperator::Minus)
26932695
&& self.root_starts_with(child, check_minus))
26942696
|| (child_pos == ChildPos::Right
2695-
&& is_binary_op(parent, "+")
2697+
&& is_binary_op(parent, BinaryExpressionOperator::Plus)
26962698
&& self.root_starts_with(child, check_plus))
26972699
{
26982700
// -(-x) or -(--x) or -(-5)
@@ -2715,6 +2717,12 @@ impl<W: Write> GenJS<W> {
27152717
// we need the left hand side to be parenthesized.
27162718
// Avoids confusing `(a?.b).c` with `a?.b.c`.
27172719
return NeedParens::Yes;
2720+
} else if (check_and_or(parent) && check_nullish(child))
2721+
|| (check_nullish(parent) && check_and_or(child))
2722+
{
2723+
// Nullish coalescing always requires parens when mixed with any
2724+
// other logical operations.
2725+
return NeedParens::Yes;
27182726
}
27192727

27202728
let (child_prec, _child_assoc) = self.get_precedence(child);
@@ -2826,9 +2834,9 @@ fn is_negative_number(node: &Node) -> bool {
28262834
}
28272835
}
28282836

2829-
fn is_binary_op(node: &Node, op: &str) -> bool {
2837+
fn is_binary_op(node: &Node, op: BinaryExpressionOperator) -> bool {
28302838
match &node.kind {
2831-
NodeKind::BinaryExpression { operator, .. } => operator.as_str() == op,
2839+
NodeKind::BinaryExpression { operator, .. } => *operator == op,
28322840
_ => false,
28332841
}
28342842
}
@@ -2850,6 +2858,26 @@ fn check_minus(node: &Node) -> bool {
28502858
|| is_update_prefix(node, UpdateExpressionOperator::Decrement)
28512859
}
28522860

2861+
fn check_and_or(node: &Node) -> bool {
2862+
matches!(
2863+
&node.kind,
2864+
NodeKind::LogicalExpression {
2865+
operator: LogicalExpressionOperator::And | LogicalExpressionOperator::Or,
2866+
..
2867+
}
2868+
)
2869+
}
2870+
2871+
fn check_nullish(node: &Node) -> bool {
2872+
matches!(
2873+
&node.kind,
2874+
NodeKind::LogicalExpression {
2875+
operator: LogicalExpressionOperator::NullishCoalesce,
2876+
..
2877+
}
2878+
)
2879+
}
2880+
28532881
fn ends_with_block(node: Option<&Node>) -> bool {
28542882
use NodeKind::*;
28552883
match node {

unsupported/juno/tests/gen_js.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ fn test_literals() {
8989
test_roundtrip("/abc/gi");
9090
}
9191

92+
#[test]
93+
fn test_identifier() {
94+
test_roundtrip("foo");
95+
test_roundtrip("class C { #foo() {} }");
96+
}
97+
9298
#[test]
9399
fn test_binop() {
94100
use NodeKind::*;
@@ -108,6 +114,17 @@ fn test_binop() {
108114
test_roundtrip("1 + 1");
109115
test_roundtrip("1 * 2 + (3 + 4)");
110116
test_roundtrip("1 ** 2 ** 3 ** 4");
117+
test_roundtrip("1 in 2 + (2 - 4) / 3");
118+
test_roundtrip("1 instanceof 2 + (2 - 4) / 3");
119+
}
120+
121+
#[test]
122+
fn test_conditional() {
123+
test_roundtrip("a ? b : c");
124+
test_roundtrip("a ? b : c ? d : e");
125+
test_roundtrip("(a ? b : c) ? d : e");
126+
test_roundtrip("a ? b : (c ? d : e)");
127+
test_roundtrip("a?.3:.4");
111128
}
112129

113130
#[test]
@@ -122,6 +139,7 @@ fn test_functions() {
122139
test_roundtrip("function foo(x, y) {}");
123140
test_roundtrip("function foo(x, y=3) {}");
124141
test_roundtrip("function foo([x, y], {z}) {}");
142+
test_roundtrip("function foo([x, y] = [1,2], {z:q}) {}");
125143
test_roundtrip("function foo() { return this; }");
126144
test_roundtrip("function *foo() {}");
127145
test_roundtrip("function *foo() { yield 1; }");
@@ -215,6 +233,15 @@ fn test_statements() {
215233
test_roundtrip("if (x) fn(); else fn();");
216234
}
217235

236+
#[test]
237+
fn test_logical() {
238+
test_roundtrip("a && b || c");
239+
test_roundtrip("a || b && c");
240+
test_roundtrip("(a || b) && c");
241+
test_roundtrip("(a || b) ?? c");
242+
test_roundtrip("(a ?? b) || c");
243+
}
244+
218245
#[test]
219246
fn test_sequences() {
220247
test_roundtrip("var x = (1, 2, 3);");
@@ -296,6 +323,38 @@ fn test_members() {
296323
test_roundtrip("(a?.b?.c?.())?.d");
297324
test_roundtrip("(a?.b?.c?.())(d)");
298325
test_roundtrip("(a?.b?.c?.())?.(d)");
326+
test_roundtrip("class C { constructor() { new.target; } }");
327+
}
328+
329+
#[test]
330+
fn test_classes() {
331+
test_roundtrip("class C {}");
332+
test_roundtrip("class C extends D {}");
333+
test_roundtrip(
334+
"class C extends D {
335+
prop1;
336+
#prop2;
337+
constructor() {}
338+
a() {}
339+
#b() {}
340+
c(x, y) {}
341+
static d() {}
342+
}",
343+
);
344+
test_roundtrip(
345+
"var cls = (class C extends D {
346+
prop1;
347+
#prop2;
348+
constructor() {}
349+
a() {}
350+
#b() {}
351+
c(x, y) {}
352+
static d() {}
353+
get e() {}
354+
set e(v) {}
355+
;
356+
})",
357+
);
299358
}
300359

301360
#[test]

0 commit comments

Comments
 (0)