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 <vector> 9 10 #include "base/basictypes.h" 11 #include "base/compiler_specific.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "tools/gn/err.h" 14 #include "tools/gn/token.h" 15 #include "tools/gn/value.h" 16 17 class AccessorNode; 18 class BinaryOpNode; 19 class BlockNode; 20 class ConditionNode; 21 class FunctionCallNode; 22 class IdentifierNode; 23 class ListNode; 24 class LiteralNode; 25 class Scope; 26 class UnaryOpNode; 27 class BlockCommentNode; 28 29 class Comments { 30 public: 31 Comments(); 32 virtual ~Comments(); 33 34 const std::vector<Token>& before() const { return before_; } 35 void append_before(Token c) { 36 before_.push_back(c); 37 } 38 39 const std::vector<Token>& suffix() const { return suffix_; } 40 void append_suffix(Token c) { 41 suffix_.push_back(c); 42 } 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 45 // up. 46 void ReverseSuffix(); 47 48 const std::vector<Token>& after() const { return after_; } 49 void append_after(Token c) { 50 after_.push_back(c); 51 } 52 53 private: 54 // Whole line comments before the expression. 55 std::vector<Token> before_; 56 57 // End-of-line comments after this expression. 58 std::vector<Token> suffix_; 59 60 // For top-level expressions only, after_ lists whole-line comments 61 // following the expression. 62 std::vector<Token> after_; 63 64 DISALLOW_COPY_AND_ASSIGN(Comments); 65 }; 66 67 // ParseNode ------------------------------------------------------------------- 68 69 // A node in the AST. 70 class ParseNode { 71 public: 72 ParseNode(); 73 virtual ~ParseNode(); 74 75 virtual const AccessorNode* AsAccessor() const; 76 virtual const BinaryOpNode* AsBinaryOp() const; 77 virtual const BlockNode* AsBlock() const; 78 virtual const ConditionNode* AsConditionNode() const; 79 virtual const FunctionCallNode* AsFunctionCall() const; 80 virtual const IdentifierNode* AsIdentifier() const; 81 virtual const ListNode* AsList() const; 82 virtual const LiteralNode* AsLiteral() const; 83 virtual const UnaryOpNode* AsUnaryOp() const; 84 virtual const BlockCommentNode* AsBlockComment() const; 85 86 virtual Value Execute(Scope* scope, Err* err) const = 0; 87 88 virtual LocationRange GetRange() const = 0; 89 90 // Returns an error with the given messages and the range set to something 91 // that indicates this node. 92 virtual Err MakeErrorDescribing( 93 const std::string& msg, 94 const std::string& help = std::string()) const = 0; 95 96 // Prints a representation of this node to the given string, indenting 97 // by the given number of spaces. 98 virtual void Print(std::ostream& out, int indent) const = 0; 99 100 const Comments* comments() const { return comments_.get(); } 101 Comments* comments_mutable(); 102 void PrintComments(std::ostream& out, int indent) const; 103 104 private: 105 scoped_ptr<Comments> comments_; 106 107 DISALLOW_COPY_AND_ASSIGN(ParseNode); 108 }; 109 110 // AccessorNode ---------------------------------------------------------------- 111 112 // Access an array or scope element. 113 // 114 // Currently, such values are only read-only. In that you can do: 115 // a = obj1.a 116 // b = obj2[0] 117 // But not 118 // obj1.a = 5 119 // obj2[0] = 6 120 // 121 // In the current design where the dot operator is used only for templates, we 122 // explicitly don't want to allow you to do "invoker.foo = 5", so if we added 123 // support for accessors to be lvalues, we would also need to add some concept 124 // of a constant scope. Supporting this would also add a lot of complications 125 // to the operator= implementation, since some accessors might return values 126 // in the const root scope that shouldn't be modified. Without a strong 127 // use-case for this, it seems simpler to just disallow it. 128 // 129 // Additionally, the left-hand-side of the accessor must currently be an 130 // identifier. So you can't do things like: 131 // function_call()[1] 132 // a = b.c.d 133 // These are easier to implement if we needed them but given the very limited 134 // use cases for this, it hasn't seemed worth the bother. 135 class AccessorNode : public ParseNode { 136 public: 137 AccessorNode(); 138 virtual ~AccessorNode(); 139 140 virtual const AccessorNode* AsAccessor() const OVERRIDE; 141 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 142 virtual LocationRange GetRange() const OVERRIDE; 143 virtual Err MakeErrorDescribing( 144 const std::string& msg, 145 const std::string& help = std::string()) const OVERRIDE; 146 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 147 148 // Base is the thing on the left of the [] or dot, currently always required 149 // to be an identifier token. 150 const Token& base() const { return base_; } 151 void set_base(const Token& b) { base_ = b; } 152 153 // Index is the expression inside the []. Will be null if member is set. 154 const ParseNode* index() const { return index_.get(); } 155 void set_index(scoped_ptr<ParseNode> i) { index_ = i.Pass(); } 156 157 // The member is the identifier on the right hand side of the dot. Will be 158 // null if the index is set. 159 const IdentifierNode* member() const { return member_.get(); } 160 void set_member(scoped_ptr<IdentifierNode> i) { member_ = i.Pass(); } 161 162 private: 163 Value ExecuteArrayAccess(Scope* scope, Err* err) const; 164 Value ExecuteScopeAccess(Scope* scope, Err* err) const; 165 166 Token base_; 167 168 // Either index or member will be set according to what type of access this 169 // is. 170 scoped_ptr<ParseNode> index_; 171 scoped_ptr<IdentifierNode> member_; 172 173 DISALLOW_COPY_AND_ASSIGN(AccessorNode); 174 }; 175 176 // BinaryOpNode ---------------------------------------------------------------- 177 178 class BinaryOpNode : public ParseNode { 179 public: 180 BinaryOpNode(); 181 virtual ~BinaryOpNode(); 182 183 virtual const BinaryOpNode* AsBinaryOp() const OVERRIDE; 184 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 185 virtual LocationRange GetRange() const OVERRIDE; 186 virtual Err MakeErrorDescribing( 187 const std::string& msg, 188 const std::string& help = std::string()) const OVERRIDE; 189 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 190 191 const Token& op() const { return op_; } 192 void set_op(const Token& t) { op_ = t; } 193 194 const ParseNode* left() const { return left_.get(); } 195 void set_left(scoped_ptr<ParseNode> left) { 196 left_ = left.Pass(); 197 } 198 199 const ParseNode* right() const { return right_.get(); } 200 void set_right(scoped_ptr<ParseNode> right) { 201 right_ = right.Pass(); 202 } 203 204 private: 205 scoped_ptr<ParseNode> left_; 206 Token op_; 207 scoped_ptr<ParseNode> right_; 208 209 DISALLOW_COPY_AND_ASSIGN(BinaryOpNode); 210 }; 211 212 // BlockNode ------------------------------------------------------------------- 213 214 class BlockNode : public ParseNode { 215 public: 216 // Set has_scope if this block introduces a nested scope. 217 explicit BlockNode(bool has_scope); 218 virtual ~BlockNode(); 219 220 virtual const BlockNode* AsBlock() const OVERRIDE; 221 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 222 virtual LocationRange GetRange() const OVERRIDE; 223 virtual Err MakeErrorDescribing( 224 const std::string& msg, 225 const std::string& help = std::string()) const OVERRIDE; 226 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 227 228 void set_begin_token(const Token& t) { begin_token_ = t; } 229 void set_end_token(const Token& t) { end_token_ = t; } 230 231 const std::vector<ParseNode*>& statements() const { return statements_; } 232 void append_statement(scoped_ptr<ParseNode> s) { 233 statements_.push_back(s.release()); 234 } 235 236 // Doesn't create a nested scope. 237 Value ExecuteBlockInScope(Scope* our_scope, Err* err) const; 238 239 private: 240 bool has_scope_; 241 242 // Tokens corresponding to { and }, if any (may be NULL). 243 Token begin_token_; 244 Token end_token_; 245 246 // Owning pointers, use unique_ptr when we can use C++11. 247 std::vector<ParseNode*> statements_; 248 249 DISALLOW_COPY_AND_ASSIGN(BlockNode); 250 }; 251 252 // ConditionNode --------------------------------------------------------------- 253 254 class ConditionNode : public ParseNode { 255 public: 256 ConditionNode(); 257 virtual ~ConditionNode(); 258 259 virtual const ConditionNode* AsConditionNode() const OVERRIDE; 260 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 261 virtual LocationRange GetRange() const OVERRIDE; 262 virtual Err MakeErrorDescribing( 263 const std::string& msg, 264 const std::string& help = std::string()) const OVERRIDE; 265 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 266 267 void set_if_token(const Token& token) { if_token_ = token; } 268 269 const ParseNode* condition() const { return condition_.get(); } 270 void set_condition(scoped_ptr<ParseNode> c) { 271 condition_ = c.Pass(); 272 } 273 274 const BlockNode* if_true() const { return if_true_.get(); } 275 void set_if_true(scoped_ptr<BlockNode> t) { 276 if_true_ = t.Pass(); 277 } 278 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(); 284 } 285 286 private: 287 // Token corresponding to the "if" string. 288 Token if_token_; 289 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. 293 294 DISALLOW_COPY_AND_ASSIGN(ConditionNode); 295 }; 296 297 // FunctionCallNode ------------------------------------------------------------ 298 299 class FunctionCallNode : public ParseNode { 300 public: 301 FunctionCallNode(); 302 virtual ~FunctionCallNode(); 303 304 virtual const FunctionCallNode* AsFunctionCall() const OVERRIDE; 305 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 306 virtual LocationRange GetRange() const OVERRIDE; 307 virtual Err MakeErrorDescribing( 308 const std::string& msg, 309 const std::string& help = std::string()) const OVERRIDE; 310 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 311 312 const Token& function() const { return function_; } 313 void set_function(Token t) { function_ = t; } 314 315 const ListNode* args() const { return args_.get(); } 316 void set_args(scoped_ptr<ListNode> a) { args_ = a.Pass(); } 317 318 const BlockNode* block() const { return block_.get(); } 319 void set_block(scoped_ptr<BlockNode> b) { block_ = b.Pass(); } 320 321 private: 322 Token function_; 323 scoped_ptr<ListNode> args_; 324 scoped_ptr<BlockNode> block_; // May be null. 325 326 DISALLOW_COPY_AND_ASSIGN(FunctionCallNode); 327 }; 328 329 // IdentifierNode -------------------------------------------------------------- 330 331 class IdentifierNode : public ParseNode { 332 public: 333 IdentifierNode(); 334 IdentifierNode(const Token& token); 335 virtual ~IdentifierNode(); 336 337 virtual const IdentifierNode* AsIdentifier() const OVERRIDE; 338 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 339 virtual LocationRange GetRange() const OVERRIDE; 340 virtual Err MakeErrorDescribing( 341 const std::string& msg, 342 const std::string& help = std::string()) const OVERRIDE; 343 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 344 345 const Token& value() const { return value_; } 346 void set_value(const Token& t) { value_ = t; } 347 348 private: 349 Token value_; 350 351 DISALLOW_COPY_AND_ASSIGN(IdentifierNode); 352 }; 353 354 // ListNode -------------------------------------------------------------------- 355 356 class ListNode : public ParseNode { 357 public: 358 ListNode(); 359 virtual ~ListNode(); 360 361 virtual const ListNode* AsList() const OVERRIDE; 362 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 363 virtual LocationRange GetRange() const OVERRIDE; 364 virtual Err MakeErrorDescribing( 365 const std::string& msg, 366 const std::string& help = std::string()) const OVERRIDE; 367 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 368 369 void set_begin_token(const Token& t) { begin_token_ = t; } 370 void set_end_token(const Token& t) { end_token_ = t; } 371 372 void append_item(scoped_ptr<ParseNode> s) { 373 contents_.push_back(s.release()); 374 } 375 const std::vector<const ParseNode*>& contents() const { return contents_; } 376 377 private: 378 // Tokens corresponding to the [ and ]. 379 Token begin_token_; 380 Token end_token_; 381 382 // Owning pointers, use unique_ptr when we can use C++11. 383 std::vector<const ParseNode*> contents_; 384 385 DISALLOW_COPY_AND_ASSIGN(ListNode); 386 }; 387 388 // LiteralNode ----------------------------------------------------------------- 389 390 class LiteralNode : public ParseNode { 391 public: 392 LiteralNode(); 393 LiteralNode(const Token& token); 394 virtual ~LiteralNode(); 395 396 virtual const LiteralNode* AsLiteral() const OVERRIDE; 397 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 398 virtual LocationRange GetRange() const OVERRIDE; 399 virtual Err MakeErrorDescribing( 400 const std::string& msg, 401 const std::string& help = std::string()) const OVERRIDE; 402 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 403 404 const Token& value() const { return value_; } 405 void set_value(const Token& t) { value_ = t; } 406 407 private: 408 Token value_; 409 410 DISALLOW_COPY_AND_ASSIGN(LiteralNode); 411 }; 412 413 // UnaryOpNode ----------------------------------------------------------------- 414 415 class UnaryOpNode : public ParseNode { 416 public: 417 UnaryOpNode(); 418 virtual ~UnaryOpNode(); 419 420 virtual const UnaryOpNode* AsUnaryOp() const OVERRIDE; 421 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 422 virtual LocationRange GetRange() const OVERRIDE; 423 virtual Err MakeErrorDescribing( 424 const std::string& msg, 425 const std::string& help = std::string()) const OVERRIDE; 426 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 427 428 const Token& op() const { return op_; } 429 void set_op(const Token& t) { op_ = t; } 430 431 const ParseNode* operand() const { return operand_.get(); } 432 void set_operand(scoped_ptr<ParseNode> operand) { 433 operand_ = operand.Pass(); 434 } 435 436 private: 437 Token op_; 438 scoped_ptr<ParseNode> operand_; 439 440 DISALLOW_COPY_AND_ASSIGN(UnaryOpNode); 441 }; 442 443 // BlockCommentNode ------------------------------------------------------------ 444 445 // This node type is only used for standalone comments (that is, those not 446 // specifically attached to another syntax element. The most common of these 447 // is a standard header block. This node contains only the last line of such 448 // a comment block as the anchor, and other lines of the block comment are 449 // hung off of it as Before comments, similar to other syntax elements. 450 class BlockCommentNode : public ParseNode { 451 public: 452 BlockCommentNode(); 453 virtual ~BlockCommentNode(); 454 455 virtual const BlockCommentNode* AsBlockComment() const OVERRIDE; 456 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 457 virtual LocationRange GetRange() const OVERRIDE; 458 virtual Err MakeErrorDescribing( 459 const std::string& msg, 460 const std::string& help = std::string()) const OVERRIDE; 461 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 462 463 const Token& comment() const { return comment_; } 464 void set_comment(const Token& t) { comment_ = t; } 465 466 private: 467 Token comment_; 468 469 DISALLOW_COPY_AND_ASSIGN(BlockCommentNode); 470 }; 471 472 #endif // TOOLS_GN_PARSE_TREE_H_ 473