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_BUILDER_H_
      6 #define TOOLS_GN_BUILDER_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/callback.h"
     10 #include "base/containers/hash_tables.h"
     11 #include "base/memory/ref_counted.h"
     12 #include "tools/gn/builder_record.h"
     13 #include "tools/gn/label.h"
     14 #include "tools/gn/label_ptr.h"
     15 #include "tools/gn/unique_vector.h"
     16 
     17 class Config;
     18 class Err;
     19 class Loader;
     20 class ParseNode;
     21 
     22 class Builder : public base::RefCountedThreadSafe<Builder> {
     23  public:
     24   typedef base::Callback<void(const BuilderRecord*)> ResolvedCallback;
     25 
     26   Builder(Loader* loader);
     27 
     28   // The resolved callback is called whenever a target has been resolved. This
     29   // will be executed only on the main thread.
     30   void set_resolved_callback(const ResolvedCallback& cb) {
     31     resolved_callback_ = cb;
     32   }
     33 
     34   Loader* loader() const { return loader_; }
     35 
     36   void ItemDefined(scoped_ptr<Item> item);
     37 
     38   // Returns NULL if there is not a thing with the corresponding label.
     39   const Item* GetItem(const Label& label) const;
     40   const Toolchain* GetToolchain(const Label& label) const;
     41 
     42   std::vector<const BuilderRecord*> GetAllRecords() const;
     43 
     44   // Returns targets which should be generated and which are defined.
     45   std::vector<const Target*> GetAllResolvedTargets() const;
     46 
     47   // Returns the record for the given label, or NULL if it doesn't exist.
     48   // Mostly used for unit tests.
     49   const BuilderRecord* GetRecord(const Label& label) const;
     50   BuilderRecord* GetRecord(const Label& label);
     51 
     52   // If there are any undefined references, returns false and sets the error.
     53   bool CheckForBadItems(Err* err) const;
     54 
     55  private:
     56   friend class base::RefCountedThreadSafe<Builder>;
     57 
     58   virtual ~Builder();
     59 
     60   bool TargetDefined(BuilderRecord* record, Err* err);
     61   bool ToolchainDefined(BuilderRecord* record, Err* err);
     62 
     63   // Returns the record associated with the given label. This function checks
     64   // that if we already have references for it, the type matches. If no record
     65   // exists yet, a new one will be created.
     66   //
     67   // If any of the conditions fail, the return value will be null and the error
     68   // will be set. request_from is used as the source of the error.
     69   BuilderRecord* GetOrCreateRecordOfType(const Label& label,
     70                                          const ParseNode* request_from,
     71                                          BuilderRecord::ItemType type,
     72                                          Err* err);
     73 
     74   // Returns the record associated with the given label. This function checks
     75   // that it's already been resolved to the correct type.
     76   //
     77   // If any of the conditions fail, the return value will be null and the error
     78   // will be set. request_from is used as the source of the error.
     79   BuilderRecord* GetResolvedRecordOfType(const Label& label,
     80                                          const ParseNode* request_from,
     81                                          BuilderRecord::ItemType type,
     82                                          Err* err);
     83 
     84   bool AddDeps(BuilderRecord* record,
     85                const LabelConfigVector& configs,
     86                Err* err);
     87   bool AddDeps(BuilderRecord* record,
     88                const UniqueVector<LabelConfigPair>& configs,
     89                Err* err);
     90   bool AddDeps(BuilderRecord* record,
     91                const LabelTargetVector& targets,
     92                Err* err);
     93   bool AddToolchainDep(BuilderRecord* record,
     94                        const Target* target,
     95                        Err* err);
     96 
     97   // Given a target, sets the "should generate" bit and pushes it through the
     98   // dependency tree. Any time the bit it set, we ensure that the given item is
     99   // scheduled to be loaded.
    100   //
    101   // If the force flag is set, we'll ignore the current state of the record's
    102   // should_generate flag, and set it on the dependents every time. This is
    103   // used when defining a target: the "should generate" may have been set
    104   // before the item was defined (if it is required by something that is
    105   // required). In this case, we need to re-push the "should generate" flag
    106   // to the item's dependencies.
    107   void RecursiveSetShouldGenerate(BuilderRecord* record, bool force);
    108 
    109   void ScheduleItemLoadIfNecessary(BuilderRecord* record);
    110 
    111   // This takes a BuilderRecord with resolved depdencies, and fills in the
    112   // target's Label*Vectors with the resolved pointers.
    113   bool ResolveItem(BuilderRecord* record, Err* err);
    114 
    115   // Fills in the pointers in the given vector based on the labels. We assume
    116   // that everything should be resolved by this point, so will return an error
    117   // if anything isn't found or if the type doesn't match.
    118   bool ResolveDeps(LabelTargetVector* deps, Err* err);
    119   bool ResolveConfigs(UniqueVector<LabelConfigPair>* configs, Err* err);
    120   bool ResolveForwardDependentConfigs(Target* target, Err* err);
    121   bool ResolveToolchain(Target* target, Err* err);
    122 
    123   // Given a list of unresolved records, tries to find any circular
    124   // dependencies and returns the string describing the problem. If no circular
    125   // deps were found, returns the empty string.
    126   std::string CheckForCircularDependencies(
    127       const std::vector<const BuilderRecord*>& bad_records) const;
    128 
    129   // Non owning pointer.
    130   Loader* loader_;
    131 
    132   // Owning pointers.
    133   typedef base::hash_map<Label, BuilderRecord*> RecordMap;
    134   RecordMap records_;
    135 
    136   ResolvedCallback resolved_callback_;
    137 
    138   DISALLOW_COPY_AND_ASSIGN(Builder);
    139 };
    140 
    141 #endif  // TOOLS_GN_BUILDER_H_
    142