Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / tools / gn / parse_tree.h
blob60d15700c0189af8d63c97b0253e96308a59a003
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 private:
382 // Tokens corresponding to the [ and ]. The end token is stored in inside an
383 // custom parse node so that it can have comments hung off of it.
384 Token begin_token_;
385 scoped_ptr<EndNode> end_;
387 // Owning pointers, use unique_ptr when we can use C++11.
388 std::vector<const ParseNode*> contents_;
390 DISALLOW_COPY_AND_ASSIGN(ListNode);
393 // LiteralNode -----------------------------------------------------------------
395 class LiteralNode : public ParseNode {
396 public:
397 LiteralNode();
398 LiteralNode(const Token& token);
399 ~LiteralNode() override;
401 const LiteralNode* AsLiteral() const override;
402 Value Execute(Scope* scope, Err* err) const override;
403 LocationRange GetRange() const override;
404 Err MakeErrorDescribing(
405 const std::string& msg,
406 const std::string& help = std::string()) const override;
407 void Print(std::ostream& out, int indent) const override;
409 const Token& value() const { return value_; }
410 void set_value(const Token& t) { value_ = t; }
412 private:
413 Token value_;
415 DISALLOW_COPY_AND_ASSIGN(LiteralNode);
418 // UnaryOpNode -----------------------------------------------------------------
420 class UnaryOpNode : public ParseNode {
421 public:
422 UnaryOpNode();
423 ~UnaryOpNode() override;
425 const UnaryOpNode* AsUnaryOp() const override;
426 Value Execute(Scope* scope, Err* err) const override;
427 LocationRange GetRange() const override;
428 Err MakeErrorDescribing(
429 const std::string& msg,
430 const std::string& help = std::string()) const override;
431 void Print(std::ostream& out, int indent) const override;
433 const Token& op() const { return op_; }
434 void set_op(const Token& t) { op_ = t; }
436 const ParseNode* operand() const { return operand_.get(); }
437 void set_operand(scoped_ptr<ParseNode> operand) {
438 operand_ = operand.Pass();
441 private:
442 Token op_;
443 scoped_ptr<ParseNode> operand_;
445 DISALLOW_COPY_AND_ASSIGN(UnaryOpNode);
448 // BlockCommentNode ------------------------------------------------------------
450 // This node type is only used for standalone comments (that is, those not
451 // specifically attached to another syntax element. The most common of these
452 // is a standard header block. This node contains only the last line of such
453 // a comment block as the anchor, and other lines of the block comment are
454 // hung off of it as Before comments, similar to other syntax elements.
455 class BlockCommentNode : public ParseNode {
456 public:
457 BlockCommentNode();
458 ~BlockCommentNode() override;
460 const BlockCommentNode* AsBlockComment() const override;
461 Value Execute(Scope* scope, Err* err) const override;
462 LocationRange GetRange() const override;
463 Err MakeErrorDescribing(
464 const std::string& msg,
465 const std::string& help = std::string()) const override;
466 void Print(std::ostream& out, int indent) const override;
468 const Token& comment() const { return comment_; }
469 void set_comment(const Token& t) { comment_ = t; }
471 private:
472 Token comment_;
474 DISALLOW_COPY_AND_ASSIGN(BlockCommentNode);
477 // EndNode ---------------------------------------------------------------------
479 // This node type is used as the end_ object for lists and blocks (rather than
480 // just the end ']', '}', or ')' token). This is so that during formatting
481 // traversal there is a node that appears at the end of the block to which
482 // comments can be attached.
483 class EndNode : public ParseNode {
484 public:
485 EndNode(const Token& token);
486 ~EndNode() override;
488 const EndNode* AsEnd() const override;
489 Value Execute(Scope* scope, Err* err) const override;
490 LocationRange GetRange() const override;
491 Err MakeErrorDescribing(
492 const std::string& msg,
493 const std::string& help = std::string()) const override;
494 void Print(std::ostream& out, int indent) const override;
496 const Token& value() const { return value_; }
497 void set_value(const Token& t) { value_ = t; }
499 private:
500 Token value_;
502 DISALLOW_COPY_AND_ASSIGN(EndNode);
505 #endif // TOOLS_GN_PARSE_TREE_H_