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 17class Config; 18class Err; 19class Loader; 20class ParseNode; 21 22class 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