Index: src/expression-classifier.h |
diff --git a/src/expression-classifier.h b/src/expression-classifier.h |
index 6edb99e8388427514f662f312c6341935150edac..fa0b67cc0e3c3da60b7fda1e11e81cd29b8b0496 100644 |
--- a/src/expression-classifier.h |
+++ b/src/expression-classifier.h |
@@ -48,10 +48,100 @@ class ExpressionClassifier { |
}; |
ExpressionClassifier() |
- : invalid_productions_(0), duplicate_finder_(nullptr) {} |
+ : lhs_type_(TARGET_NONE), |
+ assigned_(false), |
+ invalid_productions_(0), |
+ duplicate_finder_(nullptr) {} |
explicit ExpressionClassifier(DuplicateFinder* duplicate_finder) |
- : invalid_productions_(0), duplicate_finder_(duplicate_finder) {} |
+ : lhs_type_(TARGET_NONE), |
+ assigned_(false), |
+ invalid_productions_(0), |
+ duplicate_finder_(duplicate_finder) {} |
+ |
+ 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 AssignmentTargetType AssignmentTarget() const { return lhs_type_; } |
+ |
+ inline void AppendAssignmentTarget(AssignmentTargetType type) { |
+ if (lhs_type_ == UNACCEPTABLE_TARGET) return; |
+ lhs_type_ = type; |
+ } |
+ |
+ 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(); |
+ } |
+ |
+ inline bool IsValidPattern() const { return lhs_type_ == TARGET_PATTERN; } |
+ |
+ inline bool IsAssigned() const { return assigned_; } |
+ |
+ void set_assigned() { assigned_ = true; } |
+ |
+ bool is_destructuring_assignment() const { |
+ return lhs_type_ == TARGET_PATTERN && assigned_; |
+ } |
+ |
bool is_valid(unsigned productions) const { |
return (invalid_productions_ & productions) == 0; |
@@ -185,6 +275,14 @@ class ExpressionClassifier { |
strong_mode_formal_parameter_error_.arg = arg; |
} |
+ void AccumulateValidSimpleAssignmentTarget( |
+ const ExpressionClassifier& inner) { |
+ if (lhs_type_ != UNACCEPTABLE_TARGET) { |
+ lhs_type_ = inner.lhs_type_; |
+ } |
+ } |
+ |
+ |
void Accumulate(const ExpressionClassifier& inner, |
unsigned productions = StandardProductions) { |
// Propagate errors from inner, but don't overwrite already recorded |
@@ -239,6 +337,8 @@ class ExpressionClassifier { |
} |
private: |
+ AssignmentTargetType lhs_type_; |
+ bool assigned_; |
unsigned invalid_productions_; |
Error expression_error_; |
Error binding_pattern_error_; |