Skip to content

Commit

Permalink
WIP: Destructuring
Browse files Browse the repository at this point in the history
  • Loading branch information
0xe committed Jun 12, 2024
1 parent 44e544f commit a86b9b2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}
Expand Down
43 changes: 36 additions & 7 deletions rhino-runtime/src/main/java/org/mozilla/javascript/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()");
Expand All @@ -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})");
Expand Down Expand Up @@ -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;
});
}
}

0 comments on commit a86b9b2

Please sign in to comment.