// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_PARSING_EXPRESSION_CLASSIFIER_H
#define V8_PARSING_EXPRESSION_CLASSIFIER_H

#include "src/messages.h"
#include "src/parsing/scanner.h"
#include "src/parsing/token.h"

namespace v8 {
namespace internal {


class ExpressionClassifier {
 public:
  struct Error {
    Error()
        : location(Scanner::Location::invalid()),
          message(MessageTemplate::kNone),
          type(kSyntaxError),
          arg(nullptr) {}

    Scanner::Location location;
    MessageTemplate::Template message : 30;
    ParseErrorType type : 2;
    const char* arg;
  };

  enum TargetProduction {
    ExpressionProduction = 1 << 0,
    FormalParameterInitializerProduction = 1 << 1,
    BindingPatternProduction = 1 << 2,
    AssignmentPatternProduction = 1 << 3,
    DistinctFormalParametersProduction = 1 << 4,
    StrictModeFormalParametersProduction = 1 << 5,
    StrongModeFormalParametersProduction = 1 << 6,
    ArrowFormalParametersProduction = 1 << 7,
    LetPatternProduction = 1 << 8,
    CoverInitializedNameProduction = 1 << 9,

    ExpressionProductions =
        (ExpressionProduction | FormalParameterInitializerProduction),
    PatternProductions = (BindingPatternProduction |
                          AssignmentPatternProduction | LetPatternProduction),
    FormalParametersProductions = (DistinctFormalParametersProduction |
                                   StrictModeFormalParametersProduction |
                                   StrongModeFormalParametersProduction),
    StandardProductions = ExpressionProductions | PatternProductions,
    AllProductions =
        (StandardProductions | FormalParametersProductions |
         ArrowFormalParametersProduction | CoverInitializedNameProduction)
  };

  enum FunctionProperties { NonSimpleParameter = 1 << 0 };

  ExpressionClassifier()
      : invalid_productions_(0),
        function_properties_(0),
        duplicate_finder_(nullptr) {}

  explicit ExpressionClassifier(DuplicateFinder* duplicate_finder)
      : invalid_productions_(0),
        function_properties_(0),
        duplicate_finder_(duplicate_finder) {}

  bool is_valid(unsigned productions) const {
    return (invalid_productions_ & productions) == 0;
  }

  DuplicateFinder* duplicate_finder() const { return duplicate_finder_; }

  bool is_valid_expression() const { return is_valid(ExpressionProduction); }

  bool is_valid_formal_parameter_initializer() const {
    return is_valid(FormalParameterInitializerProduction);
  }

  bool is_valid_binding_pattern() const {
    return is_valid(BindingPatternProduction);
  }

  bool is_valid_assignment_pattern() const {
    return is_valid(AssignmentPatternProduction);
  }

  bool is_valid_arrow_formal_parameters() const {
    return is_valid(ArrowFormalParametersProduction);
  }

  bool is_valid_formal_parameter_list_without_duplicates() const {
    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 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 is_valid(StrongModeFormalParametersProduction);
  }

  bool is_valid_let_pattern() const { return is_valid(LetPatternProduction); }

  const Error& expression_error() const { return expression_error_; }

  const Error& formal_parameter_initializer_error() const {
    return formal_parameter_initializer_error_;
  }

  const Error& binding_pattern_error() const { return binding_pattern_error_; }

  const Error& assignment_pattern_error() const {
    return assignment_pattern_error_;
  }

  const Error& arrow_formal_parameters_error() const {
    return arrow_formal_parameters_error_;
  }

  const Error& duplicate_formal_parameter_error() const {
    return duplicate_formal_parameter_error_;
  }

  const Error& strict_mode_formal_parameter_error() const {
    return strict_mode_formal_parameter_error_;
  }

  const Error& strong_mode_formal_parameter_error() const {
    return strong_mode_formal_parameter_error_;
  }

  const Error& let_pattern_error() const { return let_pattern_error_; }

  bool has_cover_initialized_name() const {
    return !is_valid(CoverInitializedNameProduction);
  }
  const Error& cover_initialized_name_error() const {
    return cover_initialized_name_error_;
  }

  bool is_simple_parameter_list() const {
    return !(function_properties_ & NonSimpleParameter);
  }

  void RecordNonSimpleParameter() {
    function_properties_ |= NonSimpleParameter;
  }

  void RecordExpressionError(const Scanner::Location& loc,
                             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;
  }

  void RecordExpressionError(const Scanner::Location& loc,
                             MessageTemplate::Template message,
                             ParseErrorType type, const char* arg = nullptr) {
    if (!is_valid_expression()) return;
    invalid_productions_ |= ExpressionProduction;
    expression_error_.location = loc;
    expression_error_.message = message;
    expression_error_.arg = arg;
    expression_error_.type = type;
  }

  void RecordFormalParameterInitializerError(const Scanner::Location& loc,
                                             MessageTemplate::Template message,
                                             const char* arg = nullptr) {
    if (!is_valid_formal_parameter_initializer()) return;
    invalid_productions_ |= FormalParameterInitializerProduction;
    formal_parameter_initializer_error_.location = loc;
    formal_parameter_initializer_error_.message = message;
    formal_parameter_initializer_error_.arg = arg;
  }

  void RecordBindingPatternError(const Scanner::Location& loc,
                                 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;
  }

  void RecordAssignmentPatternError(const Scanner::Location& loc,
                                    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;
  }

  void RecordPatternError(const Scanner::Location& loc,
                          MessageTemplate::Template message,
                          const char* arg = nullptr) {
    RecordBindingPatternError(loc, message, arg);
    RecordAssignmentPatternError(loc, message, arg);
  }

  void RecordArrowFormalParametersError(const Scanner::Location& loc,
                                        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;
  }

  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::kParamDupe;
    duplicate_formal_parameter_error_.arg = nullptr;
  }

  // Record a binding that would be invalid in strict mode.  Confusingly this
  // is not the same as StrictFormalParameterList, which simply forbids
  // duplicate bindings.
  void RecordStrictModeFormalParameterError(const Scanner::Location& loc,
                                            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;
  }

  void RecordStrongModeFormalParameterError(const Scanner::Location& loc,
                                            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;
  }

  void RecordLetPatternError(const Scanner::Location& loc,
                             MessageTemplate::Template message,
                             const char* arg = nullptr) {
    if (!is_valid_let_pattern()) return;
    invalid_productions_ |= LetPatternProduction;
    let_pattern_error_.location = loc;
    let_pattern_error_.message = message;
    let_pattern_error_.arg = arg;
  }

  void RecordCoverInitializedNameError(const Scanner::Location& loc,
                                       MessageTemplate::Template message,
                                       const char* arg = nullptr) {
    if (has_cover_initialized_name()) return;
    invalid_productions_ |= CoverInitializedNameProduction;
    cover_initialized_name_error_.location = loc;
    cover_initialized_name_error_.message = message;
    cover_initialized_name_error_.arg = arg;
  }

  void ForgiveCoverInitializedNameError() {
    invalid_productions_ &= ~CoverInitializedNameProduction;
    cover_initialized_name_error_ = Error();
  }

  void ForgiveAssignmentPatternError() {
    invalid_productions_ &= ~AssignmentPatternProduction;
    assignment_pattern_error_ = Error();
  }

  void Accumulate(const ExpressionClassifier& inner,
                  unsigned productions = StandardProductions) {
    // 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 & FormalParameterInitializerProduction)
        formal_parameter_initializer_error_ =
            inner.formal_parameter_initializer_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 (errors & StrictModeFormalParametersProduction)
        strict_mode_formal_parameter_error_ =
            inner.strict_mode_formal_parameter_error_;
      if (errors & StrongModeFormalParametersProduction)
        strong_mode_formal_parameter_error_ =
            inner.strong_mode_formal_parameter_error_;
      if (errors & LetPatternProduction)
        let_pattern_error_ = inner.let_pattern_error_;
      if (errors & CoverInitializedNameProduction)
        cover_initialized_name_error_ = inner.cover_initialized_name_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()) {
      // Also copy function properties if expecting an arrow function
      // parameter.
      function_properties_ |= inner.function_properties_;

      if (!inner.is_valid_binding_pattern()) {
        invalid_productions_ |= ArrowFormalParametersProduction;
        arrow_formal_parameters_error_ = inner.binding_pattern_error_;
      }
    }
  }

 private:
  unsigned invalid_productions_;
  unsigned function_properties_;
  Error expression_error_;
  Error formal_parameter_initializer_error_;
  Error binding_pattern_error_;
  Error assignment_pattern_error_;
  Error arrow_formal_parameters_error_;
  Error duplicate_formal_parameter_error_;
  Error strict_mode_formal_parameter_error_;
  Error strong_mode_formal_parameter_error_;
  Error let_pattern_error_;
  Error cover_initialized_name_error_;
  DuplicateFinder* duplicate_finder_;
};

}  // namespace internal
}  // namespace v8

#endif  // V8_PARSING_EXPRESSION_CLASSIFIER_H
