Commit 2b90397d authored by nikolaos's avatar nikolaos Committed by Commit bot

Set up rewriting triggers

This patch implements eager expression rewriting when parsing.  It will
be used for desugaring spreads but may have other uses in the future.

We call Traits::RewriteExpression as soon as we realise that something
parsed as an expression is actually used as an expression (and not as
a pattern).  This patch adds a dummy implementation for this function,
doing no rewriting at all, and adds the trigers in the right places of
the parser.

R=rossberg@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1567603005

Cr-Commit-Position: refs/heads/master@{#33300}
parent 48a3227b
...@@ -745,10 +745,9 @@ class ParserBase : public Traits { ...@@ -745,10 +745,9 @@ class ParserBase : public Traits {
bool* ok); bool* ok);
enum AssignmentExpressionFlags { enum AssignmentExpressionFlags {
kIsLeftHandSide = 0, kIsNormalAssignment = 0,
kIsRightHandSide = 1 << 0, kIsPossiblePatternElement = 1 << 0,
kIsPatternElement = 1 << 1, kIsPossibleArrowFormals = 1 << 1
kIsPossibleArrowFormals = 1 << 2
}; };
ExpressionT ParseAssignmentExpression(bool accept_IN, int flags, ExpressionT ParseAssignmentExpression(bool accept_IN, int flags,
...@@ -757,7 +756,7 @@ class ParserBase : public Traits { ...@@ -757,7 +756,7 @@ class ParserBase : public Traits {
ExpressionT ParseAssignmentExpression(bool accept_IN, ExpressionT ParseAssignmentExpression(bool accept_IN,
ExpressionClassifier* classifier, ExpressionClassifier* classifier,
bool* ok) { bool* ok) {
return ParseAssignmentExpression(accept_IN, kIsLeftHandSide, classifier, return ParseAssignmentExpression(accept_IN, kIsNormalAssignment, classifier,
ok); ok);
} }
ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok); ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
...@@ -1047,9 +1046,6 @@ typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier( ...@@ -1047,9 +1046,6 @@ typename ParserBase<Traits>::IdentifierT ParserBase<Traits>::ParseIdentifier(
if (!*ok) return Traits::EmptyIdentifier(); if (!*ok) return Traits::EmptyIdentifier();
ValidateBindingPattern(&classifier, ok); ValidateBindingPattern(&classifier, ok);
if (!*ok) return Traits::EmptyIdentifier(); if (!*ok) return Traits::EmptyIdentifier();
} else {
ValidateExpression(&classifier, ok);
if (!*ok) return Traits::EmptyIdentifier();
} }
return result; return result;
...@@ -1365,7 +1361,6 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier, ...@@ -1365,7 +1361,6 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
classifier, CHECK_OK); classifier, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
if (peek() != Token::ARROW) { if (peek() != Token::ARROW) {
ValidateExpression(classifier, CHECK_OK);
expr->set_is_parenthesized(); expr->set_is_parenthesized();
} }
return expr; return expr;
...@@ -1430,7 +1425,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( ...@@ -1430,7 +1425,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
bool accept_IN, bool* ok) { bool accept_IN, bool* ok) {
ExpressionClassifier classifier; ExpressionClassifier classifier;
ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK); ExpressionT result = ParseExpression(accept_IN, &classifier, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK); result = Traits::RewriteNonPattern(result, &classifier, CHECK_OK);
return result; return result;
} }
...@@ -1438,7 +1433,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( ...@@ -1438,7 +1433,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
template <class Traits> template <class Traits>
typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
bool accept_IN, ExpressionClassifier* classifier, bool* ok) { bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
return ParseExpression(accept_IN, kIsLeftHandSide, classifier, ok); return ParseExpression(accept_IN, kIsNormalAssignment, classifier, ok);
} }
...@@ -1539,7 +1534,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral( ...@@ -1539,7 +1534,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
MessageTemplate::kElementAfterRest); MessageTemplate::kElementAfterRest);
} }
} else { } else {
elem = this->ParseAssignmentExpression(true, kIsPatternElement, elem = this->ParseAssignmentExpression(true, kIsPossiblePatternElement,
classifier, CHECK_OK); classifier, CHECK_OK);
} }
values->Add(elem, zone_); values->Add(elem, zone_);
...@@ -1596,6 +1591,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName( ...@@ -1596,6 +1591,8 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
ExpressionClassifier computed_name_classifier; ExpressionClassifier computed_name_classifier;
ExpressionT expression = ExpressionT expression =
ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
expression = Traits::RewriteNonPattern(
expression, &computed_name_classifier, CHECK_OK);
classifier->Accumulate(computed_name_classifier, classifier->Accumulate(computed_name_classifier,
ExpressionClassifier::ExpressionProductions); ExpressionClassifier::ExpressionProductions);
Expect(Token::RBRACK, CHECK_OK); Expect(Token::RBRACK, CHECK_OK);
...@@ -1667,7 +1664,7 @@ ParserBase<Traits>::ParsePropertyDefinition( ...@@ -1667,7 +1664,7 @@ ParserBase<Traits>::ParsePropertyDefinition(
} }
Consume(Token::COLON); Consume(Token::COLON);
value = this->ParseAssignmentExpression( value = this->ParseAssignmentExpression(
true, kIsPatternElement, classifier, true, kIsPossiblePatternElement, classifier,
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
return factory()->NewObjectLiteralProperty(name_expression, value, false, return factory()->NewObjectLiteralProperty(name_expression, value, false,
...@@ -1709,6 +1706,8 @@ ParserBase<Traits>::ParsePropertyDefinition( ...@@ -1709,6 +1706,8 @@ ParserBase<Traits>::ParsePropertyDefinition(
ExpressionClassifier rhs_classifier; ExpressionClassifier rhs_classifier;
ExpressionT rhs = this->ParseAssignmentExpression( ExpressionT rhs = this->ParseAssignmentExpression(
true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
rhs = Traits::RewriteNonPattern(
rhs, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
classifier->Accumulate(rhs_classifier, classifier->Accumulate(rhs_classifier,
ExpressionClassifier::ExpressionProductions); ExpressionClassifier::ExpressionProductions);
value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs, value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
...@@ -1773,9 +1772,12 @@ ParserBase<Traits>::ParsePropertyDefinition( ...@@ -1773,9 +1772,12 @@ ParserBase<Traits>::ParsePropertyDefinition(
// ClassElement (static) // ClassElement (static)
// 'static' MethodDefinition // 'static' MethodDefinition
*name = this->EmptyIdentifier(); *name = this->EmptyIdentifier();
return ParsePropertyDefinition(checker, true, has_extends, true, ObjectLiteralPropertyT property = ParsePropertyDefinition(
is_computed_name, nullptr, classifier, name, checker, true, has_extends, true, is_computed_name, nullptr, classifier,
ok); name, ok);
property = Traits::RewriteNonPatternObjectLiteralProperty(property,
classifier, ok);
return property;
} }
if (is_get || is_set) { if (is_get || is_set) {
...@@ -1914,6 +1916,8 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( ...@@ -1914,6 +1916,8 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
ExpressionT argument = this->ParseAssignmentExpression( ExpressionT argument = this->ParseAssignmentExpression(
true, classifier, CHECK_OK_CUSTOM(NullExpressionList)); true, classifier, CHECK_OK_CUSTOM(NullExpressionList));
argument = Traits::RewriteNonPattern(argument, classifier,
CHECK_OK_CUSTOM(NullExpressionList));
if (is_spread) { if (is_spread) {
if (!spread_arg.IsValid()) { if (!spread_arg.IsValid()) {
spread_arg.beg_pos = start_pos; spread_arg.beg_pos = start_pos;
...@@ -1971,10 +1975,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, ...@@ -1971,10 +1975,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
// ArrowFunction // ArrowFunction
// YieldExpression // YieldExpression
// LeftHandSideExpression AssignmentOperator AssignmentExpression // LeftHandSideExpression AssignmentOperator AssignmentExpression
bool is_rhs = flags & kIsRightHandSide; bool maybe_pattern_element = flags & kIsPossiblePatternElement;
bool is_pattern_element = flags & kIsPatternElement; bool maybe_arrow_formals = flags & kIsPossibleArrowFormals;
bool is_destructuring_assignment = false; bool is_destructuring_assignment = false;
bool is_arrow_formals = flags & kIsPossibleArrowFormals;
int lhs_beg_pos = peek_position(); int lhs_beg_pos = peek_position();
if (peek() == Token::YIELD && is_generator()) { if (peek() == Token::YIELD && is_generator()) {
...@@ -2019,7 +2022,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, ...@@ -2019,7 +2022,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
} }
expression = this->ParseArrowFunctionLiteral( expression = this->ParseArrowFunctionLiteral(
accept_IN, parameters, arrow_formals_classifier, CHECK_OK); accept_IN, parameters, arrow_formals_classifier, CHECK_OK);
if (is_pattern_element) { if (maybe_pattern_element) {
classifier->RecordPatternError( classifier->RecordPatternError(
Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), Scanner::Location(lhs_beg_pos, scanner()->location().end_pos),
MessageTemplate::kInvalidDestructuringTarget); MessageTemplate::kInvalidDestructuringTarget);
...@@ -2048,13 +2051,10 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, ...@@ -2048,13 +2051,10 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
if (!Token::IsAssignmentOp(peek())) { if (!Token::IsAssignmentOp(peek())) {
// Parsed conditional expression only (no assignment). // Parsed conditional expression only (no assignment).
if (is_pattern_element) { if (maybe_pattern_element) {
CheckDestructuringElement(expression, classifier, lhs_beg_pos, CheckDestructuringElement(expression, classifier, lhs_beg_pos,
scanner()->location().end_pos); scanner()->location().end_pos);
} else if (is_rhs && maybe_pattern) {
ValidateExpression(classifier, CHECK_OK);
} }
return expression; return expression;
} }
...@@ -2068,12 +2068,12 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, ...@@ -2068,12 +2068,12 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
classifier->ForgiveCoverInitializedNameError(); classifier->ForgiveCoverInitializedNameError();
ValidateAssignmentPattern(classifier, CHECK_OK); ValidateAssignmentPattern(classifier, CHECK_OK);
is_destructuring_assignment = true; is_destructuring_assignment = true;
} else if (is_arrow_formals) { } else if (maybe_arrow_formals) {
expression = this->ClassifyAndRewriteReferenceExpression( expression = this->ClassifyAndRewriteReferenceExpression(
classifier, expression, lhs_beg_pos, scanner()->location().end_pos, classifier, expression, lhs_beg_pos, scanner()->location().end_pos,
MessageTemplate::kInvalidLhsInAssignment); MessageTemplate::kInvalidLhsInAssignment);
} else { } else {
if (is_pattern_element) { if (maybe_pattern_element) {
CheckDestructuringElement(expression, classifier, lhs_beg_pos, CheckDestructuringElement(expression, classifier, lhs_beg_pos,
scanner()->location().end_pos); scanner()->location().end_pos);
} }
...@@ -2094,11 +2094,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, ...@@ -2094,11 +2094,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
ExpressionClassifier rhs_classifier; ExpressionClassifier rhs_classifier;
int rhs_flags = flags; ExpressionT right =
rhs_flags &= ~(kIsPatternElement | kIsPossibleArrowFormals); this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
rhs_flags |= kIsRightHandSide; right = Traits::RewriteNonPattern(right, &rhs_classifier, CHECK_OK);
ExpressionT right = this->ParseAssignmentExpression(
accept_IN, rhs_flags, &rhs_classifier, CHECK_OK);
classifier->Accumulate( classifier->Accumulate(
rhs_classifier, ExpressionClassifier::ExpressionProductions | rhs_classifier, ExpressionClassifier::ExpressionProductions |
ExpressionClassifier::CoverInitializedNameProduction); ExpressionClassifier::CoverInitializedNameProduction);
...@@ -2112,7 +2110,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags, ...@@ -2112,7 +2110,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, int flags,
function_state_->AddProperty(); function_state_->AddProperty();
} }
if (op != Token::ASSIGN && is_pattern_element) { if (op != Token::ASSIGN && maybe_pattern_element) {
classifier->RecordAssignmentPatternError( classifier->RecordAssignmentPatternError(
Scanner::Location(lhs_beg_pos, scanner()->location().end_pos), Scanner::Location(lhs_beg_pos, scanner()->location().end_pos),
MessageTemplate::kInvalidDestructuringTarget); MessageTemplate::kInvalidDestructuringTarget);
...@@ -2180,6 +2178,8 @@ ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier, ...@@ -2180,6 +2178,8 @@ ParserBase<Traits>::ParseYieldExpression(ExpressionClassifier* classifier,
// Delegating yields require an RHS; fall through. // Delegating yields require an RHS; fall through.
default: default:
expression = ParseAssignmentExpression(false, classifier, CHECK_OK); expression = ParseAssignmentExpression(false, classifier, CHECK_OK);
expression =
Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
break; break;
} }
} }
...@@ -2212,6 +2212,7 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, ...@@ -2212,6 +2212,7 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
ExpressionT expression = ExpressionT expression =
this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
if (peek() != Token::CONDITIONAL) return expression; if (peek() != Token::CONDITIONAL) return expression;
expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
ArrowFormalParametersUnexpectedToken(classifier); ArrowFormalParametersUnexpectedToken(classifier);
BindingPatternUnexpectedToken(classifier); BindingPatternUnexpectedToken(classifier);
Consume(Token::CONDITIONAL); Consume(Token::CONDITIONAL);
...@@ -2219,9 +2220,11 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN, ...@@ -2219,9 +2220,11 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
// expressions we always accept the 'in' keyword; see ECMA-262, // expressions we always accept the 'in' keyword; see ECMA-262,
// section 11.12, page 58. // section 11.12, page 58.
ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
left = Traits::RewriteNonPattern(left, classifier, CHECK_OK);
Expect(Token::COLON, CHECK_OK); Expect(Token::COLON, CHECK_OK);
ExpressionT right = ExpressionT right =
ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
right = Traits::RewriteNonPattern(right, classifier, CHECK_OK);
return factory()->NewConditional(expression, left, right, pos); return factory()->NewConditional(expression, left, right, pos);
} }
...@@ -2237,6 +2240,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, ...@@ -2237,6 +2240,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
// prec1 >= 4 // prec1 >= 4
while (Precedence(peek(), accept_IN) == prec1) { while (Precedence(peek(), accept_IN) == prec1) {
x = Traits::RewriteNonPattern(x, classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier); BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier); ArrowFormalParametersUnexpectedToken(classifier);
Token::Value op = Next(); Token::Value op = Next();
...@@ -2244,6 +2248,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, ...@@ -2244,6 +2248,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
int pos = position(); int pos = position();
ExpressionT y = ExpressionT y =
ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK); ParseBinaryExpression(prec1 + 1, accept_IN, classifier, CHECK_OK);
y = Traits::RewriteNonPattern(y, classifier, CHECK_OK);
if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
factory())) { factory())) {
...@@ -2306,6 +2311,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, ...@@ -2306,6 +2311,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
op = Next(); op = Next();
int pos = position(); int pos = position();
ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK); ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
if (op == Token::DELETE && is_strict(language_mode())) { if (op == Token::DELETE && is_strict(language_mode())) {
if (is_strong(language_mode())) { if (is_strong(language_mode())) {
...@@ -2332,6 +2338,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, ...@@ -2332,6 +2338,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
expression, beg_pos, scanner()->location().end_pos, expression, beg_pos, scanner()->location().end_pos,
MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK); MessageTemplate::kInvalidLhsInPrefixOp, CHECK_OK);
this->MarkExpressionAsAssigned(expression); this->MarkExpressionAsAssigned(expression);
expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
return factory()->NewCountOperation(op, return factory()->NewCountOperation(op,
true /* prefix */, true /* prefix */,
...@@ -2363,6 +2370,7 @@ ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier, ...@@ -2363,6 +2370,7 @@ ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
expression, lhs_beg_pos, scanner()->location().end_pos, expression, lhs_beg_pos, scanner()->location().end_pos,
MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK); MessageTemplate::kInvalidLhsInPostfixOp, CHECK_OK);
expression = this->MarkExpressionAsAssigned(expression); expression = this->MarkExpressionAsAssigned(expression);
expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
Token::Value next = Next(); Token::Value next = Next();
expression = expression =
...@@ -2393,12 +2401,14 @@ ParserBase<Traits>::ParseLeftHandSideExpression( ...@@ -2393,12 +2401,14 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
Consume(Token::LBRACK); Consume(Token::LBRACK);
int pos = position(); int pos = position();
ExpressionT index = ParseExpression(true, classifier, CHECK_OK); ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
result = factory()->NewProperty(result, index, pos); result = factory()->NewProperty(result, index, pos);
Expect(Token::RBRACK, CHECK_OK); Expect(Token::RBRACK, CHECK_OK);
break; break;
} }
case Token::LPAREN: { case Token::LPAREN: {
result = Traits::RewriteNonPattern(result, classifier, CHECK_OK);
BindingPatternUnexpectedToken(classifier); BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier); ArrowFormalParametersUnexpectedToken(classifier);
...@@ -2526,6 +2536,7 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression( ...@@ -2526,6 +2536,7 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
} else { } else {
result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK); result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
} }
result = Traits::RewriteNonPattern(result, classifier, CHECK_OK);
if (peek() == Token::LPAREN) { if (peek() == Token::LPAREN) {
// NewExpression with arguments. // NewExpression with arguments.
Scanner::Location spread_pos; Scanner::Location spread_pos;
...@@ -2625,6 +2636,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression( ...@@ -2625,6 +2636,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression(
Consume(Token::LBRACK); Consume(Token::LBRACK);
int pos = position(); int pos = position();
ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
left = factory()->NewProperty(this_expr, index, pos); left = factory()->NewProperty(this_expr, index, pos);
if (fni_ != NULL) { if (fni_ != NULL) {
this->PushPropertyName(fni_, index); this->PushPropertyName(fni_, index);
...@@ -2660,6 +2672,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression( ...@@ -2660,6 +2672,7 @@ ParserBase<Traits>::ParseStrongInitializationExpression(
ExpressionT right = ExpressionT right =
this->ParseAssignmentExpression(true, classifier, CHECK_OK); this->ParseAssignmentExpression(true, classifier, CHECK_OK);
right = Traits::RewriteNonPattern(right, classifier, CHECK_OK);
this->CheckAssigningFunctionLiteralToProperty(left, right); this->CheckAssigningFunctionLiteralToProperty(left, right);
function_state_->AddProperty(); function_state_->AddProperty();
if (fni_ != NULL) { if (fni_ != NULL) {
...@@ -2816,6 +2829,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation( ...@@ -2816,6 +2829,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
Consume(Token::LBRACK); Consume(Token::LBRACK);
int pos = position(); int pos = position();
ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK); ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
index = Traits::RewriteNonPattern(index, classifier, CHECK_OK);
expression = factory()->NewProperty(expression, index, pos); expression = factory()->NewProperty(expression, index, pos);
if (fni_ != NULL) { if (fni_ != NULL) {
this->PushPropertyName(fni_, index); this->PushPropertyName(fni_, index);
...@@ -2896,7 +2910,7 @@ void ParserBase<Traits>::ParseFormalParameter( ...@@ -2896,7 +2910,7 @@ void ParserBase<Traits>::ParseFormalParameter(
ExpressionClassifier init_classifier; ExpressionClassifier init_classifier;
initializer = ParseAssignmentExpression(true, &init_classifier, ok); initializer = ParseAssignmentExpression(true, &init_classifier, ok);
if (!*ok) return; if (!*ok) return;
ValidateExpression(&init_classifier, ok); initializer = Traits::RewriteNonPattern(initializer, &init_classifier, ok);
ValidateFormalParameterInitializer(&init_classifier, ok); ValidateFormalParameterInitializer(&init_classifier, ok);
if (!*ok) return; if (!*ok) return;
parameters->is_simple = false; parameters->is_simple = false;
...@@ -3070,7 +3084,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( ...@@ -3070,7 +3084,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
ExpressionClassifier classifier; ExpressionClassifier classifier;
ExpressionT expression = ExpressionT expression =
ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK); expression = Traits::RewriteNonPattern(expression, &classifier, CHECK_OK);
body = this->NewStatementList(1, zone()); body = this->NewStatementList(1, zone());
this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK);
body->Add(factory()->NewReturnStatement(expression, pos), zone()); body->Add(factory()->NewReturnStatement(expression, pos), zone());
...@@ -3176,6 +3190,7 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, ...@@ -3176,6 +3190,7 @@ ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start,
int expr_pos = peek_position(); int expr_pos = peek_position();
ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK); ExpressionT expression = this->ParseExpression(true, classifier, CHECK_OK);
expression = Traits::RewriteNonPattern(expression, classifier, CHECK_OK);
Traits::AddTemplateExpression(&ts, expression); Traits::AddTemplateExpression(&ts, expression);
if (peek() != Token::RBRACE) { if (peek() != Token::RBRACE) {
......
...@@ -1565,7 +1565,7 @@ Statement* Parser::ParseExportDefault(bool* ok) { ...@@ -1565,7 +1565,7 @@ Statement* Parser::ParseExportDefault(bool* ok) {
int pos = peek_position(); int pos = peek_position();
ExpressionClassifier classifier; ExpressionClassifier classifier;
Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK); Expression* expr = ParseAssignmentExpression(true, &classifier, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK); expr = ParserTraits::RewriteNonPattern(expr, &classifier, CHECK_OK);
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
result = factory()->NewExpressionStatement(expr, pos); result = factory()->NewExpressionStatement(expr, pos);
...@@ -2392,7 +2392,7 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context, ...@@ -2392,7 +2392,7 @@ void Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
value = ParseAssignmentExpression(var_context != kForStatement, value = ParseAssignmentExpression(var_context != kForStatement,
&classifier, ok); &classifier, ok);
if (!*ok) return; if (!*ok) return;
ValidateExpression(&classifier, ok); value = ParserTraits::RewriteNonPattern(value, &classifier, ok);
if (!*ok) return; if (!*ok) return;
variable_loc.end_pos = scanner()->location().end_pos; variable_loc.end_pos = scanner()->location().end_pos;
...@@ -2503,7 +2503,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement( ...@@ -2503,7 +2503,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(
} else { } else {
expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK); expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
} }
ValidateExpression(&classifier, CHECK_OK); expr = ParserTraits::RewriteNonPattern(expr, &classifier, CHECK_OK);
switch (peek()) { switch (peek()) {
case Token::SEMICOLON: case Token::SEMICOLON:
Consume(Token::SEMICOLON); Consume(Token::SEMICOLON);
...@@ -3724,7 +3724,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, ...@@ -3724,7 +3724,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
if (is_destructuring) { if (is_destructuring) {
ValidateAssignmentPattern(&classifier, CHECK_OK); ValidateAssignmentPattern(&classifier, CHECK_OK);
} else { } else {
ValidateExpression(&classifier, CHECK_OK); expression =
ParserTraits::RewriteNonPattern(expression, &classifier, CHECK_OK);
} }
if (is_for_each) { if (is_for_each) {
...@@ -4748,7 +4749,7 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name, ...@@ -4748,7 +4749,7 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
block_scope->set_start_position(scanner()->location().end_pos); block_scope->set_start_position(scanner()->location().end_pos);
ExpressionClassifier classifier; ExpressionClassifier classifier;
extends = ParseLeftHandSideExpression(&classifier, CHECK_OK); extends = ParseLeftHandSideExpression(&classifier, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK); extends = ParserTraits::RewriteNonPattern(extends, &classifier, CHECK_OK);
} else { } else {
block_scope->set_start_position(scanner()->location().end_pos); block_scope->set_start_position(scanner()->location().end_pos);
} }
...@@ -4774,7 +4775,8 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name, ...@@ -4774,7 +4775,8 @@ ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
ObjectLiteral::Property* property = ParsePropertyDefinition( ObjectLiteral::Property* property = ParsePropertyDefinition(
&checker, in_class, has_extends, is_static, &is_computed_name, &checker, in_class, has_extends, is_static, &is_computed_name,
&has_seen_constructor, &classifier, &name, CHECK_OK); &has_seen_constructor, &classifier, &name, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK); property = ParserTraits::RewriteNonPatternObjectLiteralProperty(
property, &classifier, CHECK_OK);
if (has_seen_constructor && constructor == NULL) { if (has_seen_constructor && constructor == NULL) {
constructor = GetPropertyValue(property)->AsFunctionLiteral(); constructor = GetPropertyValue(property)->AsFunctionLiteral();
...@@ -4825,7 +4827,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) { ...@@ -4825,7 +4827,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
ExpressionClassifier classifier; ExpressionClassifier classifier;
ZoneList<Expression*>* args = ZoneList<Expression*>* args =
ParseArguments(&spread_pos, &classifier, CHECK_OK); ParseArguments(&spread_pos, &classifier, CHECK_OK);
ValidateExpression(&classifier, CHECK_OK); args = RewriteNonPatternArguments(args, &classifier, CHECK_OK);
DCHECK(!spread_pos.IsValid()); DCHECK(!spread_pos.IsValid());
...@@ -5388,6 +5390,58 @@ void ParserTraits::RewriteDestructuringAssignments() { ...@@ -5388,6 +5390,58 @@ void ParserTraits::RewriteDestructuringAssignments() {
} }
Expression* ParserTraits::RewriteNonPattern(
Expression* expr, const ExpressionClassifier* classifier, bool* ok) {
return parser_->RewriteNonPattern(expr, classifier, ok);
}
ZoneList<Expression*>* ParserTraits::RewriteNonPatternArguments(
ZoneList<Expression*>* args, const ExpressionClassifier* classifier,
bool* ok) {
return parser_->RewriteNonPatternArguments(args, classifier, ok);
}
ObjectLiteralProperty* ParserTraits::RewriteNonPatternObjectLiteralProperty(
ObjectLiteralProperty* property, const ExpressionClassifier* classifier,
bool* ok) {
return parser_->RewriteNonPatternObjectLiteralProperty(property, classifier,
ok);
}
Expression* Parser::RewriteNonPattern(Expression* expr,
const ExpressionClassifier* classifier,
bool* ok) {
// For the time being, this does no rewriting at all.
ValidateExpression(classifier, ok);
return expr;
}
ZoneList<Expression*>* Parser::RewriteNonPatternArguments(
ZoneList<Expression*>* args, const ExpressionClassifier* classifier,
bool* ok) {
// For the time being, this does no rewriting at all.
ValidateExpression(classifier, ok);
return args;
}
ObjectLiteralProperty* Parser::RewriteNonPatternObjectLiteralProperty(
ObjectLiteralProperty* property, const ExpressionClassifier* classifier,
bool* ok) {
if (property != nullptr) {
Expression* key = RewriteNonPattern(property->key(), classifier, ok);
property->set_key(key);
Expression* value = RewriteNonPattern(property->value(), classifier, ok);
property->set_value(value);
}
return property;
}
void Parser::RewriteDestructuringAssignments() { void Parser::RewriteDestructuringAssignments() {
FunctionState* func = function_state_; FunctionState* func = function_state_;
if (!allow_harmony_destructuring_assignment()) return; if (!allow_harmony_destructuring_assignment()) return;
......
...@@ -649,6 +649,16 @@ class ParserTraits { ...@@ -649,6 +649,16 @@ class ParserTraits {
void SetFunctionNameFromIdentifierRef(Expression* value, void SetFunctionNameFromIdentifierRef(Expression* value,
Expression* identifier); Expression* identifier);
// Rewrite expressions that are not used as patterns
V8_INLINE Expression* RewriteNonPattern(
Expression* expr, const ExpressionClassifier* classifier, bool* ok);
V8_INLINE ZoneList<Expression*>* RewriteNonPatternArguments(
ZoneList<Expression*>* args, const ExpressionClassifier* classifier,
bool* ok);
V8_INLINE ObjectLiteralProperty* RewriteNonPatternObjectLiteralProperty(
ObjectLiteralProperty* property, const ExpressionClassifier* classifier,
bool* ok);
private: private:
Parser* parser_; Parser* parser_;
}; };
...@@ -1003,6 +1013,15 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -1003,6 +1013,15 @@ class Parser : public ParserBase<ParserTraits> {
V8_INLINE void RewriteDestructuringAssignments(); V8_INLINE void RewriteDestructuringAssignments();
V8_INLINE Expression* RewriteNonPattern(
Expression* expr, const ExpressionClassifier* classifier, bool* ok);
V8_INLINE ZoneList<Expression*>* RewriteNonPatternArguments(
ZoneList<Expression*>* args, const ExpressionClassifier* classifier,
bool* ok);
V8_INLINE ObjectLiteralProperty* RewriteNonPatternObjectLiteralProperty(
ObjectLiteralProperty* property, const ExpressionClassifier* classifier,
bool* ok);
friend class InitializerRewriter; friend class InitializerRewriter;
void RewriteParameterInitializer(Expression* expr, Scope* scope); void RewriteParameterInitializer(Expression* expr, Scope* scope);
......
...@@ -932,6 +932,16 @@ class PreParserTraits { ...@@ -932,6 +932,16 @@ class PreParserTraits {
void SetFunctionNameFromIdentifierRef(PreParserExpression, void SetFunctionNameFromIdentifierRef(PreParserExpression,
PreParserExpression) {} PreParserExpression) {}
inline PreParserExpression RewriteNonPattern(
PreParserExpression expr, const ExpressionClassifier* classifier,
bool* ok);
inline PreParserExpression RewriteNonPatternArguments(
PreParserExpression args, const ExpressionClassifier* classifier,
bool* ok);
inline PreParserExpression RewriteNonPatternObjectLiteralProperty(
PreParserExpression property, const ExpressionClassifier* classifier,
bool* ok);
private: private:
PreParser* pre_parser_; PreParser* pre_parser_;
}; };
...@@ -1113,6 +1123,30 @@ PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) { ...@@ -1113,6 +1123,30 @@ PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) {
} }
PreParserExpression PreParserTraits::RewriteNonPattern(
PreParserExpression expr, const ExpressionClassifier* classifier,
bool* ok) {
pre_parser_->ValidateExpression(classifier, ok);
return expr;
}
PreParserExpression PreParserTraits::RewriteNonPatternArguments(
PreParserExpression args, const ExpressionClassifier* classifier,
bool* ok) {
pre_parser_->ValidateExpression(classifier, ok);
return args;
}
PreParserExpression PreParserTraits::RewriteNonPatternObjectLiteralProperty(
PreParserExpression property, const ExpressionClassifier* classifier,
bool* ok) {
pre_parser_->ValidateExpression(classifier, ok);
return property;
}
PreParserStatementList PreParser::ParseEagerFunctionBody( PreParserStatementList PreParser::ParseEagerFunctionBody(
PreParserIdentifier function_name, int pos, PreParserIdentifier function_name, int pos,
const PreParserFormalParameters& parameters, FunctionKind kind, const PreParserFormalParameters& parameters, FunctionKind kind,
......
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