From a86b9b2e2e78ac877494b03d6d93f3f7bc2b470a Mon Sep 17 00:00:00 2001 From: "satish.srinivasan" Date: Tue, 11 Jun 2024 17:04:41 +0530 Subject: [PATCH] WIP: Destructuring --- .../org/mozilla/javascript/IRFactory.java | 4 ++ .../java/org/mozilla/javascript/Parser.java | 43 ++++++++++++++++--- .../tests/DefaultParametersTest.java | 39 +++++++---------- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/rhino-runtime/src/main/java/org/mozilla/javascript/IRFactory.java b/rhino-runtime/src/main/java/org/mozilla/javascript/IRFactory.java index 93508a6eec..5931c8f402 100644 --- a/rhino-runtime/src/main/java/org/mozilla/javascript/IRFactory.java +++ b/rhino-runtime/src/main/java/org/mozilla/javascript/IRFactory.java @@ -2531,6 +2531,10 @@ void decompile(AstNode node) { case Token.THIS: decompiler.addToken(node.getType()); break; + case Token.ASSIGN: + decompile(((Assignment)node).getLeft()); + decompile(((Assignment)node).getRight()); + break; default: Kit.codeBug("unexpected token: " + Token.typeToName(node.getType())); } diff --git a/rhino-runtime/src/main/java/org/mozilla/javascript/Parser.java b/rhino-runtime/src/main/java/org/mozilla/javascript/Parser.java index 869496eaea..afeb1475ea 100644 --- a/rhino-runtime/src/main/java/org/mozilla/javascript/Parser.java +++ b/rhino-runtime/src/main/java/org/mozilla/javascript/Parser.java @@ -887,6 +887,11 @@ && matchToken(Token.ASSIGN, true)) { destructuringNode.addChildToBack(assign); } fnNode.putProp(Node.DESTRUCTURING_PARAMS, destructuringNode); + + // handle default for array/object destructuring + if (matchToken(Token.ASSIGN, true)) { + AstNode rhs = assignExpr(); // TODO(satish) + } } if (mustMatchToken(Token.RP, "msg.no.paren.after.parms", true)) { @@ -927,6 +932,8 @@ private FunctionNode function(int type, boolean isGenerator) throws IOException && (compilerEnv.getLanguageVersion() >= Context.VERSION_ES6)) { // ES6 generator function return function(type, true); + } else if (matchToken(Token.ASSIGN, true)) { + AstNode rhs = assignExpr(); // TODO(satish) } else { if (compilerEnv.isAllowMemberExprAsFunctionName()) { // Note that memberExpr can not start with '(' like @@ -2404,13 +2411,6 @@ private AstNode assignExpr() throws IOException { tt = peekToken(); } if (Token.FIRST_ASSIGN <= tt && tt <= Token.LAST_ASSIGN) { - if (inDestructuringAssignment) { - // default values inside destructuring assignments, - // like 'var [a = 10] = b' or 'var {a: b = 10} = c', - // are not supported - reportError("msg.destruct.default.vals"); - } - consumeToken(); // Pull out JSDoc info and reset it before recursing. @@ -4145,6 +4145,35 @@ boolean destructuringArray( defineSymbol(variableType, name, true); destructuringNames.add(name); } + } else if (n.getType() == Token.ASSIGN + && compilerEnv.getLanguageVersion() >= Context.VERSION_ES6) { + FunctionNode fnNode = (FunctionNode) currentScriptOrFn; + Object[] existing = fnNode.getDefaultParams(); + Object[] current; + int current_size = 0; + if (existing == null) { + existing = new Object[2]; + fnNode.setDefaultParams(existing); + current = existing; + } else { + current = new Object[existing.length + 2]; + System.arraycopy(existing, 0, current, 0, existing.length); + current_size = existing.length; + existing = null; + } + AstNode paramNode = ((Assignment) n).getLeft(); + AstNode valueNode = ((Assignment) n).getRight(); + + current[current_size] = paramNode.getString(); + current[current.length - 1] = valueNode; + fnNode.setDefaultParams(current); + + parent.addChildToBack( + new Node(setOp, createName(Token.BINDNAME, paramNode.getString(), null), rightElem)); + if (variableType != -1) { + defineSymbol(variableType, paramNode.getString(), true); + destructuringNames.add(paramNode.getString()); + } } else { parent.addChildToBack( destructuringAssignmentHelper( diff --git a/tests/src/test/java/org/mozilla/javascript/tests/DefaultParametersTest.java b/tests/src/test/java/org/mozilla/javascript/tests/DefaultParametersTest.java index 55f177c287..8aff5bdf65 100644 --- a/tests/src/test/java/org/mozilla/javascript/tests/DefaultParametersTest.java +++ b/tests/src/test/java/org/mozilla/javascript/tests/DefaultParametersTest.java @@ -81,7 +81,6 @@ public void functionConstructor() throws Exception { } @Test - @Ignore("destructuring-not-supported") public void destructuringAssigmentDefaultArray() throws Exception { final String script = "function f([x = 1, y = 2] = []) {\n" + " return x + y;\n" + "}\n"; assertIntEvaluates(3, script + "f()"); @@ -91,16 +90,8 @@ public void destructuringAssigmentDefaultArray() throws Exception { } @Test - @Ignore("destructuring-not-supported") public void destructuringAssigmentDefaultObject() throws Exception { - final String script = - "function f({ z = 3 } = {}) {\n" - + " return z;\n" - + "}\n" - + "\n" - + "f();\n" - + "f({});\n" - + "f({ z: 2 });"; + final String script = "function f({ z = 3, x = 2 } = {}) {\n" + " return z;\n" + "}\n"; assertIntEvaluates(3, script + "f()"); assertIntEvaluates(3, script + "f({})"); assertIntEvaluates(2, script + "f({z: 2})"); @@ -195,21 +186,21 @@ private static void assertIntEvaluatesWithLanguageLevel( final Object expected, final String source, int languageLevel) { Utils.runWithAllOptimizationLevels( cx -> { - // if (cx.getOptimizationLevel() == 0) { - int oldVersion = cx.getLanguageVersion(); - cx.setLanguageVersion(languageLevel); - try { - final Scriptable scope = cx.initStandardObjects(); - final Object rep = cx.evaluateString(scope, source, "test.js", 0, null); - if (rep instanceof Double) - assertEquals((int) expected, ((Double) rep).intValue()); - else assertEquals(expected, rep); - return null; - } finally { - cx.setLanguageVersion(oldVersion); + if (cx.getOptimizationLevel() == -1) { + int oldVersion = cx.getLanguageVersion(); + cx.setLanguageVersion(languageLevel); + try { + final Scriptable scope = cx.initStandardObjects(); + final Object rep = cx.evaluateString(scope, source, "test.js", 0, null); + if (rep instanceof Double) + assertEquals((int) expected, ((Double) rep).intValue()); + else assertEquals(expected, rep); + return null; + } finally { + cx.setLanguageVersion(oldVersion); + } } - // } - // return null; + return null; }); } }