Home | History | Annotate | Download | only in gn
      1 // Copyright (c) 2013 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_ITEM_NODE_H_
      6 #define TOOLS_GN_ITEM_NODE_H_
      7 
      8 #include <map>
      9 #include <vector>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/callback.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "tools/gn/location.h"
     15 
     16 class BuildSettings;
     17 class Err;
     18 class Item;
     19 
     20 // Represents a node in the depdency tree. It references an Item which is
     21 // the actual thing.
     22 //
     23 // The items and nodes are split apart so that the ItemTree can manipulate
     24 // the dependencies one one thread while the Item itself is been modified on
     25 // another.
     26 class ItemNode {
     27  public:
     28   // The state of this node. As more of the load progresses, we'll move
     29   // downward in this list toward the resolved state.
     30   enum State {
     31     // Another item has referenced this one by name, but we have not yet
     32     // encountered its definition.
     33     REFERENCED = 0,
     34 
     35     // We've seen the definition of this item but have not requested that its
     36     // dependencies be loaded. In non-greedy generation mode (see item_tree.h)
     37     // some nodes will stay in this state forever as long as they're not needed
     38     // for anything that is required.
     39     DEFINED,
     40 
     41     // The item has been defined and we've requested that all of the
     42     // dependencies be loaded. Not all of the dependencies have been resolved,
     43     // however, and we're still waiting on some build files to be run (or
     44     // perhaps there are undefined dependencies).
     45     PENDING_DEPS,
     46 
     47     // All of this item's transitive dependencies have been found and
     48     // resolved.
     49     RESOLVED,
     50   };
     51 
     52   // Stores a set of ItemNodes and the associated range that the dependency
     53   // was added from.
     54   typedef std::map<ItemNode*, LocationRange> ItemNodeMap;
     55 
     56   // Takes ownership of the pointer.
     57   // Initial state will be REFERENCED.
     58   ItemNode(Item* i);
     59   ~ItemNode();
     60 
     61   State state() const { return state_; }
     62 
     63   // This closure will be executed when the item is resolved and it has the
     64   // should_generate flag set.
     65   void set_resolved_closure(const base::Closure& closure) {
     66     resolved_closure_ = closure;
     67   }
     68 
     69   const Item* item() const { return item_.get(); }
     70   Item* item() { return item_.get(); }
     71 
     72   // True if this item should be generated. In greedy mode, this will alwyas
     73   // be set. Otherwise, this bit will be "pushed" through the tree to
     74   // generate the minimum set of targets required for some special base target.
     75   // Initialized to false.
     76   //
     77   // If this item has been defined, setting this flag will schedule the load
     78   // of dependent nodes and also set their should_generate bits.
     79   bool should_generate() const { return should_generate_; }
     80   bool SetShouldGenerate(const BuildSettings* build_settings, Err* err);
     81 
     82   // Where this was created from, which might be when it was generated or
     83   // when it was first referenced from another target.
     84   const LocationRange& originally_referenced_from_here() const {
     85     return originally_referenced_from_here_;
     86   }
     87   void set_originally_referenced_from_here(const LocationRange& r) {
     88     originally_referenced_from_here_ = r;
     89   }
     90 
     91   // Where this was generated from. This will be empty for items that have
     92   // been referenced but not generated. Note that this has to be one the
     93   // ItemNode because it can be changing from multiple threads and we need
     94   // to be sure that access is serialized.
     95   const LocationRange& generated_from_here() const {
     96     return generated_from_here_;
     97   }
     98   void set_generated_from_here(const LocationRange& r) {
     99     generated_from_here_ = r;
    100   }
    101 
    102   const ItemNodeMap& direct_dependencies() const {
    103     return direct_dependencies_;
    104   }
    105   const ItemNodeMap& unresolved_dependencies() const {
    106     return unresolved_dependencies_;
    107   }
    108 
    109   bool AddDependency(const BuildSettings* build_settings,
    110                      const LocationRange& specified_from_here,
    111                      ItemNode* node,
    112                      Err* err);
    113 
    114   // Removes the given dependency from the unresolved list. Does not do
    115   // anything else to update waiters.
    116   void MarkDirectDependencyResolved(ItemNode* node);
    117 
    118   // Destructively retrieve the set of waiting nodes.
    119   void SwapOutWaitingDependencySet(ItemNodeMap* out_map);
    120 
    121   // Marks this item state as defined (see above). If the should generate
    122   // flag is set, this will schedule a load of the dependencies and
    123   // automatically transition to the PENDING_DEPS state.
    124   bool SetDefined(const BuildSettings* build_settings, Err* err);
    125 
    126   // Marks this item state as resolved (see above).
    127   void SetResolved();
    128 
    129  private:
    130   // Schedules loading the dependencies of this node. The current state must
    131   // be DEFINED, and this call will transition the state to PENDING_DEPS.
    132   //
    133   // Requesting deps can fail. On failure returns false and sets the err.
    134   bool ScheduleDepsLoad(const BuildSettings* build_settings, Err* err);
    135 
    136   State state_;
    137   scoped_ptr<Item> item_;
    138   bool should_generate_;  // See getter above.
    139 
    140   LocationRange originally_referenced_from_here_;
    141   LocationRange generated_from_here_;
    142 
    143   // What to run when this item is resolved.
    144   base::Closure resolved_closure_;
    145 
    146   // Everything this item directly depends on.
    147   ItemNodeMap direct_dependencies_;
    148 
    149   // Unresolved things this item directly depends on.
    150   ItemNodeMap unresolved_dependencies_;
    151 
    152   // These items are waiting on us to be resolved before they can be
    153   // resolved. This is the backpointer for unresolved_dependencies_.
    154   ItemNodeMap waiting_on_resolution_;
    155 
    156   DISALLOW_COPY_AND_ASSIGN(ItemNode);
    157 };
    158 
    159 #endif  // TOOLS_GN_ITEM_NODE_H_
    160