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: |