Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEAT: Support default arguments in functions #1481

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
6afa6e4
FEAT: Support default arguments in functions #WIP
0xe May 28, 2024
3d88b3a
FEAT: Add support for default parameters
0xe May 29, 2024
188214c
WIP: Add some more failing test cases
0xe May 31, 2024
3b068d1
WIP: Uncomment 262 cases that pass
0xe Jun 3, 2024
2908f3c
WIP: Added more (failing) test cases for
0xe Jun 3, 2024
21b5647
FIX: Arguments with default parameters
0xe Jun 5, 2024
e262c2c
WIP: Destructuring
0xe Jun 11, 2024
28669b6
WIP: comment out failing tests
0xe Jul 11, 2024
8360b40
WIP: revert destructuring changes
0xe Jul 15, 2024
8af362a
FIX: lint in Arguments
0xe Jul 15, 2024
8ff5bff
FIX: Use parser to create name node
0xe Jul 16, 2024
e558ecd
Tiny refactor
0xe Jul 17, 2024
62f801e
FIX: loop in IRFactory
0xe Jul 20, 2024
2327c1b
FEAT: Destructuring arrays with default parameters #1
0xe Jul 20, 2024
44ed123
FIX: default argument bugs with array literals
0xe Jul 24, 2024
410b4e3
FEAT: default arguments in arrow functions
0xe Jul 24, 2024
2454b76
FEAT: Implement object destructuring
0xe Jul 31, 2024
8e25b60
WIP: Refactor things a bit
0xe Aug 1, 2024
029661e
Merge branch 'master' into scratch/satish/support-default-arguments
0xe Aug 3, 2024
31087ea
WIP: Fix after merge
0xe Aug 3, 2024
93bb695
FIX: spotbugs issue
0xe Aug 5, 2024
2a7fc8d
FIX: Issue385Test
0xe Aug 6, 2024
96c1c1b
FIX: Destructuring with function values
0xe Aug 8, 2024
f67f056
Merge branch 'master' into scratch/satish/support-default-arguments
0xe Aug 9, 2024
91156df
Add test for defaults with destructuring assigment
0xe Aug 12, 2024
c4649be
WIP: Hack to fix inf. looping temporarily
0xe Aug 24, 2024
a0ffa64
FIX: Update 262 properties
0xe Aug 24, 2024
a5eac32
Merge branch 'master' into scratch/satish/support-default-arguments
0xe Aug 24, 2024
4c2f19a
FIX: update test262.properties after merge
0xe Aug 24, 2024
3847ee6
Merge branch 'master' into scratch/satish/support-default-arguments
0xe Aug 31, 2024
a3ddc54
FIX: codegen bug for object destructuring
0xe Sep 4, 2024
b892d86
Merge branch 'master' into scratch/satish/support-default-arguments
0xe Sep 5, 2024
272d432
FIX: Arrow functions
0xe Sep 6, 2024
047643a
Merge branch 'master' into scratch/satish/support-default-arguments
0xe Sep 12, 2024
9c5c3b9
FIX: handle ParenthesizedExpressions correectly
0xe Sep 14, 2024
b34e6a3
FIX: Style comments
0xe Sep 14, 2024
c267b47
Merge branch 'master' into scratch/satish/support-default-arguments
0xe Sep 14, 2024
361282d
Update 262 properties
0xe Sep 14, 2024
31f9358
FIX: transformObjectLiteral should be private
0xe Sep 14, 2024
b1a6dda
FIX: Simplify storage for default parameters
0xe Sep 16, 2024
f249481
FIX: Cycle in scope chain with `for (let ...`
0xe Sep 16, 2024
e2537dc
Add test for nested arrays
0xe Sep 16, 2024
0ffad68
FIX: Error reporting for versions <= VERSION_200
0xe Sep 16, 2024
33dbc76
Add ignored test for deeply nested literals
0xe Sep 16, 2024
2d305cb
Merge branch 'master' into scratch/satish/support-default-arguments
0xe Sep 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions rhino/src/main/java/org/mozilla/javascript/Arguments.java
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ private boolean sharedWithActivation(int index) {
return false;
}
NativeFunction f = activation.function;

// Check if default arguments are present
if (f == null || f.hasDefaultParameters()) {
return false;
}

