Bug 1303703 - Part 3: Syntax parse destructuring assignment patterns. r=shu

--HG--
extra : rebase_source : 0daecbc1665b17ac1746eea74821088fa73ec6de
This commit is contained in:
André Bargull 2017-04-22 02:19:10 -07:00
Родитель 2165b6d8c2
Коммит c65efe2ba4
5 изменённых файлов: 204 добавлений и 190 удалений

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

@ -865,6 +865,10 @@ class FullParseHandlerBase
return node->isKind(PNK_NAME);
}
bool isArgumentsAnyParentheses(ParseNode* node, JSContext* cx) {
return node->isKind(PNK_NAME) && node->pn_atom == cx->names().arguments;
}
bool isEvalAnyParentheses(ParseNode* node, JSContext* cx) {
return node->isKind(PNK_NAME) && node->pn_atom == cx->names().eval;
}
@ -875,7 +879,7 @@ class FullParseHandlerBase
if (isEvalAnyParentheses(node, cx))
return js_eval_str;
if (node->pn_atom == cx->names().arguments)
if (isArgumentsAnyParentheses(node, cx))
return js_arguments_str;
return nullptr;
}

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

@ -699,6 +699,19 @@ ParserBase::extraWarning(unsigned errorNumber, ...)
return result;
}
bool
ParserBase::extraWarningAt(uint32_t offset, unsigned errorNumber, ...)
{
va_list args;
va_start(args, errorNumber);
bool result =
tokenStream.reportExtraWarningErrorNumberVA(nullptr, offset, errorNumber, args);
va_end(args);
return result;
}
bool
ParserBase::strictModeError(unsigned errorNumber, ...)
{
@ -4171,8 +4184,10 @@ Parser<ParseHandler, CharT>::PossibleError::error(ErrorKind kind)
{
if (kind == ErrorKind::Expression)
return exprError_;
MOZ_ASSERT(kind == ErrorKind::Destructuring);
return destructuringError_;
if (kind == ErrorKind::Destructuring)
return destructuringError_;
MOZ_ASSERT(kind == ErrorKind::DestructuringWarning);
return destructuringWarning_;
}
template <template <typename CharT> class ParseHandler, typename CharT>
@ -4189,6 +4204,13 @@ Parser<ParseHandler, CharT>::PossibleError::hasError(ErrorKind kind)
return error(kind).state_ == ErrorState::Pending;
}
template <template <typename CharT> class ParseHandler, typename CharT>
bool
Parser<ParseHandler, CharT>::PossibleError::hasPendingDestructuringError()
{
return hasError(ErrorKind::Destructuring);
}
template <template <typename CharT> class ParseHandler, typename CharT>
void
Parser<ParseHandler, CharT>::PossibleError::setPending(ErrorKind kind, const TokenPos& pos,
@ -4214,6 +4236,14 @@ Parser<ParseHandler, CharT>::PossibleError::setPendingDestructuringErrorAt(const
setPending(ErrorKind::Destructuring, pos, errorNumber);
}
template <template <typename CharT> class ParseHandler, typename CharT>
void
Parser<ParseHandler, CharT>::PossibleError::setPendingDestructuringWarningAt(const TokenPos& pos,
unsigned errorNumber)
{
setPending(ErrorKind::DestructuringWarning, pos, errorNumber);
}
template <template <typename CharT> class ParseHandler, typename CharT>
void
Parser<ParseHandler, CharT>::PossibleError::setPendingExpressionErrorAt(const TokenPos& pos,
@ -4236,23 +4266,36 @@ Parser<ParseHandler, CharT>::PossibleError::checkForError(ErrorKind kind)
template <template <typename CharT> class ParseHandler, typename CharT>
bool
Parser<ParseHandler, CharT>::PossibleError::checkForDestructuringError()
Parser<ParseHandler, CharT>::PossibleError::checkForWarning(ErrorKind kind)
{
if (!hasError(kind))
return true;
Error& err = error(kind);
return parser_.extraWarningAt(err.offset_, err.errorNumber_);
}
template <template <typename CharT> class ParseHandler, typename CharT>
bool
Parser<ParseHandler, CharT>::PossibleError::checkForDestructuringErrorOrWarning()
{
// Clear pending expression error, because we're definitely not in an
// expression context.
setResolved(ErrorKind::Expression);
// Report any pending destructuring error.
return checkForError(ErrorKind::Destructuring);
// Report any pending destructuring error or warning.
return checkForError(ErrorKind::Destructuring) &&
checkForWarning(ErrorKind::DestructuringWarning);
}
template <template <typename CharT> class ParseHandler, typename CharT>
bool
Parser<ParseHandler, CharT>::PossibleError::checkForExpressionError()
{
// Clear pending destructuring error, because we're definitely not in a
// destructuring context.
// Clear pending destructuring error or warning, because we're definitely
// not in a destructuring context.
setResolved(ErrorKind::Destructuring);
setResolved(ErrorKind::DestructuringWarning);
// Report any pending expression error.
return checkForError(ErrorKind::Expression);
@ -4284,158 +4327,6 @@ Parser<ParseHandler, CharT>::PossibleError::transferErrorsTo(PossibleError* othe
transferErrorTo(ErrorKind::Expression, other);
}
template <>
bool
Parser<FullParseHandler, char16_t>::checkDestructuringAssignmentName(ParseNode* expr)
{
MOZ_ASSERT(!handler.isUnparenthesizedDestructuringPattern(expr));
// Parentheses are forbidden around destructuring *patterns* (but allowed
// around names). Use our nicer error message for parenthesized, nested
// patterns.
if (handler.isParenthesizedDestructuringPattern(expr)) {
errorAt(expr->pn_pos.begin, JSMSG_BAD_DESTRUCT_PARENS);
return false;
}
// The expression must be a simple assignment target, i.e. either a name
// or a property accessor.
if (handler.isNameAnyParentheses(expr)) {
if (const char* chars = handler.nameIsArgumentsEvalAnyParentheses(expr, context)) {
if (!strictModeErrorAt(expr->pn_pos.begin, JSMSG_BAD_STRICT_ASSIGN, chars))
return false;
}
return true;
}
if (handler.isPropertyAccess(expr))
return true;
errorAt(expr->pn_pos.begin, JSMSG_BAD_DESTRUCT_TARGET);
return false;
}
template <>
bool
Parser<FullParseHandler, char16_t>::checkDestructuringAssignmentPattern(ParseNode* pattern,
PossibleError* possibleError /* = nullptr */);
template <>
bool
Parser<SyntaxParseHandler, char16_t>::checkDestructuringAssignmentPattern(Node pattern,
PossibleError* possibleError /* = nullptr */)
{
return abortIfSyntaxParser();
}
template <>
bool
Parser<FullParseHandler, char16_t>::checkDestructuringAssignmentObject(ParseNode* objectPattern)
{
MOZ_ASSERT(objectPattern->isKind(PNK_OBJECT));
for (ParseNode* member = objectPattern->pn_head; member; member = member->pn_next) {
ParseNode* target;
if (member->isKind(PNK_MUTATEPROTO)) {
target = member->pn_kid;
} else {
MOZ_ASSERT(member->isKind(PNK_COLON) || member->isKind(PNK_SHORTHAND));
MOZ_ASSERT_IF(member->isKind(PNK_SHORTHAND),
member->pn_left->isKind(PNK_OBJECT_PROPERTY_NAME) &&
member->pn_right->isKind(PNK_NAME) &&
member->pn_left->pn_atom == member->pn_right->pn_atom);
target = member->pn_right;
}
if (handler.isUnparenthesizedAssignment(target))
target = target->pn_left;
if (handler.isUnparenthesizedDestructuringPattern(target)) {
if (!checkDestructuringAssignmentPattern(target))
return false;
} else {
if (!checkDestructuringAssignmentName(target))
return false;
}
}
return true;
}
template <>
bool
Parser<FullParseHandler, char16_t>::checkDestructuringAssignmentArray(ParseNode* arrayPattern)
{
MOZ_ASSERT(arrayPattern->isKind(PNK_ARRAY));
for (ParseNode* element = arrayPattern->pn_head; element; element = element->pn_next) {
if (element->isKind(PNK_ELISION))
continue;
ParseNode* target;
if (element->isKind(PNK_SPREAD)) {
if (element->pn_next) {
errorAt(element->pn_next->pn_pos.begin, JSMSG_PARAMETER_AFTER_REST);
return false;
}
target = element->pn_kid;
} else if (handler.isUnparenthesizedAssignment(element)) {
target = element->pn_left;
} else {
target = element;
}
if (handler.isUnparenthesizedDestructuringPattern(target)) {
if (!this->checkDestructuringAssignmentPattern(target))
return false;
} else {
if (!checkDestructuringAssignmentName(target))
return false;
}
}
return true;
}
/*
* Destructuring patterns can appear in two kinds of contexts:
*
* - assignment-like: assignment expressions and |for| loop heads. In
* these cases, the patterns' property value positions can be
* arbitrary lvalue expressions; the destructuring is just a fancy
* assignment.
*
* - binding-like: |var| and |let| declarations, functions' formal
* parameter lists, |catch| clauses, and comprehension tails. In
* these cases, the patterns' property value positions must be
* simple names; the destructuring defines them as new variables.
*
* 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.
*/
template <>
bool
Parser<FullParseHandler, char16_t>::checkDestructuringAssignmentPattern(ParseNode* pattern,
PossibleError* possibleError /* = nullptr */)
{
if (pattern->isKind(PNK_ARRAYCOMP)) {
errorAt(pattern->pn_pos.begin, JSMSG_ARRAY_COMP_LEFTSIDE);
return false;
}
bool isDestructuring = pattern->isKind(PNK_ARRAY)
? checkDestructuringAssignmentArray(pattern)
: checkDestructuringAssignmentObject(pattern);
// Report any pending destructuring error.
if (isDestructuring && possibleError && !possibleError->checkForDestructuringError())
return false;
return isDestructuring;
}
template <template <typename CharT> class ParseHandler, typename CharT>
typename ParseHandler<CharT>::Node
Parser<ParseHandler, CharT>::bindingInitializer(Node lhs, DeclarationKind kind,
@ -6250,7 +6141,7 @@ Parser<ParseHandler, CharT>::forHeadStart(YieldHandling yieldHandling,
// Verify the left-hand side expression doesn't have a forbidden form.
if (handler.isUnparenthesizedDestructuringPattern(*forInitialPart)) {
if (!checkDestructuringAssignmentPattern(*forInitialPart, &possibleError))
if (!possibleError.checkForDestructuringErrorOrWarning())
return false;
} else if (handler.isNameAnyParentheses(*forInitialPart)) {
const char* chars = handler.nameIsArgumentsEvalAnyParentheses(*forInitialPart, context);
@ -8219,7 +8110,7 @@ Parser<ParseHandler, CharT>::assignExpr(InHandling inHandling, YieldHandling yie
if (!tokenStream.getToken(&tt, TokenStream::Operand))
return null();
uint32_t exprOffset = pos().begin;
TokenPos exprPos = pos();
bool endsExpr;
@ -8425,12 +8316,12 @@ Parser<ParseHandler, CharT>::assignExpr(InHandling inHandling, YieldHandling yie
return null();
}
if (!checkDestructuringAssignmentPattern(lhs, &possibleErrorInner))
if (!possibleErrorInner.checkForDestructuringErrorOrWarning())
return null();
} else if (handler.isNameAnyParentheses(lhs)) {
if (const char* chars = handler.nameIsArgumentsEvalAnyParentheses(lhs, context)) {
// |chars| is "arguments" or "eval" here.
if (!strictModeErrorAt(exprOffset, JSMSG_BAD_STRICT_ASSIGN, chars))
if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_STRICT_ASSIGN, chars))
return null();
}
@ -8438,10 +8329,13 @@ Parser<ParseHandler, CharT>::assignExpr(InHandling inHandling, YieldHandling yie
} else if (handler.isPropertyAccess(lhs)) {
// Permitted: no additional testing/fixup needed.
} else if (handler.isFunctionCall(lhs)) {
if (!strictModeErrorAt(exprOffset, JSMSG_BAD_LEFTSIDE_OF_ASS))
if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS))
return null();
if (possibleError)
possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_TARGET);
} else {
errorAt(exprOffset, JSMSG_BAD_LEFTSIDE_OF_ASS);
errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
return null();
}
@ -9467,6 +9361,74 @@ Parser<ParseHandler, CharT>::newRegExp()
return handler.newRegExp(reobj, pos(), *this);
}
template <template <typename CharT> class ParseHandler, typename CharT>
void
Parser<ParseHandler, CharT>::checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos,
PossibleError* possibleError)
{
// Return early if a pending destructuring error is already present.
if (possibleError->hasPendingDestructuringError())
return;
if (pc->sc()->needStrictChecks()) {
if (handler.isArgumentsAnyParentheses(expr, context)) {
if (pc->sc()->strict()) {
possibleError->setPendingDestructuringErrorAt(exprPos,
JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
} else {
possibleError->setPendingDestructuringWarningAt(exprPos,
JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
}
return;
}
if (handler.isEvalAnyParentheses(expr, context)) {
if (pc->sc()->strict()) {
possibleError->setPendingDestructuringErrorAt(exprPos,
JSMSG_BAD_STRICT_ASSIGN_EVAL);
} else {
possibleError->setPendingDestructuringWarningAt(exprPos,
JSMSG_BAD_STRICT_ASSIGN_EVAL);
}
return;
}
}
// The expression must be either a simple assignment target, i.e. a name
// or a property accessor, or a nested destructuring pattern.
if (!handler.isUnparenthesizedDestructuringPattern(expr) &&
!handler.isNameAnyParentheses(expr) &&
!handler.isPropertyAccess(expr))
{
// Parentheses are forbidden around destructuring *patterns* (but
// allowed around names). Use our nicer error message for
// parenthesized, nested patterns.
if (handler.isParenthesizedDestructuringPattern(expr))
possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_PARENS);
else
possibleError->setPendingDestructuringErrorAt(exprPos, JSMSG_BAD_DESTRUCT_TARGET);
}
}
template <template <typename CharT> class ParseHandler, typename CharT>
void
Parser<ParseHandler, CharT>::checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
PossibleError* possibleError)
{
// ES2018 draft rev 0719f44aab93215ed9a626b2f45bd34f36916834
// 12.15.5 Destructuring Assignment
//
// AssignmentElement[Yield, Await]:
// DestructuringAssignmentTarget[?Yield, ?Await]
// DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]
// If |expr| is an assignment element with an initializer expression, its
// destructuring assignment target was already validated in assignExpr().
// Otherwise we need to check that |expr| is a valid destructuring target.
if (!handler.isUnparenthesizedAssignment(expr))
checkDestructuringAssignmentTarget(expr, exprPos, possibleError);
}
template <template <typename CharT> class ParseHandler, typename CharT>
typename ParseHandler<CharT>::Node
Parser<ParseHandler, CharT>::arrayInitializer(YieldHandling yieldHandling,
@ -9517,17 +9479,30 @@ Parser<ParseHandler, CharT>::arrayInitializer(YieldHandling yieldHandling,
} else if (tt == TOK_TRIPLEDOT) {
tokenStream.consumeKnownToken(TOK_TRIPLEDOT, TokenStream::Operand);
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.addSpreadElement(literal, begin, inner))
return null();
} else {
TokenPos elementPos;
if (!tokenStream.peekTokenPos(&elementPos, TokenStream::Operand))
return null();
Node element = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
possibleError);
if (!element)
return null();
if (possibleError)
checkDestructuringAssignmentElement(element, elementPos, possibleError);
if (foldConstants && !FoldConstants(context, &element, this))
return null();
handler.addArrayElement(literal, element);
@ -9818,6 +9793,10 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
return null();
if (propType == PropertyType::Normal) {
TokenPos exprPos;
if (!tokenStream.peekTokenPos(&exprPos, TokenStream::Operand))
return null();
Node propExpr = assignExpr(InAllowed, yieldHandling, TripledotProhibited,
possibleError);
if (!propExpr)
@ -9857,6 +9836,9 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
if (!handler.addPropertyDefinition(literal, propName, propExpr))
return null();
}
if (possibleError)
checkDestructuringAssignmentElement(propExpr, exprPos, possibleError);
} else if (propType == PropertyType::Shorthand) {
/*
* Support, e.g., |({x, y} = o)| as destructuring shorthand
@ -9871,6 +9853,9 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
if (!nameExpr)
return null();
if (possibleError)
checkDestructuringAssignmentTarget(nameExpr, namePos, possibleError);
if (!handler.addShorthand(literal, propName, nameExpr))
return null();
} else if (propType == PropertyType::CoverInitializedName) {
@ -9907,6 +9892,12 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
possibleError->setPendingExpressionErrorAt(pos(), JSMSG_COLON_AFTER_ID);
}
if (const char* chars = handler.nameIsArgumentsEvalAnyParentheses(lhs, context)) {
// |chars| is "arguments" or "eval" here.
if (!strictModeErrorAt(namePos.begin, JSMSG_BAD_STRICT_ASSIGN, chars))
return null();
}
Node rhs = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
if (!rhs)
return null();
@ -9919,9 +9910,6 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
if (!handler.addPropertyDefinition(literal, propName, propExpr))
return null();
if (!abortIfSyntaxParser())
return null();
} else {
RootedAtom funName(context);
if (!tokenStream.isCurrentTokenType(TOK_RB)) {
@ -9943,6 +9931,9 @@ Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
JSOp op = JSOpFromPropertyType(propType);
if (!handler.addObjectMethodDefinition(literal, propName, fn, op))
return null();
if (possibleError)
possibleError->setPendingDestructuringErrorAt(namePos, JSMSG_BAD_DESTRUCT_TARGET);
}
if (!tokenStream.getToken(&tt))

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

@ -891,6 +891,12 @@ class ParserBase : public StrictModeGetter
*/
MOZ_MUST_USE bool extraWarning(unsigned errorNumber, ...);
/*
* If extra warnings are enabled, report the given warning at the given
* offset.
*/
MOZ_MUST_USE bool extraWarningAt(uint32_t offset, unsigned errorNumber, ...);
bool isValidStrictBinding(PropertyName* name);
void addTelemetry(JSCompartment::DeprecatedLanguageExtension e);
@ -1020,7 +1026,7 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
class MOZ_STACK_CLASS PossibleError
{
private:
enum class ErrorKind { Expression, Destructuring };
enum class ErrorKind { Expression, Destructuring, DestructuringWarning };
enum class ErrorState { None, Pending };
@ -1035,11 +1041,12 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
Parser<ParseHandler, CharT>& parser_;
Error exprError_;
Error destructuringError_;
Error destructuringWarning_;
// Returns the error report.
Error& error(ErrorKind kind);
// Return true if an error is pending without reporting
// Return true if an error is pending without reporting.
bool hasError(ErrorKind kind);
// Resolve any pending error.
@ -1051,7 +1058,11 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
// If there is a pending error, report it and return false, otherwise
// return true.
bool checkForError(ErrorKind kind);
MOZ_MUST_USE bool checkForError(ErrorKind kind);
// If there is a pending warning, report it and return either false or
// true depending on the werror option, otherwise return true.
MOZ_MUST_USE bool checkForWarning(ErrorKind kind);
// Transfer an existing error to another instance.
void transferErrorTo(ErrorKind kind, PossibleError* other);
@ -1059,23 +1070,33 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
public:
explicit PossibleError(Parser<ParseHandler, CharT>& parser);
// Return true if a pending destructuring error is present.
bool hasPendingDestructuringError();
// Set a pending destructuring error. Only a single error may be set
// per instance, i.e. subsequent calls to this method are ignored and
// won't overwrite the existing pending error.
void setPendingDestructuringErrorAt(const TokenPos& pos, unsigned errorNumber);
// Set a pending destructuring warning. Only a single warning may be
// set per instance, i.e. subsequent calls to this method are ignored
// and won't overwrite the existing pending warning.
void setPendingDestructuringWarningAt(const TokenPos& pos, unsigned errorNumber);
// Set a pending expression error. Only a single error may be set per
// instance, i.e. subsequent calls to this method are ignored and won't
// overwrite the existing pending error.
void setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber);
// If there is a pending destructuring error, report it and return
// false, otherwise return true. Clears any pending expression error.
bool checkForDestructuringError();
// If there is a pending destructuring error or warning, report it and
// return false, otherwise return true. Clears any pending expression
// error.
MOZ_MUST_USE bool checkForDestructuringErrorOrWarning();
// If there is a pending expression error, report it and return false,
// otherwise return true. Clears any pending destructuring error.
bool checkForExpressionError();
// otherwise return true. Clears any pending destructuring error or
// warning.
MOZ_MUST_USE bool checkForExpressionError();
// Pass pending errors between possible error instances. This is useful
// for extending the lifetime of a pending error beyond the scope of
@ -1524,18 +1545,10 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
Node objectBindingPattern(DeclarationKind kind, YieldHandling yieldHandling);
Node arrayBindingPattern(DeclarationKind kind, YieldHandling yieldHandling);
// Top-level entrypoint into destructuring assignment pattern checking and
// name-analyzing.
bool checkDestructuringAssignmentPattern(Node pattern,
PossibleError* possibleError = nullptr);
// Recursive methods for checking/name-analyzing subcomponents of an
// destructuring assignment pattern. The array/object methods *must* be
// passed arrays or objects. The name method may be passed anything but
// will report an error if not passed a name.
bool checkDestructuringAssignmentArray(Node arrayPattern);
bool checkDestructuringAssignmentObject(Node objectPattern);
bool checkDestructuringAssignmentName(Node expr);
void checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos,
PossibleError* possibleError);
void checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
PossibleError* possibleError);
Node newNumber(const Token& tok) {
return handler.newNumber(tok.number(), tok.decimalPoint(), tok.pos);

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

@ -576,6 +576,10 @@ class SyntaxParseHandlerBase
node == NodeParenthesizedName;
}
bool isArgumentsAnyParentheses(Node node, JSContext* cx) {
return node == NodeUnparenthesizedArgumentsName || node == NodeParenthesizedArgumentsName;
}
bool isEvalAnyParentheses(Node node, JSContext* cx) {
return node == NodeUnparenthesizedEvalName || node == NodeParenthesizedEvalName;
}
@ -586,7 +590,7 @@ class SyntaxParseHandlerBase
if (isEvalAnyParentheses(node, cx))
return js_eval_str;
if (node == NodeUnparenthesizedArgumentsName || node == NodeParenthesizedArgumentsName)
if (isArgumentsAnyParentheses(node, cx))
return js_arguments_str;
return nullptr;
}

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

