Skip to content

Commit

Permalink
FIX: Arrow functions
Browse files Browse the repository at this point in the history
  • Loading branch information
0xe committed Sep 6, 2024
1 parent b892d86 commit 272d432
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 56 deletions.
5 changes: 3 additions & 2 deletions rhino/src/main/java/org/mozilla/javascript/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ public class Node implements Iterable<Node> {
ARROW_FUNCTION_PROP = 26,
TEMPLATE_LITERAL_PROP = 27,
TRAILING_COMMA = 28,
DESTRUCTURING_RVALUES = 29,
LAST_PROP = 29;
OBJECT_LITERAL_DESTRUCTURING = 29,
DESTRUCTURING_RVALUES = 30,
LAST_PROP = 30;

// values of ISNUMBER_PROP to specify
// which of the children are Number types
Expand Down
11 changes: 11 additions & 0 deletions rhino/src/main/java/org/mozilla/javascript/NodeTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@

package org.mozilla.javascript;

import static org.mozilla.javascript.Context.reportError;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import org.mozilla.javascript.ast.FunctionNode;
import org.mozilla.javascript.ast.Jump;
import org.mozilla.javascript.ast.Name;
import org.mozilla.javascript.ast.Scope;
import org.mozilla.javascript.ast.ScriptNode;

Expand Down Expand Up @@ -343,6 +346,14 @@ private void transformCompilationUnit_r(
case Token.SETNAME:
if (inStrictMode) {
node.setType(Token.STRICT_SETNAME);
if (node.getFirstChild().getType() == Token.BINDNAME) {
Node name = node.getFirstChild();
if (name instanceof Name
&& ((Name) name).getIdentifier().equals("eval")) {
// Don't allow set of `eval` in strict mode
reportError("syntax error");
}
}
}
/* fall through */
case Token.NAME:
Expand Down
22 changes: 15 additions & 7 deletions rhino/src/main/java/org/mozilla/javascript/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -2448,6 +2448,9 @@ private AstNode assignExpr() throws IOException {
} else if (!hasEOL && tt == Token.ARROW) {
consumeToken();
pn = arrowFunction(pn);
} else if (pn.getIntProp(Node.OBJECT_LITERAL_DESTRUCTURING, 0) == 1
&& !inDestructuringAssignment) {
reportError("msg.syntax");
}
return pn;
}
Expand Down Expand Up @@ -3282,8 +3285,11 @@ private AstNode parenExpr() throws IOException {

int length = ts.tokenEnd - begin;

boolean hasObjectLiteralDestructuring =
e.getIntProp(Node.OBJECT_LITERAL_DESTRUCTURING, 0) == 1;
boolean hasTrailingComma = e.getIntProp(Node.TRAILING_COMMA, 0) == 1;
if ((hasTrailingComma || e.getType() == Token.EMPTY) && peekToken() != Token.ARROW) {
if ((hasTrailingComma || hasObjectLiteralDestructuring || e.getType() == Token.EMPTY)
&& peekToken() != Token.ARROW) {
reportError("msg.syntax");
return makeErrorNode();
}
Expand Down Expand Up @@ -3588,7 +3594,7 @@ private ObjectLiteral objectLiteral() throws IOException {
setterNames = new HashSet<>();
}
Comment objJsdocNode = getAndResetJsDoc();

boolean objectLiteralDestructuringDefault = false;
commaLoop:
for (; ; ) {
String propertyName = null;
Expand Down Expand Up @@ -3621,10 +3627,9 @@ private ObjectLiteral objectLiteral() throws IOException {
// many tokens.)
int peeked = peekToken();
if (peeked != Token.COMMA && peeked != Token.COLON && peeked != Token.RC) {
if (peeked == Token.ASSIGN
&& inDestructuringAssignment) { // we have an object literal with
// destructuring assignment and a
// default
if (peeked == Token.ASSIGN) { // we have an object literal with
// destructuring assignment and a default value
objectLiteralDestructuringDefault = true;
if (compilerEnv.getLanguageVersion() >= Context.VERSION_ES6) {
elems.add(plainProperty(pname, tt));
if (matchToken(Token.COMMA, true)) {
Expand Down Expand Up @@ -3705,6 +3710,9 @@ private ObjectLiteral objectLiteral() throws IOException {

mustMatchToken(Token.RC, "msg.no.brace.prop", true);
ObjectLiteral pn = new ObjectLiteral(pos, ts.tokenEnd - pos);
if (objectLiteralDestructuringDefault) {
pn.putIntProp(Node.OBJECT_LITERAL_DESTRUCTURING, 1);
}
if (objJsdocNode != null) {
pn.setJsDocNode(objJsdocNode);
}
Expand Down Expand Up @@ -3782,7 +3790,7 @@ private ObjectProperty plainProperty(AstNode property, int ptt) throws IOExcepti
pn.setIsShorthand(true);
pn.setLeftAndRight(property, nn);
return pn;
} else if (tt == Token.ASSIGN && inDestructuringAssignment) {
} else if (tt == Token.ASSIGN) {
/* we're in destructuring with defaults in a object literal; treat defaults as values */
ObjectProperty pn = new ObjectProperty();
consumeToken(); // consume the `=`
Expand Down
2 changes: 2 additions & 0 deletions rhino/src/main/java/org/mozilla/javascript/Token.java
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ public static String typeToName(int token) {
return "IFNE";
case SETNAME:
return "SETNAME";
case STRICT_SETNAME:
return "STRICT_SETNAME";
case BITOR:
return "BITOR";
case BITXOR:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,6 @@ public void functionDefaultArgsArrayArrow() throws Exception {
assertIntEvaluates(6, script + "([,4])");
}

@Test
@Ignore("wip") // TODO TODO TODO!!
public void functionDefaultArgsObjectArrow() throws Exception {
final String script = "(({x = 1} = {x: 2}) => {\n return x;\n})";

assertIntEvaluates(1, script + "({})"); // TODO(satish): parsing errors with arrow fns
assertIntEvaluates(2, script + "()"); // TODO(satish): returns 1
assertIntEvaluates(3, script + "({x: 3})");
}

@Test
public void functionDefaultArgsMulti() throws Exception {
final String script = "function foo(a = 2, b = 23) { return a + b; }";
Expand All @@ -65,20 +55,30 @@ public void functionDefaultArgsUsage() throws Exception {

@Test
public void ObjIdInitSimpleStrictExpr() throws Exception {
final String script = "(0, { eval = 0 } = {});";
assertThrows("missing ( before function parameters.", script);
final String script =
"(function () { \n " + "'use strict'; \n " + "(0, { eval = 0 } = {}) })()";
assertThrows("syntax error", script);
}

@Test
public void ObjIdInitSimpleStrictForOf() throws Exception {
final String script = "for ({ eval = 0 } of [{}]) ;";
assertThrows("missing ( before function parameters.", script);
assertThrows("syntax error", script);
}

@Test
public void CoverInitName() throws Exception {
final String script = "({ a = 1 });";
assertThrows("missing ( before function parameters.", script);
assertThrows("syntax error", script);
}

@Test
public void functionDefaultArgsObjectArrow() throws Exception {
final String script = "(({x = 1} = {x: 2}) => {\n return x;\n})";

assertIntEvaluates(1, script + "({})");
assertIntEvaluates(2, script + "()");
assertIntEvaluates(3, script + "({x: 3})");
}

@Test
Expand Down
41 changes: 8 additions & 33 deletions tests/testsrc/test262.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3903,7 +3903,7 @@ language/expressions/array 41/52 (78.85%)
spread-sngl-literal.js
spread-sngl-obj-ident.js

language/expressions/arrow-function 168/343 (48.98%)
language/expressions/arrow-function 167/343 (48.69%)
dstr/ary-init-iter-close.js
dstr/ary-init-iter-get-err.js
dstr/ary-init-iter-get-err-array-prototype.js
Expand Down Expand Up @@ -3992,7 +3992,6 @@ language/expressions/arrow-function 168/343 (48.98%)
dstr/dflt-obj-ptrn-id-init-fn-name-gen.js
dstr/dflt-obj-ptrn-id-init-skipped.js
dstr/dflt-obj-ptrn-id-init-throws.js
dstr/dflt-obj-ptrn-id-init-unresolvable.js
dstr/dflt-obj-ptrn-list-err.js
dstr/dflt-obj-ptrn-prop-ary.js
dstr/dflt-obj-ptrn-prop-ary-init.js
Expand Down Expand Up @@ -4072,7 +4071,7 @@ language/expressions/arrow-function 168/343 (48.98%)
unscopables-with.js non-strict
unscopables-with-in-nested-fn.js non-strict

language/expressions/assignment 199/480 (41.46%)
language/expressions/assignment 193/480 (40.21%)
destructuring 3/3 (100.0%)
dstr/array-elem-init-evaluation.js
dstr/array-elem-init-fn-name-arrow.js
Expand Down Expand Up @@ -4192,10 +4191,6 @@ language/expressions/assignment 199/480 (41.46%)
dstr/obj-empty-null.js
dstr/obj-empty-undef.js
dstr/obj-id-identifier-yield-ident-valid.js non-strict
dstr/obj-id-init-assignment-missing.js
dstr/obj-id-init-assignment-null.js
dstr/obj-id-init-assignment-truthy.js
dstr/obj-id-init-assignment-undef.js
dstr/obj-id-init-evaluation.js
dstr/obj-id-init-fn-name-arrow.js
dstr/obj-id-init-fn-name-class.js {unsupported: [class]}
Expand All @@ -4206,11 +4201,9 @@ language/expressions/assignment 199/480 (41.46%)
dstr/obj-id-init-let.js
dstr/obj-id-init-order.js
dstr/obj-id-init-simple-no-strict.js non-strict
dstr/obj-id-init-yield-expr.js
dstr/obj-id-init-yield-ident-valid.js non-strict
dstr/obj-id-put-const.js non-strict
dstr/obj-id-put-let.js
dstr/obj-id-simple-strict.js strict
dstr/obj-prop-elem-init-evaluation.js
dstr/obj-prop-elem-init-fn-name-arrow.js
dstr/obj-prop-elem-init-fn-name-class.js {unsupported: [class]}
Expand Down Expand Up @@ -4410,7 +4403,7 @@ language/expressions/call 60/92 (65.22%)
language/expressions/comma 1/6 (16.67%)
tco-final.js {unsupported: [tail-call-optimization]}

language/expressions/compound-assignment 137/454 (30.18%)
language/expressions/compound-assignment 125/454 (27.53%)
11.13.2-34-s.js strict
11.13.2-35-s.js strict
11.13.2-36-s.js strict
Expand All @@ -4422,11 +4415,8 @@ language/expressions/compound-assignment 137/454 (30.18%)
11.13.2-42-s.js strict
11.13.2-43-s.js strict
11.13.2-44-s.js strict
11.13.2-6-1gs.js strict
add-arguments-strict.js strict
add-eval-strict.js strict
and-arguments-strict.js strict
and-eval-strict.js strict
compound-assignment-operator-calls-putvalue-lref--v-.js non-strict
compound-assignment-operator-calls-putvalue-lref--v--1.js non-strict
compound-assignment-operator-calls-putvalue-lref--v--10.js non-strict
Expand All @@ -4450,7 +4440,6 @@ language/expressions/compound-assignment 137/454 (30.18%)
compound-assignment-operator-calls-putvalue-lref--v--8.js non-strict
compound-assignment-operator-calls-putvalue-lref--v--9.js non-strict
div-arguments-strict.js strict
div-eval-strict.js strict
left-hand-side-private-reference-accessor-property-add.js {unsupported: [class-fields-private]}
left-hand-side-private-reference-accessor-property-bitand.js {unsupported: [class-fields-private]}
left-hand-side-private-reference-accessor-property-bitor.js {unsupported: [class-fields-private]}
Expand Down Expand Up @@ -4500,13 +4489,9 @@ language/expressions/compound-assignment 137/454 (30.18%)
left-hand-side-private-reference-readonly-accessor-property-srshift.js {unsupported: [class-fields-private]}
left-hand-side-private-reference-readonly-accessor-property-sub.js {unsupported: [class-fields-private]}
lshift-arguments-strict.js strict
lshift-eval-strict.js strict
mod-arguments-strict.js strict
mod-eval-strict.js strict
mult-arguments-strict.js strict
mult-eval-strict.js strict
or-arguments-strict.js strict
or-eval-strict.js strict
S11.13.2_A7.10_T1.js
S11.13.2_A7.10_T2.js
S11.13.2_A7.10_T4.js
Expand Down Expand Up @@ -4541,13 +4526,9 @@ language/expressions/compound-assignment 137/454 (30.18%)
S11.13.2_A7.9_T2.js
S11.13.2_A7.9_T4.js
srshift-arguments-strict.js strict
srshift-eval-strict.js strict
sub-arguments-strict.js strict
sub-eval-strict.js strict
urshift-arguments-strict.js strict
urshift-eval-strict.js strict
xor-arguments-strict.js strict
xor-eval-strict.js strict

language/expressions/concatenation 0/5 (0.0%)

Expand Down Expand Up @@ -4585,7 +4566,7 @@ language/expressions/exponentiation 3/44 (6.82%)
bigint-wrapped-values.js
order-of-evaluation.js

language/expressions/function 169/264 (64.02%)
language/expressions/function 168/264 (63.64%)
dstr/ary-init-iter-close.js
dstr/ary-init-iter-get-err.js
dstr/ary-init-iter-get-err-array-prototype.js
Expand Down Expand Up @@ -4726,7 +4707,6 @@ language/expressions/function 169/264 (64.02%)
eval-var-scope-syntax-err.js non-strict
length-dflt.js
name-arguments-strict-body.js non-strict
name-eval-strict-body.js non-strict
named-no-strict-reassign-fn-name-in-body.js non-strict
named-no-strict-reassign-fn-name-in-body-in-arrow.js non-strict
named-no-strict-reassign-fn-name-in-body-in-eval.js non-strict
Expand Down Expand Up @@ -5006,7 +4986,7 @@ language/expressions/less-than-or-equal 2/47 (4.26%)
language/expressions/logical-and 1/18 (5.56%)
tco-right.js {unsupported: [tail-call-optimization]}

language/expressions/logical-assignment 55/78 (70.51%)
language/expressions/logical-assignment 53/78 (67.95%)
left-hand-side-private-reference-accessor-property-and.js {unsupported: [class-fields-private]}
left-hand-side-private-reference-accessor-property-nullish.js {unsupported: [class-fields-private]}
left-hand-side-private-reference-accessor-property-or.js {unsupported: [class-fields-private]}
Expand Down Expand Up @@ -5037,7 +5017,6 @@ language/expressions/logical-assignment 55/78 (70.51%)
lgcl-and-assignment-operator-non-extensible.js strict
lgcl-and-assignment-operator-non-simple-lhs.js
lgcl-and-assignment-operator-non-writeable.js strict
lgcl-and-eval-strict.js strict
lgcl-nullish-assignment-operator.js
lgcl-nullish-assignment-operator-bigint.js
lgcl-nullish-assignment-operator-lhs-before-rhs.js
Expand All @@ -5061,7 +5040,6 @@ language/expressions/logical-assignment 55/78 (70.51%)
lgcl-or-assignment-operator-no-set-put.js strict
lgcl-or-assignment-operator-non-simple-lhs.js
lgcl-or-assignment-operator-non-writeable.js strict
lgcl-or-eval-strict.js strict

language/expressions/logical-not 0/19 (0.0%)

Expand Down Expand Up @@ -5123,7 +5101,7 @@ language/expressions/new 41/59 (69.49%)

~language/expressions/new.target

language/expressions/object 812/1169 (69.46%)
language/expressions/object 810/1169 (69.29%)
dstr/async-gen-meth-ary-init-iter-close.js {unsupported: [async-iteration, async]}
dstr/async-gen-meth-ary-init-iter-get-err.js {unsupported: [async-iteration]}
dstr/async-gen-meth-ary-init-iter-get-err-array-prototype.js {unsupported: [async-iteration]}
Expand Down Expand Up @@ -6817,7 +6795,7 @@ language/statements/for-in 39/114 (34.21%)
scope-head-lex-open.js
scope-head-var-none.js non-strict

language/statements/for-of 449/736 (61.01%)
language/statements/for-of 448/736 (60.87%)
dstr/array-elem-init-evaluation.js
dstr/array-elem-init-fn-name-arrow.js
dstr/array-elem-init-fn-name-class.js {unsupported: [class]}
Expand Down Expand Up @@ -7105,7 +7083,6 @@ language/statements/for-of 449/736 (61.01%)
dstr/obj-id-init-yield-ident-valid.js non-strict
dstr/obj-id-put-const.js non-strict
dstr/obj-id-put-let.js
dstr/obj-id-simple-strict.js strict
dstr/obj-prop-elem-init-evaluation.js
dstr/obj-prop-elem-init-fn-name-arrow.js
dstr/obj-prop-elem-init-fn-name-class.js {unsupported: [class]}
Expand Down Expand Up @@ -7268,7 +7245,7 @@ language/statements/for-of 449/736 (61.01%)
scope-head-lex-open.js
scope-head-var-none.js non-strict

language/statements/function 185/451 (41.02%)
language/statements/function 183/451 (40.58%)
dstr/ary-init-iter-close.js
dstr/ary-init-iter-get-err.js
dstr/ary-init-iter-get-err-array-prototype.js
Expand Down Expand Up @@ -7428,8 +7405,6 @@ language/statements/function 185/451 (41.02%)
dflt-params-ref-self.js
dflt-params-rest.js
dflt-params-trailing-comma.js
enable-strict-via-body.js non-strict
enable-strict-via-outer-body.js non-strict
eval-var-scope-syntax-err.js non-strict
length-dflt.js
name-arguments-strict-body.js non-strict
Expand Down

0 comments on commit 272d432

Please sign in to comment.