| // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef TOOLS_GN_BUILDER_H_ | 
 | #define TOOLS_GN_BUILDER_H_ | 
 |  | 
 | #include <map> | 
 | #include <memory> | 
 |  | 
 | #include "base/callback.h" | 
 | #include "base/macros.h" | 
 | #include "tools/gn/builder_record.h" | 
 | #include "tools/gn/label.h" | 
 | #include "tools/gn/label_ptr.h" | 
 | #include "tools/gn/unique_vector.h" | 
 |  | 
 | class ActionValues; | 
 | class Err; | 
 | class Loader; | 
 | class ParseNode; | 
 |  | 
 | // The builder assembles the dependency tree. It is not threadsafe and runs on | 
 | // the main thread only. See also BuilderRecord. | 
 | class Builder { | 
 |  public: | 
 |   typedef base::Callback<void(const BuilderRecord*)> ResolvedGeneratedCallback; | 
 |  | 
 |   explicit Builder(Loader* loader); | 
 |   ~Builder(); | 
 |  | 
 |   // The resolved callback is called when a target has been both resolved and | 
 |   // marked generated. This will be executed only on the main thread. | 
 |   void set_resolved_and_generated_callback( | 
 |       const ResolvedGeneratedCallback& cb) { | 
 |     resolved_and_generated_callback_ = cb; | 
 |   } | 
 |  | 
 |   Loader* loader() const { return loader_; } | 
 |  | 
 |   void ItemDefined(std::unique_ptr<Item> item); | 
 |  | 
 |   // Returns NULL if there is not a thing with the corresponding label. | 
 |   const Item* GetItem(const Label& label) const; | 
 |   const Toolchain* GetToolchain(const Label& label) const; | 
 |  | 
 |   std::vector<const BuilderRecord*> GetAllRecords() const; | 
 |  | 
 |   // Returns items which should be generated and which are defined. | 
 |   std::vector<const Item*> GetAllResolvedItems() const; | 
 |  | 
 |   // Returns targets which should be generated and which are defined. | 
 |   std::vector<const Target*> GetAllResolvedTargets() const; | 
 |  | 
 |   // Returns the record for the given label, or NULL if it doesn't exist. | 
 |   // Mostly used for unit tests. | 
 |   const BuilderRecord* GetRecord(const Label& label) const; | 
 |   BuilderRecord* GetRecord(const Label& label); | 
 |  | 
 |   // If there are any undefined references, returns false and sets the error. | 
 |   bool CheckForBadItems(Err* err) const; | 
 |  | 
 |  private: | 
 |   bool TargetDefined(BuilderRecord* record, Err* err); | 
 |   bool ConfigDefined(BuilderRecord* record, Err* err); | 
 |   bool ToolchainDefined(BuilderRecord* record, Err* err); | 
 |  | 
 |   // Returns the record associated with the given label. This function checks | 
 |   // that if we already have references for it, the type matches. If no record | 
 |   // exists yet, a new one will be created. | 
 |   // | 
 |   // If any of the conditions fail, the return value will be null and the error | 
 |   // will be set. request_from is used as the source of the error. | 
 |   BuilderRecord* GetOrCreateRecordOfType(const Label& label, | 
 |                                          const ParseNode* request_from, | 
 |                                          BuilderRecord::ItemType type, | 
 |                                          Err* err); | 
 |  | 
 |   // Returns the record associated with the given label. This function checks | 
 |   // that it's already been resolved to the correct type. | 
 |   // | 
 |   // If any of the conditions fail, the return value will be null and the error | 
 |   // will be set. request_from is used as the source of the error. | 
 |   BuilderRecord* GetResolvedRecordOfType(const Label& label, | 
 |                                          const ParseNode* request_from, | 
 |                                          BuilderRecord::ItemType type, | 
 |                                          Err* err); | 
 |  | 
 |   bool AddDeps(BuilderRecord* record, | 
 |                const LabelConfigVector& configs, | 
 |                Err* err); | 
 |   bool AddDeps(BuilderRecord* record, | 
 |                const UniqueVector<LabelConfigPair>& configs, | 
 |                Err* err); | 
 |   bool AddDeps(BuilderRecord* record, | 
 |                const LabelTargetVector& targets, | 
 |                Err* err); | 
 |   bool AddActionValuesDep(BuilderRecord* record, | 
 |                           const ActionValues& action_values, | 
 |                           Err* err); | 
 |   bool AddToolchainDep(BuilderRecord* record, | 
 |                        const Target* target, | 
 |                        Err* err); | 
 |  | 
 |   // Given a target, sets the "should generate" bit and pushes it through the | 
 |   // dependency tree. Any time the bit it set, we ensure that the given item is | 
 |   // scheduled to be loaded. | 
 |   // | 
 |   // If the force flag is set, we'll ignore the current state of the record's | 
 |   // should_generate flag, and set it on the dependents every time. This is | 
 |   // used when defining a target: the "should generate" may have been set | 
 |   // before the item was defined (if it is required by something that is | 
 |   // required). In this case, we need to re-push the "should generate" flag | 
 |   // to the item's dependencies. | 
 |   void RecursiveSetShouldGenerate(BuilderRecord* record, bool force); | 
 |  | 
 |   void ScheduleItemLoadIfNecessary(BuilderRecord* record); | 
 |  | 
 |   // This takes a BuilderRecord with resolved depdencies, and fills in the | 
 |   // target's Label*Vectors with the resolved pointers. | 
 |   bool ResolveItem(BuilderRecord* record, Err* err); | 
 |  | 
 |   // Fills in the pointers in the given vector based on the labels. We assume | 
 |   // that everything should be resolved by this point, so will return an error | 
 |   // if anything isn't found or if the type doesn't match. | 
 |   bool ResolveDeps(LabelTargetVector* deps, Err* err); | 
 |   bool ResolveConfigs(UniqueVector<LabelConfigPair>* configs, Err* err); | 
 |   bool ResolveActionValues(ActionValues* action_values, Err* err); | 
 |   bool ResolveToolchain(Target* target, Err* err); | 
 |   bool ResolvePools(Toolchain* toolchain, Err* err); | 
 |  | 
 |   // Given a list of unresolved records, tries to find any circular | 
 |   // dependencies and returns the string describing the problem. If no circular | 
 |   // deps were found, returns the empty string. | 
 |   std::string CheckForCircularDependencies( | 
 |       const std::vector<const BuilderRecord*>& bad_records) const; | 
 |  | 
 |   // Non owning pointer. | 
 |   Loader* loader_; | 
 |  | 
 |   std::map<Label, std::unique_ptr<BuilderRecord>> records_; | 
 |  | 
 |   ResolvedGeneratedCallback resolved_and_generated_callback_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(Builder); | 
 | }; | 
 |  | 
 | #endif  // TOOLS_GN_BUILDER_H_ |