@ -213,6 +213,8 @@ MSG_DEF(JSMSG_BAD_POW_LEFTSIDE, 0, JSEXN_SYNTAXERR, "unparenthesized unar
MSG_DEF(JSMSG_BAD_PROP_ID, 0, JSEXN_SYNTAXERR, "invalid property id")
MSG_DEF(JSMSG_BAD_RETURN_OR_YIELD, 1, JSEXN_SYNTAXERR, "{0} not in function")
MSG_DEF(JSMSG_BAD_STRICT_ASSIGN, 1, JSEXN_SYNTAXERR, "'{0}' can't be defined or assigned to in strict mode code")
MSG_DEF(JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS, 0, JSEXN_SYNTAXERR, "'arguments' can't be defined or assigned to in strict mode code")
MSG_DEF(JSMSG_BAD_STRICT_ASSIGN_EVAL, 0, JSEXN_SYNTAXERR, "'eval' can't be defined or assigned to in strict mode code")
MSG_DEF(JSMSG_BAD_SWITCH, 0, JSEXN_SYNTAXERR, "invalid switch statement")
MSG_DEF(JSMSG_BAD_SUPER, 0, JSEXN_SYNTAXERR, "invalid use of keyword 'super'")
MSG_DEF(JSMSG_BAD_SUPERPROP, 1, JSEXN_SYNTAXERR, "use of super {0} accesses only valid within methods or eval code within methods")