Skip to content

Commit

Permalink
FIX: test with all opt levels
Browse files Browse the repository at this point in the history
  • Loading branch information
0xe authored and gbrail committed Sep 11, 2024
1 parent d176c57 commit 5c8707f
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 35 deletions.
6 changes: 5 additions & 1 deletion rhino/src/main/java/org/mozilla/javascript/IRFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -2053,7 +2053,11 @@ private static Node createBinary(int nodeType, Node left, Node right) {
new Node(Token.SHEQ, nullNode, left),
new Node(Token.SHEQ, undefinedNode, left));

return new Node(Token.HOOK, conditional, right, left);
return new Node(
Token.HOOK,
/* left= */ conditional,
/* mid= */ right,
/* right= */ left);
}
}

Expand Down
12 changes: 11 additions & 1 deletion rhino/src/main/java/org/mozilla/javascript/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -2406,7 +2406,17 @@ private AstNode nullishCoalescingExpr() throws IOException {
AstNode pn = orExpr();
if (matchToken(Token.NULLISH_COALESCING, true)) {
int opPos = ts.tokenBeg;
pn = new InfixExpression(Token.NULLISH_COALESCING, pn, nullishCoalescingExpr(), opPos);
AstNode rn = nullishCoalescingExpr();

// Cannot immediately contain, or be contained within, an && or || operation.
if (pn.getType() == Token.OR
|| pn.getType() == Token.AND
|| rn.getType() == Token.OR
|| rn.getType() == Token.AND) {
reportError("msg.nullish.bad.token");
}

pn = new InfixExpression(Token.NULLISH_COALESCING, pn, rn, opPos);
}
return pn;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public abstract class AstNode extends Node implements Comparable<AstNode> {
operatorNames.put(Token.COMMA, ",");
operatorNames.put(Token.COLON, ":");
operatorNames.put(Token.OR, "||");
operatorNames.put(Token.NULLISH_COALESCING, "??");
operatorNames.put(Token.AND, "&&");
operatorNames.put(Token.INC, "++");
operatorNames.put(Token.DEC, "--");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ msg.bad.yield =\
msg.yield.parenthesized =\
yield expression must be parenthesized.

msg.nullish.bad.token =\
Syntax Error: Unexpected token.

# NativeGlobal
msg.cant.call.indirect =\
Function "{0}" must be called directly, and not by way of a \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ msg.bad.yield =\
msg.yield.parenthesized =\
L''expression suivant ''yield'' doit \u00eatre entre parenth\u00e8ses.

msg.nullish.bad.token =\
Erreur de syntaxe: Jeton inattendu.

# NativeGlobal
msg.cant.call.indirect =\
La fonction "{0}" doit \u00EAtre appel\u00E9e directement et non par l''interm\u00E9diaire \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,51 @@ public class NullishCoalescingOpTest {

@Test
public void testNullishColascingBasic() {
try (Context cx = Context.enter()) {
Scriptable scope = cx.initStandardObjects();
cx.setLanguageVersion(Context.VERSION_ES6);

String script = "null ?? 'default string'";
Assert.assertEquals(
"default string",
cx.evaluateString(scope, script, "nullish coalescing basic", 0, null));

String script2 = "undefined ?? 'default string'";
Assert.assertEquals(
"default string",
cx.evaluateString(scope, script2, "nullish coalescing basic", 0, null));
}
Utils.runWithAllOptimizationLevels(
cx -> {
Scriptable scope = cx.initStandardObjects();
cx.setLanguageVersion(Context.VERSION_ES6);

String script = "null ?? 'default string'";
Assert.assertEquals(
"default string",
cx.evaluateString(scope, script, "nullish coalescing basic", 0, null));

String script2 = "undefined ?? 'default string'";
Assert.assertEquals(
"default string",
cx.evaluateString(scope, script2, "nullish coalescing basic", 0, null));
return null;
});
}

@Test
public void testNullishColascingShortCircuit() {
String script = "0 || 0 ?? true";
Utils.assertEvaluatorExceptionES6("Syntax Error: Unexpected token. (test#1)", script);

String script2 = "0 && 0 ?? true";
Utils.assertEvaluatorExceptionES6("Syntax Error: Unexpected token. (test#1)", script2);

String script3 = "0 ?? 0 && true;";
Utils.assertEvaluatorExceptionES6("Syntax Error: Unexpected token. (test#1)", script3);

String script4 = "0 ?? 0 || true;";
Utils.assertEvaluatorExceptionES6("Syntax Error: Unexpected token. (test#1)", script4);
}

@Test
public void testNullishColascingPrecedence() {
try (Context cx = Context.enter()) {
Scriptable scope = cx.initStandardObjects();
cx.setLanguageVersion(Context.VERSION_ES6);
cx.setOptimizationLevel(-1);

String script1 = "3 == 3 ? 'yes' ?? 'default string' : 'no'";
Assert.assertEquals(
"yes", cx.evaluateString(scope, script1, "nullish coalescing basic", 0, null));

String script3 = "3 || null ?? 'default string'";
Assert.assertEquals(
3.0, cx.evaluateString(scope, script3, "nullish coalescing basic", 0, null));

String script2 = "3 && null ?? 'default string'";
Assert.assertEquals(
"default string",
cx.evaluateString(scope, script2, "nullish coalescing basic", 0, null));
}
Utils.runWithAllOptimizationLevels(
cx -> {
Scriptable scope = cx.initStandardObjects();
cx.setLanguageVersion(Context.VERSION_ES6);

String script1 = "3 == 3 ? 'yes' ?? 'default string' : 'no'";
Assert.assertEquals(
"yes",
cx.evaluateString(scope, script1, "nullish coalescing basic", 0, null));
return null;
});
}
}
4 changes: 3 additions & 1 deletion tests/testsrc/test262.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4470,7 +4470,9 @@ language/expressions/call 60/92 (65.22%)

~language/expressions/class

~language/expressions/coalesce
language/expressions/coalesce 2/24 (8.33%)
tco-pos-null.js {unsupported: [tail-call-optimization]}
tco-pos-undefined.js {unsupported: [tail-call-optimization]}

language/expressions/comma 1/6 (16.67%)
tco-final.js {unsupported: [tail-call-optimization]}
Expand Down

0 comments on commit 5c8707f

Please sign in to comment.