summaryrefslogtreecommitdiff
path: root/chromium/tools/gn/loader.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/tools/gn/loader.h')
-rw-r--r--chromium/tools/gn/loader.h181
1 files changed, 181 insertions, 0 deletions
diff --git a/chromium/tools/gn/loader.h b/chromium/tools/gn/loader.h
new file mode 100644
index 00000000000..3d61fe4b4e8
--- /dev/null
+++ b/chromium/tools/gn/loader.h
@@ -0,0 +1,181 @@
+// 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_LOADER_H_
+#define TOOLS_GN_LOADER_H_
+
+#include <map>
+#include <set>
+
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "tools/gn/label.h"
+#include "tools/gn/scope.h"
+
+namespace base {
+class MessageLoop;
+}
+
+class BuildSettings;
+class LocationRange;
+class Settings;
+class SourceFile;
+class Toolchain;
+
+// The loader manages execution of the different build files. It receives
+// requests (normally from the Builder) when new references are found, and also
+// manages loading the build config files.
+//
+// This loader class is abstract so it can be mocked out for testing the
+// Builder.
+class Loader : public base::RefCountedThreadSafe<Loader> {
+ public:
+ Loader();
+
+ // Loads the given file in the conext of the given toolchain. The initial
+ // call to this (the one that actually starts the generation) should have an
+ // empty toolchain name, which will trigger the load of the default build
+ // config.
+ virtual void Load(const SourceFile& file,
+ const LocationRange& origin,
+ const Label& toolchain_name) = 0;
+
+ // Notification that the given toolchain has loaded. This will unblock files
+ // waiting on this definition.
+ virtual void ToolchainLoaded(const Toolchain* toolchain) = 0;
+
+ // Returns the label of the default toolchain.
+ virtual Label GetDefaultToolchain() const = 0;
+
+ // Returns information about the toolchain with the given label. Will return
+ // false if we haven't processed this toolchain yet.
+ virtual const Settings* GetToolchainSettings(const Label& label) const = 0;
+
+ // Helper function that extracts the file and toolchain name from the given
+ // label, and calls Load().
+ void Load(const Label& label, const LocationRange& origin);
+
+ // Returns the build file that the given label references.
+ static SourceFile BuildFileForLabel(const Label& label);
+
+ // When processing the default build config, we want to capture the argument
+ // of set_default_build_config. The implementation of that function uses this
+ // constant as a property key to get the Label* out of the scope where the
+ // label should be stored.
+ static const void* const kDefaultToolchainKey;
+
+ protected:
+ friend class base::RefCountedThreadSafe<Loader>;
+ virtual ~Loader();
+};
+
+class LoaderImpl : public Loader {
+ public:
+ // Callback to emulate InputFileManager::AsyncLoadFile.
+ typedef base::Callback<bool(const LocationRange&,
+ const BuildSettings*,
+ const SourceFile&,
+ const base::Callback<void(const ParseNode*)>&,
+ Err*)> AsyncLoadFileCallback;
+
+ explicit LoaderImpl(const BuildSettings* build_settings);
+
+ // Loader implementation.
+ void Load(const SourceFile& file,
+ const LocationRange& origin,
+ const Label& toolchain_name) override;
+ void ToolchainLoaded(const Toolchain* toolchain) override;
+ Label GetDefaultToolchain() const override;
+ const Settings* GetToolchainSettings(const Label& label) const override;
+
+ // Sets the message loop corresponding to the main thread. By default this
+ // class will use the thread active during construction, but there is not
+ // a message loop active during construction all the time.
+ void set_main_loop(base::MessageLoop* loop) { main_loop_ = loop; }
+
+ // The complete callback is called whenever there are no more pending loads.
+ // Called on the main thread only. This may be called more than once if the
+ // queue is drained, but then more stuff gets added.
+ void set_complete_callback(const base::Closure& cb) {
+ complete_callback_ = cb;
+ }
+
+ // This callback is used when the loader finds it wants to load a file.
+ void set_async_load_file(const AsyncLoadFileCallback& cb) {
+ async_load_file_ = cb;
+ }
+
+ const Label& default_toolchain_label() const {
+ return default_toolchain_label_;
+ }
+
+ private:
+ struct LoadID;
+ struct ToolchainRecord;
+
+ ~LoaderImpl() override;
+
+ // Schedules the input file manager to load the given file.
+ void ScheduleLoadFile(const Settings* settings,
+ const LocationRange& origin,
+ const SourceFile& file);
+ void ScheduleLoadBuildConfig(
+ Settings* settings,
+ const Scope::KeyValueMap& toolchain_overrides);
+
+ // Runs the given file on the background thread. These are called by the
+ // input file manager.
+ void BackgroundLoadFile(const Settings* settings,
+ const SourceFile& file_name,
+ const ParseNode* root);
+ void BackgroundLoadBuildConfig(
+ Settings* settings,
+ const Scope::KeyValueMap& toolchain_overrides,
+ const ParseNode* root);
+
+ // Posted to the main thread when any file other than a build config file
+ // file has completed running.
+ void DidLoadFile();
+
+ // Posted to the main thread when any build config file has completed
+ // running. The label should be the name of the toolchain.
+ //
+ // If there is no defauled toolchain loaded yet, we'll assume that the first
+ // call to this indicates to the default toolchain, and this function will
+ // set the default toolchain name to the given label.
+ void DidLoadBuildConfig(const Label& label);
+
+ // Decrements the pending_loads_ variable and issues the complete callback if
+ // necessary.
+ void DecrementPendingLoads();
+
+ // Forwards to the appropriate location to load the file.
+ bool AsyncLoadFile(const LocationRange& origin,
+ const BuildSettings* build_settings,
+ const SourceFile& file_name,
+ const base::Callback<void(const ParseNode*)>& callback,
+ Err* err);
+
+ base::MessageLoop* main_loop_;
+
+ int pending_loads_;
+ base::Closure complete_callback_;
+
+ // When non-null, use this callback instead of the InputFileManager for
+ // mocking purposes.
+ AsyncLoadFileCallback async_load_file_;
+
+ typedef std::set<LoadID> LoadIDSet;
+ LoadIDSet invocations_;
+
+ const BuildSettings* build_settings_;
+ Label default_toolchain_label_;
+
+ // Records for the build config file loads.
+ // Owning pointers.
+ typedef std::map<Label, ToolchainRecord*> ToolchainRecordMap;
+ ToolchainRecordMap toolchain_records_;
+};
+
+#endif // TOOLS_GN_LOADER_H_