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_LOADER_H_ |
| 6 #define TOOLS_GN_LOADER_H_ |
| 7 |
| 8 #include <map> |
| 9 #include <set> |
| 10 |
| 11 #include "base/callback.h" |
| 12 #include "base/memory/ref_counted.h" |
| 13 #include "tools/gn/label.h" |
| 14 #include "tools/gn/scope.h" |
| 15 |
| 16 namespace base { |
| 17 class MessageLoop; |
| 18 } |
| 19 |
| 20 class BuildSettings; |
| 21 class Settings; |
| 22 class SourceFile; |
| 23 class Toolchain; |
| 24 |
| 25 // The loader manages execution of the different build files. It receives |
| 26 // requests (normally from the Builder) when new references are found, and also |
| 27 // manages loading the build config files. |
| 28 // |
| 29 // This loader class is abstract so it can be mocked out for testing the |
| 30 // Builder. |
| 31 class Loader : public base::RefCountedThreadSafe<Loader> { |
| 32 public: |
| 33 Loader(); |
| 34 |
| 35 // Loads the given file in the conext of the given toolchain. The initial |
| 36 // call to this (the one that actually starts the generation) should have an |
| 37 // empty toolchain name, which will trigger the load of the default build |
| 38 // config. |
| 39 virtual void Load(const SourceFile& file, |
| 40 const Label& toolchain_name) = 0; |
| 41 |
| 42 // Notification that the given toolchain has loaded. This will unblock files |
| 43 // waiting on this definition. |
| 44 virtual void ToolchainLoaded(const Toolchain* toolchain) = 0; |
| 45 |
| 46 // Returns the label of the default toolchain. |
| 47 virtual Label GetDefaultToolchain() const = 0; |
| 48 |
| 49 // Returns information about the toolchain with the given label. Will return |
| 50 // false if we haven't processed this toolchain yet. |
| 51 virtual const Settings* GetToolchainSettings(const Label& label) = 0; |
| 52 |
| 53 // Helper function that extracts the file and toolchain name from the given |
| 54 // label, and calls Load(). |
| 55 void Load(const Label& label); |
| 56 |
| 57 // Returns the build file that the given label references. |
| 58 static SourceFile BuildFileForLabel(const Label& label); |
| 59 |
| 60 // When processing the default build config, we want to capture the argument |
| 61 // of set_default_build_config. The implementation of that function uses this |
| 62 // constant as a property key to get the Label* out of the scope where the |
| 63 // label should be stored. |
| 64 static const void* kDefaultToolchainKey; |
| 65 |
| 66 protected: |
| 67 friend class base::RefCountedThreadSafe<Loader>; |
| 68 virtual ~Loader(); |
| 69 }; |
| 70 |
| 71 class LoaderImpl : public Loader { |
| 72 public: |
| 73 // Callback to emulate InputFileManager::AsyncLoadFile. |
| 74 typedef base::Callback<bool(const LocationRange&, |
| 75 const BuildSettings*, |
| 76 const SourceFile&, |
| 77 const base::Callback<void(const ParseNode*)>&, |
| 78 Err*)> AsyncLoadFileCallback; |
| 79 |
| 80 LoaderImpl(const BuildSettings* build_settings); |
| 81 |
| 82 // Loader implementation. |
| 83 virtual void Load(const SourceFile& file, |
| 84 const Label& toolchain_name) OVERRIDE; |
| 85 virtual void ToolchainLoaded(const Toolchain* toolchain) OVERRIDE; |
| 86 virtual Label GetDefaultToolchain() const OVERRIDE; |
| 87 virtual const Settings* GetToolchainSettings(const Label& label) OVERRIDE; |
| 88 |
| 89 // Sets the message loop corresponding to the main thread. By default this |
| 90 // class will use the thread active during construction, but there is not |
| 91 // a message loop active during construction all the time. |
| 92 void set_main_loop(base::MessageLoop* loop) { main_loop_ = loop; } |
| 93 |
| 94 // The complete callback is called whenever there are no more pending loads. |
| 95 // Called on the main thread only. This may be called more than once if the |
| 96 // queue is drained, but then more stuff gets added. |
| 97 void set_complete_callback(const base::Closure& cb) { |
| 98 complete_callback_ = cb; |
| 99 } |
| 100 |
| 101 // This callback is used when the loader finds it wants to load a file. |
| 102 void set_async_load_file(const AsyncLoadFileCallback& cb) { |
| 103 async_load_file_ = cb; |
| 104 } |
| 105 |
| 106 const Label& default_toolchain_label() const { |
| 107 return default_toolchain_label_; |
| 108 } |
| 109 |
| 110 private: |
| 111 struct LoadID; |
| 112 struct ToolchainRecord; |
| 113 |
| 114 virtual ~LoaderImpl(); |
| 115 |
| 116 // Schedules the input file manager to load the given file. |
| 117 void ScheduleLoadFile(const Settings* settings, |
| 118 const SourceFile& file); |
| 119 void ScheduleLoadBuildConfig( |
| 120 Settings* settings, |
| 121 const Scope::KeyValueMap& toolchain_overrides); |
| 122 |
| 123 // Runs the given file on the background thread. These are called by the |
| 124 // input file manager. |
| 125 void BackgroundLoadFile(const Settings* settings, |
| 126 const SourceFile& file_name, |
| 127 const ParseNode* root); |
| 128 void BackgroundLoadBuildConfig( |
| 129 Settings* settings, |
| 130 const Scope::KeyValueMap& toolchain_overrides, |
| 131 const ParseNode* root); |
| 132 |
| 133 // Posted to the main thread when any file other than a build config file |
| 134 // file has completed running. |
| 135 void DidLoadFile(); |
| 136 |
| 137 // Posted to the main thread when any build config file has completed |
| 138 // running. The label should be the name of the toolchain. |
| 139 // |
| 140 // If there is no defauled toolchain loaded yet, we'll assume that the first |
| 141 // call to this indicates to the default toolchain, and this function will |
| 142 // set the default toolchain name to the given label. |
| 143 void DidLoadBuildConfig(const Label& label); |
| 144 |
| 145 // Decrements the pending_loads_ variable and issues the complete callback if |
| 146 // necessary. |
| 147 void DecrementPendingLoads(); |
| 148 |
| 149 // Forwards to the appropriate location to load the file. |
| 150 bool AsyncLoadFile(const LocationRange& origin, |
| 151 const BuildSettings* build_settings, |
| 152 const SourceFile& file_name, |
| 153 const base::Callback<void(const ParseNode*)>& callback, |
| 154 Err* err); |
| 155 |
| 156 base::MessageLoop* main_loop_; |
| 157 |
| 158 int pending_loads_; |
| 159 base::Closure complete_callback_; |
| 160 |
| 161 // When non-null, use this callback instead of the InputFileManager for |
| 162 // mocking purposes. |
| 163 AsyncLoadFileCallback async_load_file_; |
| 164 |
| 165 typedef std::set<LoadID> LoadIDSet; |
| 166 LoadIDSet invocations_; |
| 167 |
| 168 const BuildSettings* build_settings_; |
| 169 Label default_toolchain_label_; |
| 170 |
| 171 // Records for the build config file loads. |
| 172 // Owning pointers. |
| 173 typedef std::map<Label, ToolchainRecord*> ToolchainRecordMap; |
| 174 ToolchainRecordMap toolchain_records_; |
| 175 }; |
| 176 |
| 177 #endif // TOOLS_GN_LOADER_H_ |
OLD | NEW |