diff options
Diffstat (limited to 'chromium/tools/gn/loader.h')
-rw-r--r-- | chromium/tools/gn/loader.h | 181 |
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_ |