• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 class AccessorNode;
18 class BinaryOpNode;
19 class BlockNode;
20 class ConditionNode;
21 class FunctionCallNode;
22 class IdentifierNode;
23 class ListNode;
24 class LiteralNode;
25 class Scope;
26 class UnaryOpNode;
27 class BlockCommentNode;
28 
29 class Comments {
30  public:
31   Comments();
32   virtual ~Comments();
33 
before()34   const std::vector<Token>& before() const { return before_; }
append_before(Token c)35   void append_before(Token c) {
36     before_.push_back(c);
37   }
38 
suffix()39   const std::vector<Token>& suffix() const { return suffix_; }
append_suffix(Token c)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 
after()48   const std::vector<Token>& after() const { return after_; }
append_after(Token c)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.
70 class 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 
comments()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.
135 class 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.
base()150   const Token& base() const { return base_; }
set_base(const Token & b)151   void set_base(const Token& b) { base_ = b; }
152 
153   // Index is the expression inside the []. Will be null if member is set.
index()154   const ParseNode* index() const { return index_.get(); }
set_index(scoped_ptr<ParseNode> i)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.
member()159   const IdentifierNode* member() const { return member_.get(); }
set_member(scoped_ptr<IdentifierNode> i)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 
178 class 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 
op()191   const Token& op() const { return op_; }
set_op(const Token & t)192   void set_op(const Token& t) { op_ = t; }
193 
left()194   const ParseNode* left() const { return left_.get(); }
set_left(scoped_ptr<ParseNode> left)195   void set_left(scoped_ptr<ParseNode> left) {
196     left_ = left.Pass();
197   }
198 
right()199   const ParseNode* right() const { return right_.get(); }
set_right(scoped_ptr<ParseNode> right)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 
214 class 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 
set_begin_token(const Token & t)228   void set_begin_token(const Token& t) { begin_token_ = t; }
set_end_token(const Token & t)229   void set_end_token(const Token& t) { end_token_ = t; }
230 
statements()231   const std::vector<ParseNode*>& statements() const { return statements_; }
append_statement(scoped_ptr<ParseNode> s)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 
254 class 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 
set_if_token(const Token & token)267   void set_if_token(const Token& token) { if_token_ = token; }
268 
condition()269   const ParseNode* condition() const { return condition_.get(); }
set_condition(scoped_ptr<ParseNode> c)270   void set_condition(scoped_ptr<ParseNode> c) {
271     condition_ = c.Pass();
272   }
273 
if_true()274   const BlockNode* if_true() const { return if_true_.get(); }
set_if_true(scoped_ptr<BlockNode> t)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.
if_false()281   const ParseNode* if_false() const { return if_false_.get(); }
set_if_false(scoped_ptr<ParseNode> f)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 
299 class 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 
function()312   const Token& function() const { return function_; }
set_function(Token t)313   void set_function(Token t) { function_ = t; }
314 
args()315   const ListNode* args() const { return args_.get(); }
set_args(scoped_ptr<ListNode> a)316   void set_args(scoped_ptr<ListNode> a) { args_ = a.Pass(); }
317 
block()318   const BlockNode* block() const { return block_.get(); }
set_block(scoped_ptr<BlockNode> b)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 
331 class 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 
value()345   const Token& value() const { return value_; }
set_value(const Token & t)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 
356 class 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 
set_begin_token(const Token & t)369   void set_begin_token(const Token& t) { begin_token_ = t; }
set_end_token(const Token & t)370   void set_end_token(const Token& t) { end_token_ = t; }
371 
append_item(scoped_ptr<ParseNode> s)372   void append_item(scoped_ptr<ParseNode> s) {
373     contents_.push_back(s.release());
374   }
contents()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 
390 class 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 
value()404   const Token& value() const { return value_; }
set_value(const Token & t)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 
415 class 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 
op()428   const Token& op() const { return op_; }
set_op(const Token & t)429   void set_op(const Token& t) { op_ = t; }
430 
operand()431   const ParseNode* operand() const { return operand_.get(); }
set_operand(scoped_ptr<ParseNode> operand)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.
450 class 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 
comment()463   const Token& comment() const { return comment_; }
set_comment(const Token & t)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