Change next_proto member type.
[chromium-blink-merge.git] / tools / gn / parse_tree.h
blobdcf678babc2966307453742a3a9567b20c3b5a87
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.
5 #ifndef TOOLS_GN_PARSE_TREE_H_
6 #define TOOLS_GN_PARSE_TREE_H_
8 #include <vector>
10 #include "base/basictypes.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "tools/gn/err.h"
13 #include "tools/gn/token.h"
14 #include "tools/gn/value.h"
16 class AccessorNode;
17 class BinaryOpNode;
18 class BlockCommentNode;
19 class BlockNode;
20 class ConditionNode;
21 class EndNode;
22 class FunctionCallNode;
23 class IdentifierNode;
24 class ListNode;
25 class LiteralNode;
26 class Scope;
27 class UnaryOpNode;
29 class Comments {
30 public:
31 Comments();
32 virtual ~Comments();
34 const std::vector<Token>& before() const { return before_; }
35 void append_before(Token c) {
36 before_.push_back(c);
39 const std::vector<Token>& suffix() const { return suffix_; }
40 void append_suffix(Token c) {
41 suffix_.push_back(c);
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();
48 const std::vector<Token>& after() const { return after_; }
49 void append_after(Token c) {
50 after_.push_back(c);
53 private:
54 // Whole line comments before the expression.
55 std::vector<Token> before_;
57 // End-of-line comments after this expression.
58 std::vector<Token> suffix_;
60 // For top-level expressions only, after_ lists whole-line comments
61 // following the expression.
62 std::vector<Token> after_;
64 DISALLOW_COPY_AND_ASSIGN(Comments);
67 // ParseNode -------------------------------------------------------------------
69 // A node in the AST.
70 class ParseNode {
71 public:
72 ParseNode();
73 virtual ~ParseNode();
75 virtual const AccessorNode* AsAccessor() const;
76 virtual const BinaryOpNode* AsBinaryOp() const;
77 virtual const BlockCommentNode* AsBlockComment() const;
78 virtual const BlockNode* AsBlock() const;
79 virtual const ConditionNode* AsConditionNode() const;
80 virtual const EndNode* AsEnd() const;
81 virtual const FunctionCallNode* AsFunctionCall() const;
82 virtual const IdentifierNode* AsIdentifier() const;
83 virtual const ListNode* AsList() const;
84 virtual const LiteralNode* AsLiteral() const;
85 virtual const UnaryOpNode* AsUnaryOp() const;
87 virtual Value Execute(Scope* scope, Err* err) const = 0;
89 virtual LocationRange GetRange() const = 0;
91 // Returns an error with the given messages and the range set to something
92 // that indicates this node.
93 virtual Err MakeErrorDescribing(
94 const std::string& msg,
95 const std::string& help = std::string()) const = 0;
97 // Prints a representation of this node to the given string, indenting
98 // by the given number of spaces.
99 virtual void Print(std::ostream& out, int indent) const = 0;
101 const Comments* comments() const { return comments_.get(); }
102 Comments* comments_mutable();
103 void PrintComments(std::ostream& out, int indent) const;
105 private:
106 scoped_ptr<Comments> comments_;
108 DISALLOW_COPY_AND_ASSIGN(ParseNode);
111 // AccessorNode ----------------------------------------------------------------
113 // Access an array or scope element.
115 // Currently, such values are only read-only. In that you can do:
116 // a = obj1.a
117 // b = obj2[0]
118 // But not
119 // obj1.a = 5
120 // obj2[0] = 6
122 // In the current design where the dot operator is used only for templates, we
123 // explicitly don't want to allow you to do "invoker.foo = 5", so if we added
124 // support for accessors to be lvalues, we would also need to add some concept
125 // of a constant scope. Supporting this would also add a lot of complications
126 // to the operator= implementation, since some accessors might return values
127 // in the const root scope that shouldn't be modified. Without a strong
128 // use-case for this, it seems simpler to just disallow it.
130 // Additionally, the left-hand-side of the accessor must currently be an
131 // identifier. So you can't do things like:
132 // function_call()[1]
133 // a = b.c.d
134 // These are easier to implement if we needed them but given the very limited
135 // use cases for this, it hasn't seemed worth the bother.
136 class AccessorNode : public ParseNode {
137 public:
138 AccessorNode();
139 ~AccessorNode() override;
141 const AccessorNode* AsAccessor() const override;
142 Value Execute(Scope* scope, Err* err) const override;
143 LocationRange GetRange() const override;
144 Err MakeErrorDescribing(
145 const std::string& msg,
146 const std::string& help = std::string()) const override;
147 void Print(std::ostream& out, int indent) const override;
149 // Base is the thing on the left of the [] or dot, currently always required
150 // to be an identifier token.
151 const Token& base() const { return base_; }
152 void set_base(const Token& b) { base_ = b; }
154 // Index is the expression inside the []. Will be null if member is set.
155 const ParseNode* index() const { return index_.get(); }
156 void set_index(scoped_ptr<ParseNode> i) { index_ = i.Pass(); }
158 // The member is the identifier on the right hand side of the dot. Will be
159 // null if the index is set.
160 const IdentifierNode* member() const { return member_.get(); }
161 void set_member(scoped_ptr<IdentifierNode> i) { member_ = i.Pass(); }
163 private:
164 Value ExecuteArrayAccess(Scope* scope, Err* err) const;
165 Value ExecuteScopeAccess(Scope* scope, Err* err) const;
167 Token base_;
169 // Either index or member will be set according to what type of access this
170 // is.
171 scoped_ptr<ParseNode> index_;
172 scoped_ptr<IdentifierNode> member_;
174 DISALLOW_COPY_AND_ASSIGN(AccessorNode);
177 // BinaryOpNode ----------------------------------------------------------------
179 class BinaryOpNode : public ParseNode {
180 public:
181 BinaryOpNode();
182 ~BinaryOpNode() override;
184 const BinaryOpNode* AsBinaryOp() const override;
185 Value Execute(Scope* scope, Err* err) const override;
186 LocationRange GetRange() const override;
187 Err MakeErrorDescribing(
188 const std::string& msg,
189 const std::string& help = std::string()) const override;
190 void Print(std::ostream& out, int indent) const override;
192 const Token& op() const { return op_; }
193 void set_op(const Token& t) { op_ = t; }
195 const ParseNode* left() const { return left_.get(); }
196 void set_left(scoped_ptr<ParseNode> left) {
197 left_ = left.Pass();
200 const ParseNode* right() const { return right_.get(); }
201 void set_right(scoped_ptr<ParseNode> right) {
202 right_ = right.Pass();
205 private:
206 scoped_ptr<ParseNode> left_;
207 Token op_;
208 scoped_ptr<ParseNode> right_;
210 DISALLOW_COPY_AND_ASSIGN(BinaryOpNode);
213 // BlockNode -------------------------------------------------------------------
215 class BlockNode : public ParseNode {
216 public:
217 // Set has_scope if this block introduces a nested scope.
218 explicit BlockNode(bool has_scope);
219 ~BlockNode() override;
221 const BlockNode* AsBlock() const override;
222 Value Execute(Scope* scope, Err* err) const override;
223 LocationRange GetRange() const override;
224 Err MakeErrorDescribing(
225 const std::string& msg,
226 const std::string& help = std::string()) const override;
227 void Print(std::ostream& out, int indent) const override;
229 void set_begin_token(const Token& t) { begin_token_ = t; }
230 void set_end(scoped_ptr<EndNode> e) { end_ = e.Pass(); }
231 const EndNode* End() const { return end_.get(); }
233 const std::vector<ParseNode*>& statements() const { return statements_; }
234 void append_statement(scoped_ptr<ParseNode> s) {
235 statements_.push_back(s.release());
238 // Doesn't create a nested scope.
239 Value ExecuteBlockInScope(Scope* our_scope, Err* err) const;
241 private:
242 bool has_scope_;
244 // Tokens corresponding to { and }, if any (may be NULL). The end is stored
245 // in a custom parse node so that it can have comments hung off of it.
246 Token begin_token_;
247 scoped_ptr<EndNode> end_;
249 // Owning pointers, use unique_ptr when we can use C++11.
250 std::vector<ParseNode*> statements_;
252 DISALLOW_COPY_AND_ASSIGN(BlockNode);
255 // ConditionNode ---------------------------------------------------------------
257 class ConditionNode : public ParseNode {
258 public:
259 ConditionNode();
260 ~ConditionNode() override;
262 const ConditionNode* AsConditionNode() const override;
263 Value Execute(Scope* scope, Err* err) const override;
264 LocationRange GetRange() const override;
265 Err MakeErrorDescribing(
266 const std::string& msg,
267 const std::string& help = std::string()) const override;
268 void Print(std::ostream& out, int indent) const override;
270 void set_if_token(const Token& token) { if_token_ = token; }
272 const ParseNode* condition() const { return condition_.get(); }
273 void set_condition(scoped_ptr<ParseNode> c) {
274 condition_ = c.Pass();
277 const BlockNode* if_true() const { return if_true_.get(); }
278 void set_if_true(scoped_ptr<BlockNode> t) {
279 if_true_ = t.Pass();
282 // This is either empty, a block (for the else clause), or another
283 // condition.
284 const ParseNode* if_false() const { return if_false_.get(); }
285 void set_if_false(scoped_ptr<ParseNode> f) {
286 if_false_ = f.Pass();
289 private:
290 // Token corresponding to the "if" string.
291 Token if_token_;
293 scoped_ptr<ParseNode> condition_; // Always non-null.
294 scoped_ptr<BlockNode> if_true_; // Always non-null.
295 scoped_ptr<ParseNode> if_false_; // May be null.
297 DISALLOW_COPY_AND_ASSIGN(ConditionNode);
300 // FunctionCallNode ------------------------------------------------------------
302 class FunctionCallNode : public ParseNode {
303 public:
304 FunctionCallNode();
305 ~FunctionCallNode() override;
307 const FunctionCallNode* AsFunctionCall() const override;
308 Value Execute(Scope* scope, Err* err) const override;
309 LocationRange GetRange() const override;
310 Err MakeErrorDescribing(
311 const std::string& msg,
312 const std::string& help = std::string()) const override;
313 void Print(std::ostream& out, int indent) const override;
315 const Token& function() const { return function_; }
316 void set_function(Token t) { function_ = t; }
318 const ListNode* args() const { return args_.get(); }
319 void set_args(scoped_ptr<ListNode> a) { args_ = a.Pass(); }
321 const BlockNode* block() const { return block_.get(); }
322 void set_block(scoped_ptr<BlockNode> b) { block_ = b.Pass(); }
324 private:
325 Token function_;
326 scoped_ptr<ListNode> args_;
327 scoped_ptr<BlockNode> block_; // May be null.
329 DISALLOW_COPY_AND_ASSIGN(FunctionCallNode);
332 // IdentifierNode --------------------------------------------------------------
334 class IdentifierNode : public ParseNode {
335 public:
336 IdentifierNode();
337 IdentifierNode(const Token& token);
338 ~IdentifierNode() override;
340 const IdentifierNode* AsIdentifier() const override;
341 Value Execute(Scope* scope, Err* err) const override;
342 LocationRange GetRange() const override;
343 Err MakeErrorDescribing(
344 const std::string& msg,
345 const std::string& help = std::string()) const override;
346 void Print(std::ostream& out, int indent) const override;
348 const Token& value() const { return value_; }
349 void set_value(const Token& t) { value_ = t; }
351 private:
352 Token value_;
354 DISALLOW_COPY_AND_ASSIGN(IdentifierNode);
357 // ListNode --------------------------------------------------------------------
359 class ListNode : public ParseNode {
360 public:
361 ListNode();
362 ~ListNode() override;
364 const ListNode* AsList() const override;
365 Value Execute(Scope* scope, Err* err) const override;
366 LocationRange GetRange() const override;
367 Err MakeErrorDescribing(
368 const std::string& msg,
369 const std::string& help = std::string()) const override;
370 void Print(std::ostream& out, int indent) const override;
372 void set_begin_token(const Token& t) { begin_token_ = t; }
373 void set_end(scoped_ptr<EndNode> e) { end_ = e.Pass(); }
374 const EndNode* End() const { return end_.get(); }
376 void append_item(scoped_ptr<ParseNode> s) {
377 contents_.push_back(s.release());
379 const std::vector<const ParseNode*>& contents() const { return contents_; }
381 // During formatting, do we want this list to always be multliline? This is
382 // used to make assignments to deps, sources, etc. always be multiline lists,
383 // rather than collapsed to a single line when they're one element.
384 bool prefer_multiline() const { return prefer_multiline_; }
385 void set_prefer_multiline(bool prefer_multiline) {
386 prefer_multiline_ = prefer_multiline;
389 private:
390 // Tokens corresponding to the [ and ]. The end token is stored in inside an
391 // custom parse node so that it can have comments hung off of it.
392 Token begin_token_;
393 scoped_ptr<EndNode> end_;
394 bool prefer_multiline_;
396 // Owning pointers, use unique_ptr when we can use C++11.
397 std::vector<const ParseNode*> contents_;
399 DISALLOW_COPY_AND_ASSIGN(ListNode);
402 // LiteralNode -----------------------------------------------------------------
404 class LiteralNode : public ParseNode {
405 public:
406 LiteralNode();
407 LiteralNode(const Token& token);
408 ~LiteralNode() override;
410 const LiteralNode* AsLiteral() const override;
411 Value Execute(Scope* scope, Err* err) const override;
412 LocationRange GetRange() const override;
413 Err MakeErrorDescribing(
414 const std::string& msg,
415 const std::string& help = std::string()) const override;
416 void Print(std::ostream& out, int indent) const override;
418 const Token& value() const { return value_; }
419 void set_value(const Token& t) { value_ = t; }
421 private:
422 Token value_;
424 DISALLOW_COPY_AND_ASSIGN(LiteralNode);
427 // UnaryOpNode -----------------------------------------------------------------
429 class UnaryOpNode : public ParseNode {
430 public:
431 UnaryOpNode();
432 ~UnaryOpNode() override;
434 const UnaryOpNode* AsUnaryOp() const override;
435 Value Execute(Scope* scope, Err* err) const override;
436 LocationRange GetRange() const override;
437 Err MakeErrorDescribing(
438 const std::string& msg,
439 const std::string& help = std::string()) const override;
440 void Print(std::ostream& out, int indent) const override;
442 const Token& op() const { return op_; }
443 void set_op(const Token& t) { op_ = t; }
445 const ParseNode* operand() const { return operand_.get(); }
446 void set_operand(scoped_ptr<ParseNode> operand) {
447 operand_ = operand.Pass();
450 private:
451 Token op_;
452 scoped_ptr<ParseNode> operand_;
454 DISALLOW_COPY_AND_ASSIGN(UnaryOpNode);
457 // BlockCommentNode ------------------------------------------------------------
459 // This node type is only used for standalone comments (that is, those not
460 // specifically attached to another syntax element. The most common of these
461 // is a standard header block. This node contains only the last line of such
462 // a comment block as the anchor, and other lines of the block comment are
463 // hung off of it as Before comments, similar to other syntax elements.
464 class BlockCommentNode : public ParseNode {
465 public:
466 BlockCommentNode();
467 ~BlockCommentNode() override;
469 const BlockCommentNode* AsBlockComment() const override;
470 Value Execute(Scope* scope, Err* err) const override;
471 LocationRange GetRange() const override;
472 Err MakeErrorDescribing(
473 const std::string& msg,
474 const std::string& help = std::string()) const override;
475 void Print(std::ostream& out, int indent) const override;
477 const Token& comment() const { return comment_; }
478 void set_comment(const Token& t) { comment_ = t; }
480 private:
481 Token comment_;
483 DISALLOW_COPY_AND_ASSIGN(BlockCommentNode);
486 // EndNode ---------------------------------------------------------------------
488 // This node type is used as the end_ object for lists and blocks (rather than
489 // just the end ']', '}', or ')' token). This is so that during formatting
490 // traversal there is a node that appears at the end of the block to which
491 // comments can be attached.
492 class EndNode : public ParseNode {
493 public:
494 EndNode(const Token& token);
495 ~EndNode() override;
497 const EndNode* AsEnd() const override;
498 Value Execute(Scope* scope, Err* err) const override;
499 LocationRange GetRange() const override;
500 Err MakeErrorDescribing(
501 const std::string& msg,
502 const std::string& help = std::string()) const override;
503 void Print(std::ostream& out, int indent) const override;
505 const Token& value() const { return value_; }
506 void set_value(const Token& t) { value_ = t; }
508 private:
509 Token value_;
511 DISALLOW_COPY_AND_ASSIGN(EndNode);
514 #endif // TOOLS_GN_PARSE_TREE_H_