V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
ast-source-ranges.h
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  SourceRange() : SourceRange(kNoSourcePosition, kNoSourcePosition) {}
18  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  static SourceRange ContinuationOf(const SourceRange& that,
25  int end = kNoSourcePosition) {
26  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 
59  public:
60  virtual ~AstNodeSourceRanges() = default;
61  virtual SourceRange GetRange(SourceRangeKind kind) = 0;
62 };
63 
65  public:
66  explicit BinaryOperationSourceRanges(const SourceRange& right_range)
67  : right_range_(right_range) {}
68 
69  SourceRange GetRange(SourceRangeKind kind) override {
70  DCHECK_EQ(kind, SourceRangeKind::kRight);
71  return right_range_;
72  }
73 
74  private:
75  SourceRange right_range_;
76 };
77 
79  public:
80  explicit ContinuationSourceRanges(int32_t continuation_position)
81  : continuation_position_(continuation_position) {}
82 
83  SourceRange GetRange(SourceRangeKind kind) override {
84  DCHECK_EQ(kind, SourceRangeKind::kContinuation);
85  return SourceRange::OpenEnded(continuation_position_);
86  }
87 
88  private:
89  int32_t continuation_position_;
90 };
91 
93  public:
94  explicit BlockSourceRanges(int32_t continuation_position)
95  : ContinuationSourceRanges(continuation_position) {}
96 };
97 
99  public:
100  explicit CaseClauseSourceRanges(const SourceRange& body_range)
101  : body_range_(body_range) {}
102 
103  SourceRange GetRange(SourceRangeKind kind) override {
104  DCHECK_EQ(kind, SourceRangeKind::kBody);
105  return body_range_;
106  }
107 
108  private:
109  SourceRange body_range_;
110 };
111 
113  public:
114  explicit ConditionalSourceRanges(const SourceRange& then_range,
115  const SourceRange& else_range)
116  : then_range_(then_range), else_range_(else_range) {}
117 
118  SourceRange GetRange(SourceRangeKind kind) override {
119  switch (kind) {
120  case SourceRangeKind::kThen:
121  return then_range_;
122  case SourceRangeKind::kElse:
123  return else_range_;
124  default:
125  UNREACHABLE();
126  }
127  }
128 
129  private:
130  SourceRange then_range_;
131  SourceRange else_range_;
132 };
133 
135  public:
136  explicit IfStatementSourceRanges(const SourceRange& then_range,
137  const SourceRange& else_range)
138  : then_range_(then_range), else_range_(else_range) {}
139 
140  SourceRange GetRange(SourceRangeKind kind) override {
141  switch (kind) {
142  case SourceRangeKind::kElse:
143  return else_range_;
144  case SourceRangeKind::kThen:
145  return then_range_;
146  case SourceRangeKind::kContinuation: {
147  const SourceRange& trailing_range =
148  else_range_.IsEmpty() ? then_range_ : else_range_;
149  return SourceRange::ContinuationOf(trailing_range);
150  }
151  default:
152  UNREACHABLE();
153  }
154  }
155 
156  private:
157  SourceRange then_range_;
158  SourceRange else_range_;
159 };
160 
162  public:
163  explicit IterationStatementSourceRanges(const SourceRange& body_range)
164  : body_range_(body_range) {}
165 
166  SourceRange GetRange(SourceRangeKind kind) override {
167  switch (kind) {
168  case SourceRangeKind::kBody:
169  return body_range_;
170  case SourceRangeKind::kContinuation:
171  return SourceRange::ContinuationOf(body_range_);
172  default:
173  UNREACHABLE();
174  }
175  }
176 
177  private:
178  SourceRange body_range_;
179 };
180 
182  public:
183  explicit JumpStatementSourceRanges(int32_t continuation_position)
184  : ContinuationSourceRanges(continuation_position) {}
185 };
186 
188  public:
189  NaryOperationSourceRanges(Zone* zone, const SourceRange& range)
190  : ranges_(zone) {
191  AddRange(range);
192  }
193 
194  SourceRange GetRangeAtIndex(size_t index) {
195  DCHECK(index < ranges_.size());
196  return ranges_[index];
197  }
198 
199  void AddRange(const SourceRange& range) { ranges_.push_back(range); }
200  size_t RangeCount() const { return ranges_.size(); }
201 
202  SourceRange GetRange(SourceRangeKind kind) override { UNREACHABLE(); }
203 
204  private:
205  ZoneVector<SourceRange> ranges_;
206 };
207 
209  public:
210  explicit SuspendSourceRanges(int32_t continuation_position)
211  : ContinuationSourceRanges(continuation_position) {}
212 };
213 
215  public:
216  explicit SwitchStatementSourceRanges(int32_t continuation_position)
217  : ContinuationSourceRanges(continuation_position) {}
218 };
219 
221  public:
222  explicit ThrowSourceRanges(int32_t continuation_position)
223  : ContinuationSourceRanges(continuation_position) {}
224 };
225 
227  public:
228  explicit TryCatchStatementSourceRanges(const SourceRange& catch_range)
229  : catch_range_(catch_range) {}
230 
231  SourceRange GetRange(SourceRangeKind kind) override {
232  switch (kind) {
233  case SourceRangeKind::kCatch:
234  return catch_range_;
235  case SourceRangeKind::kContinuation:
236  return SourceRange::ContinuationOf(catch_range_);
237  default:
238  UNREACHABLE();
239  }
240  }
241 
242  private:
243  SourceRange catch_range_;
244 };
245 
247  public:
248  explicit TryFinallyStatementSourceRanges(const SourceRange& finally_range)
249  : finally_range_(finally_range) {}
250 
251  SourceRange GetRange(SourceRangeKind kind) override {
252  switch (kind) {
253  case SourceRangeKind::kFinally:
254  return finally_range_;
255  case SourceRangeKind::kContinuation:
256  return SourceRange::ContinuationOf(finally_range_);
257  default:
258  UNREACHABLE();
259  }
260  }
261 
262  private:
263  SourceRange finally_range_;
264 };
265 
266 // Maps ast node pointers to associated source ranges. The parser creates these
267 // mappings and the bytecode generator consumes them.
268 class SourceRangeMap final : public ZoneObject {
269  public:
270  explicit SourceRangeMap(Zone* zone) : map_(zone) {}
271 
272  AstNodeSourceRanges* Find(ZoneObject* node) {
273  auto it = map_.find(node);
274  if (it == map_.end()) return nullptr;
275  return it->second;
276  }
277 
278 // Type-checked insertion.
279 #define DEFINE_MAP_INSERT(type) \
280  void Insert(type* node, type##SourceRanges* ranges) { \
281  DCHECK_NOT_NULL(node); \
282  map_.emplace(node, ranges); \
283  }
284  AST_SOURCE_RANGE_LIST(DEFINE_MAP_INSERT)
285 #undef DEFINE_MAP_INSERT
286 
287  private:
289 };
290 
291 } // namespace internal
292 } // namespace v8
293 
294 #endif // V8_AST_AST_SOURCE_RANGES_H_
Definition: libplatform.h:13