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

Unified Diff: src/preparser.h

Issue 1168643005: [es6] parse destructuring assignment (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix arrow function parsing 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
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index 34295c71f297bce5cdca1fc81aa80252298304e5..3a25790377e62ac27ed4426cac5c646071cfb8f6 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -570,7 +570,84 @@ class ParserBase : public Traits {
bool HasError() const { return location.IsValid(); }
};
- ExpressionClassifier() {}
+ ExpressionClassifier() : lhs_type_(TARGET_NONE), assigned_(false) {}
+
+ enum AssignmentTargetType {
+ TARGET_NONE = 0,
+
+ // IdentifierReference
+ TARGET_IDENTIFIER,
+
+ // MemberExpression . <property name>
+ // MemberExpression [<property name>]
+ TARGET_PROPERTY,
+
+ // MemberExpression ( arguments )
+ // new MemberExpression ( arguments )
+ // MemberExpression TemplateLiteral
+ TARGET_CALL,
+
+ // this
+ // Literal
+ // ArrayLiteral
+ // ObjectLiteral
+ // FunctionExpression
+ // ClassExpression
+ // GeneratorExpression
+ // RegularExpressionLiteral
+ // TemplateLiteral
+ // CoverParenthesizedExpressionAndArrowParameterList
+ TARGET_PRIMARY,
+
+ // new.target
+ // yield (in generator)
+ TARGET_RESTRICTED,
+
+ // UnaryExpression
+ // MultiplicativeExpression
+ // AdditiveExpression
+ // ShiftExpression
+ // RelationalExpression
+ // EqualityExpression
+ // BitwiseANDExpression
+ // BitwiseXORExpression
+ // BitwiseORExpression
+ // LogicalANDExpression
+ // LogicalORExpression
+ // ConditionalExpression
+ // AssignmentExpression
+ // ... Pretty much any binary operator
+ UNACCEPTABLE_TARGET,
+
+ // BindingPattern
+ TARGET_PATTERN
+ };
+
+ inline void AppendAssignmentTarget(AssignmentTargetType value) {
arv (Not doing code reviews) 2015/06/04 20:08:03 s/value/type/
caitp (gmail) 2015/06/05 18:37:13 Done.
+ if (lhs_type_ == UNACCEPTABLE_TARGET) return;
+ lhs_type_ = value;
+ }
+
+ inline void ReportInvalidSimpleAssignmentTarget() {
+ lhs_type_ = UNACCEPTABLE_TARGET;
+ }
+
+ inline bool IsValidSimpleAssignmentTarget() const {
+ // Only identifiers and properties are valid targets.
+ return lhs_type_ >= TARGET_IDENTIFIER && lhs_type_ <= TARGET_PROPERTY;
+ }
+
+ inline bool IsPatternAssignmentElement() const {
+ // Any AssignmentElement for which IsValidSimpleAssignmentTarget is false.
+ // Used for nested AssignmentPatterns
+ return lhs_type_ == TARGET_PATTERN && is_valid_assignment_pattern();
+ }
+
+ void set_assigned() { assigned_ = true; }
+
+ bool is_destructuring_assignment() const {
+ return lhs_type_ == TARGET_PATTERN && assigned_;
+ }
bool is_valid_expression() const { return !expression_error_.HasError(); }
@@ -707,6 +784,13 @@ class ParserBase : public Traits {
ArrowFormalParametersProduction),
};
+ void AccumulateValidSimpleAssignmentTarget(
+ const ExpressionClassifier& inner) {
+ if (lhs_type_ != UNACCEPTABLE_TARGET) {
+ lhs_type_ = inner.lhs_type_;
+ }
+ }
+
void Accumulate(const ExpressionClassifier& inner,
unsigned productions = StandardProductions) {
if (productions & ExpressionProduction && is_valid_expression()) {
@@ -755,6 +839,8 @@ class ParserBase : public Traits {
}
private:
+ AssignmentTargetType lhs_type_;
+ bool assigned_;
Error expression_error_;
Error binding_pattern_error_;
Error assignment_pattern_error_;
@@ -764,6 +850,20 @@ class ParserBase : public Traits {
Error strong_mode_formal_parameter_error_;
};
+ ExpressionT CheckDestructuringAssignment(ExpressionT expr,
+ ExpressionClassifier* classifier,
+ bool* ok) {
+ if (classifier->is_destructuring_assignment()) {
+ if (!classifier->is_valid_assignment_pattern()) {
+ this->ReportClassifierError(classifier->assignment_pattern_error());
+ *ok = false;
+ return this->EmptyExpression();
+ }
+ return Traits::RewriteDestructuringAssignment(expr);
+ }
+ return expr;
+ }
+
void ReportClassifierError(
const typename ExpressionClassifier::Error& error) {
Traits::ReportMessageAt(error.location, error.message, error.arg,
@@ -885,9 +985,14 @@ class ParserBase : public Traits {
typename Traits::Type::ExpressionList ParseArguments(
Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
bool* ok);
- ExpressionT ParseAssignmentExpression(bool accept_IN,
+ ExpressionT ParseAssignmentExpression(bool accept_IN, bool is_rhs,
ExpressionClassifier* classifier,
bool* ok);
+ ExpressionT ParseAssignmentExpression(bool accept_IN,
+ ExpressionClassifier* classifier,
+ bool* ok) {
+ return ParseAssignmentExpression(accept_IN, false, classifier, ok);
+ }
ExpressionT ParseYieldExpression(ExpressionClassifier* classifier, bool* ok);
ExpressionT ParseConditionalExpression(bool accept_IN,
ExpressionClassifier* classifier,
@@ -1836,6 +1941,11 @@ class PreParserTraits {
PreParserExpressionList args,
int pos);
+ inline PreParserExpression RewriteDestructuringAssignment(
+ PreParserExpression expr) {
+ return expr;
+ }
+
private:
PreParser* pre_parser_;
};
@@ -2313,6 +2423,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);
@@ -2353,6 +2465,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());
@@ -2416,8 +2529,15 @@ 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::FormalParametersProduction);
+ }
}
break;
@@ -2453,6 +2573,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
@@ -2465,6 +2586,10 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
}
}
+ if (*ok && lhs_part != ExpressionClassifier::TARGET_NONE) {
+ classifier->AppendAssignmentTarget(lhs_part);
+ }
+
return result;
}
@@ -2490,15 +2615,27 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
ExpressionClassifier binding_classifier;
arv (Not doing code reviews) 2015/06/04 20:08:03 rename this?
caitp (gmail) 2015/06/05 18:37:13 Done.
ExpressionT result =
this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
- classifier->Accumulate(binding_classifier,
- ExpressionClassifier::AllProductions);
+ if (binding_classifier.is_destructuring_assignment()) {
+ classifier->Accumulate(binding_classifier,
+ ExpressionClassifier::PatternProductions);
+ } else {
+ classifier->Accumulate(binding_classifier,
+ ExpressionClassifier::AllProductions);
+ }
while (peek() == Token::COMMA) {
Expect(Token::COMMA, CHECK_OK);
int pos = position();
+ ExpressionClassifier binding_classifier;
ExpressionT right = this->ParseAssignmentExpression(
accept_IN, &binding_classifier, CHECK_OK);
- classifier->Accumulate(binding_classifier,
- ExpressionClassifier::AllProductions);
+ if (binding_classifier.is_destructuring_assignment()) {
+ classifier->Accumulate(binding_classifier,
+ ExpressionClassifier::PatternProductions);
+ } else {
+ classifier->Accumulate(binding_classifier,
+ ExpressionClassifier::AllProductions);
+ }
+
result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
}
return result;
@@ -2518,6 +2655,7 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
while (peek() != Token::RBRACK) {
bool seen_spread = false;
ExpressionT elem = this->EmptyExpression();
+ ExpressionClassifier element_classifier;
if (peek() == Token::COMMA) {
if (is_strong(language_mode())) {
ReportMessageAt(scanner()->peek_location(),
@@ -2537,7 +2675,16 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
elem = factory()->NewSpread(argument, start_pos);
seen_spread = true;
} else {
- elem = this->ParseAssignmentExpression(true, classifier, CHECK_OK);
+ int start_pos = peek_position();
+ elem =
+ this->ParseAssignmentExpression(true, &element_classifier, CHECK_OK);
+ if (!element_classifier.IsValidSimpleAssignmentTarget() &&
+ !element_classifier.IsPatternAssignmentElement()) {
+ 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) {
@@ -2631,13 +2778,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);
@@ -2651,12 +2801,16 @@ ParserBase<Traits>::ParsePropertyDefinition(
CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
}
Consume(Token::COLON);
+ property_classifier = ExpressionClassifier();
+ value_start = peek_position();
value = this->ParseAssignmentExpression(
- true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
-
+ 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,
@@ -2687,10 +2841,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();
@@ -2722,6 +2878,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,
@@ -2740,7 +2901,8 @@ ParserBase<Traits>::ParsePropertyDefinition(
Consume(Token::ASSIGN);
ExpressionClassifier rhs_classifier;
ExpressionT rhs = this->ParseAssignmentExpression(
- true, &rhs_classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+ true, true, &rhs_classifier,
+ CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
classifier->AccumulateReclassifyingAsPattern(rhs_classifier);
value = factory()->NewAssignment(Token::ASSIGN, lhs, rhs,
RelocInfo::kNoPosition);
@@ -2757,6 +2919,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);
}
@@ -2899,7 +3069,7 @@ 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(bool accept_IN, bool is_rhs,
arv (Not doing code reviews) 2015/06/04 20:08:03 TODO: Maybe add enums for this and accept_IN?
caitp (gmail) 2015/06/05 18:37:13 Done.
ExpressionClassifier* classifier,
bool* ok) {
// AssignmentExpression ::
@@ -2914,6 +3084,11 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
return this->ParseYieldExpression(classifier, ok);
}
+ bool maybeAssignmentPattern =
arv (Not doing code reviews) 2015/06/04 20:08:03 maybe_assignment_pattern
caitp (gmail) 2015/06/05 18:37:13 Done.
+ allow_harmony_destructuring() && !is_rhs &&
arv (Not doing code reviews) 2015/06/04 20:08:04 maybe rename is_rhs to is_lhs?
caitp (gmail) 2015/06/05 18:37:13 renamed to `pattern_lhs` in a previous patch
+ 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;
@@ -2922,13 +3097,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 (maybeAssignmentPattern && 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);
@@ -2953,6 +3141,22 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
classifier->Accumulate(arrow_formals_classifier,
ExpressionClassifier::FormalParametersProduction);
+ bool validDestructuringAssignmentTarget =
arv (Not doing code reviews) 2015/06/04 20:08:04 s/validDestructuringAssignmentTarget/valid_destruc
caitp (gmail) 2015/06/05 18:37:13 Done.
+ arrow_formals_classifier.IsValidSimpleAssignmentTarget();
+ if (validDestructuringAssignmentTarget) {
+ classifier->AccumulateValidSimpleAssignmentTarget(arrow_formals_classifier);
+ } else if (!maybeAssignmentPattern ||
+ !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 (maybeAssignmentPattern) {
+ classifier->AppendAssignmentTarget(ExpressionClassifier::TARGET_PATTERN);
+ }
+
if (!Token::IsAssignmentOp(peek())) {
if (fni_ != NULL) fni_->Leave();
// Parsed conditional expression only (no assignment).
@@ -2963,9 +3167,12 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
BindingPatternUnexpectedToken(classifier);
}
- expression = this->CheckAndRewriteReferenceExpression(
- expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment,
- CHECK_OK);
+ if (!maybeAssignmentPattern || peek() != Token::ASSIGN) {
+ expression = this->CheckAndRewriteReferenceExpression(
+ expression, lhs_location, MessageTemplate::kInvalidLhsInAssignment,
+ CHECK_OK);
+ }
+
expression = this->MarkExpressionAsAssigned(expression);
Token::Value op = Next(); // Get assignment operator.
@@ -2973,6 +3180,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
classifier->RecordBindingPatternError(scanner()->location(),
MessageTemplate::kUnexpectedToken,
Token::String(op));
+ } else {
+ classifier->set_assigned();
}
int pos = position();
@@ -3007,7 +3216,8 @@ 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, CHECK_OK);
}
template <class Traits>
@@ -3074,6 +3284,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,
@@ -3098,6 +3309,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();
@@ -3160,7 +3372,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);
@@ -3182,6 +3394,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);
@@ -3214,7 +3427,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);
@@ -3245,6 +3458,8 @@ 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);
@@ -3255,7 +3470,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);
@@ -3306,6 +3521,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);
@@ -3345,6 +3562,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();
@@ -3396,7 +3614,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);
@@ -3585,12 +3803,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(),
@@ -3621,10 +3841,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);
@@ -3634,6 +3858,8 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
}
case Token::PERIOD: {
BindingPatternUnexpectedToken(classifier);
+ classifier->AppendAssignmentTarget(
+ ExpressionClassifier::TARGET_PROPERTY);
Consume(Token::PERIOD);
int pos = position();
@@ -3648,6 +3874,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();
@@ -3659,8 +3886,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') | test/cctest/test-parsing.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698