зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1303703 - Part 2: Clean-up bits of destructuring parsing which are no longer needed. r=shu
--HG-- extra : rebase_source : dd040437e34804224a343dc4560fd91155b06833
This commit is contained in:
Родитель
3eb0058955
Коммит
2165b6d8c2
|
@ -4414,20 +4414,6 @@ Parser<FullParseHandler, char16_t>::checkDestructuringAssignmentArray(ParseNode*
|
|||
* In the first case, other code parses the pattern as an arbitrary
|
||||
* primaryExpr, and then, here in checkDestructuringAssignmentPattern, verify
|
||||
* that the tree is a valid AssignmentPattern.
|
||||
*
|
||||
* In assignment-like contexts, we parse the pattern with
|
||||
* pc->inDestructuringDecl clear, so the lvalue expressions in the pattern are
|
||||
* parsed normally. identifierReference() links variable references into the
|
||||
* appropriate use chains; creates placeholder definitions; and so on.
|
||||
* checkDestructuringAssignmentPattern won't bind any new names and we
|
||||
* specialize lvalues as appropriate.
|
||||
*
|
||||
* In declaration-like contexts, the normal variable reference processing
|
||||
* would just be an obstruction, because we're going to define the names that
|
||||
* appear in the property value positions as new variables anyway. In this
|
||||
* case, we parse the pattern in destructuringDeclaration() with
|
||||
* pc->inDestructuringDecl set, which directs identifierReference() to leave
|
||||
* whatever name nodes it creates unconnected.
|
||||
*/
|
||||
template <>
|
||||
bool
|
||||
|
@ -4450,39 +4436,19 @@ Parser<FullParseHandler, char16_t>::checkDestructuringAssignmentPattern(ParseNod
|
|||
return isDestructuring;
|
||||
}
|
||||
|
||||
class AutoClearInDestructuringDecl
|
||||
{
|
||||
ParseContext* pc_;
|
||||
Maybe<DeclarationKind> saved_;
|
||||
|
||||
public:
|
||||
explicit AutoClearInDestructuringDecl(ParseContext* pc)
|
||||
: pc_(pc),
|
||||
saved_(pc->inDestructuringDecl)
|
||||
{
|
||||
pc->inDestructuringDecl = Nothing();
|
||||
if (saved_ && *saved_ == DeclarationKind::FormalParameter)
|
||||
pc->functionBox()->hasParameterExprs = true;
|
||||
}
|
||||
|
||||
~AutoClearInDestructuringDecl() {
|
||||
pc_->inDestructuringDecl = saved_;
|
||||
}
|
||||
};
|
||||
|
||||
template <template <typename CharT> class ParseHandler, typename CharT>
|
||||
typename ParseHandler<CharT>::Node
|
||||
Parser<ParseHandler, CharT>::bindingInitializer(Node lhs, YieldHandling yieldHandling)
|
||||
Parser<ParseHandler, CharT>::bindingInitializer(Node lhs, DeclarationKind kind,
|
||||
YieldHandling yieldHandling)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_ASSIGN));
|
||||
|
||||
Node rhs;
|
||||
{
|
||||
AutoClearInDestructuringDecl autoClear(pc);
|
||||
rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
if (kind == DeclarationKind::FormalParameter)
|
||||
pc->functionBox()->hasParameterExprs = true;
|
||||
|
||||
Node rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
if (!rhs)
|
||||
return null();
|
||||
}
|
||||
|
||||
handler.checkAndSetIsDirectRHSAnonFunction(rhs);
|
||||
|
||||
|
@ -4500,7 +4466,7 @@ template <template <typename CharT> class ParseHandler, typename CharT>
|
|||
typename ParseHandler<CharT>::Node
|
||||
Parser<ParseHandler, CharT>::bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling)
|
||||
{
|
||||
Rooted<PropertyName*> name(context, bindingIdentifier(yieldHandling));
|
||||
RootedPropertyName name(context, bindingIdentifier(yieldHandling));
|
||||
if (!name)
|
||||
return null();
|
||||
|
||||
|
@ -4545,6 +4511,7 @@ Parser<ParseHandler, CharT>::objectBindingPattern(DeclarationKind kind,
|
|||
if (!literal)
|
||||
return null();
|
||||
|
||||
Maybe<DeclarationKind> declKind = Some(kind);
|
||||
RootedAtom propAtom(context);
|
||||
for (;;) {
|
||||
TokenKind tt;
|
||||
|
@ -4558,7 +4525,7 @@ Parser<ParseHandler, CharT>::objectBindingPattern(DeclarationKind kind,
|
|||
tokenStream.ungetToken();
|
||||
|
||||
PropertyType propType;
|
||||
Node propName = propertyName(yieldHandling, literal, &propType, &propAtom);
|
||||
Node propName = propertyName(yieldHandling, declKind, literal, &propType, &propAtom);
|
||||
if (!propName)
|
||||
return null();
|
||||
|
||||
|
@ -4577,7 +4544,7 @@ Parser<ParseHandler, CharT>::objectBindingPattern(DeclarationKind kind,
|
|||
return null();
|
||||
|
||||
Node bindingExpr = hasInitializer
|
||||
? bindingInitializer(binding, yieldHandling)
|
||||
? bindingInitializer(binding, kind, yieldHandling)
|
||||
: binding;
|
||||
if (!bindingExpr)
|
||||
return null();
|
||||
|
@ -4606,7 +4573,7 @@ Parser<ParseHandler, CharT>::objectBindingPattern(DeclarationKind kind,
|
|||
|
||||
tokenStream.consumeKnownToken(TOK_ASSIGN);
|
||||
|
||||
Node bindingExpr = bindingInitializer(binding, yieldHandling);
|
||||
Node bindingExpr = bindingInitializer(binding, kind, yieldHandling);
|
||||
if (!bindingExpr)
|
||||
return null();
|
||||
|
||||
|
@ -4687,7 +4654,9 @@ Parser<ParseHandler, CharT>::arrayBindingPattern(DeclarationKind kind, YieldHand
|
|||
if (!tokenStream.matchToken(&hasInitializer, TOK_ASSIGN))
|
||||
return null();
|
||||
|
||||
Node element = hasInitializer ? bindingInitializer(binding, yieldHandling) : binding;
|
||||
Node element = hasInitializer
|
||||
? bindingInitializer(binding, kind, yieldHandling)
|
||||
: binding;
|
||||
if (!element)
|
||||
return null();
|
||||
|
||||
|
@ -4727,17 +4696,9 @@ Parser<ParseHandler, CharT>::destructuringDeclaration(DeclarationKind kind,
|
|||
MOZ_ASSERT(tokenStream.isCurrentTokenType(tt));
|
||||
MOZ_ASSERT(tt == TOK_LB || tt == TOK_LC);
|
||||
|
||||
Node pattern;
|
||||
{
|
||||
pc->inDestructuringDecl = Some(kind);
|
||||
if (tt == TOK_LB)
|
||||
pattern = arrayBindingPattern(kind, yieldHandling);
|
||||
else
|
||||
pattern = objectBindingPattern(kind, yieldHandling);
|
||||
pc->inDestructuringDecl = Nothing();
|
||||
}
|
||||
|
||||
return pattern;
|
||||
return tt == TOK_LB
|
||||
? arrayBindingPattern(kind, yieldHandling)
|
||||
: objectBindingPattern(kind, yieldHandling);
|
||||
}
|
||||
|
||||
template <template <typename CharT> class ParseHandler, typename CharT>
|
||||
|
@ -7128,14 +7089,10 @@ Parser<ParseHandler, CharT>::tryStatement(YieldHandling yieldHandling)
|
|||
return null();
|
||||
}
|
||||
|
||||
RootedPropertyName param(context, bindingIdentifier(yieldHandling));
|
||||
if (!param)
|
||||
return null();
|
||||
catchName = newName(param);
|
||||
catchName = bindingIdentifier(DeclarationKind::SimpleCatchParameter,
|
||||
yieldHandling);
|
||||
if (!catchName)
|
||||
return null();
|
||||
if (!noteDeclaredName(param, DeclarationKind::SimpleCatchParameter, pos()))
|
||||
return null();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -7364,6 +7321,7 @@ Parser<ParseHandler, CharT>::classDefinition(YieldHandling yieldHandling,
|
|||
if (!classMethods)
|
||||
return null();
|
||||
|
||||
Maybe<DeclarationKind> declKind = Nothing();
|
||||
for (;;) {
|
||||
TokenKind tt;
|
||||
if (!tokenStream.getToken(&tt))
|
||||
|
@ -7397,7 +7355,7 @@ Parser<ParseHandler, CharT>::classDefinition(YieldHandling yieldHandling,
|
|||
return null();
|
||||
|
||||
PropertyType propType;
|
||||
Node propName = propertyName(yieldHandling, classMethods, &propType, &propAtom);
|
||||
Node propName = propertyName(yieldHandling, declKind, classMethods, &propType, &propAtom);
|
||||
if (!propName)
|
||||
return null();
|
||||
|
||||
|
@ -8490,13 +8448,9 @@ Parser<ParseHandler, CharT>::assignExpr(InHandling inHandling, YieldHandling yie
|
|||
if (!possibleErrorInner.checkForExpressionError())
|
||||
return null();
|
||||
|
||||
Node rhs;
|
||||
{
|
||||
AutoClearInDestructuringDecl autoClear(pc);
|
||||
rhs = assignExpr(inHandling, yieldHandling, TripledotProhibited);
|
||||
Node rhs = assignExpr(inHandling, yieldHandling, TripledotProhibited);
|
||||
if (!rhs)
|
||||
return null();
|
||||
}
|
||||
|
||||
if (kind == PNK_ASSIGN)
|
||||
handler.checkAndSetIsDirectRHSAnonFunction(rhs);
|
||||
|
@ -9460,7 +9414,7 @@ Parser<ParseHandler, CharT>::identifierReference(Handle<PropertyName*> name)
|
|||
if (!pn)
|
||||
return null();
|
||||
|
||||
if (!pc->inDestructuringDecl && !noteUsedName(name))
|
||||
if (!noteUsedName(name))
|
||||
return null();
|
||||
|
||||
return pn;
|
||||
|
@ -9611,7 +9565,8 @@ DoubleToAtom(JSContext* cx, double value)
|
|||
|
||||
template <template <typename CharT> class ParseHandler, typename CharT>
|
||||
typename ParseHandler<CharT>::Node
|
||||
Parser<ParseHandler, CharT>::propertyName(YieldHandling yieldHandling, Node propList,
|
||||
Parser<ParseHandler, CharT>::propertyName(YieldHandling yieldHandling,
|
||||
const Maybe<DeclarationKind>& maybeDecl, Node propList,
|
||||
PropertyType* propType, MutableHandleAtom propAtom)
|
||||
{
|
||||
TokenKind ltok;
|
||||
|
@ -9678,7 +9633,7 @@ Parser<ParseHandler, CharT>::propertyName(YieldHandling yieldHandling, Node prop
|
|||
break;
|
||||
|
||||
case TOK_LB:
|
||||
propName = computedPropertyName(yieldHandling, propList);
|
||||
propName = computedPropertyName(yieldHandling, maybeDecl, propList);
|
||||
if (!propName)
|
||||
return null();
|
||||
break;
|
||||
|
@ -9736,7 +9691,7 @@ Parser<ParseHandler, CharT>::propertyName(YieldHandling yieldHandling, Node prop
|
|||
if (tt == TOK_LB) {
|
||||
tokenStream.consumeKnownToken(TOK_LB);
|
||||
|
||||
return computedPropertyName(yieldHandling, propList);
|
||||
return computedPropertyName(yieldHandling, maybeDecl, propList);
|
||||
}
|
||||
|
||||
// Not an accessor property after all.
|
||||
|
@ -9808,28 +9763,25 @@ Parser<ParseHandler, CharT>::propertyName(YieldHandling yieldHandling, Node prop
|
|||
|
||||
template <template <typename CharT> class ParseHandler, typename CharT>
|
||||
typename ParseHandler<CharT>::Node
|
||||
Parser<ParseHandler, CharT>::computedPropertyName(YieldHandling yieldHandling, Node literal)
|
||||
Parser<ParseHandler, CharT>::computedPropertyName(YieldHandling yieldHandling,
|
||||
const Maybe<DeclarationKind>& maybeDecl,
|
||||
Node literal)
|
||||
{
|
||||
uint32_t begin = pos().begin;
|
||||
|
||||
Node assignNode;
|
||||
{
|
||||
// Turn off the inDestructuringDecl flag when parsing computed property
|
||||
// names. In short, when parsing 'let {[x + y]: z} = obj;', noteUsedName()
|
||||
// should be called on x and y, but not on z. See the comment on
|
||||
// Parser<>::checkDestructuringAssignmentPattern() for details.
|
||||
AutoClearInDestructuringDecl autoClear(pc);
|
||||
assignNode = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
if (!assignNode)
|
||||
return null();
|
||||
if (maybeDecl) {
|
||||
if (*maybeDecl == DeclarationKind::FormalParameter)
|
||||
pc->functionBox()->hasParameterExprs = true;
|
||||
} else {
|
||||
handler.setListFlag(literal, PNX_NONCONST);
|
||||
}
|
||||
|
||||
MUST_MATCH_TOKEN(TOK_RB, JSMSG_COMP_PROP_UNTERM_EXPR);
|
||||
Node propname = handler.newComputedName(assignNode, begin, pos().end);
|
||||
if (!propname)
|
||||
Node assignNode = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
if (!assignNode)
|
||||
return null();
|
||||
handler.setListFlag(literal, PNX_NONCONST);
|
||||
return propname;
|
||||
|
||||
MUST_MATCH_TOKEN(TOK_RB, JSMSG_COMP_PROP_UNTERM_EXPR);
|
||||
return handler.newComputedName(assignNode, begin, pos().end);
|
||||
}
|
||||
|
||||
template <template <typename CharT> class ParseHandler, typename CharT>
|
||||
|
@ -9847,6 +9799,7 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
|
|||
|
||||
bool seenPrototypeMutation = false;
|
||||
bool seenCoverInitializedName = false;
|
||||
Maybe<DeclarationKind> declKind = Nothing();
|
||||
RootedAtom propAtom(context);
|
||||
for (;;) {
|
||||
TokenKind tt;
|
||||
|
@ -9860,7 +9813,7 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
|
|||
tokenStream.ungetToken();
|
||||
|
||||
PropertyType propType;
|
||||
Node propName = propertyName(yieldHandling, literal, &propType, &propAtom);
|
||||
Node propName = propertyName(yieldHandling, declKind, literal, &propType, &propAtom);
|
||||
if (!propName)
|
||||
return null();
|
||||
|
||||
|
@ -9954,15 +9907,9 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
|
|||
possibleError->setPendingExpressionErrorAt(pos(), JSMSG_COLON_AFTER_ID);
|
||||
}
|
||||
|
||||
Node rhs;
|
||||
{
|
||||
// Clearing `inDestructuringDecl` allows name use to be noted
|
||||
// in Parser::identifierReference. See bug 1255167.
|
||||
AutoClearInDestructuringDecl autoClear(pc);
|
||||
rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
Node rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||
if (!rhs)
|
||||
return null();
|
||||
}
|
||||
|
||||
handler.checkAndSetIsDirectRHSAnonFunction(rhs);
|
||||
|
||||
|
|
|
@ -340,17 +340,6 @@ class ParseContext : public Nestable<ParseContext>
|
|||
// pointer may be nullptr.
|
||||
Directives* newDirectives;
|
||||
|
||||
// Set when parsing a declaration-like destructuring pattern. This flag
|
||||
// causes PrimaryExpr to create PN_NAME parse nodes for variable references
|
||||
// which are not hooked into any definition's use chain, added to any tree
|
||||
// context's AtomList, etc. etc. checkDestructuring will do that work
|
||||
// later.
|
||||
//
|
||||
// The comments atop checkDestructuring explain the distinction between
|
||||
// assignment-like and declaration-like destructuring patterns, and why
|
||||
// they need to be treated differently.
|
||||
mozilla::Maybe<DeclarationKind> inDestructuringDecl;
|
||||
|
||||
// Set when parsing a function and it has 'return <expr>;'
|
||||
bool funHasReturnExpr;
|
||||
|
||||
|
@ -1518,15 +1507,17 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
|
|||
|
||||
Node finishLexicalScope(ParseContext::Scope& scope, Node body);
|
||||
|
||||
Node propertyName(YieldHandling yieldHandling, Node propList,
|
||||
Node propertyName(YieldHandling yieldHandling,
|
||||
const mozilla::Maybe<DeclarationKind>& maybeDecl, Node propList,
|
||||
PropertyType* propType, MutableHandleAtom propAtom);
|
||||
Node computedPropertyName(YieldHandling yieldHandling, Node literal);
|
||||
Node computedPropertyName(YieldHandling yieldHandling,
|
||||
const mozilla::Maybe<DeclarationKind>& maybeDecl, Node literal);
|
||||
Node arrayInitializer(YieldHandling yieldHandling, PossibleError* possibleError);
|
||||
Node newRegExp();
|
||||
|
||||
Node objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError);
|
||||
|
||||
Node bindingInitializer(Node lhs, YieldHandling yieldHandling);
|
||||
Node bindingInitializer(Node lhs, DeclarationKind kind, YieldHandling yieldHandling);
|
||||
Node bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling);
|
||||
Node bindingIdentifierOrPattern(DeclarationKind kind, YieldHandling yieldHandling,
|
||||
TokenKind tt);
|
||||
|
|
Загрузка…
Ссылка в новой задаче