Home | History | Annotate | Download | only in gn
      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