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:
André Bargull 2017-04-22 02:09:23 -07:00
Родитель 3eb0058955
Коммит 2165b6d8c2
2 изменённых файлов: 54 добавлений и 116 удалений

Просмотреть файл

@ -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 (!rhs)
return null();
}
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);
if (!rhs)
return null();
}
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);
if (!rhs)
return null();
}
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);