Skip to content

Commit

Permalink
ref. #1187 Transform AstNode within Parser when called by IRFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
tuchida authored and gbrail committed Jul 22, 2024
1 parent dc08eb5 commit fbcbb5a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 21 deletions.
7 changes: 5 additions & 2 deletions rhino/src/main/java/org/mozilla/javascript/IRFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -1476,7 +1476,9 @@ private Node createForIn(
Node newBody = new Node(Token.BLOCK);
Node assign;
if (destructuring != -1) {
assign = parser.createDestructuringAssignment(declType, lvalue, id);
assign =
parser.createDestructuringAssignment(
declType, lvalue, id, (AstNode node) -> transform(node));
if (!isForEach
&& !isForOf
&& (destructuring == Token.OBJECTLIT || destructuringLen != 2)) {
Expand Down Expand Up @@ -2053,7 +2055,8 @@ private Node createAssignment(int assignType, Node left, Node right) {
parser.reportError("msg.bad.destruct.op");
return right;
}
return parser.createDestructuringAssignment(-1, left, right);
return parser.createDestructuringAssignment(
-1, left, right, (AstNode node) -> transform(node));
}
parser.reportError("msg.bad.assign.left");
return right;
Expand Down
50 changes: 37 additions & 13 deletions rhino/src/main/java/org/mozilla/javascript/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ public static class ParserException extends RuntimeException {
private static final long serialVersionUID = 5882582646773765630L;
}

static interface Transformer {
Node transform(AstNode node);
}

public Parser() {
this(new CompilerEnvirons());
}
Expand Down Expand Up @@ -4012,14 +4016,19 @@ PerFunctionVariables createPerFunctionVariables(FunctionNode fnNode) {
* @return expression that performs a series of assignments to the variables defined in left
*/
Node createDestructuringAssignment(int type, Node left, Node right) {
return createDestructuringAssignment(type, left, right, null);
}

Node createDestructuringAssignment(int type, Node left, Node right, Transformer transformer) {
String tempName = currentScriptOrFn.getNextTempName();
Node result = destructuringAssignmentHelper(type, left, right, tempName);
Node result = destructuringAssignmentHelper(type, left, right, tempName, transformer);
Node comma = result.getLastChild();
comma.addChildToBack(createName(tempName));
return result;
}

Node destructuringAssignmentHelper(int variableType, Node left, Node right, String tempName) {
Node destructuringAssignmentHelper(
int variableType, Node left, Node right, String tempName, Transformer transformer) {
Scope result = createScopeNode(Token.LETEXPR, left.getLineno());
result.addChildToFront(new Node(Token.LET, createName(Token.NAME, tempName, right)));
try {
Expand All @@ -4040,7 +4049,8 @@ Node destructuringAssignmentHelper(int variableType, Node left, Node right, Stri
variableType,
tempName,
comma,
destructuringNames);
destructuringNames,
transformer);
break;
case Token.OBJECTLIT:
empty =
Expand All @@ -4049,7 +4059,8 @@ Node destructuringAssignmentHelper(int variableType, Node left, Node right, Stri
variableType,
tempName,
comma,
destructuringNames);
destructuringNames,
transformer);
break;
case Token.GETPROP:
case Token.GETELEM:
Expand All @@ -4059,7 +4070,7 @@ Node destructuringAssignmentHelper(int variableType, Node left, Node right, Stri
case Token.VAR:
reportError("msg.bad.assign.left");
}
comma.addChildToBack(simpleAssignment(left, createName(tempName)));
comma.addChildToBack(simpleAssignment(left, createName(tempName), transformer));
break;
default:
reportError("msg.bad.assign.left");
Expand All @@ -4077,7 +4088,8 @@ boolean destructuringArray(
int variableType,
String tempName,
Node parent,
List<String> destructuringNames) {
List<String> destructuringNames,
Transformer transformer) {
boolean empty = true;
int setOp = variableType == Token.CONST ? Token.SETCONST : Token.SETNAME;
int index = 0;
Expand All @@ -4098,7 +4110,11 @@ boolean destructuringArray(
} else {
parent.addChildToBack(
destructuringAssignmentHelper(
variableType, n, rightElem, currentScriptOrFn.getNextTempName()));
variableType,
n,
rightElem,
currentScriptOrFn.getNextTempName(),
transformer));
}
index++;
empty = false;
Expand All @@ -4111,7 +4127,8 @@ boolean destructuringObject(
int variableType,
String tempName,
Node parent,
List<String> destructuringNames) {
List<String> destructuringNames,
Transformer transformer) {
boolean empty = true;
int setOp = variableType == Token.CONST ? Token.SETCONST : Token.SETNAME;

Expand Down Expand Up @@ -4156,7 +4173,8 @@ boolean destructuringObject(
variableType,
value,
rightElem,
currentScriptOrFn.getNextTempName()));
currentScriptOrFn.getNextTempName(),
transformer));
}
empty = false;
}
Expand Down Expand Up @@ -4215,8 +4233,11 @@ protected Scope createScopeNode(int token, int lineno) {
// specific object containing the property ("binding" the property
// to the object) so that it's always the same object, regardless of
// side effects in the RHS.

protected Node simpleAssignment(Node left, Node right) {
return simpleAssignment(left, right, null);
}

protected Node simpleAssignment(Node left, Node right, Transformer transformer) {
int nodeType = left.getType();
switch (nodeType) {
case Token.NAME:
Expand All @@ -4236,11 +4257,14 @@ protected Node simpleAssignment(Node left, Node right) {
// override getFirstChild/getLastChild and return the appropriate
// field, but that seems just as ugly as this casting.
if (left instanceof PropertyGet) {
obj = ((PropertyGet) left).getTarget();
AstNode target = ((PropertyGet) left).getTarget();
obj = transformer != null ? transformer.transform(target) : target;
id = ((PropertyGet) left).getProperty();
} else if (left instanceof ElementGet) {
obj = ((ElementGet) left).getTarget();
id = ((ElementGet) left).getElement();
AstNode target = ((ElementGet) left).getTarget();
AstNode elem = ((ElementGet) left).getElement();
obj = transformer != null ? transformer.transform(target) : target;
id = transformer != null ? transformer.transform(elem) : elem;
} else {
// This branch is called during IRFactory transform pass.
obj = left.getFirstChild();
Expand Down
11 changes: 11 additions & 0 deletions tests/testsrc/jstests/harmony/destructuring.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,15 @@ var e;
for ([e] = d; false; );
assertEquals(e, 234);

var arr = [];
[arr[+false + 1]] = [123];
assertEquals(arr[1], 123);

[(NaN, arr)[1]] = [234];
assertEquals(arr[1], 234);

var obj = {};
[(NaN, obj).b] = [345];
assertEquals(obj.b, 345);

"success";
8 changes: 2 additions & 6 deletions tests/testsrc/test262.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3245,7 +3245,7 @@ language/expressions/arrow-function 209/333 (62.76%)
scope-paramsbody-var-close.js
scope-paramsbody-var-open.js

language/expressions/assignment 202/468 (43.16%)
language/expressions/assignment 200/468 (42.74%)
destructuring 3/3 (100.0%)
dstr/array-elem-init-assignment.js
dstr/array-elem-init-evaluation.js
Expand Down Expand Up @@ -3276,7 +3276,6 @@ language/expressions/assignment 202/468 (43.16%)
dstr/array-elem-nested-obj-yield-ident-valid.js non-strict
dstr/array-elem-put-const.js non-strict
dstr/array-elem-put-let.js
dstr/array-elem-put-obj-literal-prop-ref.js
dstr/array-elem-put-obj-literal-prop-ref-init.js
dstr/array-elem-put-obj-literal-prop-ref-init-active.js
dstr/array-elem-target-simple-strict.js strict
Expand Down Expand Up @@ -3401,7 +3400,6 @@ language/expressions/assignment 202/468 (43.16%)
dstr/obj-prop-elem-init-let.js
dstr/obj-prop-elem-init-yield-expr.js
dstr/obj-prop-elem-init-yield-ident-valid.js non-strict
dstr/obj-prop-elem-target-obj-literal-prop-ref.js
dstr/obj-prop-elem-target-obj-literal-prop-ref-init.js
dstr/obj-prop-elem-target-obj-literal-prop-ref-init-active.js
dstr/obj-prop-elem-target-yield-ident-valid.js non-strict
Expand Down Expand Up @@ -5930,7 +5928,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 471/725 (64.97%)
language/statements/for-of 469/725 (64.69%)
dstr/array-elem-init-assignment.js
dstr/array-elem-init-evaluation.js
dstr/array-elem-init-fn-name-arrow.js
Expand Down Expand Up @@ -5960,7 +5958,6 @@ language/statements/for-of 471/725 (64.97%)
dstr/array-elem-nested-obj-yield-ident-valid.js non-strict
dstr/array-elem-put-const.js non-strict
dstr/array-elem-put-let.js
dstr/array-elem-put-obj-literal-prop-ref.js
dstr/array-elem-put-obj-literal-prop-ref-init.js
dstr/array-elem-put-obj-literal-prop-ref-init-active.js
dstr/array-elem-target-simple-strict.js strict
Expand Down Expand Up @@ -6246,7 +6243,6 @@ language/statements/for-of 471/725 (64.97%)
dstr/obj-prop-elem-init-let.js
dstr/obj-prop-elem-init-yield-expr.js
dstr/obj-prop-elem-init-yield-ident-valid.js non-strict
dstr/obj-prop-elem-target-obj-literal-prop-ref.js
dstr/obj-prop-elem-target-obj-literal-prop-ref-init.js
dstr/obj-prop-elem-target-obj-literal-prop-ref-init-active.js
dstr/obj-prop-elem-target-yield-ident-valid.js non-strict
Expand Down

0 comments on commit fbcbb5a

Please sign in to comment.