int definedCount = f.getParamCount();
if (index < definedCount) {
// Check if argument is not hidden by later argument with the same
Expand Down
5 changes: 5 additions & 0 deletions rhino/src/main/java/org/mozilla/javascript/BaseFunction.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ protected boolean isGeneratorFunction() {
return isGeneratorFunction;
}

// Generated code will override this
protected boolean hasDefaultParameters() {
return false;
}

/**
* Gets the value returned by calling the typeof operator on this object.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ private void generateICodeFromTree(Node tree) {
itsData.argIsConst = scriptOrFn.getParamAndVarConst();
itsData.argCount = scriptOrFn.getParamCount();
itsData.argsHasRest = scriptOrFn.hasRestParameter();
itsData.argsHasDefaults = scriptOrFn.getDefaultParams() != null;

itsData.rawSourceStart = scriptOrFn.getRawSourceStart();
itsData.rawSourceEnd = scriptOrFn.getRawSourceEnd();
Expand Down
67 changes: 44 additions & 23 deletions rhino/src/main/java/org/mozilla/javascript/IRFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,44 @@ private Node transformFunction(FunctionNode fn) {
++parser.nestingOfFunction; // only for body, not params
Node body = transform(fn.getBody());

/* Process simple default parameters */
List<Object> defaultParams = fn.getDefaultParams();
if (defaultParams != null) {
for (int i = defaultParams.size() - 1; i > 0; ) {
if (defaultParams.get(i) instanceof AstNode
&& defaultParams.get(i - 1) instanceof String) {
AstNode rhs = (AstNode) defaultParams.get(i);
String name = (String) defaultParams.get(i - 1);
body.addChildToFront(
createIf(
createBinary(
Token.SHEQ,
parser.createName(name),
parser.createName("undefined")),
new Node(
Token.EXPR_VOID,
createAssignment(
Token.ASSIGN,
parser.createName(name),
transform(rhs)),
body.getLineno()),
null,
body.getLineno()));
}
i -= 2;
}
}

/* transform nodes used as default parameters */
List<Node[]> dfns = fn.getDestructuringRvalues();
if (dfns != null) {
for (var i : dfns) {
Node a = i[0];
AstNode b = (AstNode) i[1];
a.replaceChild(b, transform(b));
}
}

if (destructuring != null) {
body.addChildToFront(new Node(Token.EXPR_VOID, destructuring, lineno));
}
Expand Down Expand Up @@ -859,7 +897,7 @@ private Node transformObjectLiteral(ObjectLiteral node) {
int size = elems.size(), i = 0;
properties = new Object[size];
for (ObjectProperty prop : elems) {
Object propKey = getPropKey(prop.getLeft());
Object propKey = Parser.getPropKey(prop.getLeft());
if (propKey == null) {
Node theId = transform(prop.getLeft());
properties[i++] = theId;
Expand All @@ -882,23 +920,6 @@ private Node transformObjectLiteral(ObjectLiteral node) {
return object;
}

private Object getPropKey(Node id) {
Object key;
if (id instanceof Name) {
String s = ((Name) id).getIdentifier();
key = ScriptRuntime.getIndexObject(s);
} else if (id instanceof StringLiteral) {
String s = ((StringLiteral) id).getValue();
key = ScriptRuntime.getIndexObject(s);
} else if (id instanceof NumberLiteral) {
double n = ((NumberLiteral) id).getNumber();
key = ScriptRuntime.getIndexObject(n);
} else {
key = null; // Filled later
}
return key;
}

private Node transformParenExpr(ParenthesizedExpression node) {
AstNode expr = node.getExpression();
while (expr instanceof ParenthesizedExpression) {
Expand Down Expand Up @@ -1133,7 +1154,9 @@ private Node transformVariableInitializers(VariableDeclaration node) {
} else {
astNodePos.push(var);
try {
Node d = parser.createDestructuringAssignment(node.getType(), left, right);
Node d =
parser.createDestructuringAssignment(
node.getType(), left, right, this::transform);
node.addChildToBack(d);
} finally {
astNodePos.pop();
Expand Down Expand Up @@ -1501,8 +1524,7 @@ private Node createForIn(
Node assign;
if (destructuring != -1) {
assign =
parser.createDestructuringAssignment(
declType, lvalue, id, (AstNode node) -> transform(node));
0xe marked this conversation as resolved.
Show resolved Hide resolved
parser.createDestructuringAssignment(declType, lvalue, id, this::transform);
if (!isForEach
&& !isForOf
&& (destructuring == Token.OBJECTLIT || destructuringLen != 2)) {
Expand Down Expand Up @@ -2079,8 +2101,7 @@ private Node createAssignment(int assignType, Node left, Node right) {
parser.reportError("msg.bad.destruct.op");
return right;
}
return parser.createDestructuringAssignment(
-1, left, right, (AstNode node) -> transform(node));
return parser.createDestructuringAssignment(-1, left, right, this::transform);
}
parser.reportError("msg.bad.assign.left");
return right;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,9 @@ boolean hasFunctionNamed(String name) {
}
return true;
}

@Override
public boolean hasDefaultParameters() {
return idata.argsHasDefaults;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ private void init() {
boolean[] argIsConst;
int argCount;
boolean argsHasRest;
boolean argsHasDefaults;

int itsMaxCalleeArgs;

Expand Down
3 changes: 2 additions & 1 deletion rhino/src/main/java/org/mozilla/javascript/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ public class Node implements Iterable<Node> {
ARROW_FUNCTION_PROP = 26,
TEMPLATE_LITERAL_PROP = 27,
TRAILING_COMMA = 28,
LAST_PROP = 28;
OBJECT_LITERAL_DESTRUCTURING = 29,
LAST_PROP = 29;

// 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
Loading
Loading