parse_tree.h revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright 2014 The Chromium 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 TOOLS_GN_PARSE_TREE_H_
6#define TOOLS_GN_PARSE_TREE_H_
7
8#include <vector>
9
10#include "base/basictypes.h"
11#include "base/compiler_specific.h"
12#include "base/memory/scoped_ptr.h"
13#include "tools/gn/err.h"
14#include "tools/gn/token.h"
15#include "tools/gn/value.h"
16
17class AccessorNode;
18class BinaryOpNode;
19class BlockNode;
20class ConditionNode;
21class FunctionCallNode;
22class IdentifierNode;
23class ListNode;
24class LiteralNode;
25class Scope;
26class UnaryOpNode;
27class BlockCommentNode;
28
29class Comments {
30 public:
31  Comments();
32  virtual ~Comments();
33
34  const std::vector<Token>& before() const { return before_; }
35  void append_before(Token c) {
36    before_.push_back(c);
37  }
38
39  const std::vector<Token>& suffix() const { return suffix_; }
40  void append_suffix(Token c) {
41    suffix_.push_back(c);
42  }
43  // Reverse the order of the suffix comments. When walking the tree in
44  // post-order we append suffix comments in reverse order, so this fixes them
45  // up.
46  void ReverseSuffix();
47
48  const std::vector<Token>& after() const { return after_; }
49  void append_after(Token c) {
50    after_.push_back(c);
51  }
52
53 private:
54  // Whole line comments before the expression.
55  std::vector<Token> before_;
56
57  // End-of-line comments after this expression.
58  std::vector<Token> suffix_;
59
60  // For top-level expressions only, after_ lists whole-line comments
61  // following the expression.
62  std::vector<Token> after_;
63
64  DISALLOW_COPY_AND_ASSIGN(Comments);
65};
66
67// ParseNode -------------------------------------------------------------------
68
69// A node in the AST.
70class ParseNode {
71 public:
72  ParseNode();
73  virtual ~ParseNode();
74
75  virtual const AccessorNode* AsAccessor() const;
76  virtual const BinaryOpNode* AsBinaryOp() const;
77  virtual const BlockNode* AsBlock() const;
78  virtual const ConditionNode* AsConditionNode() const;
79  virtual const FunctionCallNode* AsFunctionCall() const;
80  virtual const IdentifierNode* AsIdentifier() const;
81  virtual const ListNode* AsList() const;
82  virtual const LiteralNode* AsLiteral() const;
83  virtual const UnaryOpNode* AsUnaryOp() const;
84  virtual const BlockCommentNode* AsBlockComment() const;
85
86  virtual Value Execute(Scope* scope, Err* err) const = 0;
87
88  virtual LocationRange GetRange() const = 0;
89
90  // Returns an error with the given messages and the range set to something
91  // that indicates this node.
92  virtual Err MakeErrorDescribing(
93      const std::string& msg,
94      const std::string& help = std::string()) const = 0;
95
96  // Prints a representation of this node to the given string, indenting
97  // by the given number of spaces.
98  virtual void Print(std::ostream& out, int indent) const = 0;
99
100  const Comments* comments() const { return comments_.get(); }
101  Comments* comments_mutable();
102  void PrintComments(std::ostream& out, int indent) const;
103
104 private:
105  scoped_ptr<Comments> comments_;
106
107  DISALLOW_COPY_AND_ASSIGN(ParseNode);
108};
109
110// AccessorNode ----------------------------------------------------------------
111
112// Access an array or scope element.
113//
114// Currently, such values are only read-only. In that you can do:
115//   a = obj1.a
116//   b = obj2[0]
117// But not
118//   obj1.a = 5
119//   obj2[0] = 6
120//
121// In the current design where the dot operator is used only for templates, we
122// explicitly don't want to allow you to do "invoker.foo = 5", so if we added
123// support for accessors to be lvalues, we would also need to add some concept
124// of a constant scope. Supporting this would also add a lot of complications
125// to the operator= implementation, since some accessors might return values
126// in the const root scope that shouldn't be modified. Without a strong
127// use-case for this, it seems simpler to just disallow it.
128//
129// Additionally, the left-hand-side of the accessor must currently be an
130// identifier. So you can't do things like:
131//   function_call()[1]
132//   a = b.c.d
133// These are easier to implement if we needed them but given the very limited
134// use cases for this, it hasn't seemed worth the bother.
135class AccessorNode : public ParseNode {
136 public:
137  AccessorNode();
138  virtual ~AccessorNode();
139
140  virtual const AccessorNode* AsAccessor() const OVERRIDE;
141  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
142  virtual LocationRange GetRange() const OVERRIDE;
143  virtual Err MakeErrorDescribing(
144      const std::string& msg,
145      const std::string& help = std::string()) const OVERRIDE;
146  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
147
148  // Base is the thing on the left of the [] or dot, currently always required
149  // to be an identifier token.
150  const Token& base() const { return base_; }
151  void set_base(const Token& b) { base_ = b; }
152
153  // Index is the expression inside the []. Will be null if member is set.
154  const ParseNode* index() const { return index_.get(); }
155  void set_index(scoped_ptr<ParseNode> i) { index_ = i.Pass(); }
156
157  // The member is the identifier on the right hand side of the dot. Will be
158  // null if the index is set.
159  const IdentifierNode* member() const { return member_.get(); }
160  void set_member(scoped_ptr<IdentifierNode> i) { member_ = i.Pass(); }
161
162 private:
163  Value ExecuteArrayAccess(Scope* scope, Err* err) const;
164  Value ExecuteScopeAccess(Scope* scope, Err* err) const;
165
166  Token base_;
167
168  // Either index or member will be set according to what type of access this
169  // is.
170  scoped_ptr<ParseNode> index_;
171  scoped_ptr<IdentifierNode> member_;
172
173  DISALLOW_COPY_AND_ASSIGN(AccessorNode);
174};
175
176// BinaryOpNode ----------------------------------------------------------------
177
178class BinaryOpNode : public ParseNode {
179 public:
180  BinaryOpNode();
181  virtual ~BinaryOpNode();
182
183  virtual const BinaryOpNode* AsBinaryOp() const OVERRIDE;
184  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
185  virtual LocationRange GetRange() const OVERRIDE;
186  virtual Err MakeErrorDescribing(
187      const std::string& msg,
188      const std::string& help = std::string()) const OVERRIDE;
189  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
190
191  const Token& op() const { return op_; }
192  void set_op(const Token& t) { op_ = t; }
193
194  const ParseNode* left() const { return left_.get(); }
195  void set_left(scoped_ptr<ParseNode> left) {
196    left_ = left.Pass();
197  }
198
199  const ParseNode* right() const { return right_.get(); }
200  void set_right(scoped_ptr<ParseNode> right) {
201    right_ = right.Pass();
202  }
203
204 private:
205  scoped_ptr<ParseNode> left_;
206  Token op_;
207  scoped_ptr<ParseNode> right_;
208
209  DISALLOW_COPY_AND_ASSIGN(BinaryOpNode);
210};
211
212// BlockNode -------------------------------------------------------------------
213
214class BlockNode : public ParseNode {
215 public:
216  // Set has_scope if this block introduces a nested scope.
217  explicit BlockNode(bool has_scope);
218  virtual ~BlockNode();
219
220  virtual const BlockNode* AsBlock() const OVERRIDE;
221  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
222  virtual LocationRange GetRange() const OVERRIDE;
223  virtual Err MakeErrorDescribing(
224      const std::string& msg,
225      const std::string& help = std::string()) const OVERRIDE;
226  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
227
228  void set_begin_token(const Token& t) { begin_token_ = t; }
229  void set_end_token(const Token& t) { end_token_ = t; }
230
231  const std::vector<ParseNode*>& statements() const { return statements_; }
232  void append_statement(scoped_ptr<ParseNode> s) {
233    statements_.push_back(s.release());
234  }
235
236  // Doesn't create a nested scope.
237  Value ExecuteBlockInScope(Scope* our_scope, Err* err) const;
238
239 private:
240  bool has_scope_;
241
242  // Tokens corresponding to { and }, if any (may be NULL).
243  Token begin_token_;
244  Token end_token_;
245
246  // Owning pointers, use unique_ptr when we can use C++11.
247  std::vector<ParseNode*> statements_;
248
249  DISALLOW_COPY_AND_ASSIGN(BlockNode);
250};
251
252// ConditionNode ---------------------------------------------------------------
253
254class ConditionNode : public ParseNode {
255 public:
256  ConditionNode();
257  virtual ~ConditionNode();
258
259  virtual const ConditionNode* AsConditionNode() const OVERRIDE;
260  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
261  virtual LocationRange GetRange() const OVERRIDE;
262  virtual Err MakeErrorDescribing(
263      const std::string& msg,
264      const std::string& help = std::string()) const OVERRIDE;
265  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
266
267  void set_if_token(const Token& token) { if_token_ = token; }
268
269  const ParseNode* condition() const { return condition_.get(); }
270  void set_condition(scoped_ptr<ParseNode> c) {
271    condition_ = c.Pass();
272  }
273
274  const BlockNode* if_true() const { return if_true_.get(); }
275  void set_if_true(scoped_ptr<BlockNode> t) {
276    if_true_ = t.Pass();
277  }
278
279  // This is either empty, a block (for the else clause), or another
280  // condition.
281  const ParseNode* if_false() const { return if_false_.get(); }
282  void set_if_false(scoped_ptr<ParseNode> f) {
283    if_false_ = f.Pass();
284  }
285
286 private:
287  // Token corresponding to the "if" string.
288  Token if_token_;
289
290  scoped_ptr<ParseNode> condition_;  // Always non-null.
291  scoped_ptr<BlockNode> if_true_;  // Always non-null.
292  scoped_ptr<ParseNode> if_false_;  // May be null.
293
294  DISALLOW_COPY_AND_ASSIGN(ConditionNode);
295};
296
297// FunctionCallNode ------------------------------------------------------------
298
299class FunctionCallNode : public ParseNode {
300 public:
301  FunctionCallNode();
302  virtual ~FunctionCallNode();
303
304  virtual const FunctionCallNode* AsFunctionCall() const OVERRIDE;
305  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
306  virtual LocationRange GetRange() const OVERRIDE;
307  virtual Err MakeErrorDescribing(
308      const std::string& msg,
309      const std::string& help = std::string()) const OVERRIDE;
310  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
311
312  const Token& function() const { return function_; }
313  void set_function(Token t) { function_ = t; }
314
315  const ListNode* args() const { return args_.get(); }
316  void set_args(scoped_ptr<ListNode> a) { args_ = a.Pass(); }
317
318  const BlockNode* block() const { return block_.get(); }
319  void set_block(scoped_ptr<BlockNode> b) { block_ = b.Pass(); }
320
321 private:
322  Token function_;
323  scoped_ptr<ListNode> args_;
324  scoped_ptr<BlockNode> block_;  // May be null.
325
326  DISALLOW_COPY_AND_ASSIGN(FunctionCallNode);
327};
328
329// IdentifierNode --------------------------------------------------------------
330
331class IdentifierNode : public ParseNode {
332 public:
333  IdentifierNode();
334  IdentifierNode(const Token& token);
335  virtual ~IdentifierNode();
336
337  virtual const IdentifierNode* AsIdentifier() const OVERRIDE;
338  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
339  virtual LocationRange GetRange() const OVERRIDE;
340  virtual Err MakeErrorDescribing(
341      const std::string& msg,
342      const std::string& help = std::string()) const OVERRIDE;
343  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
344
345  const Token& value() const { return value_; }
346  void set_value(const Token& t) { value_ = t; }
347
348 private:
349  Token value_;
350
351  DISALLOW_COPY_AND_ASSIGN(IdentifierNode);
352};
353
354// ListNode --------------------------------------------------------------------
355
356class ListNode : public ParseNode {
357 public:
358  ListNode();
359  virtual ~ListNode();
360
361  virtual const ListNode* AsList() const OVERRIDE;
362  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
363  virtual LocationRange GetRange() const OVERRIDE;
364  virtual Err MakeErrorDescribing(
365      const std::string& msg,
366      const std::string& help = std::string()) const OVERRIDE;
367  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
368
369  void set_begin_token(const Token& t) { begin_token_ = t; }
370  void set_end_token(const Token& t) { end_token_ = t; }
371
372  void append_item(scoped_ptr<ParseNode> s) {
373    contents_.push_back(s.release());
374  }
375  const std::vector<const ParseNode*>& contents() const { return contents_; }
376
377 private:
378  // Tokens corresponding to the [ and ].
379  Token begin_token_;
380  Token end_token_;
381
382  // Owning pointers, use unique_ptr when we can use C++11.
383  std::vector<const ParseNode*> contents_;
384
385  DISALLOW_COPY_AND_ASSIGN(ListNode);
386};
387
388// LiteralNode -----------------------------------------------------------------
389
390class LiteralNode : public ParseNode {
391 public:
392  LiteralNode();
393  LiteralNode(const Token& token);
394  virtual ~LiteralNode();
395
396  virtual const LiteralNode* AsLiteral() const OVERRIDE;
397  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
398  virtual LocationRange GetRange() const OVERRIDE;
399  virtual Err MakeErrorDescribing(
400      const std::string& msg,
401      const std::string& help = std::string()) const OVERRIDE;
402  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
403
404  const Token& value() const { return value_; }
405  void set_value(const Token& t) { value_ = t; }
406
407 private:
408  Token value_;
409
410  DISALLOW_COPY_AND_ASSIGN(LiteralNode);
411};
412
413// UnaryOpNode -----------------------------------------------------------------
414
415class UnaryOpNode : public ParseNode {
416 public:
417  UnaryOpNode();
418  virtual ~UnaryOpNode();
419
420  virtual const UnaryOpNode* AsUnaryOp() const OVERRIDE;
421  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
422  virtual LocationRange GetRange() const OVERRIDE;
423  virtual Err MakeErrorDescribing(
424      const std::string& msg,
425      const std::string& help = std::string()) const OVERRIDE;
426  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
427
428  const Token& op() const { return op_; }
429  void set_op(const Token& t) { op_ = t; }
430
431  const ParseNode* operand() const { return operand_.get(); }
432  void set_operand(scoped_ptr<ParseNode> operand) {
433    operand_ = operand.Pass();
434  }
435
436 private:
437  Token op_;
438  scoped_ptr<ParseNode> operand_;
439
440  DISALLOW_COPY_AND_ASSIGN(UnaryOpNode);
441};
442
443// BlockCommentNode ------------------------------------------------------------
444
445// This node type is only used for standalone comments (that is, those not
446// specifically attached to another syntax element. The most common of these
447// is a standard header block. This node contains only the last line of such
448// a comment block as the anchor, and other lines of the block comment are
449// hung off of it as Before comments, similar to other syntax elements.
450class BlockCommentNode : public ParseNode {
451 public:
452  BlockCommentNode();
453  virtual ~BlockCommentNode();
454
455  virtual const BlockCommentNode* AsBlockComment() const OVERRIDE;
456  virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
457  virtual LocationRange GetRange() const OVERRIDE;
458  virtual Err MakeErrorDescribing(
459      const std::string& msg,
460      const std::string& help = std::string()) const OVERRIDE;
461  virtual void Print(std::ostream& out, int indent) const OVERRIDE;
462
463  const Token& comment() const { return comment_; }
464  void set_comment(const Token& t) { comment_ = t; }
465
466 private:
467  Token comment_;
468
469  DISALLOW_COPY_AND_ASSIGN(BlockCommentNode);
470};
471
472#endif  // TOOLS_GN_PARSE_TREE_H_
473