зеркало из 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
|
* In the first case, other code parses the pattern as an arbitrary
|
||||||
* primaryExpr, and then, here in checkDestructuringAssignmentPattern, verify
|
* primaryExpr, and then, here in checkDestructuringAssignmentPattern, verify
|
||||||
* that the tree is a valid AssignmentPattern.
|
* 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 <>
|
template <>
|
||||||
bool
|
bool
|
||||||
|
@ -4450,39 +4436,19 @@ Parser<FullParseHandler, char16_t>::checkDestructuringAssignmentPattern(ParseNod
|
||||||
return isDestructuring;
|
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>
|
template <template <typename CharT> class ParseHandler, typename CharT>
|
||||||
typename ParseHandler<CharT>::Node
|
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));
|
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_ASSIGN));
|
||||||
|
|
||||||
Node rhs;
|
if (kind == DeclarationKind::FormalParameter)
|
||||||
{
|
pc->functionBox()->hasParameterExprs = true;
|
||||||
AutoClearInDestructuringDecl autoClear(pc);
|
|
||||||
rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
Node rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||||
if (!rhs)
|
if (!rhs)
|
||||||
return null();
|
return null();
|
||||||
}
|
|
||||||
|
|
||||||
handler.checkAndSetIsDirectRHSAnonFunction(rhs);
|
handler.checkAndSetIsDirectRHSAnonFunction(rhs);
|
||||||
|
|
||||||
|
@ -4500,7 +4466,7 @@ template <template <typename CharT> class ParseHandler, typename CharT>
|
||||||
typename ParseHandler<CharT>::Node
|
typename ParseHandler<CharT>::Node
|
||||||
Parser<ParseHandler, CharT>::bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling)
|
Parser<ParseHandler, CharT>::bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling)
|
||||||
{
|
{
|
||||||
Rooted<PropertyName*> name(context, bindingIdentifier(yieldHandling));
|
RootedPropertyName name(context, bindingIdentifier(yieldHandling));
|
||||||
if (!name)
|
if (!name)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
|
@ -4545,6 +4511,7 @@ Parser<ParseHandler, CharT>::objectBindingPattern(DeclarationKind kind,
|
||||||
if (!literal)
|
if (!literal)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
|
Maybe<DeclarationKind> declKind = Some(kind);
|
||||||
RootedAtom propAtom(context);
|
RootedAtom propAtom(context);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
TokenKind tt;
|
TokenKind tt;
|
||||||
|
@ -4558,7 +4525,7 @@ Parser<ParseHandler, CharT>::objectBindingPattern(DeclarationKind kind,
|
||||||
tokenStream.ungetToken();
|
tokenStream.ungetToken();
|
||||||
|
|
||||||
PropertyType propType;
|
PropertyType propType;
|
||||||
Node propName = propertyName(yieldHandling, literal, &propType, &propAtom);
|
Node propName = propertyName(yieldHandling, declKind, literal, &propType, &propAtom);
|
||||||
if (!propName)
|
if (!propName)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
|
@ -4577,7 +4544,7 @@ Parser<ParseHandler, CharT>::objectBindingPattern(DeclarationKind kind,
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
Node bindingExpr = hasInitializer
|
Node bindingExpr = hasInitializer
|
||||||
? bindingInitializer(binding, yieldHandling)
|
? bindingInitializer(binding, kind, yieldHandling)
|
||||||
: binding;
|
: binding;
|
||||||
if (!bindingExpr)
|
if (!bindingExpr)
|
||||||
return null();
|
return null();
|
||||||
|
@ -4606,7 +4573,7 @@ Parser<ParseHandler, CharT>::objectBindingPattern(DeclarationKind kind,
|
||||||
|
|
||||||
tokenStream.consumeKnownToken(TOK_ASSIGN);
|
tokenStream.consumeKnownToken(TOK_ASSIGN);
|
||||||
|
|
||||||
Node bindingExpr = bindingInitializer(binding, yieldHandling);
|
Node bindingExpr = bindingInitializer(binding, kind, yieldHandling);
|
||||||
if (!bindingExpr)
|
if (!bindingExpr)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
|
@ -4687,7 +4654,9 @@ Parser<ParseHandler, CharT>::arrayBindingPattern(DeclarationKind kind, YieldHand
|
||||||
if (!tokenStream.matchToken(&hasInitializer, TOK_ASSIGN))
|
if (!tokenStream.matchToken(&hasInitializer, TOK_ASSIGN))
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
Node element = hasInitializer ? bindingInitializer(binding, yieldHandling) : binding;
|
Node element = hasInitializer
|
||||||
|
? bindingInitializer(binding, kind, yieldHandling)
|
||||||
|
: binding;
|
||||||
if (!element)
|
if (!element)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
|
@ -4727,17 +4696,9 @@ Parser<ParseHandler, CharT>::destructuringDeclaration(DeclarationKind kind,
|
||||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(tt));
|
MOZ_ASSERT(tokenStream.isCurrentTokenType(tt));
|
||||||
MOZ_ASSERT(tt == TOK_LB || tt == TOK_LC);
|
MOZ_ASSERT(tt == TOK_LB || tt == TOK_LC);
|
||||||
|
|
||||||
Node pattern;
|
return tt == TOK_LB
|
||||||
{
|
? arrayBindingPattern(kind, yieldHandling)
|
||||||
pc->inDestructuringDecl = Some(kind);
|
: objectBindingPattern(kind, yieldHandling);
|
||||||
if (tt == TOK_LB)
|
|
||||||
pattern = arrayBindingPattern(kind, yieldHandling);
|
|
||||||
else
|
|
||||||
pattern = objectBindingPattern(kind, yieldHandling);
|
|
||||||
pc->inDestructuringDecl = Nothing();
|
|
||||||
}
|
|
||||||
|
|
||||||
return pattern;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <typename CharT> class ParseHandler, typename CharT>
|
template <template <typename CharT> class ParseHandler, typename CharT>
|
||||||
|
@ -7128,14 +7089,10 @@ Parser<ParseHandler, CharT>::tryStatement(YieldHandling yieldHandling)
|
||||||
return null();
|
return null();
|
||||||
}
|
}
|
||||||
|
|
||||||
RootedPropertyName param(context, bindingIdentifier(yieldHandling));
|
catchName = bindingIdentifier(DeclarationKind::SimpleCatchParameter,
|
||||||
if (!param)
|
yieldHandling);
|
||||||
return null();
|
|
||||||
catchName = newName(param);
|
|
||||||
if (!catchName)
|
if (!catchName)
|
||||||
return null();
|
return null();
|
||||||
if (!noteDeclaredName(param, DeclarationKind::SimpleCatchParameter, pos()))
|
|
||||||
return null();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7364,6 +7321,7 @@ Parser<ParseHandler, CharT>::classDefinition(YieldHandling yieldHandling,
|
||||||
if (!classMethods)
|
if (!classMethods)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
|
Maybe<DeclarationKind> declKind = Nothing();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
TokenKind tt;
|
TokenKind tt;
|
||||||
if (!tokenStream.getToken(&tt))
|
if (!tokenStream.getToken(&tt))
|
||||||
|
@ -7397,7 +7355,7 @@ Parser<ParseHandler, CharT>::classDefinition(YieldHandling yieldHandling,
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
PropertyType propType;
|
PropertyType propType;
|
||||||
Node propName = propertyName(yieldHandling, classMethods, &propType, &propAtom);
|
Node propName = propertyName(yieldHandling, declKind, classMethods, &propType, &propAtom);
|
||||||
if (!propName)
|
if (!propName)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
|
@ -8490,13 +8448,9 @@ Parser<ParseHandler, CharT>::assignExpr(InHandling inHandling, YieldHandling yie
|
||||||
if (!possibleErrorInner.checkForExpressionError())
|
if (!possibleErrorInner.checkForExpressionError())
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
Node rhs;
|
Node rhs = assignExpr(inHandling, yieldHandling, TripledotProhibited);
|
||||||
{
|
if (!rhs)
|
||||||
AutoClearInDestructuringDecl autoClear(pc);
|
return null();
|
||||||
rhs = assignExpr(inHandling, yieldHandling, TripledotProhibited);
|
|
||||||
if (!rhs)
|
|
||||||
return null();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kind == PNK_ASSIGN)
|
if (kind == PNK_ASSIGN)
|
||||||
handler.checkAndSetIsDirectRHSAnonFunction(rhs);
|
handler.checkAndSetIsDirectRHSAnonFunction(rhs);
|
||||||
|
@ -9460,7 +9414,7 @@ Parser<ParseHandler, CharT>::identifierReference(Handle<PropertyName*> name)
|
||||||
if (!pn)
|
if (!pn)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
if (!pc->inDestructuringDecl && !noteUsedName(name))
|
if (!noteUsedName(name))
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
return pn;
|
return pn;
|
||||||
|
@ -9611,7 +9565,8 @@ DoubleToAtom(JSContext* cx, double value)
|
||||||
|
|
||||||
template <template <typename CharT> class ParseHandler, typename CharT>
|
template <template <typename CharT> class ParseHandler, typename CharT>
|
||||||
typename ParseHandler<CharT>::Node
|
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)
|
PropertyType* propType, MutableHandleAtom propAtom)
|
||||||
{
|
{
|
||||||
TokenKind ltok;
|
TokenKind ltok;
|
||||||
|
@ -9678,7 +9633,7 @@ Parser<ParseHandler, CharT>::propertyName(YieldHandling yieldHandling, Node prop
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_LB:
|
case TOK_LB:
|
||||||
propName = computedPropertyName(yieldHandling, propList);
|
propName = computedPropertyName(yieldHandling, maybeDecl, propList);
|
||||||
if (!propName)
|
if (!propName)
|
||||||
return null();
|
return null();
|
||||||
break;
|
break;
|
||||||
|
@ -9736,7 +9691,7 @@ Parser<ParseHandler, CharT>::propertyName(YieldHandling yieldHandling, Node prop
|
||||||
if (tt == TOK_LB) {
|
if (tt == TOK_LB) {
|
||||||
tokenStream.consumeKnownToken(TOK_LB);
|
tokenStream.consumeKnownToken(TOK_LB);
|
||||||
|
|
||||||
return computedPropertyName(yieldHandling, propList);
|
return computedPropertyName(yieldHandling, maybeDecl, propList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not an accessor property after all.
|
// 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>
|
template <template <typename CharT> class ParseHandler, typename CharT>
|
||||||
typename ParseHandler<CharT>::Node
|
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;
|
uint32_t begin = pos().begin;
|
||||||
|
|
||||||
Node assignNode;
|
if (maybeDecl) {
|
||||||
{
|
if (*maybeDecl == DeclarationKind::FormalParameter)
|
||||||
// Turn off the inDestructuringDecl flag when parsing computed property
|
pc->functionBox()->hasParameterExprs = true;
|
||||||
// names. In short, when parsing 'let {[x + y]: z} = obj;', noteUsedName()
|
} else {
|
||||||
// should be called on x and y, but not on z. See the comment on
|
handler.setListFlag(literal, PNX_NONCONST);
|
||||||
// Parser<>::checkDestructuringAssignmentPattern() for details.
|
|
||||||
AutoClearInDestructuringDecl autoClear(pc);
|
|
||||||
assignNode = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
|
||||||
if (!assignNode)
|
|
||||||
return null();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MUST_MATCH_TOKEN(TOK_RB, JSMSG_COMP_PROP_UNTERM_EXPR);
|
Node assignNode = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||||
Node propname = handler.newComputedName(assignNode, begin, pos().end);
|
if (!assignNode)
|
||||||
if (!propname)
|
|
||||||
return null();
|
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>
|
template <template <typename CharT> class ParseHandler, typename CharT>
|
||||||
|
@ -9847,6 +9799,7 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
|
||||||
|
|
||||||
bool seenPrototypeMutation = false;
|
bool seenPrototypeMutation = false;
|
||||||
bool seenCoverInitializedName = false;
|
bool seenCoverInitializedName = false;
|
||||||
|
Maybe<DeclarationKind> declKind = Nothing();
|
||||||
RootedAtom propAtom(context);
|
RootedAtom propAtom(context);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
TokenKind tt;
|
TokenKind tt;
|
||||||
|
@ -9860,7 +9813,7 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
|
||||||
tokenStream.ungetToken();
|
tokenStream.ungetToken();
|
||||||
|
|
||||||
PropertyType propType;
|
PropertyType propType;
|
||||||
Node propName = propertyName(yieldHandling, literal, &propType, &propAtom);
|
Node propName = propertyName(yieldHandling, declKind, literal, &propType, &propAtom);
|
||||||
if (!propName)
|
if (!propName)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
|
@ -9954,15 +9907,9 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
|
||||||
possibleError->setPendingExpressionErrorAt(pos(), JSMSG_COLON_AFTER_ID);
|
possibleError->setPendingExpressionErrorAt(pos(), JSMSG_COLON_AFTER_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node rhs;
|
Node rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
||||||
{
|
if (!rhs)
|
||||||
// Clearing `inDestructuringDecl` allows name use to be noted
|
return null();
|
||||||
// in Parser::identifierReference. See bug 1255167.
|
|
||||||
AutoClearInDestructuringDecl autoClear(pc);
|
|
||||||
rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
|
|
||||||
if (!rhs)
|
|
||||||
return null();
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.checkAndSetIsDirectRHSAnonFunction(rhs);
|
handler.checkAndSetIsDirectRHSAnonFunction(rhs);
|
||||||
|
|
||||||
|
|
|
@ -340,17 +340,6 @@ class ParseContext : public Nestable<ParseContext>
|
||||||
// pointer may be nullptr.
|
// pointer may be nullptr.
|
||||||
Directives* newDirectives;
|
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>;'
|
// Set when parsing a function and it has 'return <expr>;'
|
||||||
bool funHasReturnExpr;
|
bool funHasReturnExpr;
|
||||||
|
|
||||||
|
@ -1518,15 +1507,17 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
|
||||||
|
|
||||||
Node finishLexicalScope(ParseContext::Scope& scope, Node body);
|
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);
|
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 arrayInitializer(YieldHandling yieldHandling, PossibleError* possibleError);
|
||||||
Node newRegExp();
|
Node newRegExp();
|
||||||
|
|
||||||
Node objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError);
|
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 bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling);
|
||||||
Node bindingIdentifierOrPattern(DeclarationKind kind, YieldHandling yieldHandling,
|
Node bindingIdentifierOrPattern(DeclarationKind kind, YieldHandling yieldHandling,
|
||||||
TokenKind tt);
|
TokenKind tt);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче