// Copyright 2017 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_AST_AST_SOURCE_RANGES_H_
#define V8_AST_AST_SOURCE_RANGES_H_

#include "src/ast/ast.h"
#include "src/zone/zone-containers.h"

namespace v8 {
namespace internal {

// Specifies a range within the source code. {start} is 0-based and inclusive,
// {end} is 0-based and exclusive.
struct SourceRange {
  SourceRange() : SourceRange(kNoSourcePosition, kNoSourcePosition) {}
  SourceRange(int start, int end) : start(start), end(end) {}
  bool IsEmpty() const { return start == kNoSourcePosition; }
  static SourceRange Empty() { return SourceRange(); }
  static SourceRange OpenEnded(int32_t start) {
    return SourceRange(start, kNoSourcePosition);
  }
  static SourceRange ContinuationOf(const SourceRange& that,
                                    int end = kNoSourcePosition) {
    return that.IsEmpty() ? Empty() : SourceRange(that.end, end);
  }

  static constexpr int kFunctionLiteralSourcePosition = -2;
  STATIC_ASSERT(kFunctionLiteralSourcePosition == kNoSourcePosition - 1);

  // Source ranges associated with a function literal do not contain real
  // source positions; instead, they are created with special marker values.
  // These are later recognized and rewritten during processing in
  // Coverage::Collect().
  static SourceRange FunctionLiteralMarkerRange() {
    return {kFunctionLiteralSourcePosition, kFunctionLiteralSourcePosition};
  }

  int32_t start, end;
};

// The list of ast node kinds that have associated source ranges. Note that this
// macro is not undefined at the end of this file.
#define AST_SOURCE_RANGE_LIST(V) \
  V(BinaryOperation)             \
  V(Block)                       \
  V(CaseClause)                  \
  V(Conditional)                 \
  V(FunctionLiteral)             \
  V(IfStatement)                 \
  V(IterationStatement)          \
  V(JumpStatement)               \
  V(NaryOperation)               \
  V(Suspend)                     \
  V(SwitchStatement)             \
  V(Throw)                       \
  V(TryCatchStatement)           \
  V(TryFinallyStatement)

enum class SourceRangeKind {
  kBody,
  kCatch,
  kContinuation,
  kElse,
  kFinally,
  kRight,
  kThen,
};

class AstNodeSourceRanges : public ZoneObject {
 public:
  virtual ~AstNodeSourceRanges() = default;
  virtual SourceRange GetRange(SourceRangeKind kind) = 0;
  virtual bool HasRange(SourceRangeKind kind) = 0;
  virtual void RemoveContinuationRange() { UNREACHABLE(); }
};

class BinaryOperationSourceRanges final : public AstNodeSourceRanges {
 public:
  explicit BinaryOperationSourceRanges(const SourceRange& right_range)
      : right_range_(right_range) {}

  SourceRange GetRange(SourceRangeKind kind) override {
    DCHECK(HasRange(kind));
    return right_range_;
  }

  bool HasRange(SourceRangeKind kind) override {
    return kind == SourceRangeKind::kRight;
  }

 private:
  SourceRange right_range_;
};

class ContinuationSourceRanges : public AstNodeSourceRanges {
 public:
  explicit ContinuationSourceRanges(int32_t continuation_position)
      : continuation_position_(continuation_position) {}

  SourceRange GetRange(SourceRangeKind kind) override {
    DCHECK(HasRange(kind));
    return SourceRange::OpenEnded(continuation_position_);
  }

  bool HasRange(SourceRangeKind kind) override {
    return kind == SourceRangeKind::kContinuation;
  }

  void RemoveContinuationRange() override {
    DCHECK(HasRange(SourceRangeKind::kContinuation));
    continuation_position_ = kNoSourcePosition;
  }

 private:
  int32_t continuation_position_;
};

class BlockSourceRanges final : public ContinuationSourceRanges {
 public:
  explicit BlockSourceRanges(int32_t continuation_position)
      : ContinuationSourceRanges(continuation_position) {}
};

class CaseClauseSourceRanges final : public AstNodeSourceRanges {
 public:
  explicit CaseClauseSourceRanges(const SourceRange& body_range)
      : body_range_(body_range) {}

  SourceRange GetRange(SourceRangeKind kind) override {
    DCHECK(HasRange(kind));
    return body_range_;
  }

  bool HasRange(SourceRangeKind kind) override {
    return kind == SourceRangeKind::kBody;
  }

 private:
  SourceRange body_range_;
};

class ConditionalSourceRanges final : public AstNodeSourceRanges {
 public:
  explicit ConditionalSourceRanges(const SourceRange& then_range,
                                   const SourceRange& else_range)
      : then_range_(then_range), else_range_(else_range) {}

  SourceRange GetRange(SourceRangeKind kind) override {
    DCHECK(HasRange(kind));
    switch (kind) {
      case SourceRangeKind::kThen:
        return then_range_;
      case SourceRangeKind::kElse:
        return else_range_;
      default:
        UNREACHABLE();
    }
  }

  bool HasRange(SourceRangeKind kind) override {
    return kind == SourceRangeKind::kThen || kind == SourceRangeKind::kElse;
  }

 private:
  SourceRange then_range_;
  SourceRange else_range_;
};

class FunctionLiteralSourceRanges final : public AstNodeSourceRanges {
 public:
  SourceRange GetRange(SourceRangeKind kind) override {
    DCHECK(HasRange(kind));
    return SourceRange::FunctionLiteralMarkerRange();
  }

  bool HasRange(SourceRangeKind kind) override {
    return kind == SourceRangeKind::kBody;
  }
};

class IfStatementSourceRanges final : public AstNodeSourceRanges {
 public:
  explicit IfStatementSourceRanges(const SourceRange& then_range,
                                   const SourceRange& else_range)
      : then_range_(then_range), else_range_(else_range) {}

  SourceRange GetRange(SourceRangeKind kind) override {
    DCHECK(HasRange(kind));
    switch (kind) {
      case SourceRangeKind::kElse:
        return else_range_;
      case SourceRangeKind::kThen:
        return then_range_;
      case SourceRangeKind::kContinuation: {
        if (!has_continuation_) return SourceRange::Empty();
        const SourceRange& trailing_range =
            else_range_.IsEmpty() ? then_range_ : else_range_;
        return SourceRange::ContinuationOf(trailing_range);
      }
      default:
        UNREACHABLE();
    }
  }

  bool HasRange(SourceRangeKind kind) override {
    return kind == SourceRangeKind::kThen || kind == SourceRangeKind::kElse ||
           kind == SourceRangeKind::kContinuation;
  }

  void RemoveContinuationRange() override {
    DCHECK(HasRange(SourceRangeKind::kContinuation));
    has_continuation_ = false;
  }

 private:
  SourceRange then_range_;
  SourceRange else_range_;
  bool has_continuation_ = true;
};

class IterationStatementSourceRanges final : public AstNodeSourceRanges {
 public:
  explicit IterationStatementSourceRanges(const SourceRange& body_range)
      : body_range_(body_range) {}

  SourceRange GetRange(SourceRangeKind kind) override {
    DCHECK(HasRange(kind));
    switch (kind) {
      case SourceRangeKind::kBody:
        return body_range_;
      case SourceRangeKind::kContinuation:
        if (!has_continuation_) return SourceRange::Empty();
        return SourceRange::ContinuationOf(body_range_);
      default:
        UNREACHABLE();
    }
  }

  bool HasRange(SourceRangeKind kind) override {
    return kind == SourceRangeKind::kBody ||
           kind == SourceRangeKind::kContinuation;
  }

  void RemoveContinuationRange() override {
    DCHECK(HasRange(SourceRangeKind::kContinuation));
    has_continuation_ = false;
  }

 private:
  SourceRange body_range_;
  bool has_continuation_ = true;
};

class JumpStatementSourceRanges final : public ContinuationSourceRanges {
 public:
  explicit JumpStatementSourceRanges(int32_t continuation_position)
      : ContinuationSourceRanges(continuation_position) {}
};

class NaryOperationSourceRanges final : public AstNodeSourceRanges {
 public:
  NaryOperationSourceRanges(Zone* zone, const SourceRange& range)
      : ranges_(zone) {
    AddRange(range);
  }

  SourceRange GetRangeAtIndex(size_t index) {
    DCHECK(index < ranges_.size());
    return ranges_[index];
  }

  void AddRange(const SourceRange& range) { ranges_.push_back(range); }
  size_t RangeCount() const { return ranges_.size(); }

  SourceRange GetRange(SourceRangeKind kind) override { UNREACHABLE(); }
  bool HasRange(SourceRangeKind kind) override { return false; }

 private:
  ZoneVector<SourceRange> ranges_;
};

class SuspendSourceRanges final : public ContinuationSourceRanges {
 public:
  explicit SuspendSourceRanges(int32_t continuation_position)
      : ContinuationSourceRanges(continuation_position) {}
};

class SwitchStatementSourceRanges final : public ContinuationSourceRanges {
 public:
  explicit SwitchStatementSourceRanges(int32_t continuation_position)
      : ContinuationSourceRanges(continuation_position) {}
};

class ThrowSourceRanges final : public ContinuationSourceRanges {
 public:
  explicit ThrowSourceRanges(int32_t continuation_position)
      : ContinuationSourceRanges(continuation_position) {}
};

class TryCatchStatementSourceRanges final : public AstNodeSourceRanges {
 public:
  explicit TryCatchStatementSourceRanges(const SourceRange& catch_range)
      : catch_range_(catch_range) {}

  SourceRange GetRange(SourceRangeKind kind) override {
    DCHECK(HasRange(kind));
    switch (kind) {
      case SourceRangeKind::kCatch:
        return catch_range_;
      case SourceRangeKind::kContinuation:
        if (!has_continuation_) return SourceRange::Empty();
        return SourceRange::ContinuationOf(catch_range_);
      default:
        UNREACHABLE();
    }
  }

  bool HasRange(SourceRangeKind kind) override {
    return kind == SourceRangeKind::kCatch ||
           kind == SourceRangeKind::kContinuation;
  }

  void RemoveContinuationRange() override {
    DCHECK(HasRange(SourceRangeKind::kContinuation));
    has_continuation_ = false;
  }

 private:
  SourceRange catch_range_;
  bool has_continuation_ = true;
};

class TryFinallyStatementSourceRanges final : public AstNodeSourceRanges {
 public:
  explicit TryFinallyStatementSourceRanges(const SourceRange& finally_range)
      : finally_range_(finally_range) {}

  SourceRange GetRange(SourceRangeKind kind) override {
    DCHECK(HasRange(kind));
    switch (kind) {
      case SourceRangeKind::kFinally:
        return finally_range_;
      case SourceRangeKind::kContinuation:
        if (!has_continuation_) return SourceRange::Empty();
        return SourceRange::ContinuationOf(finally_range_);
      default:
        UNREACHABLE();
    }
  }

  bool HasRange(SourceRangeKind kind) override {
    return kind == SourceRangeKind::kFinally ||
           kind == SourceRangeKind::kContinuation;
  }

  void RemoveContinuationRange() override {
    DCHECK(HasRange(SourceRangeKind::kContinuation));
    has_continuation_ = false;
  }

 private:
  SourceRange finally_range_;
  bool has_continuation_ = true;
};

// Maps ast node pointers to associated source ranges. The parser creates these
// mappings and the bytecode generator consumes them.
class SourceRangeMap final : public ZoneObject {
 public:
  explicit SourceRangeMap(Zone* zone) : map_(zone) {}

  AstNodeSourceRanges* Find(ZoneObject* node) {
    auto it = map_.find(node);
    if (it == map_.end()) return nullptr;
    return it->second;
  }

// Type-checked insertion.
#define DEFINE_MAP_INSERT(type)                         \
  void Insert(type* node, type##SourceRanges* ranges) { \
    DCHECK_NOT_NULL(node);                              \
    map_.emplace(node, ranges);                         \
  }
  AST_SOURCE_RANGE_LIST(DEFINE_MAP_INSERT)
#undef DEFINE_MAP_INSERT

 private:
  ZoneMap<ZoneObject*, AstNodeSourceRanges*> map_;
};

}  // namespace internal
}  // namespace v8

#endif  // V8_AST_AST_SOURCE_RANGES_H_
