Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1231)

Unified Diff: src/preparser.h

Issue 1173003002: Rebase for "parse destructuring assignment" patch (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.cc ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index 263e16aab8910925dec24d3ac121710344fb3929..b93bc668830168543d3b532263114df407d3299e 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -504,6 +504,29 @@ class ParserBase : public Traits {
void ReportUnexpectedToken(Token::Value token);
void ReportUnexpectedTokenAt(Scanner::Location location, Token::Value token);
+ ExpressionT CheckDestructuringAssignment(ExpressionT expr,
+ ExpressionClassifier* classifier,
+ bool needs_destructuring,
+ unsigned flags, bool* ok) {
+ // Don't rewrite AssignmentElement or RHS
+ // An AssignmentElement's optional initializer is parsed as a separate
+ // assignment expression.
+ bool rewrite =
+ flags & ~(ASSIGNMENT_RHS | ASSIGNMENT_ELEMENT) && needs_destructuring;
+ if (classifier->is_destructuring_assignment()) {
+ if (!classifier->is_valid_assignment_pattern()) {
+ this->ReportClassifierError(classifier->assignment_pattern_error());
+ *ok = false;
+ return this->EmptyExpression();
+ }
+ } else if (flags & ~ASSIGNMENT_ELEMENT) {
+ // If not a destructuring assignment, expect an expression
+ ValidateExpression(classifier, ok);
+ if (!*ok) return this->EmptyExpression();
+ }
+ if (rewrite) return Traits::RewriteDestructuringAssignment(expr, ok);
+ return expr;
+ }
void ReportClassifierError(const ExpressionClassifier::Error& error) {
Traits::ReportMessageAt(error.location, error.message, error.arg,
@@ -579,6 +602,17 @@ class ParserBase : public Traits {
Token::String(peek()));
}
+ void AssignmentPatternUnexpectedToken(ExpressionClassifier* classifier) {
+ classifier->RecordAssignmentPatternError(scanner()->peek_location(),
+ MessageTemplate::kUnexpectedToken,
+ Token::String(peek()));
+ }
+
+ void PatternUnexpectedToken(ExpressionClassifier* classifier) {
+ BindingPatternUnexpectedToken(classifier);
+ AssignmentPatternUnexpectedToken(classifier);
+ }
+
void ArrowFormalParametersUnexpectedToken(ExpressionClassifier* classifier) {
classifier->RecordArrowFormalParametersError(
scanner()->peek_location(), MessageTemplate::kUnexpectedToken,
@@ -625,9 +659,32 @@ class ParserBase : public Traits {
typename Traits::Type::ExpressionList ParseArguments(
Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
bool* ok);
- ExpressionT ParseAssignmentExpression(bool accept_IN,
+ enum AssignmentExpressionFlags {
+ ACCEPT_IN = 1 << 0,
+ ASSIGNMENT_RHS = 1 << 1,
+ ASSIGNMENT_ELEMENT = 1 << 2
+ };
+ ExpressionT ParseAssignmentExpression(unsigned flags,
+ bool* needs_destructuring,
ExpressionClassifier* classifier,
bool* ok);
+ ExpressionT ParseAssignmentExpression(bool accept_IN,
+ ExpressionClassifier* classifier,
+ bool* ok) {
+ // Overloaded for legacy compat
+ bool destructuring = false;
+ unsigned flags = accept_IN ? ACCEPT_IN : 0;
+ return ParseAssignmentExpression(flags, &destructuring, classifier, ok);
+ }
+ ExpressionT ParseAssignmentElement(bool accept_IN,
+ ExpressionClassifier* classifier,
+ bool* ok) {
+ // Don't automatically rewrite AssignmentExpressions which are meant to be
+ // AssignmentElements
+ bool destructuring = false;
+ unsigned flags = (accept_IN ? ACCEPT_IN : 0) | ASSIGNMENT_ELEMENT;
+ return ParseAssignmentExpression(flags, &destructuring, classifier, ok);
+ }
ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
ExpressionT ParseConditionalExpression(bool accept_IN,
ExpressionClassifier* classifier,
@@ -1586,6 +1643,11 @@ class PreParserTraits {
PreParserExpressionList args,
int pos);
+ inline PreParserExpression RewriteDestructuringAssignment(
+ PreParserExpression expr, bool* ok) {
+ return expr;
+ }
+
private:
PreParser* pre_parser_;
};
@@ -2060,6 +2122,8 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
int end_pos = scanner()->peek_location().end_pos;
ExpressionT result = this->EmptyExpression();
Token::Value token = peek();
+ typename ExpressionClassifier::AssignmentTargetType lhs_part =
+ ExpressionClassifier::TARGET_PRIMARY;
switch (token) {
case Token::THIS: {
BindingPatternUnexpectedToken(classifier);
@@ -2100,6 +2164,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
case Token::YIELD:
case Token::FUTURE_STRICT_RESERVED_WORD: {
// Using eval or arguments in this context is OK even in strict mode.
+ lhs_part = ExpressionClassifier::TARGET_IDENTIFIER;
IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
result = this->ExpressionFromIdentifier(name, beg_pos, end_pos, scope_,
factory());
@@ -2163,8 +2228,17 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
// Heuristically try to detect immediately called functions before
// seeing the call parentheses.
parenthesized_function_ = (peek() == Token::FUNCTION);
- result = this->ParseExpression(true, classifier, CHECK_OK);
+ ExpressionClassifier expr_classifier;
+ result = this->ParseExpression(true, &expr_classifier, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
+ if (peek() == Token::ARROW || parenthesized_function_) {
+ classifier->Accumulate(
+ expr_classifier,
+ ExpressionClassifier::ArrowFormalParametersProduction |
+ ExpressionClassifier::FormalParametersProductions);
+ } else {
+ lhs_part = expr_classifier.AssignmentTarget();
+ }
}
break;
@@ -2200,6 +2274,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
case Token::MOD:
if (allow_natives() || extension_ != NULL) {
result = this->ParseV8Intrinsic(CHECK_OK);
+ lhs_part = ExpressionClassifier::TARGET_CALL;
break;
}
// If we're not allowing special syntax we fall-through to the
@@ -2212,6 +2287,10 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
}
}
+ if (*ok && lhs_part != ExpressionClassifier::TARGET_NONE) {
+ classifier->AppendAssignmentTarget(lhs_part);
+ }
+
return result;
}
@@ -2234,18 +2313,27 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
// AssignmentExpression
// Expression ',' AssignmentExpression
- ExpressionClassifier binding_classifier;
+ ExpressionClassifier expr_classifier;
ExpressionT result =
- this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
- classifier->Accumulate(binding_classifier,
- ExpressionClassifier::AllProductions);
+ this->ParseAssignmentExpression(accept_IN, &expr_classifier, CHECK_OK);
+ classifier->AccumulateValidSimpleAssignmentTarget(expr_classifier);
+ classifier->Accumulate(expr_classifier,
+ expr_classifier.is_destructuring_assignment()
+ ? ExpressionClassifier::PatternProductions
+ : ExpressionClassifier::AllProductions);
while (peek() == Token::COMMA) {
Expect(Token::COMMA, CHECK_OK);
int pos = position();
- ExpressionT right = this->ParseAssignmentExpression(
- accept_IN, &binding_classifier, CHECK_OK);
- classifier->Accumulate(binding_classifier,
- ExpressionClassifier::AllProductions);
+ classifier->ReportInvalidSimpleAssignmentTarget();
+ ExpressionClassifier expr_classifier;
+ ExpressionT right =
+ this->ParseAssignmentExpression(accept_IN, &expr_classifier, CHECK_OK);
+ classifier->Accumulate(expr_classifier,
+ expr_classifier.is_destructuring_assignment()
+ ? ExpressionClassifier::PatternProductions
+ : ExpressionClassifier::AllProductions);
+
+
result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
}
return result;
@@ -2265,6 +2353,9 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
while (peek() != Token::RBRACK) {
bool seen_spread = false;
ExpressionT elem = this->EmptyExpression();
+ ExpressionClassifier element_classifier;
+ bool accumulate_element = true;
+ int start_pos = peek_position();
if (peek() == Token::COMMA) {
if (is_strong(language_mode())) {
ReportMessageAt(scanner()->peek_location(),
@@ -2273,23 +2364,40 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
return this->EmptyExpression();
}
elem = this->GetLiteralTheHole(peek_position(), factory());
+ accumulate_element = false;
} else if (peek() == Token::ELLIPSIS) {
if (!allow_harmony_spread_arrays()) {
ExpressionUnexpectedToken(classifier);
}
- int start_pos = peek_position();
Consume(Token::ELLIPSIS);
ExpressionT argument =
- this->ParseAssignmentExpression(true, classifier, CHECK_OK);
+ this->ParseAssignmentElement(true, &element_classifier, CHECK_OK);
elem = factory()->NewSpread(argument, start_pos);
seen_spread = true;
+
+ // AssignmentRestElements may not have initializers
+ if (element_classifier.IsAssigned()) {
+ Scanner::Location location(start_pos, scanner()->location().end_pos);
+ classifier->RecordAssignmentPatternError(
+ location, MessageTemplate::kInitializedAssignmentRestElement);
+ }
} else {
- elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
+ elem = this->ParseAssignmentElement(true, &element_classifier, CHECK_OK);
}
+ if (accumulate_element) {
+ if (!element_classifier.IsValidSimpleAssignmentTarget() &&
+ !element_classifier.IsValidPattern()) {
+ Scanner::Location location(start_pos, scanner()->location().end_pos);
+ classifier->RecordAssignmentPatternError(
+ location, MessageTemplate::kInvalidDestructuringAssignmentTarget);
+ }
+ classifier->Accumulate(element_classifier);
+ }
+
values->Add(elem, zone_);
if (peek() != Token::RBRACK) {
if (seen_spread) {
- BindingPatternUnexpectedToken(classifier);
+ PatternUnexpectedToken(classifier);
}
Expect(Token::COMMA, CHECK_OK);
}
@@ -2378,13 +2486,16 @@ ParserBase<Traits>::ParsePropertyDefinition(
bool is_set = false;
bool name_is_static = false;
bool is_generator = allow_harmony_object_literals_ && Check(Token::MUL);
-
+ // Classify destructuring assignment target for ObjectAssignmentPattern
+ ExpressionClassifier property_classifier;
Token::Value name_token = peek();
int next_beg_pos = scanner()->peek_location().beg_pos;
int next_end_pos = scanner()->peek_location().end_pos;
+ int value_start = next_beg_pos;
+ int value_end = next_end_pos;
ExpressionT name_expression = ParsePropertyName(
- &name, &is_get, &is_set, &name_is_static, is_computed_name, classifier,
- CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ &name, &is_get, &is_set, &name_is_static, is_computed_name,
+ &property_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
if (fni_ != nullptr && !*is_computed_name) {
this->PushLiteralName(fni_, name);
@@ -2398,12 +2509,16 @@ ParserBase<Traits>::ParsePropertyDefinition(
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
}
Consume(Token::COLON);
- value = this->ParseAssignmentExpression(
- true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
-
+ property_classifier = ExpressionClassifier();
+ value_start = peek_position();
+ value = this->ParseAssignmentElement(
+ true, &property_classifier,
+ CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ value_end = scanner()->location().end_pos;
} else if (is_generator ||
(allow_harmony_object_literals_ && peek() == Token::LPAREN)) {
// Concise Method
+ property_classifier.ReportInvalidSimpleAssignmentTarget();
if (!*is_computed_name) {
checker->CheckProperty(name_token, kMethodProperty, is_static,
is_generator,
@@ -2434,10 +2549,12 @@ ParserBase<Traits>::ParsePropertyDefinition(
} else if (in_class && name_is_static && !is_static) {
// static MethodDefinition
+ property_classifier.ReportInvalidSimpleAssignmentTarget();
return ParsePropertyDefinition(checker, true, has_extends, true,
is_computed_name, nullptr, classifier, ok);
} else if (is_get || is_set) {
// Accessor
+ property_classifier.ReportInvalidSimpleAssignmentTarget();
name = this->EmptyIdentifier();
bool dont_care = false;
name_token = peek();
@@ -2469,6 +2586,11 @@ ParserBase<Traits>::ParsePropertyDefinition(
factory()->NewStringLiteral(name, name_expression->position());
}
+ value_end = scanner()->location().end_pos;
+ Scanner::Location location(value_start, value_end);
+ classifier->RecordAssignmentPatternError(
+ location, MessageTemplate::kInvalidDestructuringAssignmentTarget);
+
return factory()->NewObjectLiteralProperty(
name_expression, value,
is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
@@ -2504,6 +2626,14 @@ ParserBase<Traits>::ParsePropertyDefinition(
return this->EmptyObjectLiteralProperty();
}
+ if (!property_classifier.IsValidSimpleAssignmentTarget() &&
+ !property_classifier.IsPatternAssignmentElement()) {
+ Scanner::Location location(value_start, value_end);
+ classifier->RecordAssignmentPatternError(
+ location, MessageTemplate::kInvalidDestructuringAssignmentTarget);
+ }
+ classifier->Accumulate(property_classifier);
+
return factory()->NewObjectLiteralProperty(name_expression, value, is_static,
*is_computed_name);
}
@@ -2646,7 +2776,8 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
// Precedence = 2
template <class Traits>
typename ParserBase<Traits>::ExpressionT
-ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
+ParserBase<Traits>::ParseAssignmentExpression(unsigned flags,
+ bool* needs_destructuring,
ExpressionClassifier* classifier,
bool* ok) {
// AssignmentExpression ::
@@ -2654,6 +2785,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
// ArrowFunction
// YieldExpression
// LeftHandSideExpression AssignmentOperator AssignmentExpression
+ bool accept_IN = flags & ACCEPT_IN;
+ bool is_assignment_element = flags & ASSIGNMENT_ELEMENT;
Scanner::Location lhs_location = scanner()->peek_location();
@@ -2661,6 +2794,11 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
return this->ParseYieldExpression(classifier, ok);
}
+ bool maybe_assignment_pattern =
+ allow_harmony_destructuring() &&
+ classifier->is_valid_assignment_pattern() &&
+ (peek() == Token::LBRACK || peek() == Token::LBRACE);
+
if (fni_ != NULL) fni_->Enter();
ParserBase<Traits>::Checkpoint checkpoint(this);
ExpressionClassifier arrow_formals_classifier;
@@ -2669,13 +2807,26 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
// formal parameter list.
ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
}
+
ExpressionT expression = this->ParseConditionalExpression(
accept_IN, &arrow_formals_classifier, CHECK_OK);
+
+ if (!arrow_formals_classifier.is_valid_assignment_pattern()) {
+ if (maybe_assignment_pattern && peek() == Token::ASSIGN) {
+ // ObjectAssignmentPattern or ArrayAssignmentPattern contains an error
+ ReportClassifierError(
+ arrow_formals_classifier.assignment_pattern_error());
+ *ok = false;
+ return this->EmptyExpression();
+ }
+ }
+
classifier->Accumulate(arrow_formals_classifier);
if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
checkpoint.Restore();
BindingPatternUnexpectedToken(classifier);
+ classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PRIMARY);
ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
CHECK_OK);
Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos);
@@ -2700,6 +2851,25 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
classifier->Accumulate(arrow_formals_classifier,
ExpressionClassifier::FormalParametersProductions);
+ bool valid_destructuring_assignment_target =
+ arrow_formals_classifier.IsValidSimpleAssignmentTarget();
+ if (valid_destructuring_assignment_target) {
+ classifier->AccumulateValidSimpleAssignmentTarget(arrow_formals_classifier);
+ } else if (!maybe_assignment_pattern ||
+ !arrow_formals_classifier.is_valid_assignment_pattern()) {
+ // Potentially a bad DestructuringAssignmentTarget
+ classifier->RecordAssignmentPatternError(
+ Scanner::Location(lhs_location.beg_pos, scanner()->location().end_pos),
+ MessageTemplate::kInvalidDestructuringAssignmentTarget);
+ }
+
+ if (maybe_assignment_pattern) {
+ classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PATTERN);
+ if ((maybe_assignment_pattern = peek() == Token::ASSIGN)) {
+ *needs_destructuring = true;
+ }
+ }
+
if (!Token::IsAssignmentOp(peek())) {
if (fni_ != NULL) fni_->Leave();
// Parsed conditional expression only (no assignment).
@@ -2710,9 +2880,12 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
BindingPatternUnexpectedToken(classifier);
}
- expression = this->CheckAndRewriteReferenceExpression(
- expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment,
- CHECK_OK);
+ if (!maybe_assignment_pattern) {
+ expression = this->CheckAndRewriteReferenceExpression(
+ expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment,
+ CHECK_OK);
+ }
+
expression = this->MarkExpressionAsAssigned(expression);
Token::Value op = Next(); // Get assignment operator.
@@ -2720,12 +2893,20 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
classifier->RecordBindingPatternError(scanner()->location(),
MessageTemplate::kUnexpectedToken,
Token::String(op));
+ } else {
+ classifier->set_assigned();
}
int pos = position();
ExpressionClassifier rhs_classifier;
- ExpressionT right =
- this->ParseAssignmentExpression(accept_IN, &rhs_classifier, CHECK_OK);
+ unsigned rhs_flags = flags | ASSIGNMENT_RHS;
+ if (is_assignment_element) {
+ // Parse an assignment element's initializer as a regular
+ // AssignmentExpression
+ rhs_flags &= ~(ASSIGNMENT_RHS | ASSIGNMENT_ELEMENT);
+ }
+ ExpressionT right = this->ParseAssignmentExpression(
+ rhs_flags, needs_destructuring, &rhs_classifier, CHECK_OK);
classifier->AccumulateReclassifyingAsPattern(rhs_classifier);
// TODO(1231235): We try to estimate the set of properties set by
@@ -2754,7 +2935,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
fni_->Leave();
}
- return factory()->NewAssignment(op, expression, right, pos);
+ ExpressionT result = factory()->NewAssignment(op, expression, right, pos);
+ return this->CheckDestructuringAssignment(
+ result, classifier, *needs_destructuring, flags, CHECK_OK);
}
template <class Traits>
@@ -2818,6 +3001,7 @@ ParserBase<Traits>::ParseConditionalExpression(bool accept_IN,
this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
if (peek() != Token::CONDITIONAL) return expression;
BindingPatternUnexpectedToken(classifier);
+ classifier->ReportInvalidSimpleAssignmentTarget();
Consume(Token::CONDITIONAL);
// In parsing the first assignment expression in conditional
// expressions we always accept the 'in' keyword; see ECMA-262,
@@ -2842,6 +3026,7 @@ ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN,
// prec1 >= 4
while (Precedence(peek(), accept_IN) == prec1) {
BindingPatternUnexpectedToken(classifier);
+ classifier->ReportInvalidSimpleAssignmentTarget();
Token::Value op = Next();
Scanner::Location op_location = scanner()->location();
int pos = position();
@@ -2904,7 +3089,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
Token::Value op = peek();
if (Token::IsUnaryOp(op)) {
BindingPatternUnexpectedToken(classifier);
-
+ classifier->ReportInvalidSimpleAssignmentTarget();
op = Next();
int pos = position();
ExpressionT expression = ParseUnaryExpression(classifier, CHECK_OK);
@@ -2926,6 +3111,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
return this->BuildUnaryExpression(expression, op, pos, factory());
} else if (Token::IsCountOp(op)) {
BindingPatternUnexpectedToken(classifier);
+ classifier->ReportInvalidSimpleAssignmentTarget();
op = Next();
Scanner::Location lhs_location = scanner()->peek_location();
ExpressionT expression = this->ParseUnaryExpression(classifier, CHECK_OK);
@@ -2958,7 +3144,7 @@ ParserBase<Traits>::ParsePostfixExpression(ExpressionClassifier* classifier,
if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
Token::IsCountOp(peek())) {
BindingPatternUnexpectedToken(classifier);
-
+ classifier->ReportInvalidSimpleAssignmentTarget();
expression = this->CheckAndRewriteReferenceExpression(
expression, lhs_location, MessageTemplate::kInvalidLhsInPostfixOp,
CHECK_OK);
@@ -2989,9 +3175,11 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
switch (peek()) {
case Token::LBRACK: {
BindingPatternUnexpectedToken(classifier);
+ classifier->AppendAssignmentTarget(
+ ExpressionClassifier::TARGET_PROPERTY);
Consume(Token::LBRACK);
int pos = position();
- ExpressionT index = ParseExpression(true, classifier, CHECK_OK);
+ ExpressionT index = ParseExpression(true, CHECK_OK);
result = factory()->NewProperty(result, index, pos);
Expect(Token::RBRACK, CHECK_OK);
break;
@@ -2999,7 +3187,7 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
case Token::LPAREN: {
BindingPatternUnexpectedToken(classifier);
-
+ classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
if (is_strong(language_mode()) && this->IsIdentifier(result) &&
this->IsEval(this->AsIdentifier(result))) {
ReportMessage(MessageTemplate::kStrongDirectEval);
@@ -3050,6 +3238,8 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
case Token::PERIOD: {
BindingPatternUnexpectedToken(classifier);
+ classifier->AppendAssignmentTarget(
+ ExpressionClassifier::TARGET_PROPERTY);
Consume(Token::PERIOD);
int pos = position();
IdentifierT name = ParseIdentifierName(CHECK_OK);
@@ -3092,6 +3282,7 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
if (peek() == Token::NEW) {
BindingPatternUnexpectedToken(classifier);
+ classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
Consume(Token::NEW);
int new_pos = position();
ExpressionT result = this->EmptyExpression();
@@ -3145,7 +3336,7 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
ExpressionT result = this->EmptyExpression();
if (peek() == Token::FUNCTION) {
BindingPatternUnexpectedToken(classifier);
-
+ classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PRIMARY);
Consume(Token::FUNCTION);
int function_token_position = position();
bool is_generator = Check(Token::MUL);
@@ -3333,12 +3524,14 @@ ParserBase<Traits>::ParseSuperExpression(bool is_new,
if (IsConciseMethod(kind) || IsAccessorFunction(kind) ||
i::IsConstructor(kind)) {
if (peek() == Token::PERIOD || peek() == Token::LBRACK) {
+ classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PROPERTY);
scope->RecordSuperPropertyUsage();
return this->SuperPropertyReference(scope_, factory(), pos);
}
// new super() is never allowed.
// super() is only allowed in derived constructor
if (!is_new && peek() == Token::LPAREN && IsSubclassConstructor(kind)) {
+ classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
if (is_strong(language_mode())) {
// Super calls in strong mode are parsed separately.
ReportMessageAt(scanner()->location(),
@@ -3394,10 +3587,14 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
switch (peek()) {
case Token::LBRACK: {
BindingPatternUnexpectedToken(classifier);
-
+ classifier->AppendAssignmentTarget(
+ ExpressionClassifier::TARGET_PROPERTY);
Consume(Token::LBRACK);
int pos = position();
- ExpressionT index = this->ParseExpression(true, classifier, CHECK_OK);
+ // Ignore pattern errors within expression
+ ExpressionClassifier prop_classifier;
+ ExpressionT index =
+ this->ParseExpression(true, &prop_classifier, CHECK_OK);
expression = factory()->NewProperty(expression, index, pos);
if (fni_ != NULL) {
this->PushPropertyName(fni_, index);
@@ -3407,6 +3604,8 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
}
case Token::PERIOD: {
BindingPatternUnexpectedToken(classifier);
+ classifier->AppendAssignmentTarget(
+ ExpressionClassifier::TARGET_PROPERTY);
Consume(Token::PERIOD);
int pos = position();
@@ -3421,6 +3620,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL: {
BindingPatternUnexpectedToken(classifier);
+ classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_CALL);
int pos;
if (scanner()->current_token() == Token::IDENTIFIER) {
pos = position();
@@ -3432,8 +3632,10 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
expression->AsFunctionLiteral()->set_should_eager_compile();
}
}
+ // Ignore classifying tagged template
+ ExpressionClassifier call_classifier;
expression =
- ParseTemplateLiteral(expression, pos, classifier, CHECK_OK);
+ ParseTemplateLiteral(expression, pos, &call_classifier, CHECK_OK);
break;
}
default:
« no previous file with comments | « src/parser.cc ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698