Index: tools/gn/config.cc |
diff --git a/tools/gn/config.cc b/tools/gn/config.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1175d7f3c8bf66e528969893e45e9a07850b8a53 |
--- /dev/null |
+++ b/tools/gn/config.cc |
@@ -0,0 +1,78 @@ |
+// 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. |
+ |
+#include "tools/gn/config.h" |
+ |
+#include "tools/gn/err.h" |
+#include "tools/gn/input_file_manager.h" |
+#include "tools/gn/item_node.h" |
+#include "tools/gn/item_tree.h" |
+#include "tools/gn/scheduler.h" |
+ |
+Config::Config(const Label& label) : Item(label) { |
+} |
+ |
+Config::~Config() { |
+} |
+ |
+Config* Config::AsConfig() { |
+ return this; |
+} |
+ |
+const Config* Config::AsConfig() const { |
+ return this; |
+} |
+ |
+// static |
+Config* Config::GetConfig(const Settings* settings, |
+ const LocationRange& specified_from_here, |
+ const Label& label, |
+ Item* dep_from, |
+ Err* err) { |
+ DCHECK(!label.is_null()); |
+ |
+ ItemTree* tree = &settings->build_settings()->item_tree(); |
+ base::AutoLock lock(tree->lock()); |
+ |
+ ItemNode* node = tree->GetExistingNodeLocked(label); |
+ Config* config = NULL; |
+ if (!node) { |
+ config = new Config(label); |
+ node = new ItemNode(config); |
+ tree->AddNodeLocked(node); |
+ |
+ // Only schedule loading the given target if somebody is depending on it |
+ // (and we optimize by not re-asking it to run the current file). |
+ // Otherwise, we're probably generating it right now. |
+ if (dep_from && dep_from->label().dir() != label.dir()) { |
+ settings->build_settings()->toolchain_manager().ScheduleInvocationLocked( |
+ specified_from_here, label.GetToolchainLabel(), label.dir(), |
+ err); |
+ } |
+ } else if ((config = node->item()->AsConfig())) { |
+ // Previously saw this item as a config. |
+ |
+ // If we have no dep_from, we're generating it. In this case, it had better |
+ // not already be generated. |
+ if (!dep_from && node->state() != ItemNode::REFERENCED) { |
+ *err = Err(specified_from_here, "Duplicate config definition.", |
+ "You already told me about a config with this name."); |
+ return NULL; |
+ } |
+ } else { |
+ // Previously saw this thing as a non-config. |
+ *err = Err(specified_from_here, |
+ "Config name already used.", |
+ "Previously you specified a " + |
+ node->item()->GetItemTypeName() + " with this name instead."); |
+ return NULL; |
+ } |
+ |
+ // Keep a record of the guy asking us for this dependency. We know if |
+ // somebody is adding a dependency, that guy it himself not resolved. |
+ if (dep_from && node->state() != ItemNode::RESOLVED) |
+ tree->GetExistingNodeLocked(dep_from->label())->AddDependency(node); |
+ |
+ return config; |
+} |