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
{
215 ~BlockNode() override
;
217 const BlockNode
* AsBlock() const override
;
218 Value
Execute(Scope
* scope
, Err
* err
) const override
;
219 LocationRange
GetRange() const override
;
220 Err
MakeErrorDescribing(
221 const std::string
& msg
,
222 const std::string
& help
= std::string()) const override
;
223 void Print(std::ostream
& out
, int indent
) const override
;
225 void set_begin_token(const Token
& t
) { begin_token_
= t
; }
226 void set_end(scoped_ptr
<EndNode
> e
) { end_
= e
.Pass(); }
227 const EndNode
* End() const { return end_
.get(); }
229 const std::vector
<ParseNode
*>& statements() const { return statements_
; }
230 void append_statement(scoped_ptr
<ParseNode
> s
) {
231 statements_
.push_back(s
.release());
235 // Tokens corresponding to { and }, if any (may be NULL). The end is stored
236 // in a custom parse node so that it can have comments hung off of it.
238 scoped_ptr
<EndNode
> end_
;
240 // Owning pointers, use unique_ptr when we can use C++11.
241 std::vector
<ParseNode
*> statements_
;
243 DISALLOW_COPY_AND_ASSIGN(BlockNode
);
246 // ConditionNode ---------------------------------------------------------------
248 class ConditionNode
: public ParseNode
{
251 ~ConditionNode() override
;
253 const ConditionNode
* AsConditionNode() const override
;
254 Value
Execute(Scope
* scope
, Err
* err
) const override
;
255 LocationRange
GetRange() const override
;
256 Err
MakeErrorDescribing(
257 const std::string
& msg
,
258 const std::string
& help
= std::string()) const override
;
259 void Print(std::ostream
& out
, int indent
) const override
;
261 void set_if_token(const Token
& token
) { if_token_
= token
; }
263 const ParseNode
* condition() const { return condition_
.get(); }
264 void set_condition(scoped_ptr
<ParseNode
> c
) {
265 condition_
= c
.Pass();
268 const BlockNode
* if_true() const { return if_true_
.get(); }
269 void set_if_true(scoped_ptr
<BlockNode
> t
) {
273 // This is either empty, a block (for the else clause), or another
275 const ParseNode
* if_false() const { return if_false_
.get(); }
276 void set_if_false(scoped_ptr
<ParseNode
> f
) {
277 if_false_
= f
.Pass();
281 // Token corresponding to the "if" string.
284 scoped_ptr
<ParseNode
> condition_
; // Always non-null.
285 scoped_ptr
<BlockNode
> if_true_
; // Always non-null.
286 scoped_ptr
<ParseNode
> if_false_
; // May be null.
288 DISALLOW_COPY_AND_ASSIGN(ConditionNode
);
291 // FunctionCallNode ------------------------------------------------------------
293 class FunctionCallNode
: public ParseNode
{
296 ~FunctionCallNode() override
;
298 const FunctionCallNode
* AsFunctionCall() const override
;
299 Value
Execute(Scope
* scope
, Err
* err
) const override
;
300 LocationRange
GetRange() const override
;
301 Err
MakeErrorDescribing(
302 const std::string
& msg
,
303 const std::string
& help
= std::string()) const override
;
304 void Print(std::ostream
& out
, int indent
) const override
;
306 const Token
& function() const { return function_
; }
307 void set_function(Token t
) { function_
= t
; }
309 const ListNode
* args() const { return args_
.get(); }
310 void set_args(scoped_ptr
<ListNode
> a
) { args_
= a
.Pass(); }
312 const BlockNode
* block() const { return block_
.get(); }
313 void set_block(scoped_ptr
<BlockNode
> b
) { block_
= b
.Pass(); }
317 scoped_ptr
<ListNode
> args_
;
318 scoped_ptr
<BlockNode
> block_
; // May be null.
320 DISALLOW_COPY_AND_ASSIGN(FunctionCallNode
);
323 // IdentifierNode --------------------------------------------------------------
325 class IdentifierNode
: public ParseNode
{
328 explicit IdentifierNode(const Token
& token
);
329 ~IdentifierNode() override
;
331 const IdentifierNode
* AsIdentifier() const override
;
332 Value
Execute(Scope
* scope
, Err
* err
) const override
;
333 LocationRange
GetRange() const override
;
334 Err
MakeErrorDescribing(
335 const std::string
& msg
,
336 const std::string
& help
= std::string()) const override
;
337 void Print(std::ostream
& out
, int indent
) const override
;
339 const Token
& value() const { return value_
; }
340 void set_value(const Token
& t
) { value_
= t
; }
342 void SetNewLocation(int line_number
);
347 DISALLOW_COPY_AND_ASSIGN(IdentifierNode
);
350 // ListNode --------------------------------------------------------------------
352 class ListNode
: public ParseNode
{
355 ~ListNode() override
;
357 const ListNode
* AsList() const override
;
358 Value
Execute(Scope
* scope
, Err
* err
) const override
;
359 LocationRange
GetRange() const override
;
360 Err
MakeErrorDescribing(
361 const std::string
& msg
,
362 const std::string
& help
= std::string()) const override
;
363 void Print(std::ostream
& out
, int indent
) const override
;
365 void set_begin_token(const Token
& t
) { begin_token_
= t
; }
366 void set_end(scoped_ptr
<EndNode
> e
) { end_
= e
.Pass(); }
367 const EndNode
* End() const { return end_
.get(); }
369 void append_item(scoped_ptr
<ParseNode
> s
) {
370 contents_
.push_back(s
.release());
372 const std::vector
<const ParseNode
*>& contents() const { return contents_
; }
374 void SortAsStringsList();
376 // During formatting, do we want this list to always be multliline? This is
377 // used to make assignments to deps, sources, etc. always be multiline lists,
378 // rather than collapsed to a single line when they're one element.
379 bool prefer_multiline() const { return prefer_multiline_
; }
380 void set_prefer_multiline(bool prefer_multiline
) {
381 prefer_multiline_
= prefer_multiline
;
387 SortRange(size_t begin
, size_t end
) : begin(begin
), end(end
) {}
389 // Only public for testing.
390 std::vector
<SortRange
> GetSortRanges() const;
393 // Tokens corresponding to the [ and ]. The end token is stored in inside an
394 // custom parse node so that it can have comments hung off of it.
396 scoped_ptr
<EndNode
> end_
;
397 bool prefer_multiline_
;
399 // Owning pointers, use unique_ptr when we can use C++11.
400 std::vector
<const ParseNode
*> contents_
;
402 DISALLOW_COPY_AND_ASSIGN(ListNode
);
405 // LiteralNode -----------------------------------------------------------------
407 class LiteralNode
: public ParseNode
{
410 explicit LiteralNode(const Token
& token
);
411 ~LiteralNode() override
;
413 const LiteralNode
* AsLiteral() const override
;
414 Value
Execute(Scope
* scope
, Err
* err
) const override
;
415 LocationRange
GetRange() const override
;
416 Err
MakeErrorDescribing(
417 const std::string
& msg
,
418 const std::string
& help
= std::string()) const override
;
419 void Print(std::ostream
& out
, int indent
) const override
;
421 const Token
& value() const { return value_
; }
422 void set_value(const Token
& t
) { value_
= t
; }
424 void SetNewLocation(int line_number
);
429 DISALLOW_COPY_AND_ASSIGN(LiteralNode
);
432 // UnaryOpNode -----------------------------------------------------------------
434 class UnaryOpNode
: public ParseNode
{
437 ~UnaryOpNode() override
;
439 const UnaryOpNode
* AsUnaryOp() const override
;
440 Value
Execute(Scope
* scope
, Err
* err
) const override
;
441 LocationRange
GetRange() const override
;
442 Err
MakeErrorDescribing(
443 const std::string
& msg
,
444 const std::string
& help
= std::string()) const override
;
445 void Print(std::ostream
& out
, int indent
) const override
;
447 const Token
& op() const { return op_
; }
448 void set_op(const Token
& t
) { op_
= t
; }
450 const ParseNode
* operand() const { return operand_
.get(); }
451 void set_operand(scoped_ptr
<ParseNode
> operand
) {
452 operand_
= operand
.Pass();
457 scoped_ptr
<ParseNode
> operand_
;
459 DISALLOW_COPY_AND_ASSIGN(UnaryOpNode
);
462 // BlockCommentNode ------------------------------------------------------------
464 // This node type is only used for standalone comments (that is, those not
465 // specifically attached to another syntax element. The most common of these
466 // is a standard header block. This node contains only the last line of such
467 // a comment block as the anchor, and other lines of the block comment are
468 // hung off of it as Before comments, similar to other syntax elements.
469 class BlockCommentNode
: public ParseNode
{
472 ~BlockCommentNode() override
;
474 const BlockCommentNode
* AsBlockComment() const override
;
475 Value
Execute(Scope
* scope
, Err
* err
) const override
;
476 LocationRange
GetRange() const override
;
477 Err
MakeErrorDescribing(
478 const std::string
& msg
,
479 const std::string
& help
= std::string()) const override
;
480 void Print(std::ostream
& out
, int indent
) const override
;
482 const Token
& comment() const { return comment_
; }
483 void set_comment(const Token
& t
) { comment_
= t
; }
488 DISALLOW_COPY_AND_ASSIGN(BlockCommentNode
);
491 // EndNode ---------------------------------------------------------------------
493 // This node type is used as the end_ object for lists and blocks (rather than
494 // just the end ']', '}', or ')' token). This is so that during formatting
495 // traversal there is a node that appears at the end of the block to which
496 // comments can be attached.
497 class EndNode
: public ParseNode
{
499 explicit EndNode(const Token
& token
);
502 const EndNode
* AsEnd() const override
;
503 Value
Execute(Scope
* scope
, Err
* err
) const override
;
504 LocationRange
GetRange() const override
;
505 Err
MakeErrorDescribing(
506 const std::string
& msg
,
507 const std::string
& help
= std::string()) const override
;
508 void Print(std::ostream
& out
, int indent
) const override
;
510 const Token
& value() const { return value_
; }
511 void set_value(const Token
& t
) { value_
= t
; }
516 DISALLOW_COPY_AND_ASSIGN(EndNode
);
519 #endif // TOOLS_GN_PARSE_TREE_H_