Commit c75ca589 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Move strict formal parameter classification

Move from ParseAndClassifyIdentifier to places where we either know that what
we're parsing are parameters, or where they could become (async) arrow formals.

Change-Id: Ic69bb586ed29ba9ac7b4dbef5d11a2e1954e7332
Reviewed-on: https://chromium-review.googlesource.com/c/1356503Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57957}
parent ff0cf00c
...@@ -869,7 +869,8 @@ class ParserBase { ...@@ -869,7 +869,8 @@ class ParserBase {
} }
void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos); void CheckDestructuringElement(ExpressionT element, int beg_pos, int end_pos);
void CheckArrowFormalParameter(ExpressionT formal); void ClassifyFormalParameter(IdentifierT formal, int beg_pos, int end_pos);
void ClassifyArrowFormalParameter(ExpressionT formal);
// Checking the name of a function literal. This has to be done after parsing // Checking the name of a function literal. This has to be done after parsing
// the function, since the function can declare itself strict. // the function, since the function can declare itself strict.
...@@ -1543,20 +1544,10 @@ ParserBase<Impl>::ParseAndClassifyIdentifier() { ...@@ -1543,20 +1544,10 @@ ParserBase<Impl>::ParseAndClassifyIdentifier() {
if (IsInRange(next, Token::IDENTIFIER, Token::ASYNC)) { if (IsInRange(next, Token::IDENTIFIER, Token::ASYNC)) {
IdentifierT name = impl()->GetSymbol(); IdentifierT name = impl()->GetSymbol();
// When this function is used to read a formal parameter, we don't always if (V8_UNLIKELY(impl()->IsArguments(name) &&
// know whether the function is going to be strict or sloppy. Indeed for scope()->ShouldBanArguments())) {
// arrow functions we don't always know that the identifier we are reading ReportMessage(MessageTemplate::kArgumentsDisallowedInInitializer);
// is actually a formal parameter. Therefore besides the errors that we return impl()->EmptyIdentifierString();
// must detect because we know we're in strict mode, we also record any
// error that we might make in the future once we know the language mode.
if (V8_UNLIKELY(impl()->IsEvalOrArguments(name))) {
if (impl()->IsArguments(name) && scope()->ShouldBanArguments()) {
ReportMessage(MessageTemplate::kArgumentsDisallowedInInitializer);
return impl()->EmptyIdentifierString();
}
classifier()->RecordStrictModeFormalParameterError(
scanner()->location(), MessageTemplate::kStrictEvalArguments);
} }
return name; return name;
...@@ -1730,6 +1721,7 @@ ParserBase<Impl>::ParsePrimaryExpression() { ...@@ -1730,6 +1721,7 @@ ParserBase<Impl>::ParsePrimaryExpression() {
} }
// async Identifier => AsyncConciseBody // async Identifier => AsyncConciseBody
if (peek_any_identifier() && PeekAhead() == Token::ARROW) { if (peek_any_identifier() && PeekAhead() == Token::ARROW) {
beg_pos = peek_position();
name = ParseAndClassifyIdentifier(); name = ParseAndClassifyIdentifier();
if (!classifier()->is_valid_async_arrow_formal_parameters()) { if (!classifier()->is_valid_async_arrow_formal_parameters()) {
...@@ -1744,6 +1736,7 @@ ParserBase<Impl>::ParsePrimaryExpression() { ...@@ -1744,6 +1736,7 @@ ParserBase<Impl>::ParsePrimaryExpression() {
} }
if (peek() == Token::ARROW) { if (peek() == Token::ARROW) {
ClassifyFormalParameter(name, beg_pos, end_position());
scope_snapshot_ = std::move(Scope::Snapshot(scope())); scope_snapshot_ = std::move(Scope::Snapshot(scope()));
rewritable_length_ = static_cast<int>( rewritable_length_ = static_cast<int>(
function_state_->destructuring_assignments_to_rewrite().size()); function_state_->destructuring_assignments_to_rewrite().size());
...@@ -1866,7 +1859,7 @@ ParserBase<Impl>::ParseExpressionCoverGrammar() { ...@@ -1866,7 +1859,7 @@ ParserBase<Impl>::ParseExpressionCoverGrammar() {
} }
expression = ParseAssignmentExpression(); expression = ParseAssignmentExpression();
CheckArrowFormalParameter(expression); ClassifyArrowFormalParameter(expression);
list.Add(expression); list.Add(expression);
if (!Check(Token::COMMA)) break; if (!Check(Token::COMMA)) break;
...@@ -2602,7 +2595,7 @@ void ParserBase<Impl>::ParseArguments( ...@@ -2602,7 +2595,7 @@ void ParserBase<Impl>::ParseArguments(
ExpressionT argument = ParseAssignmentExpression(); ExpressionT argument = ParseAssignmentExpression();
if (V8_UNLIKELY(maybe_arrow)) { if (V8_UNLIKELY(maybe_arrow)) {
CheckArrowFormalParameter(argument); ClassifyArrowFormalParameter(argument);
if (is_spread) { if (is_spread) {
classifier()->RecordNonSimpleParameter(); classifier()->RecordNonSimpleParameter();
if (argument->IsAssignment()) { if (argument->IsAssignment()) {
...@@ -3476,7 +3469,10 @@ void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters) { ...@@ -3476,7 +3469,10 @@ void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters) {
FuncNameInferrerState fni_state(&fni_); FuncNameInferrerState fni_state(&fni_);
ExpressionT pattern = ParseBindingPattern(); ExpressionT pattern = ParseBindingPattern();
if (!impl()->IsIdentifier(pattern)) { if (impl()->IsIdentifier(pattern)) {
ClassifyFormalParameter(impl()->AsIdentifier(pattern), pattern->position(),
end_position());
} else {
parameters->is_simple = false; parameters->is_simple = false;
} }
...@@ -4440,14 +4436,26 @@ ParserBase<Impl>::RewriteInvalidReferenceExpression(ExpressionT expression, ...@@ -4440,14 +4436,26 @@ ParserBase<Impl>::RewriteInvalidReferenceExpression(ExpressionT expression,
} }
template <typename Impl> template <typename Impl>
void ParserBase<Impl>::CheckArrowFormalParameter(ExpressionT formal) { void ParserBase<Impl>::ClassifyFormalParameter(IdentifierT formal, int begin,
int end) {
if (impl()->IsEvalOrArguments(formal)) {
classifier()->RecordStrictModeFormalParameterError(
Scanner::Location(begin, end), MessageTemplate::kStrictEvalArguments);
}
}
template <typename Impl>
void ParserBase<Impl>::ClassifyArrowFormalParameter(ExpressionT formal) {
if (formal->is_parenthesized() || if (formal->is_parenthesized() ||
!(impl()->IsIdentifier(formal) || formal->IsPattern() || !(impl()->IsIdentifier(formal) || formal->IsPattern() ||
formal->IsAssignment())) { formal->IsAssignment())) {
classifier()->RecordBindingPatternError( classifier()->RecordBindingPatternError(
Scanner::Location(formal->position(), end_position()), Scanner::Location(formal->position(), end_position()),
MessageTemplate::kInvalidDestructuringTarget); MessageTemplate::kInvalidDestructuringTarget);
} else if (!impl()->IsIdentifier(formal)) { } else if (impl()->IsIdentifier(formal)) {
ClassifyFormalParameter(impl()->AsIdentifier(formal), formal->position(),
end_position());
} else {
classifier()->RecordNonSimpleParameter(); classifier()->RecordNonSimpleParameter();
} }
} }
...@@ -4470,6 +4478,10 @@ void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression, ...@@ -4470,6 +4478,10 @@ void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression,
classifier()->RecordBindingPatternError( classifier()->RecordBindingPatternError(
Scanner::Location(begin, end), Scanner::Location(begin, end),
MessageTemplate::kInvalidPropertyBindingPattern); MessageTemplate::kInvalidPropertyBindingPattern);
} else if (is_strict(language_mode()) && impl()->IsIdentifier(expression)) {
// Only classify if we are already in strict mode since the language mode
// cannot change in the presence of non-simple parameters.
ClassifyFormalParameter(impl()->AsIdentifier(expression), begin, end);
} }
return; return;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment