| Index: tools/gn/loader.h
|
| diff --git a/tools/gn/loader.h b/tools/gn/loader.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..63a10de777817b8f35f0dd45546f5461d99eda79
|
| --- /dev/null
|
| +++ b/tools/gn/loader.h
|
| @@ -0,0 +1,177 @@
|
| +// 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 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 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) = 0;
|
| +
|
| + // Helper function that extracts the file and toolchain name from the given
|
| + // label, and calls Load().
|
| + void Load(const Label& label);
|
| +
|
| + // 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* 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;
|
| +
|
| + LoaderImpl(const BuildSettings* build_settings);
|
| +
|
| + // Loader implementation.
|
| + virtual void Load(const SourceFile& file,
|
| + const Label& toolchain_name) OVERRIDE;
|
| + virtual void ToolchainLoaded(const Toolchain* toolchain) OVERRIDE;
|
| + virtual Label GetDefaultToolchain() const OVERRIDE;
|
| + virtual const Settings* GetToolchainSettings(const Label& label) 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;
|
| +
|
| + virtual ~LoaderImpl();
|
| +
|
| + // Schedules the input file manager to load the given file.
|
| + void ScheduleLoadFile(const Settings* settings,
|
| + 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_
|
|
|