| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index b89263229fe372368d3dcd9f20e7313f3fab9aa5..e1d2d1acee7f9bafa4012b10f6a0a0961b90d603 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -557,40 +557,61 @@ class ParserBase : public Traits {
|
| Scanner::Location location;
|
| MessageTemplate::Template message;
|
| const char* arg;
|
| + };
|
| +
|
| + enum TargetProduction {
|
| + ExpressionProduction = 1 << 0,
|
| + BindingPatternProduction = 1 << 1,
|
| + AssignmentPatternProduction = 1 << 2,
|
| + DistinctFormalParametersProduction = 1 << 3,
|
| + StrictModeFormalParametersProduction = 1 << 4,
|
| + StrongModeFormalParametersProduction = 1 << 5,
|
| + ArrowFormalParametersProduction = 1 << 6,
|
|
|
| - bool HasError() const { return location.IsValid(); }
|
| + PatternProductions =
|
| + (BindingPatternProduction | AssignmentPatternProduction),
|
| + FormalParametersProductions = (DistinctFormalParametersProduction |
|
| + StrictModeFormalParametersProduction |
|
| + StrongModeFormalParametersProduction),
|
| + StandardProductions = ExpressionProduction | PatternProductions,
|
| + AllProductions = (StandardProductions | FormalParametersProductions |
|
| + ArrowFormalParametersProduction)
|
| };
|
|
|
| - ExpressionClassifier() {}
|
| + ExpressionClassifier() : invalid_productions_(0) {}
|
| +
|
| + bool is_valid(unsigned productions) const {
|
| + return (invalid_productions_ & productions) == 0;
|
| + }
|
|
|
| - bool is_valid_expression() const { return !expression_error_.HasError(); }
|
| + bool is_valid_expression() const { return is_valid(ExpressionProduction); }
|
|
|
| bool is_valid_binding_pattern() const {
|
| - return !binding_pattern_error_.HasError();
|
| + return is_valid(BindingPatternProduction);
|
| }
|
|
|
| bool is_valid_assignment_pattern() const {
|
| - return !assignment_pattern_error_.HasError();
|
| + return is_valid(AssignmentPatternProduction);
|
| }
|
|
|
| bool is_valid_arrow_formal_parameters() const {
|
| - return !arrow_formal_parameters_error_.HasError();
|
| + return is_valid(ArrowFormalParametersProduction);
|
| }
|
|
|
| bool is_valid_formal_parameter_list_without_duplicates() const {
|
| - return !duplicate_formal_parameter_error_.HasError();
|
| + return is_valid(DistinctFormalParametersProduction);
|
| }
|
|
|
| // Note: callers should also check
|
| // is_valid_formal_parameter_list_without_duplicates().
|
| bool is_valid_strict_mode_formal_parameters() const {
|
| - return !strict_mode_formal_parameter_error_.HasError();
|
| + return is_valid(StrictModeFormalParametersProduction);
|
| }
|
|
|
| // Note: callers should also check is_valid_strict_mode_formal_parameters()
|
| // and is_valid_formal_parameter_list_without_duplicates().
|
| bool is_valid_strong_mode_formal_parameters() const {
|
| - return !strong_mode_formal_parameter_error_.HasError();
|
| + return is_valid(StrongModeFormalParametersProduction);
|
| }
|
|
|
| const Error& expression_error() const { return expression_error_; }
|
| @@ -623,6 +644,7 @@ class ParserBase : public Traits {
|
| MessageTemplate::Template message,
|
| const char* arg = nullptr) {
|
| if (!is_valid_expression()) return;
|
| + invalid_productions_ |= ExpressionProduction;
|
| expression_error_.location = loc;
|
| expression_error_.message = message;
|
| expression_error_.arg = arg;
|
| @@ -632,6 +654,7 @@ class ParserBase : public Traits {
|
| MessageTemplate::Template message,
|
| const char* arg = nullptr) {
|
| if (!is_valid_binding_pattern()) return;
|
| + invalid_productions_ |= BindingPatternProduction;
|
| binding_pattern_error_.location = loc;
|
| binding_pattern_error_.message = message;
|
| binding_pattern_error_.arg = arg;
|
| @@ -641,6 +664,7 @@ class ParserBase : public Traits {
|
| MessageTemplate::Template message,
|
| const char* arg = nullptr) {
|
| if (!is_valid_assignment_pattern()) return;
|
| + invalid_productions_ |= AssignmentPatternProduction;
|
| assignment_pattern_error_.location = loc;
|
| assignment_pattern_error_.message = message;
|
| assignment_pattern_error_.arg = arg;
|
| @@ -650,6 +674,7 @@ class ParserBase : public Traits {
|
| MessageTemplate::Template message,
|
| const char* arg = nullptr) {
|
| if (!is_valid_arrow_formal_parameters()) return;
|
| + invalid_productions_ |= ArrowFormalParametersProduction;
|
| arrow_formal_parameters_error_.location = loc;
|
| arrow_formal_parameters_error_.message = message;
|
| arrow_formal_parameters_error_.arg = arg;
|
| @@ -657,6 +682,7 @@ class ParserBase : public Traits {
|
|
|
| void RecordDuplicateFormalParameterError(const Scanner::Location& loc) {
|
| if (!is_valid_formal_parameter_list_without_duplicates()) return;
|
| + invalid_productions_ |= DistinctFormalParametersProduction;
|
| duplicate_formal_parameter_error_.location = loc;
|
| duplicate_formal_parameter_error_.message =
|
| MessageTemplate::kStrictParamDupe;
|
| @@ -670,6 +696,7 @@ class ParserBase : public Traits {
|
| MessageTemplate::Template message,
|
| const char* arg = nullptr) {
|
| if (!is_valid_strict_mode_formal_parameters()) return;
|
| + invalid_productions_ |= StrictModeFormalParametersProduction;
|
| strict_mode_formal_parameter_error_.location = loc;
|
| strict_mode_formal_parameter_error_.message = message;
|
| strict_mode_formal_parameter_error_.arg = arg;
|
| @@ -679,56 +706,49 @@ class ParserBase : public Traits {
|
| MessageTemplate::Template message,
|
| const char* arg = nullptr) {
|
| if (!is_valid_strong_mode_formal_parameters()) return;
|
| + invalid_productions_ |= StrongModeFormalParametersProduction;
|
| strong_mode_formal_parameter_error_.location = loc;
|
| strong_mode_formal_parameter_error_.message = message;
|
| strong_mode_formal_parameter_error_.arg = arg;
|
| }
|
|
|
| - enum TargetProduction {
|
| - ExpressionProduction = 1 << 0,
|
| - BindingPatternProduction = 1 << 1,
|
| - AssignmentPatternProduction = 1 << 2,
|
| - FormalParametersProduction = 1 << 3,
|
| - ArrowFormalParametersProduction = 1 << 4,
|
| - StandardProductions = (ExpressionProduction | BindingPatternProduction |
|
| - AssignmentPatternProduction),
|
| - PatternProductions =
|
| - BindingPatternProduction | AssignmentPatternProduction,
|
| - AllProductions = (StandardProductions | FormalParametersProduction |
|
| - ArrowFormalParametersProduction),
|
| - };
|
| -
|
| void Accumulate(const ExpressionClassifier& inner,
|
| unsigned productions = StandardProductions) {
|
| - if (productions & ExpressionProduction && is_valid_expression()) {
|
| - expression_error_ = inner.expression_error_;
|
| - }
|
| - if (productions & BindingPatternProduction &&
|
| - is_valid_binding_pattern()) {
|
| - binding_pattern_error_ = inner.binding_pattern_error_;
|
| - }
|
| - if (productions & AssignmentPatternProduction &&
|
| - is_valid_assignment_pattern()) {
|
| - assignment_pattern_error_ = inner.assignment_pattern_error_;
|
| - }
|
| - if (productions & FormalParametersProduction) {
|
| - if (is_valid_formal_parameter_list_without_duplicates()) {
|
| + // Propagate errors from inner, but don't overwrite already recorded
|
| + // errors.
|
| + unsigned non_arrow_inner_invalid_productions =
|
| + inner.invalid_productions_ & ~ArrowFormalParametersProduction;
|
| + if (non_arrow_inner_invalid_productions == 0) return;
|
| + unsigned non_arrow_productions =
|
| + productions & ~ArrowFormalParametersProduction;
|
| + unsigned errors =
|
| + non_arrow_productions & non_arrow_inner_invalid_productions;
|
| + errors &= ~invalid_productions_;
|
| + if (errors != 0) {
|
| + invalid_productions_ |= errors;
|
| + if (errors & ExpressionProduction)
|
| + expression_error_ = inner.expression_error_;
|
| + if (errors & BindingPatternProduction)
|
| + binding_pattern_error_ = inner.binding_pattern_error_;
|
| + if (errors & AssignmentPatternProduction)
|
| + assignment_pattern_error_ = inner.assignment_pattern_error_;
|
| + if (errors & DistinctFormalParametersProduction)
|
| duplicate_formal_parameter_error_ =
|
| inner.duplicate_formal_parameter_error_;
|
| - }
|
| - if (is_valid_strict_mode_formal_parameters()) {
|
| + if (errors & StrictModeFormalParametersProduction)
|
| strict_mode_formal_parameter_error_ =
|
| inner.strict_mode_formal_parameter_error_;
|
| - }
|
| - if (is_valid_strong_mode_formal_parameters()) {
|
| + if (errors & StrongModeFormalParametersProduction)
|
| strong_mode_formal_parameter_error_ =
|
| inner.strong_mode_formal_parameter_error_;
|
| - }
|
| }
|
| +
|
| + // As an exception to the above, the result continues to be a valid arrow
|
| + // formal parameters if the inner expression is a valid binding pattern.
|
| if (productions & ArrowFormalParametersProduction &&
|
| - is_valid_arrow_formal_parameters()) {
|
| - // The result continues to be a valid arrow formal parameters if the
|
| - // inner expression is a valid binding pattern.
|
| + is_valid_arrow_formal_parameters() &&
|
| + !inner.is_valid_binding_pattern()) {
|
| + invalid_productions_ |= ArrowFormalParametersProduction;
|
| arrow_formal_parameters_error_ = inner.binding_pattern_error_;
|
| }
|
| }
|
| @@ -746,6 +766,7 @@ class ParserBase : public Traits {
|
| }
|
|
|
| private:
|
| + unsigned invalid_productions_;
|
| Error expression_error_;
|
| Error binding_pattern_error_;
|
| Error assignment_pattern_error_;
|
| @@ -2945,7 +2966,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
|
| // "expression" was not itself an arrow function parameter list, but it might
|
| // form part of one. Propagate speculative formal parameter error locations.
|
| classifier->Accumulate(arrow_formals_classifier,
|
| - ExpressionClassifier::FormalParametersProduction);
|
| + ExpressionClassifier::FormalParametersProductions);
|
|
|
| if (!Token::IsAssignmentOp(peek())) {
|
| if (fni_ != NULL) fni_->Leave();
|
|
|