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. 4 5 #ifndef TOOLS_GN_PARSE_TREE_H_ 6 #define TOOLS_GN_PARSE_TREE_H_ 7 8 #include <stddef.h> 9 10 #include <memory> 11 #include <string_view> 12 #include <utility> 13 #include <vector> 14 15 #include "base/values.h" 16 #include "gn/err.h" 17 #include "gn/token.h" 18 #include "gn/value.h" 19 20 class AccessorNode; 21 class BinaryOpNode; 22 class BlockCommentNode; 23 class BlockNode; 24 class ConditionNode; 25 class EndNode; 26 class FunctionCallNode; 27 class IdentifierNode; 28 class ListNode; 29 class LiteralNode; 30 class Scope; 31 class UnaryOpNode; 32 33 // Dictionary keys used for JSON-formatted tree dump. 34 extern const char kJsonNodeChild[]; 35 extern const char kJsonNodeType[]; 36 extern const char kJsonNodeValue[]; 37 extern const char kJsonBeforeComment[]; 38 extern const char kJsonSuffixComment[]; 39 extern const char kJsonAfterComment[]; 40 41 class Comments { 42 public: 43 Comments(); 44 virtual ~Comments(); 45 before()46 const std::vector<Token>& before() const { return before_; } append_before(Token c)47 void append_before(Token c) { before_.push_back(c); } clear_before()48 void clear_before() { before_.clear(); } 49 suffix()50 const std::vector<Token>& suffix() const { return suffix_; } append_suffix(Token c)51 void append_suffix(Token c) { suffix_.push_back(c); } 52 // Reverse the order of the suffix comments. When walking the tree in 53 // post-order we append suffix comments in reverse order, so this fixes them 54 // up. 55 void ReverseSuffix(); 56 after()57 const std::vector<Token>& after() const { return after_; } append_after(Token c)58 void append_after(Token c) { after_.push_back(c); } 59 60 private: 61 // Whole line comments before the expression. 62 std::vector<Token> before_; 63 64 // End-of-line comments after this expression. 65 std::vector<Token> suffix_; 66 67 // For top-level expressions only, after_ lists whole-line comments 68 // following the expression. 69 std::vector<Token> after_; 70 71 Comments(const Comments&) = delete; 72 Comments& operator=(const Comments&) = delete; 73 }; 74 75 // ParseNode ------------------------------------------------------------------- 76 77 // A node in the AST. 78 class ParseNode { 79 public: 80 ParseNode(); 81 virtual ~ParseNode(); 82 83 virtual const AccessorNode* AsAccessor() const; 84 virtual const BinaryOpNode* AsBinaryOp() const; 85 virtual const BlockCommentNode* AsBlockComment() const; 86 virtual const BlockNode* AsBlock() const; 87 virtual const ConditionNode* AsCondition() const; 88 virtual const EndNode* AsEnd() const; 89 virtual const FunctionCallNode* AsFunctionCall() const; 90 virtual const IdentifierNode* AsIdentifier() const; 91 virtual const ListNode* AsList() const; 92 virtual const LiteralNode* AsLiteral() const; 93 virtual const UnaryOpNode* AsUnaryOp() const; 94 95 virtual Value Execute(Scope* scope, Err* err) const = 0; 96 97 virtual LocationRange GetRange() const = 0; 98 99 // Returns an error with the given messages and the range set to something 100 // that indicates this node. 101 virtual Err MakeErrorDescribing( 102 const std::string& msg, 103 const std::string& help = std::string()) const = 0; 104 105 // Generates a representation of this node in base::Value, to be used for 106 // exporting the tree as a JSON or formatted text with indents. 107 virtual base::Value GetJSONNode() const = 0; 108 comments()109 const Comments* comments() const { return comments_.get(); } 110 Comments* comments_mutable(); 111 112 static std::unique_ptr<ParseNode> BuildFromJSON(const base::Value& value); 113 114 protected: 115 // Helper functions for GetJSONNode. Creates and fills a Value object with 116 // given type (and value). 117 base::Value CreateJSONNode(const char* type, LocationRange location) const; 118 base::Value CreateJSONNode(const char* type, 119 std::string_view value, 120 LocationRange location) const; 121 122 private: 123 // Helper function for CreateJSONNode. 124 void AddCommentsJSONNodes(base::Value* out_value) const; 125 126 std::unique_ptr<Comments> comments_; 127 128 ParseNode(const ParseNode&) = delete; 129 ParseNode& operator=(const ParseNode&) = delete; 130 }; 131 132 // AccessorNode ---------------------------------------------------------------- 133 134 // Access an array or scope element. 135 // 136 // Currently, such values are only read-only. In that you can do: 137 // a = obj1.a 138 // b = obj2[0] 139 // But not 140 // obj1.a = 5 141 // obj2[0] = 6 142 // 143 // In the current design where the dot operator is used only for templates, we 144 // explicitly don't want to allow you to do "invoker.foo = 5", so if we added 145 // support for accessors to be lvalues, we would also need to add some concept 146 // of a constant scope. Supporting this would also add a lot of complications 147 // to the operator= implementation, since some accessors might return values 148 // in the const root scope that shouldn't be modified. Without a strong 149 // use-case for this, it seems simpler to just disallow it. 150 // 151 // Additionally, the left-hand-side of the accessor must currently be an 152 // identifier. So you can't do things like: 153 // function_call()[1] 154 // a = b.c.d 155 // These are easier to implement if we needed them but given the very limited 156 // use cases for this, it hasn't seemed worth the bother. 157 class AccessorNode : public ParseNode { 158 public: 159 AccessorNode(); 160 ~AccessorNode() override; 161 162 const AccessorNode* AsAccessor() const override; 163 Value Execute(Scope* scope, Err* err) const override; 164 LocationRange GetRange() const override; 165 Err MakeErrorDescribing( 166 const std::string& msg, 167 const std::string& help = std::string()) const override; 168 base::Value GetJSONNode() const override; 169 static std::unique_ptr<AccessorNode> NewFromJSON(const base::Value& value); 170 171 // Base is the thing on the left of the [] or dot, currently always required 172 // to be an identifier token. base()173 const Token& base() const { return base_; } set_base(const Token & b)174 void set_base(const Token& b) { base_ = b; } 175 176 // Subscript is the expression inside the []. Will be null if member is set. subscript()177 const ParseNode* subscript() const { return subscript_.get(); } set_subscript(std::unique_ptr<ParseNode> key)178 void set_subscript(std::unique_ptr<ParseNode> key) { 179 subscript_ = std::move(key); 180 } 181 182 // The member is the identifier on the right hand side of the dot. Will be 183 // null if the index is set. member()184 const IdentifierNode* member() const { return member_.get(); } set_member(std::unique_ptr<IdentifierNode> i)185 void set_member(std::unique_ptr<IdentifierNode> i) { member_ = std::move(i); } 186 187 void SetNewLocation(int line_number); 188 189 // Evaluates the index for list accessor operations and range checks it 190 // against the max length of the list. If the index is OK, sets 191 // |*computed_index| and returns true. Otherwise sets the |*err| and returns 192 // false. 193 bool ComputeAndValidateListIndex(Scope* scope, 194 size_t max_len, 195 size_t* computed_index, 196 Err* err) const; 197 198 static constexpr const char* kDumpNodeName = "ACCESSOR"; 199 200 private: 201 Value ExecuteSubscriptAccess(Scope* scope, Err* err) const; 202 Value ExecuteArrayAccess(Scope* scope, 203 const Value* base_value, 204 Err* err) const; 205 Value ExecuteScopeSubscriptAccess(Scope* scope, 206 const Value* base_value, 207 Err* err) const; 208 Value ExecuteScopeAccess(Scope* scope, Err* err) const; 209 210 static constexpr const char* kDumpAccessorKind = "accessor_kind"; 211 static constexpr const char* kDumpAccessorKindSubscript = "subscript"; 212 static constexpr const char* kDumpAccessorKindMember = "member"; 213 214 Token base_; 215 216 // Either index or member will be set according to what type of access this 217 // is. 218 std::unique_ptr<ParseNode> subscript_; 219 std::unique_ptr<IdentifierNode> member_; 220 221 AccessorNode(const AccessorNode&) = delete; 222 AccessorNode& operator=(const AccessorNode&) = delete; 223 }; 224 225 // BinaryOpNode ---------------------------------------------------------------- 226 227 class BinaryOpNode : public ParseNode { 228 public: 229 BinaryOpNode(); 230 ~BinaryOpNode() override; 231 232 const BinaryOpNode* AsBinaryOp() const override; 233 Value Execute(Scope* scope, Err* err) const override; 234 LocationRange GetRange() const override; 235 Err MakeErrorDescribing( 236 const std::string& msg, 237 const std::string& help = std::string()) const override; 238 base::Value GetJSONNode() const override; 239 static std::unique_ptr<BinaryOpNode> NewFromJSON(const base::Value& value); 240 op()241 const Token& op() const { return op_; } set_op(const Token & t)242 void set_op(const Token& t) { op_ = t; } 243 left()244 const ParseNode* left() const { return left_.get(); } set_left(std::unique_ptr<ParseNode> left)245 void set_left(std::unique_ptr<ParseNode> left) { left_ = std::move(left); } 246 right()247 const ParseNode* right() const { return right_.get(); } set_right(std::unique_ptr<ParseNode> right)248 void set_right(std::unique_ptr<ParseNode> right) { 249 right_ = std::move(right); 250 } 251 252 static constexpr const char* kDumpNodeName = "BINARY"; 253 254 private: 255 std::unique_ptr<ParseNode> left_; 256 Token op_; 257 std::unique_ptr<ParseNode> right_; 258 259 BinaryOpNode(const BinaryOpNode&) = delete; 260 BinaryOpNode& operator=(const BinaryOpNode&) = delete; 261 }; 262 263 // BlockNode ------------------------------------------------------------------- 264 265 class BlockNode : public ParseNode { 266 public: 267 // How Execute manages the scopes and results. 268 enum ResultMode { 269 // Creates a new scope for the execution of this block and returns it as 270 // a Value from Execute(). 271 RETURNS_SCOPE, 272 273 // Executes in the context of the calling scope (variables set will go 274 // into the invoking scope) and Execute will return an empty Value. 275 DISCARDS_RESULT 276 }; 277 278 BlockNode(ResultMode result_mode); 279 ~BlockNode() override; 280 281 const BlockNode* AsBlock() const override; 282 Value Execute(Scope* scope, Err* err) const override; 283 LocationRange GetRange() const override; 284 Err MakeErrorDescribing( 285 const std::string& msg, 286 const std::string& help = std::string()) const override; 287 base::Value GetJSONNode() const override; 288 static std::unique_ptr<BlockNode> NewFromJSON(const base::Value& value); 289 set_begin_token(const Token & t)290 void set_begin_token(const Token& t) { begin_token_ = t; } set_end(std::unique_ptr<EndNode> e)291 void set_end(std::unique_ptr<EndNode> e) { end_ = std::move(e); } End()292 const EndNode* End() const { return end_.get(); } 293 result_mode()294 ResultMode result_mode() const { return result_mode_; } 295 statements()296 const std::vector<std::unique_ptr<ParseNode>>& statements() const { 297 return statements_; 298 } append_statement(std::unique_ptr<ParseNode> s)299 void append_statement(std::unique_ptr<ParseNode> s) { 300 statements_.push_back(std::move(s)); 301 } 302 303 static constexpr const char* kDumpNodeName = "BLOCK"; 304 305 private: 306 static constexpr const char* kDumpResultMode = "result_mode"; 307 static constexpr const char* kDumpResultModeReturnsScope = "returns_scope"; 308 static constexpr const char* kDumpResultModeDiscardsResult = 309 "discards_result"; 310 311 const ResultMode result_mode_; 312 313 // Tokens corresponding to { and }, if any (may be NULL). The end is stored 314 // in a custom parse node so that it can have comments hung off of it. 315 Token begin_token_; 316 std::unique_ptr<EndNode> end_; 317 318 std::vector<std::unique_ptr<ParseNode>> statements_; 319 320 BlockNode(const BlockNode&) = delete; 321 BlockNode& operator=(const BlockNode&) = delete; 322 }; 323 324 // ConditionNode --------------------------------------------------------------- 325 326 class ConditionNode : public ParseNode { 327 public: 328 ConditionNode(); 329 ~ConditionNode() override; 330 331 const ConditionNode* AsCondition() 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 base::Value GetJSONNode() const override; 338 static std::unique_ptr<ConditionNode> NewFromJSON(const base::Value& value); 339 set_if_token(const Token & token)340 void set_if_token(const Token& token) { if_token_ = token; } 341 condition()342 const ParseNode* condition() const { return condition_.get(); } set_condition(std::unique_ptr<ParseNode> c)343 void set_condition(std::unique_ptr<ParseNode> c) { 344 condition_ = std::move(c); 345 } 346 if_true()347 const BlockNode* if_true() const { return if_true_.get(); } set_if_true(std::unique_ptr<BlockNode> t)348 void set_if_true(std::unique_ptr<BlockNode> t) { if_true_ = std::move(t); } 349 350 // This is either empty, a block (for the else clause), or another 351 // condition. if_false()352 const ParseNode* if_false() const { return if_false_.get(); } set_if_false(std::unique_ptr<ParseNode> f)353 void set_if_false(std::unique_ptr<ParseNode> f) { if_false_ = std::move(f); } 354 355 static constexpr const char* kDumpNodeName = "CONDITION"; 356 357 private: 358 // Token corresponding to the "if" string. 359 Token if_token_; 360 361 std::unique_ptr<ParseNode> condition_; // Always non-null. 362 std::unique_ptr<BlockNode> if_true_; // Always non-null. 363 std::unique_ptr<ParseNode> if_false_; // May be null. 364 365 ConditionNode(const ConditionNode&) = delete; 366 ConditionNode& operator=(const ConditionNode&) = delete; 367 }; 368 369 // FunctionCallNode ------------------------------------------------------------ 370 371 class FunctionCallNode : public ParseNode { 372 public: 373 FunctionCallNode(); 374 ~FunctionCallNode() override; 375 376 const FunctionCallNode* AsFunctionCall() const override; 377 Value Execute(Scope* scope, Err* err) const override; 378 LocationRange GetRange() const override; 379 Err MakeErrorDescribing( 380 const std::string& msg, 381 const std::string& help = std::string()) const override; 382 base::Value GetJSONNode() const override; 383 static std::unique_ptr<FunctionCallNode> NewFromJSON( 384 const base::Value& value); 385 function()386 const Token& function() const { return function_; } set_function(Token t)387 void set_function(Token t) { function_ = t; } 388 args()389 const ListNode* args() const { return args_.get(); } set_args(std::unique_ptr<ListNode> a)390 void set_args(std::unique_ptr<ListNode> a) { args_ = std::move(a); } 391 block()392 const BlockNode* block() const { return block_.get(); } set_block(std::unique_ptr<BlockNode> b)393 void set_block(std::unique_ptr<BlockNode> b) { block_ = std::move(b); } 394 395 void SetNewLocation(int line_number); 396 397 static constexpr const char* kDumpNodeName = "FUNCTION"; 398 399 private: 400 Token function_; 401 std::unique_ptr<ListNode> args_; 402 std::unique_ptr<BlockNode> block_; // May be null. 403 404 FunctionCallNode(const FunctionCallNode&) = delete; 405 FunctionCallNode& operator=(const FunctionCallNode&) = delete; 406 }; 407 408 // IdentifierNode -------------------------------------------------------------- 409 410 class IdentifierNode : public ParseNode { 411 public: 412 IdentifierNode(); 413 explicit IdentifierNode(const Token& token); 414 ~IdentifierNode() override; 415 416 const IdentifierNode* AsIdentifier() const override; 417 Value Execute(Scope* scope, Err* err) const override; 418 LocationRange GetRange() const override; 419 Err MakeErrorDescribing( 420 const std::string& msg, 421 const std::string& help = std::string()) const override; 422 base::Value GetJSONNode() const override; 423 static std::unique_ptr<IdentifierNode> NewFromJSON(const base::Value& value); 424 value()425 const Token& value() const { return value_; } set_value(const Token & t)426 void set_value(const Token& t) { value_ = t; } 427 428 void SetNewLocation(int line_number); 429 430 static constexpr const char* kDumpNodeName = "IDENTIFIER"; 431 432 private: 433 Token value_; 434 435 IdentifierNode(const IdentifierNode&) = delete; 436 IdentifierNode& operator=(const IdentifierNode&) = delete; 437 }; 438 439 // ListNode -------------------------------------------------------------------- 440 441 class ListNode : public ParseNode { 442 public: 443 ListNode(); 444 ~ListNode() override; 445 446 const ListNode* AsList() const override; 447 Value Execute(Scope* scope, Err* err) const override; 448 LocationRange GetRange() const override; 449 Err MakeErrorDescribing( 450 const std::string& msg, 451 const std::string& help = std::string()) const override; 452 base::Value GetJSONNode() const override; 453 static std::unique_ptr<ListNode> NewFromJSON(const base::Value& value); 454 set_begin_token(const Token & t)455 void set_begin_token(const Token& t) { begin_token_ = t; } Begin()456 const Token& Begin() const { return begin_token_; } set_end(std::unique_ptr<EndNode> e)457 void set_end(std::unique_ptr<EndNode> e) { end_ = std::move(e); } End()458 const EndNode* End() const { return end_.get(); } 459 append_item(std::unique_ptr<ParseNode> s)460 void append_item(std::unique_ptr<ParseNode> s) { 461 contents_.push_back(std::move(s)); 462 } contents()463 const std::vector<std::unique_ptr<const ParseNode>>& contents() const { 464 return contents_; 465 } 466 467 void SortAsStringsList(); 468 void SortAsTargetsList(); 469 470 struct SortRange { 471 size_t begin; 472 size_t end; SortRangeSortRange473 SortRange(size_t begin, size_t end) : begin(begin), end(end) {} 474 }; 475 // Only public for testing. 476 std::vector<SortRange> GetSortRanges() const; 477 478 static constexpr const char* kDumpNodeName = "LIST"; 479 480 private: 481 template <typename Comparator> 482 void SortList(Comparator comparator); 483 484 // Tokens corresponding to the [ and ]. The end token is stored in inside an 485 // custom parse node so that it can have comments hung off of it. 486 Token begin_token_; 487 std::unique_ptr<EndNode> end_; 488 489 std::vector<std::unique_ptr<const ParseNode>> contents_; 490 491 ListNode(const ListNode&) = delete; 492 ListNode& operator=(const ListNode&) = delete; 493 }; 494 495 // LiteralNode ----------------------------------------------------------------- 496 497 class LiteralNode : public ParseNode { 498 public: 499 LiteralNode(); 500 explicit LiteralNode(const Token& token); 501 ~LiteralNode() override; 502 503 const LiteralNode* AsLiteral() const override; 504 Value Execute(Scope* scope, Err* err) const override; 505 LocationRange GetRange() const override; 506 Err MakeErrorDescribing( 507 const std::string& msg, 508 const std::string& help = std::string()) const override; 509 base::Value GetJSONNode() const override; 510 static std::unique_ptr<LiteralNode> NewFromJSON(const base::Value& value); 511 value()512 const Token& value() const { return value_; } set_value(const Token & t)513 void set_value(const Token& t) { value_ = t; } 514 515 void SetNewLocation(int line_number); 516 517 static constexpr const char* kDumpNodeName = "LITERAL"; 518 519 private: 520 Token value_; 521 522 LiteralNode(const LiteralNode&) = delete; 523 LiteralNode& operator=(const LiteralNode&) = delete; 524 }; 525 526 // UnaryOpNode ----------------------------------------------------------------- 527 528 class UnaryOpNode : public ParseNode { 529 public: 530 UnaryOpNode(); 531 ~UnaryOpNode() override; 532 533 const UnaryOpNode* AsUnaryOp() const override; 534 Value Execute(Scope* scope, Err* err) const override; 535 LocationRange GetRange() const override; 536 Err MakeErrorDescribing( 537 const std::string& msg, 538 const std::string& help = std::string()) const override; 539 base::Value GetJSONNode() const override; 540 static std::unique_ptr<UnaryOpNode> NewFromJSON(const base::Value& value); 541 op()542 const Token& op() const { return op_; } set_op(const Token & t)543 void set_op(const Token& t) { op_ = t; } 544 operand()545 const ParseNode* operand() const { return operand_.get(); } set_operand(std::unique_ptr<ParseNode> operand)546 void set_operand(std::unique_ptr<ParseNode> operand) { 547 operand_ = std::move(operand); 548 } 549 550 static constexpr const char* kDumpNodeName = "UNARY"; 551 552 private: 553 Token op_; 554 std::unique_ptr<ParseNode> operand_; 555 556 UnaryOpNode(const UnaryOpNode&) = delete; 557 UnaryOpNode& operator=(const UnaryOpNode&) = delete; 558 }; 559 560 // BlockCommentNode ------------------------------------------------------------ 561 562 // This node type is only used for standalone comments (that is, those not 563 // specifically attached to another syntax element. The most common of these 564 // is a standard header block. This node contains only the last line of such 565 // a comment block as the anchor, and other lines of the block comment are 566 // hung off of it as Before comments, similar to other syntax elements. 567 class BlockCommentNode : public ParseNode { 568 public: 569 BlockCommentNode(); 570 ~BlockCommentNode() override; 571 572 const BlockCommentNode* AsBlockComment() const override; 573 Value Execute(Scope* scope, Err* err) const override; 574 LocationRange GetRange() const override; 575 Err MakeErrorDescribing( 576 const std::string& msg, 577 const std::string& help = std::string()) const override; 578 base::Value GetJSONNode() const override; 579 static std::unique_ptr<BlockCommentNode> NewFromJSON( 580 const base::Value& value); 581 comment()582 const Token& comment() const { return comment_; } set_comment(const Token & t)583 void set_comment(const Token& t) { comment_ = t; } 584 585 static constexpr const char* kDumpNodeName = "BLOCK_COMMENT"; 586 587 private: 588 Token comment_; 589 590 BlockCommentNode(const BlockCommentNode&) = delete; 591 BlockCommentNode& operator=(const BlockCommentNode&) = delete; 592 }; 593 594 // EndNode --------------------------------------------------------------------- 595 596 // This node type is used as the end_ object for lists and blocks (rather than 597 // just the end ']', '}', or ')' token). This is so that during formatting 598 // traversal there is a node that appears at the end of the block to which 599 // comments can be attached. 600 class EndNode : public ParseNode { 601 public: 602 explicit EndNode(const Token& token); 603 ~EndNode() override; 604 605 const EndNode* AsEnd() const override; 606 Value Execute(Scope* scope, Err* err) const override; 607 LocationRange GetRange() const override; 608 Err MakeErrorDescribing( 609 const std::string& msg, 610 const std::string& help = std::string()) const override; 611 base::Value GetJSONNode() const override; 612 static std::unique_ptr<EndNode> NewFromJSON(const base::Value& value); 613 value()614 const Token& value() const { return value_; } set_value(const Token & t)615 void set_value(const Token& t) { value_ = t; } 616 617 static constexpr const char* kDumpNodeName = "END"; 618 619 private: 620 Token value_; 621 622 EndNode(const EndNode&) = delete; 623 EndNode& operator=(const EndNode&) = delete; 624 }; 625 626 #endif // TOOLS_GN_PARSE_TREE_H_ 627