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

Unified Diff: src/preparser.h

Issue 1168643005: [es6] parse destructuring assignment (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase + Bunch of tests + Nits fixed 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 862b7fb40dd894b53dfcec80d36aedde5b441e3f..23cc57d41bb2676773b3c109786e13e02f5f5333 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.
+ const 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());
@@ -2181,6 +2246,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
// Heuristically try to detect immediately called functions before
// seeing the call parentheses.
parenthesized_function_ = (peek() == Token::FUNCTION);
+ lhs_part = ExpressionClassifier::TARGET_NONE;
result = this->ParseExpression(true, classifier, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
}
@@ -2218,6 +2284,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
@@ -2230,6 +2297,10 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
}
}
+ if (*ok && lhs_part != ExpressionClassifier::TARGET_NONE) {
+ classifier->AppendAssignmentTarget(lhs_part);
+ }
+
return result;
}
@@ -2252,13 +2323,19 @@ 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);
+ ExpressionClassifier::AssignmentTargetType lhs_type =
+ expr_classifier.AssignmentTarget();
+ classifier->Accumulate(expr_classifier,
+ expr_classifier.is_destructuring_assignment()
+ ? ExpressionClassifier::PatternProductions
+ : ExpressionClassifier::AllProductions);
bool seen_rest = false;
while (peek() == Token::COMMA) {
+ ExpressionClassifier expr_classifier;
+ lhs_type = ExpressionClassifier::TARGET_PRIMARY;
if (seen_rest) {
// At this point the production can't possibly be valid, but we don't know
// which error to signal.
@@ -2277,13 +2354,17 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
seen_rest = is_rest = true;
}
int pos = position();
- ExpressionT right = this->ParseAssignmentExpression(
- accept_IN, &binding_classifier, CHECK_OK);
+ ExpressionT right =
+ this->ParseAssignmentExpression(accept_IN, &expr_classifier, CHECK_OK);
if (is_rest) right = factory()->NewSpread(right, pos);
- classifier->Accumulate(binding_classifier,
- ExpressionClassifier::AllProductions);
+ classifier->Accumulate(expr_classifier,
+ expr_classifier.is_destructuring_assignment()
+ ? ExpressionClassifier::PatternProductions
+ : ExpressionClassifier::AllProductions);
+
result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
}
+ classifier->AppendAssignmentTarget(lhs_type);
return result;
}
@@ -2301,6 +2382,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(),
@@ -2309,23 +2393,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);
}
@@ -2414,13 +2515,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);
@@ -2434,12 +2538,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,
@@ -2470,10 +2578,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();
@@ -2505,6 +2615,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,
@@ -2540,6 +2655,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);
}
@@ -2682,7 +2805,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 ::
@@ -2690,6 +2814,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();
@@ -2697,6 +2823,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;
@@ -2708,9 +2839,20 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
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();
+ }
+ }
+
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);
@@ -2736,6 +2878,25 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
ExpressionClassifier::StandardProductions |
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).
@@ -2746,13 +2907,18 @@ 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.
- if (op != Token::ASSIGN) {
+ if (op == Token::ASSIGN) {
+ classifier->set_assigned();
+ } else {
classifier->RecordBindingPatternError(scanner()->location(),
MessageTemplate::kUnexpectedToken,
Token::String(op));
@@ -2760,8 +2926,14 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
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);
arv (Not doing code reviews) 2015/06/19 18:49:05 Don't we need to pass in a new boolean here? The o
classifier->AccumulateReclassifyingAsPattern(rhs_classifier);
// TODO(1231235): We try to estimate the set of properties set by
@@ -2790,7 +2962,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>
@@ -2854,6 +3028,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,
@@ -2878,6 +3053,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();
@@ -2940,7 +3116,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);
@@ -2962,6 +3138,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);
@@ -2994,7 +3171,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);
@@ -3025,9 +3202,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;
@@ -3035,7 +3214,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);
@@ -3086,6 +3265,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);
@@ -3135,6 +3316,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();
@@ -3188,7 +3370,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);
@@ -3376,12 +3558,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(),
@@ -3437,10 +3621,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);
@@ -3450,6 +3638,8 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
}
case Token::PERIOD: {
BindingPatternUnexpectedToken(classifier);
+ classifier->AppendAssignmentTarget(
+ ExpressionClassifier::TARGET_PROPERTY);
Consume(Token::PERIOD);
int pos = position();
@@ -3464,6 +3654,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();
@@ -3475,8 +3666,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