summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklinDM <mrmineshafter17@gmail.com>2022-04-27 23:57:55 +0800
committerFranklinDM <mrmineshafter17@gmail.com>2022-05-04 14:57:16 +0800
commit9ecfdbe358f2f72ea65a36a68473d71016f68d74 (patch)
tree6c187864ec785cf480e4563aa5bc0679c7d051ca
parent97dcd8009ae0b59355c5a9022fa6273825d5010d (diff)
downloaduxp-9ecfdbe358f2f72ea65a36a68473d71016f68d74.tar.gz
Issue #1658 - Part 3: Implement support for optional chaining in JS reflection
Partially based on: Bug 1610447 - Update Reflect to handle Optional Chaining operator Bug 1657835 - Assertion failure: false, at js/src/builtin/ReflectParse.cpp:3168
-rw-r--r--js/src/builtin/ReflectParse.cpp85
-rw-r--r--js/src/jsast.tbl4
2 files changed, 72 insertions, 17 deletions
diff --git a/js/src/builtin/ReflectParse.cpp b/js/src/builtin/ReflectParse.cpp
index 65bd16b270..7b230b07a0 100644
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -576,10 +576,11 @@ class NodeBuilder
MutableHandleValue dst);
MOZ_MUST_USE bool callExpression(HandleValue callee, NodeVector& args, TokenPos* pos,
- MutableHandleValue dst);
+ MutableHandleValue dst, bool isOptional = false);
MOZ_MUST_USE bool memberExpression(bool computed, HandleValue expr, HandleValue member,
- TokenPos* pos, MutableHandleValue dst);
+ TokenPos* pos, MutableHandleValue dst,
+ bool isOptional = false);
MOZ_MUST_USE bool arrayExpression(NodeVector& elts, TokenPos* pos, MutableHandleValue dst);
@@ -593,6 +594,11 @@ class NodeBuilder
MOZ_MUST_USE bool spreadExpression(HandleValue expr, TokenPos* pos, MutableHandleValue dst);
+ MOZ_MUST_USE bool optionalExpression(HandleValue expr, TokenPos* pos, MutableHandleValue dst);
+
+ MOZ_MUST_USE bool deleteOptionalExpression(HandleValue expr, TokenPos* pos,
+ MutableHandleValue dst);
+
MOZ_MUST_USE bool computedName(HandleValue name, TokenPos* pos, MutableHandleValue dst);
MOZ_MUST_USE bool objectExpression(NodeVector& elts, TokenPos* pos, MutableHandleValue dst);
@@ -1121,7 +1127,7 @@ NodeBuilder::sequenceExpression(NodeVector& elts, TokenPos* pos, MutableHandleVa
bool
NodeBuilder::callExpression(HandleValue callee, NodeVector& args, TokenPos* pos,
- MutableHandleValue dst)
+ MutableHandleValue dst, bool isOptional)
{
RootedValue array(cx);
if (!newArray(args, &array))
@@ -1131,9 +1137,12 @@ NodeBuilder::callExpression(HandleValue callee, NodeVector& args, TokenPos* pos,
if (!cb.isNull())
return callback(cb, callee, array, pos, dst);
- return newNode(AST_CALL_EXPR, pos,
- "callee", callee,
- "arguments", array,
+ return newNode(isOptional ? AST_OPT_CALL_EXPR : AST_CALL_EXPR,
+ pos,
+ "callee",
+ callee,
+ "arguments",
+ array,
dst);
}
@@ -1157,7 +1166,7 @@ NodeBuilder::newExpression(HandleValue callee, NodeVector& args, TokenPos* pos,
bool
NodeBuilder::memberExpression(bool computed, HandleValue expr, HandleValue member, TokenPos* pos,
- MutableHandleValue dst)
+ MutableHandleValue dst, bool isOptional)
{
RootedValue computedVal(cx, BooleanValue(computed));
@@ -1165,10 +1174,14 @@ NodeBuilder::memberExpression(bool computed, HandleValue expr, HandleValue membe
if (!cb.isNull())
return callback(cb, computedVal, expr, member, pos, dst);
- return newNode(AST_MEMBER_EXPR, pos,
- "object", expr,
- "property", member,
- "computed", computedVal,
+ return newNode(isOptional ? AST_OPT_MEMBER_EXPR : AST_MEMBER_EXPR,
+ pos,
+ "object",
+ expr,
+ "property",
+ member,
+ "computed",
+ computedVal,
dst);
}
@@ -1232,6 +1245,22 @@ NodeBuilder::spreadExpression(HandleValue expr, TokenPos* pos, MutableHandleValu
}
bool
+NodeBuilder::optionalExpression(HandleValue expr, TokenPos* pos, MutableHandleValue dst)
+{
+ return newNode(AST_OPTIONAL_EXPR, pos,
+ "expression", expr,
+ dst);
+}
+
+bool
+NodeBuilder::deleteOptionalExpression(HandleValue expr, TokenPos* pos, MutableHandleValue dst)
+{
+ return newNode(AST_DELETE_OPTIONAL_EXPR, pos,
+ "expression", expr,
+ dst);
+}
+
+bool
NodeBuilder::propertyPattern(HandleValue key, HandleValue patt, bool isShorthand, TokenPos* pos,
MutableHandleValue dst)
{
@@ -2950,9 +2979,22 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
case PNK_GENEXP:
return generatorExpression(pn->generatorExpr(), dst);
+ case PNK_DELETEOPTCHAIN: {
+ RootedValue expr(cx);
+ return expression(pn->pn_kid, &expr) &&
+ builder.deleteOptionalExpression(expr, &pn->pn_pos, dst);
+ }
+
+ case PNK_OPTCHAIN: {
+ RootedValue expr(cx);
+ return expression(pn->pn_kid, &expr) &&
+ builder.optionalExpression(expr, &pn->pn_pos, dst);
+ }
+
case PNK_NEW:
case PNK_TAGGED_TEMPLATE:
case PNK_CALL:
+ case PNK_OPTCALL:
case PNK_SUPERCALL:
{
ParseNode* next = pn->pn_head;
@@ -2984,13 +3026,15 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
if (pn->getKind() == PNK_TAGGED_TEMPLATE)
return builder.taggedTemplate(callee, args, &pn->pn_pos, dst);
+ bool isOptional = pn->isKind(PNK_OPTCALL);
+
// SUPERCALL is Call(super, args)
return pn->isKind(PNK_NEW)
? builder.newExpression(callee, args, &pn->pn_pos, dst)
-
- : builder.callExpression(callee, args, &pn->pn_pos, dst);
+ : builder.callExpression(callee, args, &pn->pn_pos, dst, isOptional);
}
+ case PNK_OPTDOT:
case PNK_DOT:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_expr->pn_pos));
@@ -2999,7 +3043,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
RootedValue propname(cx);
RootedAtom pnAtom(cx, pn->pn_atom);
- if (pn->as<PropertyAccess>().isSuper()) {
+ if (pn->as<PropertyAccessBase>().isSuper()) {
if (!builder.super(&pn->pn_expr->pn_pos, &expr))
return false;
} else {
@@ -3007,10 +3051,14 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
return false;
}
+ bool isOptional = pn->isKind(PNK_OPTDOT);
+
return identifier(pnAtom, nullptr, &propname) &&
- builder.memberExpression(false, expr, propname, &pn->pn_pos, dst);
+ builder.memberExpression(false, expr, propname, &pn->pn_pos,
+ dst, isOptional);
}
+ case PNK_OPTELEM:
case PNK_ELEM:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
@@ -3018,7 +3066,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
RootedValue left(cx), right(cx);
- if (pn->as<PropertyByValue>().isSuper()) {
+ if (pn->as<PropertyByValueBase>().isSuper()) {
if (!builder.super(&pn->pn_left->pn_pos, &left))
return false;
} else {
@@ -3026,8 +3074,11 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
return false;
}
+ bool isOptional = pn->isKind(PNK_OPTELEM);
+
return expression(pn->pn_right, &right) &&
- builder.memberExpression(true, left, right, &pn->pn_pos, dst);
+ builder.memberExpression(true, left, right, &pn->pn_pos, dst,
+ isOptional);
}
case PNK_CALLSITEOBJ:
diff --git a/js/src/jsast.tbl b/js/src/jsast.tbl
index a83ad74c6a..a50e31d7ba 100644
--- a/js/src/jsast.tbl
+++ b/js/src/jsast.tbl
@@ -27,10 +27,14 @@ ASTDEF(AST_LOGICAL_EXPR, "LogicalExpression", "logicalExpr
ASTDEF(AST_UPDATE_EXPR, "UpdateExpression", "updateExpression")
ASTDEF(AST_NEW_EXPR, "NewExpression", "newExpression")
ASTDEF(AST_CALL_EXPR, "CallExpression", "callExpression")
+ASTDEF(AST_OPT_CALL_EXPR, "OptionalCallExpression", "optionalCallExpression")
ASTDEF(AST_MEMBER_EXPR, "MemberExpression", "memberExpression")
+ASTDEF(AST_OPT_MEMBER_EXPR, "OptionalMemberExpression", "optionalMemberExpression")
ASTDEF(AST_FUNC_EXPR, "FunctionExpression", "functionExpression")
ASTDEF(AST_ARROW_EXPR, "ArrowFunctionExpression", "arrowFunctionExpression")
ASTDEF(AST_ARRAY_EXPR, "ArrayExpression", "arrayExpression")
+ASTDEF(AST_DELETE_OPTIONAL_EXPR, "DeleteOptionalExpression", "deleteOptionalExpression")
+ASTDEF(AST_OPTIONAL_EXPR, "OptionalExpression", "optionalExpression")
ASTDEF(AST_SPREAD_EXPR, "SpreadExpression", "spreadExpression")
ASTDEF(AST_OBJECT_EXPR, "ObjectExpression", "objectExpression")
ASTDEF(AST_THIS_EXPR, "ThisExpression", "thisExpression")