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_
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"
18 class BlockCommentNode
;
22 class FunctionCallNode
;
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
45 const std::vector
<Token
>& after() const { return after_
; }
46 void append_after(Token c
) { after_
.push_back(c
); }
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 -------------------------------------------------------------------
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;
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:
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]
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
{
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
);
161 Value
ExecuteArrayAccess(Scope
* scope
, Err
* err
) const;
162 Value
ExecuteScopeAccess(Scope
* scope
, Err
* err
) const;
166 // Either index or member will be set according to what type of access this
168 scoped_ptr
<ParseNode
> index_
;
169 scoped_ptr
<IdentifierNode
> member_
;
171 DISALLOW_COPY_AND_ASSIGN(AccessorNode
);
174 // BinaryOpNode ----------------------------------------------------------------
176 class BinaryOpNode
: public ParseNode
{
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
) {
197 const ParseNode
* right() const { return right_
.get(); }
198 void set_right(scoped_ptr
<ParseNode
> right
) {
199 right_
= right
.Pass();
203 scoped_ptr
<ParseNode
> left_
;
205 scoped_ptr
<ParseNode
> right_
;
207 DISALLOW_COPY_AND_ASSIGN(BinaryOpNode
);
210 // BlockNode -------------------------------------------------------------------
212 class BlockNode
: public ParseNode
{
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;
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.
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
{
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
) {
279 // This is either empty, a block (for the else clause), or another
281 const ParseNode
* if_false() const { return if_false_
.get(); }
282 void set_if_false(scoped_ptr
<ParseNode
> f
) {
283 if_false_
= f
.Pass();
287 // Token corresponding to the "if" string.
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
{
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(); }
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
{
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
);
353 DISALLOW_COPY_AND_ASSIGN(IdentifierNode
);
356 // ListNode --------------------------------------------------------------------
358 class ListNode
: public ParseNode
{
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
;
393 SortRange(size_t begin
, size_t end
) : begin(begin
), end(end
) {}
395 // Only public for testing.
396 std::vector
<SortRange
> GetSortRanges() const;
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.
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
{
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
);
435 DISALLOW_COPY_AND_ASSIGN(LiteralNode
);
438 // UnaryOpNode -----------------------------------------------------------------
440 class UnaryOpNode
: public ParseNode
{
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();
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
{
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
; }
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
{
505 explicit EndNode(const Token
& token
);
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
; }
522 DISALLOW_COPY_AND_ASSIGN(EndNode
);
525 #endif // TOOLS_GN_PARSE_TREE_H_