From fbcbb5a018cd9652de19aa8e318df4839862b614 Mon Sep 17 00:00:00 2001 From: tuchida Date: Fri, 19 Jul 2024 01:00:45 +0900 Subject: [PATCH] ref. #1187 Transform AstNode within Parser when called by IRFactory --- .../org/mozilla/javascript/IRFactory.java | 7 ++- .../java/org/mozilla/javascript/Parser.java | 50 ++++++++++++++----- .../testsrc/jstests/harmony/destructuring.js | 11 ++++ tests/testsrc/test262.properties | 8 +-- 4 files changed, 55 insertions(+), 21 deletions(-) diff --git a/rhino/src/main/java/org/mozilla/javascript/IRFactory.java b/rhino/src/main/java/org/mozilla/javascript/IRFactory.java index 723f7d12c9..8db07c665d 100644 --- a/rhino/src/main/java/org/mozilla/javascript/IRFactory.java +++ b/rhino/src/main/java/org/mozilla/javascript/IRFactory.java @@ -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)) { @@ -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; diff --git a/rhino/src/main/java/org/mozilla/javascript/Parser.java b/rhino/src/main/java/org/mozilla/javascript/Parser.java index 754dc43ed7..5f28811c25 100644 --- a/rhino/src/main/java/org/mozilla/javascript/Parser.java +++ b/rhino/src/main/java/org/mozilla/javascript/Parser.java @@ -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()); } @@ -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 { @@ -4040,7 +4049,8 @@ Node destructuringAssignmentHelper(int variableType, Node left, Node right, Stri variableType, tempName, comma, - destructuringNames); + destructuringNames, + transformer); break; case Token.OBJECTLIT: empty = @@ -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: @@ -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"); @@ -4077,7 +4088,8 @@ boolean destructuringArray( int variableType, String tempName, Node parent, - List destructuringNames) { + List destructuringNames, + Transformer transformer) { boolean empty = true; int setOp = variableType == Token.CONST ? Token.SETCONST : Token.SETNAME; int index = 0; @@ -4098,7 +4110,11 @@ boolean destructuringArray( } else { parent.addChildToBack( destructuringAssignmentHelper( - variableType, n, rightElem, currentScriptOrFn.getNextTempName())); + variableType, + n, + rightElem, + currentScriptOrFn.getNextTempName(), + transformer)); } index++; empty = false; @@ -4111,7 +4127,8 @@ boolean destructuringObject( int variableType, String tempName, Node parent, - List destructuringNames) { + List destructuringNames, + Transformer transformer) { boolean empty = true; int setOp = variableType == Token.CONST ? Token.SETCONST : Token.SETNAME; @@ -4156,7 +4173,8 @@ boolean destructuringObject( variableType, value, rightElem, - currentScriptOrFn.getNextTempName())); + currentScriptOrFn.getNextTempName(), + transformer)); } empty = false; } @@ -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: @@ -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(); diff --git a/tests/testsrc/jstests/harmony/destructuring.js b/tests/testsrc/jstests/harmony/destructuring.js index 4f4ab25a2c..5b27ddbebb 100644 --- a/tests/testsrc/jstests/harmony/destructuring.js +++ b/tests/testsrc/jstests/harmony/destructuring.js @@ -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"; diff --git a/tests/testsrc/test262.properties b/tests/testsrc/test262.properties index 3a612ed763..a1a35b2730 100644 --- a/tests/testsrc/test262.properties +++ b/tests/testsrc/test262.properties @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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