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