LCOV - code coverage report
Current view: top level - src/ast - ast-source-ranges.h (source / functions) Hit Total Coverage
Test: app.info Lines: 101 125 80.8 %
Date: 2019-02-19 Functions: 50 83 60.2 %

          Line data    Source code
       1             : // Copyright 2017 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_AST_AST_SOURCE_RANGES_H_
       6             : #define V8_AST_AST_SOURCE_RANGES_H_
       7             : 
       8             : #include "src/ast/ast.h"
       9             : #include "src/zone/zone-containers.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14             : // Specifies a range within the source code. {start} is 0-based and inclusive,
      15             : // {end} is 0-based and exclusive.
      16             : struct SourceRange {
      17      382876 :   SourceRange() : SourceRange(kNoSourcePosition, kNoSourcePosition) {}
      18     4087561 :   SourceRange(int start, int end) : start(start), end(end) {}
      19             :   bool IsEmpty() const { return start == kNoSourcePosition; }
      20             :   static SourceRange Empty() { return SourceRange(); }
      21             :   static SourceRange OpenEnded(int32_t start) {
      22             :     return SourceRange(start, kNoSourcePosition);
      23             :   }
      24       58685 :   static SourceRange ContinuationOf(const SourceRange& that,
      25             :                                     int end = kNoSourcePosition) {
      26       58685 :     return that.IsEmpty() ? Empty() : SourceRange(that.end, end);
      27             :   }
      28             :   int32_t start, end;
      29             : };
      30             : 
      31             : // The list of ast node kinds that have associated source ranges. Note that this
      32             : // macro is not undefined at the end of this file.
      33             : #define AST_SOURCE_RANGE_LIST(V) \
      34             :   V(BinaryOperation)             \
      35             :   V(Block)                       \
      36             :   V(CaseClause)                  \
      37             :   V(Conditional)                 \
      38             :   V(IfStatement)                 \
      39             :   V(IterationStatement)          \
      40             :   V(JumpStatement)               \
      41             :   V(NaryOperation)               \
      42             :   V(Suspend)                     \
      43             :   V(SwitchStatement)             \
      44             :   V(Throw)                       \
      45             :   V(TryCatchStatement)           \
      46             :   V(TryFinallyStatement)
      47             : 
      48             : enum class SourceRangeKind {
      49             :   kBody,
      50             :   kCatch,
      51             :   kContinuation,
      52             :   kElse,
      53             :   kFinally,
      54             :   kRight,
      55             :   kThen,
      56             : };
      57             : 
      58        2532 : class AstNodeSourceRanges : public ZoneObject {
      59             :  public:
      60           0 :   virtual ~AstNodeSourceRanges() = default;
      61             :   virtual SourceRange GetRange(SourceRangeKind kind) = 0;
      62             :   virtual bool HasRange(SourceRangeKind kind) = 0;
      63           0 :   virtual void RemoveContinuationRange() { UNREACHABLE(); }
      64             : };
      65             : 
      66           0 : class BinaryOperationSourceRanges final : public AstNodeSourceRanges {
      67             :  public:
      68         232 :   explicit BinaryOperationSourceRanges(const SourceRange& right_range)
      69         232 :       : right_range_(right_range) {}
      70             : 
      71         224 :   SourceRange GetRange(SourceRangeKind kind) override {
      72             :     DCHECK(HasRange(kind));
      73         224 :     return right_range_;
      74             :   }
      75             : 
      76         128 :   bool HasRange(SourceRangeKind kind) override {
      77         128 :     return kind == SourceRangeKind::kRight;
      78             :   }
      79             : 
      80             :  private:
      81             :   SourceRange right_range_;
      82             : };
      83             : 
      84           0 : class ContinuationSourceRanges : public AstNodeSourceRanges {
      85             :  public:
      86             :   explicit ContinuationSourceRanges(int32_t continuation_position)
      87        1312 :       : continuation_position_(continuation_position) {}
      88             : 
      89        2580 :   SourceRange GetRange(SourceRangeKind kind) override {
      90             :     DCHECK(HasRange(kind));
      91        2580 :     return SourceRange::OpenEnded(continuation_position_);
      92             :   }
      93             : 
      94        2196 :   bool HasRange(SourceRangeKind kind) override {
      95        2196 :     return kind == SourceRangeKind::kContinuation;
      96             :   }
      97             : 
      98         960 :   void RemoveContinuationRange() override {
      99             :     DCHECK(HasRange(SourceRangeKind::kContinuation));
     100         960 :     continuation_position_ = kNoSourcePosition;
     101         960 :   }
     102             : 
     103             :  private:
     104             :   int32_t continuation_position_;
     105             : };
     106             : 
     107           0 : class BlockSourceRanges final : public ContinuationSourceRanges {
     108             :  public:
     109         580 :   explicit BlockSourceRanges(int32_t continuation_position)
     110         580 :       : ContinuationSourceRanges(continuation_position) {}
     111             : };
     112             : 
     113           0 : class CaseClauseSourceRanges final : public AstNodeSourceRanges {
     114             :  public:
     115          24 :   explicit CaseClauseSourceRanges(const SourceRange& body_range)
     116          24 :       : body_range_(body_range) {}
     117             : 
     118          24 :   SourceRange GetRange(SourceRangeKind kind) override {
     119             :     DCHECK(HasRange(kind));
     120          24 :     return body_range_;
     121             :   }
     122             : 
     123           0 :   bool HasRange(SourceRangeKind kind) override {
     124           0 :     return kind == SourceRangeKind::kBody;
     125             :   }
     126             : 
     127             :  private:
     128             :   SourceRange body_range_;
     129             : };
     130             : 
     131           0 : class ConditionalSourceRanges final : public AstNodeSourceRanges {
     132             :  public:
     133          80 :   explicit ConditionalSourceRanges(const SourceRange& then_range,
     134             :                                    const SourceRange& else_range)
     135          80 :       : then_range_(then_range), else_range_(else_range) {}
     136             : 
     137         160 :   SourceRange GetRange(SourceRangeKind kind) override {
     138             :     DCHECK(HasRange(kind));
     139         160 :     switch (kind) {
     140             :       case SourceRangeKind::kThen:
     141          80 :         return then_range_;
     142             :       case SourceRangeKind::kElse:
     143          80 :         return else_range_;
     144             :       default:
     145           0 :         UNREACHABLE();
     146             :     }
     147             :   }
     148             : 
     149          80 :   bool HasRange(SourceRangeKind kind) override {
     150          80 :     return kind == SourceRangeKind::kThen || kind == SourceRangeKind::kElse;
     151             :   }
     152             : 
     153             :  private:
     154             :   SourceRange then_range_;
     155             :   SourceRange else_range_;
     156             : };
     157             : 
     158           0 : class IfStatementSourceRanges final : public AstNodeSourceRanges {
     159             :  public:
     160         456 :   explicit IfStatementSourceRanges(const SourceRange& then_range,
     161             :                                    const SourceRange& else_range)
     162         456 :       : then_range_(then_range), else_range_(else_range) {}
     163             : 
     164        1776 :   SourceRange GetRange(SourceRangeKind kind) override {
     165             :     DCHECK(HasRange(kind));
     166        1776 :     switch (kind) {
     167             :       case SourceRangeKind::kElse:
     168         440 :         return else_range_;
     169             :       case SourceRangeKind::kThen:
     170         440 :         return then_range_;
     171             :       case SourceRangeKind::kContinuation: {
     172         896 :         if (!has_continuation_) return SourceRange::Empty();
     173             :         const SourceRange& trailing_range =
     174         732 :             else_range_.IsEmpty() ? then_range_ : else_range_;
     175             :         return SourceRange::ContinuationOf(trailing_range);
     176             :       }
     177             :       default:
     178           0 :         UNREACHABLE();
     179             :     }
     180             :   }
     181             : 
     182         620 :   bool HasRange(SourceRangeKind kind) override {
     183         620 :     return kind == SourceRangeKind::kThen || kind == SourceRangeKind::kElse ||
     184         620 :            kind == SourceRangeKind::kContinuation;
     185             :   }
     186             : 
     187         180 :   void RemoveContinuationRange() override {
     188             :     DCHECK(HasRange(SourceRangeKind::kContinuation));
     189         180 :     has_continuation_ = false;
     190         180 :   }
     191             : 
     192             :  private:
     193             :   SourceRange then_range_;
     194             :   SourceRange else_range_;
     195             :   bool has_continuation_ = true;
     196             : };
     197             : 
     198           0 : class IterationStatementSourceRanges final : public AstNodeSourceRanges {
     199             :  public:
     200         244 :   explicit IterationStatementSourceRanges(const SourceRange& body_range)
     201         244 :       : body_range_(body_range) {}
     202             : 
     203         732 :   SourceRange GetRange(SourceRangeKind kind) override {
     204             :     DCHECK(HasRange(kind));
     205         732 :     switch (kind) {
     206             :       case SourceRangeKind::kBody:
     207         244 :         return body_range_;
     208             :       case SourceRangeKind::kContinuation:
     209         488 :         if (!has_continuation_) return SourceRange::Empty();
     210             :         return SourceRange::ContinuationOf(body_range_);
     211             :       default:
     212           0 :         UNREACHABLE();
     213             :     }
     214             :   }
     215             : 
     216         296 :   bool HasRange(SourceRangeKind kind) override {
     217         296 :     return kind == SourceRangeKind::kBody ||
     218         296 :            kind == SourceRangeKind::kContinuation;
     219             :   }
     220             : 
     221          56 :   void RemoveContinuationRange() override {
     222             :     DCHECK(HasRange(SourceRangeKind::kContinuation));
     223          56 :     has_continuation_ = false;
     224          56 :   }
     225             : 
     226             :  private:
     227             :   SourceRange body_range_;
     228             :   bool has_continuation_ = true;
     229             : };
     230             : 
     231           0 : class JumpStatementSourceRanges final : public ContinuationSourceRanges {
     232             :  public:
     233         576 :   explicit JumpStatementSourceRanges(int32_t continuation_position)
     234         576 :       : ContinuationSourceRanges(continuation_position) {}
     235             : };
     236             : 
     237           0 : class NaryOperationSourceRanges final : public AstNodeSourceRanges {
     238             :  public:
     239         104 :   NaryOperationSourceRanges(Zone* zone, const SourceRange& range)
     240         104 :       : ranges_(zone) {
     241             :     AddRange(range);
     242         104 :   }
     243             : 
     244             :   SourceRange GetRangeAtIndex(size_t index) {
     245             :     DCHECK(index < ranges_.size());
     246         488 :     return ranges_[index];
     247             :   }
     248             : 
     249         244 :   void AddRange(const SourceRange& range) { ranges_.push_back(range); }
     250             :   size_t RangeCount() const { return ranges_.size(); }
     251             : 
     252           0 :   SourceRange GetRange(SourceRangeKind kind) override { UNREACHABLE(); }
     253         104 :   bool HasRange(SourceRangeKind kind) override { return false; }
     254             : 
     255             :  private:
     256             :   ZoneVector<SourceRange> ranges_;
     257             : };
     258             : 
     259           0 : class SuspendSourceRanges final : public ContinuationSourceRanges {
     260             :  public:
     261         116 :   explicit SuspendSourceRanges(int32_t continuation_position)
     262         116 :       : ContinuationSourceRanges(continuation_position) {}
     263             : };
     264             : 
     265           0 : class SwitchStatementSourceRanges final : public ContinuationSourceRanges {
     266             :  public:
     267          12 :   explicit SwitchStatementSourceRanges(int32_t continuation_position)
     268          12 :       : ContinuationSourceRanges(continuation_position) {}
     269             : };
     270             : 
     271           0 : class ThrowSourceRanges final : public ContinuationSourceRanges {
     272             :  public:
     273          28 :   explicit ThrowSourceRanges(int32_t continuation_position)
     274          28 :       : ContinuationSourceRanges(continuation_position) {}
     275             : };
     276             : 
     277           0 : class TryCatchStatementSourceRanges final : public AstNodeSourceRanges {
     278             :  public:
     279          52 :   explicit TryCatchStatementSourceRanges(const SourceRange& catch_range)
     280          52 :       : catch_range_(catch_range) {}
     281             : 
     282         156 :   SourceRange GetRange(SourceRangeKind kind) override {
     283             :     DCHECK(HasRange(kind));
     284         156 :     switch (kind) {
     285             :       case SourceRangeKind::kCatch:
     286          52 :         return catch_range_;
     287             :       case SourceRangeKind::kContinuation:
     288         104 :         if (!has_continuation_) return SourceRange::Empty();
     289             :         return SourceRange::ContinuationOf(catch_range_);
     290             :       default:
     291           0 :         UNREACHABLE();
     292             :     }
     293             :   }
     294             : 
     295          64 :   bool HasRange(SourceRangeKind kind) override {
     296          64 :     return kind == SourceRangeKind::kCatch ||
     297          64 :            kind == SourceRangeKind::kContinuation;
     298             :   }
     299             : 
     300          12 :   void RemoveContinuationRange() override {
     301             :     DCHECK(HasRange(SourceRangeKind::kContinuation));
     302          12 :     has_continuation_ = false;
     303          12 :   }
     304             : 
     305             :  private:
     306             :   SourceRange catch_range_;
     307             :   bool has_continuation_ = true;
     308             : };
     309             : 
     310           0 : class TryFinallyStatementSourceRanges final : public AstNodeSourceRanges {
     311             :  public:
     312          28 :   explicit TryFinallyStatementSourceRanges(const SourceRange& finally_range)
     313          28 :       : finally_range_(finally_range) {}
     314             : 
     315          84 :   SourceRange GetRange(SourceRangeKind kind) override {
     316             :     DCHECK(HasRange(kind));
     317          84 :     switch (kind) {
     318             :       case SourceRangeKind::kFinally:
     319          28 :         return finally_range_;
     320             :       case SourceRangeKind::kContinuation:
     321          56 :         if (!has_continuation_) return SourceRange::Empty();
     322             :         return SourceRange::ContinuationOf(finally_range_);
     323             :       default:
     324           0 :         UNREACHABLE();
     325             :     }
     326             :   }
     327             : 
     328          36 :   bool HasRange(SourceRangeKind kind) override {
     329          36 :     return kind == SourceRangeKind::kFinally ||
     330          36 :            kind == SourceRangeKind::kContinuation;
     331             :   }
     332             : 
     333           8 :   void RemoveContinuationRange() override {
     334             :     DCHECK(HasRange(SourceRangeKind::kContinuation));
     335           8 :     has_continuation_ = false;
     336           8 :   }
     337             : 
     338             :  private:
     339             :   SourceRange finally_range_;
     340             :   bool has_continuation_ = true;
     341             : };
     342             : 
     343             : // Maps ast node pointers to associated source ranges. The parser creates these
     344             : // mappings and the bytecode generator consumes them.
     345             : class SourceRangeMap final : public ZoneObject {
     346             :  public:
     347             :   explicit SourceRangeMap(Zone* zone) : map_(zone) {}
     348             : 
     349         244 :   AstNodeSourceRanges* Find(ZoneObject* node) {
     350             :     auto it = map_.find(node);
     351       24640 :     if (it == map_.end()) return nullptr;
     352        7552 :     return it->second;
     353             :   }
     354             : 
     355             : // Type-checked insertion.
     356             : #define DEFINE_MAP_INSERT(type)                         \
     357             :   void Insert(type* node, type##SourceRanges* ranges) { \
     358             :     DCHECK_NOT_NULL(node);                              \
     359             :     map_.emplace(node, ranges);                         \
     360             :   }
     361        5064 :   AST_SOURCE_RANGE_LIST(DEFINE_MAP_INSERT)
     362             : #undef DEFINE_MAP_INSERT
     363             : 
     364             :  private:
     365             :   ZoneMap<ZoneObject*, AstNodeSourceRanges*> map_;
     366             : };
     367             : 
     368             : }  // namespace internal
     369             : }  // namespace v8
     370             : 
     371             : #endif  // V8_AST_AST_SOURCE_RANGES_H_

Generated by: LCOV version 1.10