• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
set_resolved_callback(const ResolvedCallback & cb)29   void set_resolved_callback(const ResolvedCallback& cb) {
30     resolved_callback_ = cb;
31   }
32 
loader()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_
136