mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-30 12:27:29 +09:00
Issue #2142 - Factor out PropertyName parsing from Parser::propertyName()
Based-on: m-c 1529772/{1,2}
This commit is contained in:
parent
235ca77949
commit
014953c532
2 changed files with 126 additions and 115 deletions
|
|
@ -4469,7 +4469,8 @@ Parser<ParseHandler>::objectBindingPattern(DeclarationKind kind, YieldHandling y
|
||||||
TokenPos namePos = tokenStream.nextToken().pos;
|
TokenPos namePos = tokenStream.nextToken().pos;
|
||||||
|
|
||||||
PropertyType propType;
|
PropertyType propType;
|
||||||
Node propName = propertyName(yieldHandling, PropertyNameInPattern, declKind, literal, &propType, &propAtom);
|
Node propName = propertyOrMethodName(yieldHandling, PropertyNameInPattern, declKind,
|
||||||
|
literal, &propType, &propAtom);
|
||||||
if (!propName)
|
if (!propName)
|
||||||
return null();
|
return null();
|
||||||
if (propType == PropertyType::Normal) {
|
if (propType == PropertyType::Normal) {
|
||||||
|
|
@ -7452,7 +7453,8 @@ Parser<ParseHandler>::classMember(YieldHandling yieldHandling, DefaultHandling d
|
||||||
|
|
||||||
RootedAtom propAtom(context);
|
RootedAtom propAtom(context);
|
||||||
PropertyType propType;
|
PropertyType propType;
|
||||||
Node propName = propertyName(yieldHandling, PropertyNameInClass, /* maybeDecl = */ Nothing(),
|
Node propName = propertyOrMethodName(yieldHandling, PropertyNameInClass,
|
||||||
|
/* maybeDecl = */ Nothing(),
|
||||||
classMembers, &propType, &propAtom);
|
classMembers, &propType, &propAtom);
|
||||||
if (!propName)
|
if (!propName)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -10559,25 +10561,9 @@ typename ParseHandler::Node
|
||||||
Parser<ParseHandler>::propertyName(YieldHandling yieldHandling,
|
Parser<ParseHandler>::propertyName(YieldHandling yieldHandling,
|
||||||
PropertyNameContext propertyNameContext,
|
PropertyNameContext propertyNameContext,
|
||||||
const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
|
const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
|
||||||
PropertyType* propType, MutableHandleAtom propAtom)
|
MutableHandleAtom propAtom)
|
||||||
{
|
{
|
||||||
TokenKind ltok;
|
// PropertyName[Yield, Await]:
|
||||||
if (!tokenStream.getToken(<ok))
|
|
||||||
return null();
|
|
||||||
|
|
||||||
MOZ_ASSERT(ltok != TOK_RC, "caller should have handled TOK_RC");
|
|
||||||
|
|
||||||
bool isGenerator = false;
|
|
||||||
bool isAsync = false;
|
|
||||||
|
|
||||||
if (ltok == TOK_ASYNC) {
|
|
||||||
// AsyncMethod[Yield, Await]:
|
|
||||||
// async [no LineTerminator here] PropertyName[?Yield, ?Await] ...
|
|
||||||
//
|
|
||||||
// AsyncGeneratorMethod[Yield, Await]:
|
|
||||||
// async [no LineTerminator here] * PropertyName[?Yield, ?Await] ...
|
|
||||||
//
|
|
||||||
// PropertyName:
|
|
||||||
// LiteralPropertyName
|
// LiteralPropertyName
|
||||||
// ComputedPropertyName[?Yield, ?Await]
|
// ComputedPropertyName[?Yield, ?Await]
|
||||||
//
|
//
|
||||||
|
|
@ -10585,14 +10571,106 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling,
|
||||||
// IdentifierName
|
// IdentifierName
|
||||||
// StringLiteral
|
// StringLiteral
|
||||||
// NumericLiteral
|
// NumericLiteral
|
||||||
|
TokenKind ltok = tokenStream.currentToken().type;
|
||||||
|
|
||||||
|
propAtom.set(nullptr);
|
||||||
|
switch (ltok) {
|
||||||
|
case TOK_NUMBER:
|
||||||
|
propAtom.set(DoubleToAtom(context, tokenStream.currentToken().number()));
|
||||||
|
if (!propAtom.get())
|
||||||
|
return null();
|
||||||
|
return newNumber(tokenStream.currentToken());
|
||||||
|
|
||||||
|
case TOK_STRING: {
|
||||||
|
propAtom.set(tokenStream.currentToken().atom());
|
||||||
|
uint32_t index;
|
||||||
|
if (propAtom->isIndex(&index)) {
|
||||||
|
return handler.newNumber(index, NoDecimal, pos());
|
||||||
|
}
|
||||||
|
return stringLiteral();
|
||||||
|
}
|
||||||
|
|
||||||
|
case TOK_LB:
|
||||||
|
return computedPropertyName(yieldHandling, maybeDecl, propList);
|
||||||
|
|
||||||
|
default: {
|
||||||
|
if (!TokenKindIsPossibleIdentifierName(ltok)) {
|
||||||
|
error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(ltok));
|
||||||
|
return null();
|
||||||
|
}
|
||||||
|
|
||||||
|
propAtom.set(tokenStream.currentName());
|
||||||
|
return handler.newObjectLiteralPropertyName(propAtom, pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// True if `kind` can be the first token of a PropertyName.
|
||||||
|
static bool
|
||||||
|
TokenKindCanStartPropertyName(TokenKind tt)
|
||||||
|
{
|
||||||
|
return TokenKindIsPossibleIdentifierName(tt) || tt == TOK_STRING ||
|
||||||
|
tt == TOK_NUMBER || tt == TOK_LB ||
|
||||||
|
tt == TOK_MUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ParseHandler>
|
||||||
|
typename ParseHandler::Node
|
||||||
|
Parser<ParseHandler>::propertyOrMethodName(YieldHandling yieldHandling,
|
||||||
|
PropertyNameContext propertyNameContext,
|
||||||
|
const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
|
||||||
|
PropertyType* propType, MutableHandleAtom propAtom)
|
||||||
|
{
|
||||||
|
// We're parsing an object literal, class, or destructuring pattern;
|
||||||
|
// propertyNameContext tells which one. This method parses any of the
|
||||||
|
// following, storing the corresponding PropertyType in `*propType` to tell
|
||||||
|
// the caller what we parsed:
|
||||||
//
|
//
|
||||||
// ComputedPropertyName[Yield, Await]:
|
// async [no LineTerminator here] PropertyName
|
||||||
// [ ...
|
// ==> PropertyType::AsyncMethod
|
||||||
|
// async [no LineTerminator here] * PropertyName
|
||||||
|
// ==> PropertyType::AsyncGeneratorMethod
|
||||||
|
// * PropertyName ==> PropertyType::GeneratorMethod
|
||||||
|
// get PropertyName ==> PropertyType::Getter
|
||||||
|
// set PropertyName ==> PropertyType::Setter
|
||||||
|
// PropertyName : ==> PropertyType::Normal
|
||||||
|
// PropertyName ==> see below
|
||||||
|
//
|
||||||
|
// In the last case, where there's not a `:` token to consume, we peek at
|
||||||
|
// (but don't consume) the next token to decide how to set `*propType`.
|
||||||
|
//
|
||||||
|
// `=` or `;` ==> PropertyType::Field (classes only)
|
||||||
|
// `=` ==> PropertyType::CoverInitializedName
|
||||||
|
// `,` or `}` ==> PropertyType::Shorthand
|
||||||
|
// `(` ==> PropertyType::Method
|
||||||
|
//
|
||||||
|
// The caller must check `*propType` and throw if whatever we parsed isn't
|
||||||
|
// allowed here (for example, a getter in a destructuring pattern).
|
||||||
|
//
|
||||||
|
// This method does *not* match `static` (allowed in classes) or `...`
|
||||||
|
// (allowed in object literals and patterns). The caller must take care of
|
||||||
|
// those before calling this method.
|
||||||
|
|
||||||
|
TokenKind ltok;
|
||||||
|
if (!tokenStream.getToken(<ok))
|
||||||
|
return null();
|
||||||
|
|
||||||
|
MOZ_ASSERT(ltok != TOK_RC, "caller should have handled TOK_RC");
|
||||||
|
|
||||||
|
// Accept `async` and/or `*`, indicating an async or generator method;
|
||||||
|
// or `get` or `set`, indicating an accessor.
|
||||||
|
bool isGenerator = false;
|
||||||
|
bool isAsync = false;
|
||||||
|
bool isGetter = false;
|
||||||
|
bool isSetter = false;
|
||||||
|
|
||||||
|
if (ltok == TOK_ASYNC) {
|
||||||
|
// `async` is also a PropertyName by itself (it's a conditional keyword),
|
||||||
|
// so peek at the next token to see if we're really looking at a method.
|
||||||
TokenKind tt = TOK_EOF;
|
TokenKind tt = TOK_EOF;
|
||||||
if (!tokenStream.peekTokenSameLine(&tt))
|
if (!tokenStream.peekTokenSameLine(&tt))
|
||||||
return null();
|
return null();
|
||||||
if (tt == TOK_STRING || tt == TOK_NUMBER || tt == TOK_LB ||
|
if (TokenKindCanStartPropertyName(tt))
|
||||||
TokenKindIsPossibleIdentifierName(tt) || tt == TOK_MUL)
|
|
||||||
{
|
{
|
||||||
isAsync = true;
|
isAsync = true;
|
||||||
tokenStream.consumeKnownToken(tt);
|
tokenStream.consumeKnownToken(tt);
|
||||||
|
|
@ -10606,109 +10684,33 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling,
|
||||||
return null();
|
return null();
|
||||||
}
|
}
|
||||||
|
|
||||||
propAtom.set(nullptr);
|
if (!isAsync && !isGenerator &&
|
||||||
Node propName;
|
(ltok == TOK_GET || ltok == TOK_SET)) {
|
||||||
switch (ltok) {
|
|
||||||
case TOK_NUMBER:
|
|
||||||
propAtom.set(DoubleToAtom(context, tokenStream.currentToken().number()));
|
|
||||||
if (!propAtom.get())
|
|
||||||
return null();
|
|
||||||
propName = newNumber(tokenStream.currentToken());
|
|
||||||
if (!propName)
|
|
||||||
return null();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TOK_STRING: {
|
|
||||||
propAtom.set(tokenStream.currentToken().atom());
|
|
||||||
uint32_t index;
|
|
||||||
if (propAtom->isIndex(&index)) {
|
|
||||||
propName = handler.newNumber(index, NoDecimal, pos());
|
|
||||||
if (!propName)
|
|
||||||
return null();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
propName = stringLiteral();
|
|
||||||
if (!propName)
|
|
||||||
return null();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case TOK_LB:
|
|
||||||
propName = computedPropertyName(yieldHandling, maybeDecl, propList);
|
|
||||||
if (!propName)
|
|
||||||
return null();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: {
|
|
||||||
if (!TokenKindIsPossibleIdentifierName(ltok)) {
|
|
||||||
error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(ltok));
|
|
||||||
return null();
|
|
||||||
}
|
|
||||||
|
|
||||||
propAtom.set(tokenStream.currentName());
|
|
||||||
// Do not look for accessor syntax on generator or async methods.
|
|
||||||
if (isGenerator || isAsync || !(ltok == TOK_GET || ltok == TOK_SET)) {
|
|
||||||
propName = handler.newObjectLiteralPropertyName(propAtom, pos());
|
|
||||||
if (!propName)
|
|
||||||
return null();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*propType = ltok == TOK_GET ? PropertyType::Getter : PropertyType::Setter;
|
|
||||||
|
|
||||||
// We have parsed |get| or |set|. Look for an accessor property
|
// We have parsed |get| or |set|. Look for an accessor property
|
||||||
// name next.
|
// name next.
|
||||||
TokenKind tt;
|
TokenKind tt;
|
||||||
if (!tokenStream.peekToken(&tt))
|
if (!tokenStream.peekToken(&tt))
|
||||||
return null();
|
return null();
|
||||||
if (TokenKindIsPossibleIdentifierName(tt)) {
|
if (TokenKindCanStartPropertyName(tt)) {
|
||||||
tokenStream.consumeKnownToken(tt);
|
tokenStream.consumeKnownToken(tt);
|
||||||
|
isGetter = (ltok == TOK_GET);
|
||||||
propAtom.set(tokenStream.currentName());
|
isSetter = (ltok == TOK_SET);
|
||||||
return handler.newObjectLiteralPropertyName(propAtom, pos());
|
|
||||||
}
|
}
|
||||||
if (tt == TOK_STRING) {
|
|
||||||
tokenStream.consumeKnownToken(TOK_STRING);
|
|
||||||
|
|
||||||
propAtom.set(tokenStream.currentToken().atom());
|
|
||||||
|
|
||||||
uint32_t index;
|
|
||||||
if (propAtom->isIndex(&index)) {
|
|
||||||
propAtom.set(DoubleToAtom(context, index));
|
|
||||||
if (!propAtom.get())
|
|
||||||
return null();
|
|
||||||
return handler.newNumber(index, NoDecimal, pos());
|
|
||||||
}
|
|
||||||
return stringLiteral();
|
|
||||||
}
|
|
||||||
if (tt == TOK_NUMBER) {
|
|
||||||
tokenStream.consumeKnownToken(TOK_NUMBER);
|
|
||||||
|
|
||||||
propAtom.set(DoubleToAtom(context, tokenStream.currentToken().number()));
|
|
||||||
if (!propAtom.get())
|
|
||||||
return null();
|
|
||||||
return newNumber(tokenStream.currentToken());
|
|
||||||
}
|
|
||||||
if (tt == TOK_LB) {
|
|
||||||
tokenStream.consumeKnownToken(TOK_LB);
|
|
||||||
|
|
||||||
return computedPropertyName(yieldHandling, maybeDecl, propList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not an accessor property after all.
|
Node propName = propertyName(yieldHandling, propertyNameContext, maybeDecl,
|
||||||
propName = handler.newObjectLiteralPropertyName(propAtom.get(), pos());
|
propList, propAtom);
|
||||||
if (!propName)
|
if (!propName)
|
||||||
return null();
|
return null();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Grab the next token following the property/method name.
|
||||||
|
// (If this isn't a colon, we're going to either put it back or throw.)
|
||||||
TokenKind tt;
|
TokenKind tt;
|
||||||
if (!tokenStream.getToken(&tt))
|
if (!tokenStream.getToken(&tt))
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
if (tt == TOK_COLON) {
|
if (tt == TOK_COLON) {
|
||||||
if (isGenerator || isAsync) {
|
if (isGenerator || isAsync || isGetter || isSetter) {
|
||||||
error(JSMSG_BAD_PROP_ID);
|
error(JSMSG_BAD_PROP_ID);
|
||||||
return null();
|
return null();
|
||||||
}
|
}
|
||||||
|
|
@ -10717,7 +10719,7 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propertyNameContext == PropertyNameInClass && (tt == TOK_SEMI || tt == TOK_ASSIGN)) {
|
if (propertyNameContext == PropertyNameInClass && (tt == TOK_SEMI || tt == TOK_ASSIGN)) {
|
||||||
if (isGenerator || isAsync) {
|
if (isGenerator || isAsync || isGetter || isSetter) {
|
||||||
error(JSMSG_BAD_PROP_ID);
|
error(JSMSG_BAD_PROP_ID);
|
||||||
return null();
|
return null();
|
||||||
}
|
}
|
||||||
|
|
@ -10729,7 +10731,7 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling,
|
||||||
if (TokenKindIsPossibleIdentifierName(ltok) &&
|
if (TokenKindIsPossibleIdentifierName(ltok) &&
|
||||||
(tt == TOK_COMMA || tt == TOK_RC || tt == TOK_ASSIGN))
|
(tt == TOK_COMMA || tt == TOK_RC || tt == TOK_ASSIGN))
|
||||||
{
|
{
|
||||||
if (isGenerator || isAsync) {
|
if (isGenerator || isAsync || isGetter || isSetter) {
|
||||||
error(JSMSG_BAD_PROP_ID);
|
error(JSMSG_BAD_PROP_ID);
|
||||||
return null();
|
return null();
|
||||||
}
|
}
|
||||||
|
|
@ -10748,6 +10750,10 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling,
|
||||||
*propType = PropertyType::GeneratorMethod;
|
*propType = PropertyType::GeneratorMethod;
|
||||||
else if (isAsync)
|
else if (isAsync)
|
||||||
*propType = PropertyType::AsyncMethod;
|
*propType = PropertyType::AsyncMethod;
|
||||||
|
else if (isGetter)
|
||||||
|
*propType = PropertyType::Getter;
|
||||||
|
else if (isSetter)
|
||||||
|
*propType = PropertyType::Setter;
|
||||||
else
|
else
|
||||||
*propType = PropertyType::Method;
|
*propType = PropertyType::Method;
|
||||||
return propName;
|
return propName;
|
||||||
|
|
@ -10826,7 +10832,8 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError*
|
||||||
TokenPos namePos = tokenStream.nextToken().pos;
|
TokenPos namePos = tokenStream.nextToken().pos;
|
||||||
|
|
||||||
PropertyType propType;
|
PropertyType propType;
|
||||||
Node propName = propertyName(yieldHandling, PropertyNameInLiteral, declKind, literal, &propType, &propAtom);
|
Node propName = propertyOrMethodName(yieldHandling, PropertyNameInLiteral, declKind,
|
||||||
|
literal, &propType, &propAtom);
|
||||||
if (!propName)
|
if (!propName)
|
||||||
|
|
||||||
return null();
|
return null();
|
||||||
|
|
|
||||||
|
|
@ -1627,6 +1627,10 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
||||||
|
|
||||||
enum PropertyNameContext { PropertyNameInLiteral, PropertyNameInPattern, PropertyNameInClass };
|
enum PropertyNameContext { PropertyNameInLiteral, PropertyNameInPattern, PropertyNameInClass };
|
||||||
Node propertyName(YieldHandling yieldHandling,
|
Node propertyName(YieldHandling yieldHandling,
|
||||||
|
PropertyNameContext propertyNameContext,
|
||||||
|
const mozilla::Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
|
||||||
|
MutableHandleAtom propAtom);
|
||||||
|
Node propertyOrMethodName(YieldHandling yieldHandling,
|
||||||
PropertyNameContext propertyNameContext,
|
PropertyNameContext propertyNameContext,
|
||||||
const mozilla::Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
|
const mozilla::Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
|
||||||
PropertyType* propType, MutableHandleAtom propAtom);
|
PropertyType* propType, MutableHandleAtom propAtom);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue