11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_AST_AST_SOURCE_RANGES_H_
61cb0ef41Sopenharmony_ci#define V8_AST_AST_SOURCE_RANGES_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/ast/ast.h"
91cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h"
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_cinamespace v8 {
121cb0ef41Sopenharmony_cinamespace internal {
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci// Specifies a range within the source code. {start} is 0-based and inclusive,
151cb0ef41Sopenharmony_ci// {end} is 0-based and exclusive.
161cb0ef41Sopenharmony_cistruct SourceRange {
171cb0ef41Sopenharmony_ci  SourceRange() : SourceRange(kNoSourcePosition, kNoSourcePosition) {}
181cb0ef41Sopenharmony_ci  SourceRange(int start, int end) : start(start), end(end) {}
191cb0ef41Sopenharmony_ci  bool IsEmpty() const { return start == kNoSourcePosition; }
201cb0ef41Sopenharmony_ci  static SourceRange Empty() { return SourceRange(); }
211cb0ef41Sopenharmony_ci  static SourceRange OpenEnded(int32_t start) {
221cb0ef41Sopenharmony_ci    return SourceRange(start, kNoSourcePosition);
231cb0ef41Sopenharmony_ci  }
241cb0ef41Sopenharmony_ci  static SourceRange ContinuationOf(const SourceRange& that,
251cb0ef41Sopenharmony_ci                                    int end = kNoSourcePosition) {
261cb0ef41Sopenharmony_ci    return that.IsEmpty() ? Empty() : SourceRange(that.end, end);
271cb0ef41Sopenharmony_ci  }
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci  static constexpr int kFunctionLiteralSourcePosition = -2;
301cb0ef41Sopenharmony_ci  STATIC_ASSERT(kFunctionLiteralSourcePosition == kNoSourcePosition - 1);
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  // Source ranges associated with a function literal do not contain real
331cb0ef41Sopenharmony_ci  // source positions; instead, they are created with special marker values.
341cb0ef41Sopenharmony_ci  // These are later recognized and rewritten during processing in
351cb0ef41Sopenharmony_ci  // Coverage::Collect().
361cb0ef41Sopenharmony_ci  static SourceRange FunctionLiteralMarkerRange() {
371cb0ef41Sopenharmony_ci    return {kFunctionLiteralSourcePosition, kFunctionLiteralSourcePosition};
381cb0ef41Sopenharmony_ci  }
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  int32_t start, end;
411cb0ef41Sopenharmony_ci};
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci// The list of ast node kinds that have associated source ranges. Note that this
441cb0ef41Sopenharmony_ci// macro is not undefined at the end of this file.
451cb0ef41Sopenharmony_ci#define AST_SOURCE_RANGE_LIST(V) \
461cb0ef41Sopenharmony_ci  V(BinaryOperation)             \
471cb0ef41Sopenharmony_ci  V(Block)                       \
481cb0ef41Sopenharmony_ci  V(CaseClause)                  \
491cb0ef41Sopenharmony_ci  V(Conditional)                 \
501cb0ef41Sopenharmony_ci  V(Expression)                  \
511cb0ef41Sopenharmony_ci  V(FunctionLiteral)             \
521cb0ef41Sopenharmony_ci  V(IfStatement)                 \
531cb0ef41Sopenharmony_ci  V(IterationStatement)          \
541cb0ef41Sopenharmony_ci  V(JumpStatement)               \
551cb0ef41Sopenharmony_ci  V(NaryOperation)               \
561cb0ef41Sopenharmony_ci  V(Suspend)                     \
571cb0ef41Sopenharmony_ci  V(SwitchStatement)             \
581cb0ef41Sopenharmony_ci  V(Throw)                       \
591cb0ef41Sopenharmony_ci  V(TryCatchStatement)           \
601cb0ef41Sopenharmony_ci  V(TryFinallyStatement)
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_cienum class SourceRangeKind {
631cb0ef41Sopenharmony_ci  kBody,
641cb0ef41Sopenharmony_ci  kCatch,
651cb0ef41Sopenharmony_ci  kContinuation,
661cb0ef41Sopenharmony_ci  kElse,
671cb0ef41Sopenharmony_ci  kFinally,
681cb0ef41Sopenharmony_ci  kRight,
691cb0ef41Sopenharmony_ci  kThen,
701cb0ef41Sopenharmony_ci};
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ciclass AstNodeSourceRanges : public ZoneObject {
731cb0ef41Sopenharmony_ci public:
741cb0ef41Sopenharmony_ci  virtual ~AstNodeSourceRanges() = default;
751cb0ef41Sopenharmony_ci  virtual SourceRange GetRange(SourceRangeKind kind) = 0;
761cb0ef41Sopenharmony_ci  virtual bool HasRange(SourceRangeKind kind) = 0;
771cb0ef41Sopenharmony_ci  virtual void RemoveContinuationRange() { UNREACHABLE(); }
781cb0ef41Sopenharmony_ci};
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ciclass BinaryOperationSourceRanges final : public AstNodeSourceRanges {
811cb0ef41Sopenharmony_ci public:
821cb0ef41Sopenharmony_ci  explicit BinaryOperationSourceRanges(const SourceRange& right_range)
831cb0ef41Sopenharmony_ci      : right_range_(right_range) {}
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  SourceRange GetRange(SourceRangeKind kind) override {
861cb0ef41Sopenharmony_ci    DCHECK(HasRange(kind));
871cb0ef41Sopenharmony_ci    return right_range_;
881cb0ef41Sopenharmony_ci  }
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  bool HasRange(SourceRangeKind kind) override {
911cb0ef41Sopenharmony_ci    return kind == SourceRangeKind::kRight;
921cb0ef41Sopenharmony_ci  }
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci private:
951cb0ef41Sopenharmony_ci  SourceRange right_range_;
961cb0ef41Sopenharmony_ci};
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ciclass ContinuationSourceRanges : public AstNodeSourceRanges {
991cb0ef41Sopenharmony_ci public:
1001cb0ef41Sopenharmony_ci  explicit ContinuationSourceRanges(int32_t continuation_position)
1011cb0ef41Sopenharmony_ci      : continuation_position_(continuation_position) {}
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci  SourceRange GetRange(SourceRangeKind kind) override {
1041cb0ef41Sopenharmony_ci    DCHECK(HasRange(kind));
1051cb0ef41Sopenharmony_ci    return SourceRange::OpenEnded(continuation_position_);
1061cb0ef41Sopenharmony_ci  }
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci  bool HasRange(SourceRangeKind kind) override {
1091cb0ef41Sopenharmony_ci    return kind == SourceRangeKind::kContinuation;
1101cb0ef41Sopenharmony_ci  }
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci  void RemoveContinuationRange() override {
1131cb0ef41Sopenharmony_ci    DCHECK(HasRange(SourceRangeKind::kContinuation));
1141cb0ef41Sopenharmony_ci    continuation_position_ = kNoSourcePosition;
1151cb0ef41Sopenharmony_ci  }
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci private:
1181cb0ef41Sopenharmony_ci  int32_t continuation_position_;
1191cb0ef41Sopenharmony_ci};
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ciclass BlockSourceRanges final : public ContinuationSourceRanges {
1221cb0ef41Sopenharmony_ci public:
1231cb0ef41Sopenharmony_ci  explicit BlockSourceRanges(int32_t continuation_position)
1241cb0ef41Sopenharmony_ci      : ContinuationSourceRanges(continuation_position) {}
1251cb0ef41Sopenharmony_ci};
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ciclass CaseClauseSourceRanges final : public AstNodeSourceRanges {
1281cb0ef41Sopenharmony_ci public:
1291cb0ef41Sopenharmony_ci  explicit CaseClauseSourceRanges(const SourceRange& body_range)
1301cb0ef41Sopenharmony_ci      : body_range_(body_range) {}
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  SourceRange GetRange(SourceRangeKind kind) override {
1331cb0ef41Sopenharmony_ci    DCHECK(HasRange(kind));
1341cb0ef41Sopenharmony_ci    return body_range_;
1351cb0ef41Sopenharmony_ci  }
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  bool HasRange(SourceRangeKind kind) override {
1381cb0ef41Sopenharmony_ci    return kind == SourceRangeKind::kBody;
1391cb0ef41Sopenharmony_ci  }
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci private:
1421cb0ef41Sopenharmony_ci  SourceRange body_range_;
1431cb0ef41Sopenharmony_ci};
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ciclass ConditionalSourceRanges final : public AstNodeSourceRanges {
1461cb0ef41Sopenharmony_ci public:
1471cb0ef41Sopenharmony_ci  explicit ConditionalSourceRanges(const SourceRange& then_range,
1481cb0ef41Sopenharmony_ci                                   const SourceRange& else_range)
1491cb0ef41Sopenharmony_ci      : then_range_(then_range), else_range_(else_range) {}
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  SourceRange GetRange(SourceRangeKind kind) override {
1521cb0ef41Sopenharmony_ci    DCHECK(HasRange(kind));
1531cb0ef41Sopenharmony_ci    switch (kind) {
1541cb0ef41Sopenharmony_ci      case SourceRangeKind::kThen:
1551cb0ef41Sopenharmony_ci        return then_range_;
1561cb0ef41Sopenharmony_ci      case SourceRangeKind::kElse:
1571cb0ef41Sopenharmony_ci        return else_range_;
1581cb0ef41Sopenharmony_ci      default:
1591cb0ef41Sopenharmony_ci        UNREACHABLE();
1601cb0ef41Sopenharmony_ci    }
1611cb0ef41Sopenharmony_ci  }
1621cb0ef41Sopenharmony_ci
1631cb0ef41Sopenharmony_ci  bool HasRange(SourceRangeKind kind) override {
1641cb0ef41Sopenharmony_ci    return kind == SourceRangeKind::kThen || kind == SourceRangeKind::kElse;
1651cb0ef41Sopenharmony_ci  }
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci private:
1681cb0ef41Sopenharmony_ci  SourceRange then_range_;
1691cb0ef41Sopenharmony_ci  SourceRange else_range_;
1701cb0ef41Sopenharmony_ci};
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ciclass FunctionLiteralSourceRanges final : public AstNodeSourceRanges {
1731cb0ef41Sopenharmony_ci public:
1741cb0ef41Sopenharmony_ci  SourceRange GetRange(SourceRangeKind kind) override {
1751cb0ef41Sopenharmony_ci    DCHECK(HasRange(kind));
1761cb0ef41Sopenharmony_ci    return SourceRange::FunctionLiteralMarkerRange();
1771cb0ef41Sopenharmony_ci  }
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci  bool HasRange(SourceRangeKind kind) override {
1801cb0ef41Sopenharmony_ci    return kind == SourceRangeKind::kBody;
1811cb0ef41Sopenharmony_ci  }
1821cb0ef41Sopenharmony_ci};
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ciclass IfStatementSourceRanges final : public AstNodeSourceRanges {
1851cb0ef41Sopenharmony_ci public:
1861cb0ef41Sopenharmony_ci  explicit IfStatementSourceRanges(const SourceRange& then_range,
1871cb0ef41Sopenharmony_ci                                   const SourceRange& else_range)
1881cb0ef41Sopenharmony_ci      : then_range_(then_range), else_range_(else_range) {}
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  SourceRange GetRange(SourceRangeKind kind) override {
1911cb0ef41Sopenharmony_ci    DCHECK(HasRange(kind));
1921cb0ef41Sopenharmony_ci    switch (kind) {
1931cb0ef41Sopenharmony_ci      case SourceRangeKind::kElse:
1941cb0ef41Sopenharmony_ci        return else_range_;
1951cb0ef41Sopenharmony_ci      case SourceRangeKind::kThen:
1961cb0ef41Sopenharmony_ci        return then_range_;
1971cb0ef41Sopenharmony_ci      case SourceRangeKind::kContinuation: {
1981cb0ef41Sopenharmony_ci        if (!has_continuation_) return SourceRange::Empty();
1991cb0ef41Sopenharmony_ci        const SourceRange& trailing_range =
2001cb0ef41Sopenharmony_ci            else_range_.IsEmpty() ? then_range_ : else_range_;
2011cb0ef41Sopenharmony_ci        return SourceRange::ContinuationOf(trailing_range);
2021cb0ef41Sopenharmony_ci      }
2031cb0ef41Sopenharmony_ci      default:
2041cb0ef41Sopenharmony_ci        UNREACHABLE();
2051cb0ef41Sopenharmony_ci    }
2061cb0ef41Sopenharmony_ci  }
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci  bool HasRange(SourceRangeKind kind) override {
2091cb0ef41Sopenharmony_ci    return kind == SourceRangeKind::kThen || kind == SourceRangeKind::kElse ||
2101cb0ef41Sopenharmony_ci           kind == SourceRangeKind::kContinuation;
2111cb0ef41Sopenharmony_ci  }
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_ci  void RemoveContinuationRange() override {
2141cb0ef41Sopenharmony_ci    DCHECK(HasRange(SourceRangeKind::kContinuation));
2151cb0ef41Sopenharmony_ci    has_continuation_ = false;
2161cb0ef41Sopenharmony_ci  }
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci private:
2191cb0ef41Sopenharmony_ci  SourceRange then_range_;
2201cb0ef41Sopenharmony_ci  SourceRange else_range_;
2211cb0ef41Sopenharmony_ci  bool has_continuation_ = true;
2221cb0ef41Sopenharmony_ci};
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ciclass IterationStatementSourceRanges final : public AstNodeSourceRanges {
2251cb0ef41Sopenharmony_ci public:
2261cb0ef41Sopenharmony_ci  explicit IterationStatementSourceRanges(const SourceRange& body_range)
2271cb0ef41Sopenharmony_ci      : body_range_(body_range) {}
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci  SourceRange GetRange(SourceRangeKind kind) override {
2301cb0ef41Sopenharmony_ci    DCHECK(HasRange(kind));
2311cb0ef41Sopenharmony_ci    switch (kind) {
2321cb0ef41Sopenharmony_ci      case SourceRangeKind::kBody:
2331cb0ef41Sopenharmony_ci        return body_range_;
2341cb0ef41Sopenharmony_ci      case SourceRangeKind::kContinuation:
2351cb0ef41Sopenharmony_ci        if (!has_continuation_) return SourceRange::Empty();
2361cb0ef41Sopenharmony_ci        return SourceRange::ContinuationOf(body_range_);
2371cb0ef41Sopenharmony_ci      default:
2381cb0ef41Sopenharmony_ci        UNREACHABLE();
2391cb0ef41Sopenharmony_ci    }
2401cb0ef41Sopenharmony_ci  }
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci  bool HasRange(SourceRangeKind kind) override {
2431cb0ef41Sopenharmony_ci    return kind == SourceRangeKind::kBody ||
2441cb0ef41Sopenharmony_ci           kind == SourceRangeKind::kContinuation;
2451cb0ef41Sopenharmony_ci  }
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci  void RemoveContinuationRange() override {
2481cb0ef41Sopenharmony_ci    DCHECK(HasRange(SourceRangeKind::kContinuation));
2491cb0ef41Sopenharmony_ci    has_continuation_ = false;
2501cb0ef41Sopenharmony_ci  }
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci private:
2531cb0ef41Sopenharmony_ci  SourceRange body_range_;
2541cb0ef41Sopenharmony_ci  bool has_continuation_ = true;
2551cb0ef41Sopenharmony_ci};
2561cb0ef41Sopenharmony_ci
2571cb0ef41Sopenharmony_ciclass JumpStatementSourceRanges final : public ContinuationSourceRanges {
2581cb0ef41Sopenharmony_ci public:
2591cb0ef41Sopenharmony_ci  explicit JumpStatementSourceRanges(int32_t continuation_position)
2601cb0ef41Sopenharmony_ci      : ContinuationSourceRanges(continuation_position) {}
2611cb0ef41Sopenharmony_ci};
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_ciclass NaryOperationSourceRanges final : public AstNodeSourceRanges {
2641cb0ef41Sopenharmony_ci public:
2651cb0ef41Sopenharmony_ci  NaryOperationSourceRanges(Zone* zone, const SourceRange& range)
2661cb0ef41Sopenharmony_ci      : ranges_(zone) {
2671cb0ef41Sopenharmony_ci    AddRange(range);
2681cb0ef41Sopenharmony_ci  }
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci  SourceRange GetRangeAtIndex(size_t index) {
2711cb0ef41Sopenharmony_ci    DCHECK(index < ranges_.size());
2721cb0ef41Sopenharmony_ci    return ranges_[index];
2731cb0ef41Sopenharmony_ci  }
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci  void AddRange(const SourceRange& range) { ranges_.push_back(range); }
2761cb0ef41Sopenharmony_ci  size_t RangeCount() const { return ranges_.size(); }
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ci  SourceRange GetRange(SourceRangeKind kind) override { UNREACHABLE(); }
2791cb0ef41Sopenharmony_ci  bool HasRange(SourceRangeKind kind) override { return false; }
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci private:
2821cb0ef41Sopenharmony_ci  ZoneVector<SourceRange> ranges_;
2831cb0ef41Sopenharmony_ci};
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ciclass ExpressionSourceRanges final : public AstNodeSourceRanges {
2861cb0ef41Sopenharmony_ci public:
2871cb0ef41Sopenharmony_ci  explicit ExpressionSourceRanges(const SourceRange& right_range)
2881cb0ef41Sopenharmony_ci      : right_range_(right_range) {}
2891cb0ef41Sopenharmony_ci
2901cb0ef41Sopenharmony_ci  SourceRange GetRange(SourceRangeKind kind) override {
2911cb0ef41Sopenharmony_ci    DCHECK(HasRange(kind));
2921cb0ef41Sopenharmony_ci    return right_range_;
2931cb0ef41Sopenharmony_ci  }
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci  bool HasRange(SourceRangeKind kind) override {
2961cb0ef41Sopenharmony_ci    return kind == SourceRangeKind::kRight;
2971cb0ef41Sopenharmony_ci  }
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_ci private:
3001cb0ef41Sopenharmony_ci  SourceRange right_range_;
3011cb0ef41Sopenharmony_ci};
3021cb0ef41Sopenharmony_ci
3031cb0ef41Sopenharmony_ciclass SuspendSourceRanges final : public ContinuationSourceRanges {
3041cb0ef41Sopenharmony_ci public:
3051cb0ef41Sopenharmony_ci  explicit SuspendSourceRanges(int32_t continuation_position)
3061cb0ef41Sopenharmony_ci      : ContinuationSourceRanges(continuation_position) {}
3071cb0ef41Sopenharmony_ci};
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ciclass SwitchStatementSourceRanges final : public ContinuationSourceRanges {
3101cb0ef41Sopenharmony_ci public:
3111cb0ef41Sopenharmony_ci  explicit SwitchStatementSourceRanges(int32_t continuation_position)
3121cb0ef41Sopenharmony_ci      : ContinuationSourceRanges(continuation_position) {}
3131cb0ef41Sopenharmony_ci};
3141cb0ef41Sopenharmony_ci
3151cb0ef41Sopenharmony_ciclass ThrowSourceRanges final : public ContinuationSourceRanges {
3161cb0ef41Sopenharmony_ci public:
3171cb0ef41Sopenharmony_ci  explicit ThrowSourceRanges(int32_t continuation_position)
3181cb0ef41Sopenharmony_ci      : ContinuationSourceRanges(continuation_position) {}
3191cb0ef41Sopenharmony_ci};
3201cb0ef41Sopenharmony_ci
3211cb0ef41Sopenharmony_ciclass TryCatchStatementSourceRanges final : public AstNodeSourceRanges {
3221cb0ef41Sopenharmony_ci public:
3231cb0ef41Sopenharmony_ci  explicit TryCatchStatementSourceRanges(const SourceRange& catch_range)
3241cb0ef41Sopenharmony_ci      : catch_range_(catch_range) {}
3251cb0ef41Sopenharmony_ci
3261cb0ef41Sopenharmony_ci  SourceRange GetRange(SourceRangeKind kind) override {
3271cb0ef41Sopenharmony_ci    DCHECK(HasRange(kind));
3281cb0ef41Sopenharmony_ci    switch (kind) {
3291cb0ef41Sopenharmony_ci      case SourceRangeKind::kCatch:
3301cb0ef41Sopenharmony_ci        return catch_range_;
3311cb0ef41Sopenharmony_ci      case SourceRangeKind::kContinuation:
3321cb0ef41Sopenharmony_ci        if (!has_continuation_) return SourceRange::Empty();
3331cb0ef41Sopenharmony_ci        return SourceRange::ContinuationOf(catch_range_);
3341cb0ef41Sopenharmony_ci      default:
3351cb0ef41Sopenharmony_ci        UNREACHABLE();
3361cb0ef41Sopenharmony_ci    }
3371cb0ef41Sopenharmony_ci  }
3381cb0ef41Sopenharmony_ci
3391cb0ef41Sopenharmony_ci  bool HasRange(SourceRangeKind kind) override {
3401cb0ef41Sopenharmony_ci    return kind == SourceRangeKind::kCatch ||
3411cb0ef41Sopenharmony_ci           kind == SourceRangeKind::kContinuation;
3421cb0ef41Sopenharmony_ci  }
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_ci  void RemoveContinuationRange() override {
3451cb0ef41Sopenharmony_ci    DCHECK(HasRange(SourceRangeKind::kContinuation));
3461cb0ef41Sopenharmony_ci    has_continuation_ = false;
3471cb0ef41Sopenharmony_ci  }
3481cb0ef41Sopenharmony_ci
3491cb0ef41Sopenharmony_ci private:
3501cb0ef41Sopenharmony_ci  SourceRange catch_range_;
3511cb0ef41Sopenharmony_ci  bool has_continuation_ = true;
3521cb0ef41Sopenharmony_ci};
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_ciclass TryFinallyStatementSourceRanges final : public AstNodeSourceRanges {
3551cb0ef41Sopenharmony_ci public:
3561cb0ef41Sopenharmony_ci  explicit TryFinallyStatementSourceRanges(const SourceRange& finally_range)
3571cb0ef41Sopenharmony_ci      : finally_range_(finally_range) {}
3581cb0ef41Sopenharmony_ci
3591cb0ef41Sopenharmony_ci  SourceRange GetRange(SourceRangeKind kind) override {
3601cb0ef41Sopenharmony_ci    DCHECK(HasRange(kind));
3611cb0ef41Sopenharmony_ci    switch (kind) {
3621cb0ef41Sopenharmony_ci      case SourceRangeKind::kFinally:
3631cb0ef41Sopenharmony_ci        return finally_range_;
3641cb0ef41Sopenharmony_ci      case SourceRangeKind::kContinuation:
3651cb0ef41Sopenharmony_ci        if (!has_continuation_) return SourceRange::Empty();
3661cb0ef41Sopenharmony_ci        return SourceRange::ContinuationOf(finally_range_);
3671cb0ef41Sopenharmony_ci      default:
3681cb0ef41Sopenharmony_ci        UNREACHABLE();
3691cb0ef41Sopenharmony_ci    }
3701cb0ef41Sopenharmony_ci  }
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ci  bool HasRange(SourceRangeKind kind) override {
3731cb0ef41Sopenharmony_ci    return kind == SourceRangeKind::kFinally ||
3741cb0ef41Sopenharmony_ci           kind == SourceRangeKind::kContinuation;
3751cb0ef41Sopenharmony_ci  }
3761cb0ef41Sopenharmony_ci
3771cb0ef41Sopenharmony_ci  void RemoveContinuationRange() override {
3781cb0ef41Sopenharmony_ci    DCHECK(HasRange(SourceRangeKind::kContinuation));
3791cb0ef41Sopenharmony_ci    has_continuation_ = false;
3801cb0ef41Sopenharmony_ci  }
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ci private:
3831cb0ef41Sopenharmony_ci  SourceRange finally_range_;
3841cb0ef41Sopenharmony_ci  bool has_continuation_ = true;
3851cb0ef41Sopenharmony_ci};
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_ci// Maps ast node pointers to associated source ranges. The parser creates these
3881cb0ef41Sopenharmony_ci// mappings and the bytecode generator consumes them.
3891cb0ef41Sopenharmony_ciclass SourceRangeMap final : public ZoneObject {
3901cb0ef41Sopenharmony_ci public:
3911cb0ef41Sopenharmony_ci  explicit SourceRangeMap(Zone* zone) : map_(zone) {}
3921cb0ef41Sopenharmony_ci
3931cb0ef41Sopenharmony_ci  AstNodeSourceRanges* Find(ZoneObject* node) {
3941cb0ef41Sopenharmony_ci    auto it = map_.find(node);
3951cb0ef41Sopenharmony_ci    if (it == map_.end()) return nullptr;
3961cb0ef41Sopenharmony_ci    return it->second;
3971cb0ef41Sopenharmony_ci  }
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci// Type-checked insertion.
4001cb0ef41Sopenharmony_ci#define DEFINE_MAP_INSERT(type)                         \
4011cb0ef41Sopenharmony_ci  void Insert(type* node, type##SourceRanges* ranges) { \
4021cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(node);                              \
4031cb0ef41Sopenharmony_ci    map_.emplace(node, ranges);                         \
4041cb0ef41Sopenharmony_ci  }
4051cb0ef41Sopenharmony_ci  AST_SOURCE_RANGE_LIST(DEFINE_MAP_INSERT)
4061cb0ef41Sopenharmony_ci#undef DEFINE_MAP_INSERT
4071cb0ef41Sopenharmony_ci
4081cb0ef41Sopenharmony_ci private:
4091cb0ef41Sopenharmony_ci  ZoneMap<ZoneObject*, AstNodeSourceRanges*> map_;
4101cb0ef41Sopenharmony_ci};
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ci}  // namespace internal
4131cb0ef41Sopenharmony_ci}  // namespace v8
4141cb0ef41Sopenharmony_ci
4151cb0ef41Sopenharmony_ci#endif  // V8_AST_AST_SOURCE_RANGES_H_
416