ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / tools / gn / parse_tree.h
blob0611ce1f95979ad5a9a5f24a6ea0a27dc40ba525
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) { before_.push_back(c); }
36 void clear_before() { before_.clear(); }
38 const std::vector<Token>& suffix() const { return suffix_; }
39 void append_suffix(Token c) { suffix_.push_back(c); }
40 // Reverse the order of the suffix comments. When walking the tree in
41 // post-order we append suffix comments in reverse order, so this fixes them
42 // up.
43 void ReverseSuffix();
45 const std::vector<Token>& after() const { return after_; }
46 void append_after(Token c) { after_.push_back(c); }
48 private:
49 // Whole line comments before the expression.
50 std::vector<Token> before_;
52 // End-of-line comments after this expression.
53 std::vector<Token> suffix_;
55 // For top-level expressions only, after_ lists whole-line comments
56 // following the expression.
57 std::vector<Token> after_;
59 DISALLOW_COPY_AND_ASSIGN(Comments);
62 // ParseNode -------------------------------------------------------------------
64 // A node in the AST.
65 class ParseNode {
66 public:
67 ParseNode();
68 virtual ~ParseNode();
70 virtual const AccessorNode* AsAccessor() const;
71 virtual const BinaryOpNode* AsBinaryOp() const;
72 virtual const BlockCommentNode* AsBlockComment() const;
73 virtual const BlockNode* AsBlock() const;
74 virtual const ConditionNode* AsConditionNode() const;
75 virtual const EndNode* AsEnd() const;
76 virtual const FunctionCallNode* AsFunctionCall() const;
77 virtual const IdentifierNode* AsIdentifier() const;
78 virtual const ListNode* AsList() const;
79 virtual const LiteralNode* AsLiteral() const;
80 virtual const UnaryOpNode* AsUnaryOp() const;
82 virtual Value Execute(Scope* scope, Err* err) const = 0;
84 virtual LocationRange GetRange() const = 0;
86 // Returns an error with the given messages and the range set to something
87 // that indicates this node.
88 virtual Err MakeErrorDescribing(
89 const std::string& msg,
90 const std::string& help = std::string()) const = 0;
92 // Prints a representation of this node to the given string, indenting
93 // by the given number of spaces.
94 virtual void Print(std::ostream& out, int indent) const = 0;
96 const Comments* comments() const { return comments_.get(); }
97 Comments* comments_mutable();
98 void PrintComments(std::ostream& out, int indent) const;
100 private:
101 scoped_ptr<Comments> comments_;
103 DISALLOW_COPY_AND_ASSIGN(ParseNode);
106 // AccessorNode ----------------------------------------------------------------
108 // Access an array or scope element.
110 // Currently, such values are only read-only. In that you can do:
111 // a = obj1.a
112 // b = obj2[0]
113 // But not
114 // obj1.a = 5
115 // obj2[0] = 6
117 // In the current design where the dot operator is used only for templates, we
118 // explicitly don't want to allow you to do "invoker.foo = 5", so if we added
119 // support for accessors to be lvalues, we would also need to add some concept
120 // of a constant scope. Supporting this would also add a lot of complications
121 // to the operator= implementation, since some accessors might return values
122 // in the const root scope that shouldn't be modified. Without a strong
123 // use-case for this, it seems simpler to just disallow it.
125 // Additionally, the left-hand-side of the accessor must currently be an
126 // identifier. So you can't do things like:
127 // function_call()[1]
128 // a = b.c.d
129 // These are easier to implement if we needed them but given the very limited
130 // use cases for this, it hasn't seemed worth the bother.
131 class AccessorNode : public ParseNode {
132 public:
133 AccessorNode();
134 ~AccessorNode() override;
136 const AccessorNode* AsAccessor() const override;
137 Value Execute(Scope* scope, Err* err) const override;
138 LocationRange GetRange() const override;
139 Err MakeErrorDescribing(
140 const std::string& msg,
141 const std::string& help = std::string()) const override;
142 void Print(std::ostream& out, int indent) const override;
144 // Base is the thing on the left of the [] or dot, currently always required
145 // to be an identifier token.
146 const Token& base() const { return base_; }
147 void set_base(const Token& b) { base_ = b; }
149 // Index is the expression inside the []. Will be null if member is set.
150 const ParseNode* index() const { return index_.get(); }
151 void set_index(scoped_ptr<ParseNode> i) { index_ = i.Pass(); }
153 // The member is the identifier on the right hand side of the dot. Will be
154 // null if the index is set.
155 const IdentifierNode* member() const { return member_.get(); }
156 void set_member(scoped_ptr<IdentifierNode> i) { member_ = i.Pass(); }
158 void SetNewLocation(int line_number);
160 private:
161 Value ExecuteArrayAccess(Scope* scope, Err* err) const;
162 Value ExecuteScopeAccess(Scope* scope, Err* err) const;
164 Token base_;
166 // Either index or member will be set according to what type of access this
167 // is.
168 scoped_ptr<ParseNode> index_;
169 scoped_ptr<IdentifierNode> member_;
171 DISALLOW_COPY_AND_ASSIGN(AccessorNode);
174 // BinaryOpNode ----------------------------------------------------------------
176 class BinaryOpNode : public ParseNode {
177 public:
178 BinaryOpNode();
179 ~BinaryOpNode() override;
181 const BinaryOpNode* AsBinaryOp() const override;
182 Value Execute(Scope* scope, Err* err) const override;
183 LocationRange GetRange() const override;
184 Err MakeErrorDescribing(
185 const std::string& msg,
186 const std::string& help = std::string()) const override;
187 void Print(std::ostream& out, int indent) const override;
189 const Token& op() const { return op_; }
190 void set_op(const Token& t) { op_ = t; }
192 const ParseNode* left() const { return left_.get(); }
193 void set_left(scoped_ptr<ParseNode> left) {
194 left_ = left.Pass();
197 const ParseNode* right() const { return right_.get(); }
198 void set_right(scoped_ptr<ParseNode> right) {
199 right_ = right.Pass();
202 private:
203 scoped_ptr<ParseNode> left_;
204 Token op_;
205 scoped_ptr<ParseNode> right_;
207 DISALLOW_COPY_AND_ASSIGN(BinaryOpNode);
210 // BlockNode -------------------------------------------------------------------
212 class BlockNode : public ParseNode {
213 public:
214 // Set has_scope if this block introduces a nested scope.
215 explicit BlockNode(bool has_scope);
216 ~BlockNode() override;
218 const BlockNode* AsBlock() const override;
219 Value Execute(Scope* scope, Err* err) const override;
220 LocationRange GetRange() const override;
221 Err MakeErrorDescribing(
222 const std::string& msg,
223 const std::string& help = std::string()) const override;
224 void Print(std::ostream& out, int indent) const override;
226 void set_begin_token(const Token& t) { begin_token_ = t; }
227 void set_end(scoped_ptr<EndNode> e) { end_ = e.Pass(); }
228 const EndNode* End() const { return end_.get(); }
230 const std::vector<ParseNode*>& statements() const { return statements_; }
231 void append_statement(scoped_ptr<ParseNode> s) {
232 statements_.push_back(s.release());
235 // Doesn't create a nested scope.
236 Value ExecuteBlockInScope(Scope* our_scope, Err* err) const;
238 private:
239 bool has_scope_;
241 // Tokens corresponding to { and }, if any (may be NULL). The end is stored
242 // in a custom parse node so that it can have comments hung off of it.
243 Token begin_token_;
244 scoped_ptr<EndNode> end_;
246 // Owning pointers, use unique_ptr when we can use C++11.
247 std::vector<ParseNode*> statements_;
249 DISALLOW_COPY_AND_ASSIGN(BlockNode);
252 // ConditionNode ---------------------------------------------------------------
254 class ConditionNode : public ParseNode {
255 public:
256 ConditionNode();
257 ~ConditionNode() override;
259 const ConditionNode* AsConditionNode() const override;
260 Value Execute(Scope* scope, Err* err) const override;
261 LocationRange GetRange() const override;
262 Err MakeErrorDescribing(
263 const std::string& msg,
264 const std::string& help = std::string()) const override;
265 void Print(std::ostream& out, int indent) const override;
267 void set_if_token(const Token& token) { if_token_ = token; }
269 const ParseNode* condition() const { return condition_.get(); }
270 void set_condition(scoped_ptr<ParseNode> c) {
271 condition_ = c.Pass();
274 const BlockNode* if_true() const { return if_true_.get(); }
275 void set_if_true(scoped_ptr<BlockNode> t) {
276 if_true_ = t.Pass();
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();
286 private:
287 // Token corresponding to the "if" string.
288 Token if_token_;
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.
294 DISALLOW_COPY_AND_ASSIGN(ConditionNode);
297 // FunctionCallNode ------------------------------------------------------------
299 class FunctionCallNode : public ParseNode {
300 public:
301 FunctionCallNode();
302 ~FunctionCallNode() override;
304 const FunctionCallNode* AsFunctionCall() const override;
305 Value Execute(Scope* scope, Err* err) const override;
306 LocationRange GetRange() const override;
307 Err MakeErrorDescribing(
308 const std::string& msg,
309 const std::string& help = std::string()) const override;
310 void Print(std::ostream& out, int indent) const override;
312 const Token& function() const { return function_; }
313 void set_function(Token t) { function_ = t; }
315 const ListNode* args() const { return args_.get(); }
316 void set_args(scoped_ptr<ListNode> a) { args_ = a.Pass(); }
318 const BlockNode* block() const { return block_.get(); }
319 void set_block(scoped_ptr<BlockNode> b) { block_ = b.Pass(); }
321 private:
322 Token function_;
323 scoped_ptr<ListNode> args_;
324 scoped_ptr<BlockNode> block_; // May be null.
326 DISALLOW_COPY_AND_ASSIGN(FunctionCallNode);
329 // IdentifierNode --------------------------------------------------------------
331 class IdentifierNode : public ParseNode {
332 public:
333 IdentifierNode();
334 explicit IdentifierNode(const Token& token);
335 ~IdentifierNode() override;
337 const IdentifierNode* AsIdentifier() const override;
338 Value Execute(Scope* scope, Err* err) const override;
339 LocationRange GetRange() const override;
340 Err MakeErrorDescribing(
341 const std::string& msg,
342 const std::string& help = std::string()) const override;
343 void Print(std::ostream& out, int indent) const override;
345 const Token& value() const { return value_; }
346 void set_value(const Token& t) { value_ = t; }
348 void SetNewLocation(int line_number);
350 private:
351 Token value_;
353 DISALLOW_COPY_AND_ASSIGN(IdentifierNode);
356 // ListNode --------------------------------------------------------------------
358 class ListNode : public ParseNode {
359 public:
360 ListNode();
361 ~ListNode() override;
363 const ListNode* AsList() const override;
364 Value Execute(Scope* scope, Err* err) const override;
365 LocationRange GetRange() const override;
366 Err MakeErrorDescribing(
367 const std::string& msg,
368 const std::string& help = std::string()) const override;
369 void Print(std::ostream& out, int indent) const override;
371 void set_begin_token(const Token& t) { begin_token_ = t; }
372 void set_end(scoped_ptr<EndNode> e) { end_ = e.Pass(); }
373 const EndNode* End() const { return end_.get(); }
375 void append_item(scoped_ptr<ParseNode> s) {
376 contents_.push_back(s.release());
378 const std::vector<const ParseNode*>& contents() const { return contents_; }
380 void SortAsStringsList();
382 // During formatting, do we want this list to always be multliline? This is
383 // used to make assignments to deps, sources, etc. always be multiline lists,
384 // rather than collapsed to a single line when they're one element.
385 bool prefer_multiline() const { return prefer_multiline_; }
386 void set_prefer_multiline(bool prefer_multiline) {
387 prefer_multiline_ = prefer_multiline;
390 struct SortRange {
391 size_t begin;
392 size_t end;
393 SortRange(size_t begin, size_t end) : begin(begin), end(end) {}
395 // Only public for testing.
396 std::vector<SortRange> GetSortRanges() const;
398 private:
399 // Tokens corresponding to the [ and ]. The end token is stored in inside an
400 // custom parse node so that it can have comments hung off of it.
401 Token begin_token_;
402 scoped_ptr<EndNode> end_;
403 bool prefer_multiline_;
405 // Owning pointers, use unique_ptr when we can use C++11.
406 std::vector<const ParseNode*> contents_;
408 DISALLOW_COPY_AND_ASSIGN(ListNode);
411 // LiteralNode -----------------------------------------------------------------
413 class LiteralNode : public ParseNode {
414 public:
415 LiteralNode();
416 explicit LiteralNode(const Token& token);
417 ~LiteralNode() override;
419 const LiteralNode* AsLiteral() const override;
420 Value Execute(Scope* scope, Err* err) const override;
421 LocationRange GetRange() const override;
422 Err MakeErrorDescribing(
423 const std::string& msg,
424 const std::string& help = std::string()) const override;
425 void Print(std::ostream& out, int indent) const override;
427 const Token& value() const { return value_; }
428 void set_value(const Token& t) { value_ = t; }
430 void SetNewLocation(int line_number);
432 private:
433 Token value_;
435 DISALLOW_COPY_AND_ASSIGN(LiteralNode);
438 // UnaryOpNode -----------------------------------------------------------------
440 class UnaryOpNode : public ParseNode {
441 public:
442 UnaryOpNode();
443 ~UnaryOpNode() override;
445 const UnaryOpNode* AsUnaryOp() const override;
446 Value Execute(Scope* scope, Err* err) const override;
447 LocationRange GetRange() const override;
448 Err MakeErrorDescribing(
449 const std::string& msg,
450 const std::string& help = std::string()) const override;
451 void Print(std::ostream& out, int indent) const override;
453 const Token& op() const { return op_; }
454 void set_op(const Token& t) { op_ = t; }
456 const ParseNode* operand() const { return operand_.get(); }
457 void set_operand(scoped_ptr<ParseNode> operand) {
458 operand_ = operand.Pass();
461 private:
462 Token op_;
463 scoped_ptr<ParseNode> operand_;
465 DISALLOW_COPY_AND_ASSIGN(UnaryOpNode);
468 // BlockCommentNode ------------------------------------------------------------
470 // This node type is only used for standalone comments (that is, those not
471 // specifically attached to another syntax element. The most common of these
472 // is a standard header block. This node contains only the last line of such
473 // a comment block as the anchor, and other lines of the block comment are
474 // hung off of it as Before comments, similar to other syntax elements.
475 class BlockCommentNode : public ParseNode {
476 public:
477 BlockCommentNode();
478 ~BlockCommentNode() override;
480 const BlockCommentNode* AsBlockComment() const override;
481 Value Execute(Scope* scope, Err* err) const override;
482 LocationRange GetRange() const override;
483 Err MakeErrorDescribing(
484 const std::string& msg,
485 const std::string& help = std::string()) const override;
486 void Print(std::ostream& out, int indent) const override;
488 const Token& comment() const { return comment_; }
489 void set_comment(const Token& t) { comment_ = t; }
491 private:
492 Token comment_;
494 DISALLOW_COPY_AND_ASSIGN(BlockCommentNode);
497 // EndNode ---------------------------------------------------------------------
499 // This node type is used as the end_ object for lists and blocks (rather than
500 // just the end ']', '}', or ')' token). This is so that during formatting
501 // traversal there is a node that appears at the end of the block to which
502 // comments can be attached.
503 class EndNode : public ParseNode {
504 public:
505 explicit EndNode(const Token& token);
506 ~EndNode() override;
508 const EndNode* AsEnd() const override;
509 Value Execute(Scope* scope, Err* err) const override;
510 LocationRange GetRange() const override;
511 Err MakeErrorDescribing(
512 const std::string& msg,
513 const std::string& help = std::string()) const override;
514 void Print(std::ostream& out, int indent) const override;
516 const Token& value() const { return value_; }
517 void set_value(const Token& t) { value_ = t; }
519 private:
520 Token value_;
522 DISALLOW_COPY_AND_ASSIGN(EndNode);
525 #endif // TOOLS_GN_PARSE_TREE_H_