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
) {
39 const std::vector
<Token
>& suffix() const { return suffix_
; }
40 void append_suffix(Token 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
48 const std::vector
<Token
>& after() const { return after_
; }
49 void append_after(Token c
) {
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 -------------------------------------------------------------------
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;
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:
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]
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
{
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(); }
164 Value
ExecuteArrayAccess(Scope
* scope
, Err
* err
) const;
165 Value
ExecuteScopeAccess(Scope
* scope
, Err
* err
) const;
169 // Either index or member will be set according to what type of access this
171 scoped_ptr
<ParseNode
> index_
;
172 scoped_ptr
<IdentifierNode
> member_
;
174 DISALLOW_COPY_AND_ASSIGN(AccessorNode
);
177 // BinaryOpNode ----------------------------------------------------------------
179 class BinaryOpNode
: public ParseNode
{
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
) {
200 const ParseNode
* right() const { return right_
.get(); }
201 void set_right(scoped_ptr
<ParseNode
> right
) {
202 right_
= right
.Pass();
206 scoped_ptr
<ParseNode
> left_
;
208 scoped_ptr
<ParseNode
> right_
;
210 DISALLOW_COPY_AND_ASSIGN(BinaryOpNode
);
213 // BlockNode -------------------------------------------------------------------
215 class BlockNode
: public ParseNode
{
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;
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.
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
{
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
) {
282 // This is either empty, a block (for the else clause), or another
284 const ParseNode
* if_false() const { return if_false_
.get(); }
285 void set_if_false(scoped_ptr
<ParseNode
> f
) {
286 if_false_
= f
.Pass();
290 // Token corresponding to the "if" string.
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
{
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(); }
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
{
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
; }
354 DISALLOW_COPY_AND_ASSIGN(IdentifierNode
);
357 // ListNode --------------------------------------------------------------------
359 class ListNode
: public ParseNode
{
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
;
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.
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
{
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
; }
424 DISALLOW_COPY_AND_ASSIGN(LiteralNode
);
427 // UnaryOpNode -----------------------------------------------------------------
429 class UnaryOpNode
: public ParseNode
{
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();
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
{
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
; }
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
{
494 EndNode(const Token
& token
);
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
; }
511 DISALLOW_COPY_AND_ASSIGN(EndNode
);
514 #endif // TOOLS_GN_PARSE_TREE_H_