1339395 - Part 2: Add parser support for rest and spread object properties.

This commit is contained in:
Gaming4JC 2019-07-14 16:37:57 -04:00 committed by Roy Tam
commit 85350c0655
5 changed files with 73 additions and 6 deletions

View file

@ -3222,6 +3222,8 @@ ASTSerializer::property(ParseNode* pn, MutableHandleValue dst)
return expression(pn->pn_kid, &val) &&
builder.prototypeMutation(val, &pn->pn_pos, dst);
}
if (pn->isKind(PNK_SPREAD))
return expression(pn, dst);
PropKind kind;
switch (pn->getOp()) {
@ -3342,6 +3344,16 @@ ASTSerializer::objectPattern(ParseNode* pn, MutableHandleValue dst)
return false;
for (ParseNode* propdef = pn->pn_head; propdef; propdef = propdef->pn_next) {
if (propdef->isKind(PNK_SPREAD)) {
RootedValue target(cx);
RootedValue spread(cx);
if (!pattern(propdef->pn_kid, &target))
return false;
if(!builder.spreadExpression(target, &propdef->pn_pos, &spread))
return false;
elts.infallibleAppend(spread);
continue;
}
LOCAL_ASSERT(propdef->isKind(PNK_MUTATEPROTO) != propdef->isOp(JSOP_INITPROP));
RootedValue key(cx);

View file

@ -5815,6 +5815,11 @@ BytecodeEmitter::emitDestructuringOpsObject(ParseNode* pattern, DestructuringFla
return false;
for (ParseNode* member = pattern->pn_head; member; member = member->pn_next) {
if (member->isKind(PNK_SPREAD)) {
// FIXME: Implement
continue;
}
ParseNode* subpattern;
if (member->isKind(PNK_MUTATEPROTO))
subpattern = member->pn_kid;
@ -9449,6 +9454,13 @@ BytecodeEmitter::emitPropertyList(ParseNode* pn, MutableHandlePlainObject objp,
continue;
}
if (propdef->isKind(PNK_SPREAD)) {
MOZ_ASSERT(type == ObjectLiteral);
objp.set(nullptr);
// FIXME: implement
continue;
}
bool extraPop = false;
if (type == ClassBody && propdef->as<ClassMethod>().isStatic()) {
extraPop = true;

View file

@ -395,6 +395,18 @@ class FullParseHandler
return true;
}
MOZ_MUST_USE bool addSpreadProperty(ParseNode* literal, uint32_t begin, ParseNode* inner) {
MOZ_ASSERT(literal->isKind(PNK_OBJECT));
MOZ_ASSERT(literal->isArity(PN_LIST));
setListFlag(literal, PNX_NONCONST);
ParseNode* spread = newSpread(begin, inner);
if (!spread)
return false;
literal->append(spread);
return true;
}
MOZ_MUST_USE bool addObjectMethodDefinition(ParseNode* literal, ParseNode* key, ParseNode* fn,
JSOp op)
{

View file

@ -4367,9 +4367,20 @@ Parser<ParseHandler>::objectBindingPattern(DeclarationKind kind, YieldHandling y
break;
if (tt == TOK_TRIPLEDOT) {
// TODO: rest-binding property
error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(tt));
return null();
// rest-binding property
tokenStream.consumeKnownToken(TOK_TRIPLEDOT);
uint32_t begin = pos().begin;
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
Node inner = bindingIdentifierOrPattern(kind, yieldHandling, tt);
if (!inner)
return null();
if (!handler.addSpreadProperty(literal, begin, inner))
return null();
} else {
TokenPos namePos = tokenStream.nextToken().pos;
@ -4439,6 +4450,10 @@ Parser<ParseHandler>::objectBindingPattern(DeclarationKind kind, YieldHandling y
return null();
if (!matched)
break;
if (tt == TOK_TRIPLEDOT) {
error(JSMSG_REST_WITH_COMMA);
return null();
}
}
MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::None,
@ -9693,9 +9708,22 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError*
break;
if (tt == TOK_TRIPLEDOT) {
// TODO: object spread
error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(tt));
return null();
// object spread
tokenStream.consumeKnownToken(TOK_TRIPLEDOT);
uint32_t begin = pos().begin;
TokenPos innerPos;
if (!tokenStream.peekTokenPos(&innerPos, TokenStream::Operand))
return null();
Node inner = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
possibleError);
if (!inner)
return null();
if (possibleError)
checkDestructuringAssignmentTarget(inner, innerPos, possibleError);
if (!handler.addSpreadProperty(literal, begin, inner))
return null();
} else {
TokenPos namePos = tokenStream.nextToken().pos;
@ -9860,6 +9888,8 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError*
return null();
if (!matched)
break;
if (tt == TOK_TRIPLEDOT && possibleError)
possibleError->setPendingDestructuringErrorAt(pos(), JSMSG_REST_WITH_COMMA);
}
MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::None,

View file

@ -298,6 +298,7 @@ class SyntaxParseHandler
MOZ_MUST_USE bool addPrototypeMutation(Node literal, uint32_t begin, Node expr) { return true; }
MOZ_MUST_USE bool addPropertyDefinition(Node literal, Node name, Node expr) { return true; }
MOZ_MUST_USE bool addShorthand(Node literal, Node name, Node expr) { return true; }
MOZ_MUST_USE bool addSpreadProperty(Node literal, uint32_t begin, Node inner) { return true; }
MOZ_MUST_USE bool addObjectMethodDefinition(Node literal, Node name, Node fn, JSOp op) { return true; }
MOZ_MUST_USE bool addClassMethodDefinition(Node literal, Node name, Node fn, JSOp op, bool isStatic) { return true; }
Node newYieldExpression(uint32_t begin, Node value, Node gen) { return NodeGeneric; }