summaryrefslogtreecommitdiffstats
path: root/tools/gn/item_tree.cc
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gn/item_tree.cc')
-rw-r--r--tools/gn/item_tree.cc193
1 files changed, 0 insertions, 193 deletions
diff --git a/tools/gn/item_tree.cc b/tools/gn/item_tree.cc
deleted file mode 100644
index a4d1181..0000000
--- a/tools/gn/item_tree.cc
+++ /dev/null
@@ -1,193 +0,0 @@
-// 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/item_tree.h"
-
-#include <algorithm>
-
-#include "base/stl_util.h"
-#include "tools/gn/err.h"
-#include "tools/gn/item.h"
-#include "tools/gn/item_node.h"
-
-namespace {
-
-// Recursively looks in the tree for a given node, returning true if it
-// was found in the dependecy graph. This is used to see if a given node
-// participates in a cycle.
-//
-// Note that "look_for" and "search_in" will be the same node when starting the
-// search, so we don't want to return true in that case.
-//
-// If a cycle is found, the return value will be true and the cycle vector will
-// be filled with the path (in reverse order).
-bool RecursiveFindCycle(const ItemNode* look_for,
- const ItemNode* search_in,
- std::vector<const ItemNode*>* cycle) {
- const ItemNode::ItemNodeSet& unresolved =
- search_in->unresolved_dependencies();
- for (ItemNode::ItemNodeSet::const_iterator i = unresolved.begin();
- i != unresolved.end(); ++i) {
- if (*i == look_for) {
- cycle->push_back(*i);
- return true;
- }
-
- if (RecursiveFindCycle(look_for, *i, cycle)) {
- // Found a cycle inside this one, record our path and return.
- cycle->push_back(*i);
- return true;
- }
- }
- return false;
-}
-
-} // namespace
-
-ItemTree::ItemTree() {
-}
-
-ItemTree::~ItemTree() {
- STLDeleteContainerPairSecondPointers(items_.begin(), items_.end());
-}
-
-ItemNode* ItemTree::GetExistingNodeLocked(const Label& label) {
- lock_.AssertAcquired();
- StringToNodeHash::iterator found = items_.find(label);
- if (found == items_.end())
- return NULL;
- return found->second;
-}
-
-void ItemTree::AddNodeLocked(ItemNode* node) {
- lock_.AssertAcquired();
- DCHECK(items_.find(node->item()->label()) == items_.end());
- items_[node->item()->label()] = node;
-}
-
-Err ItemTree::MarkItemGeneratedLocked(const Label& label) {
- lock_.AssertAcquired();
- DCHECK(items_.find(label) != items_.end());
-
- ItemNode* node = items_[label];
-
- if (!node->unresolved_dependencies().empty()) {
- // Still some pending dependencies, wait for those to be resolved.
- node->SetGenerated();
- return Err();
- }
- return MarkItemResolvedLocked(node);
-}
-
-void ItemTree::GetAllItemsLocked(std::vector<const Item*>* dest) const {
- lock_.AssertAcquired();
- dest->reserve(items_.size());
- for (StringToNodeHash::const_iterator i = items_.begin();
- i != items_.end(); ++i) {
- dest->push_back(i->second->item());
- }
-}
-
-Err ItemTree::CheckForBadItems() const {
- base::AutoLock lock(lock_);
-
- // Look for errors where we find a GENERATED node that refers to a REFERENCED
- // one. There may be other nodes depending on the GENERATED one, but listing
- // all of those isn't helpful, we want to find the broken link.
- //
- // This finds normal "missing dependency" errors but does not find circular
- // dependencies because in this case all items in the cycle will be GENERATED
- // but none will be resolved. If this happens, we'll check explicitly for
- // that below.
- std::vector<const ItemNode*> bad_nodes;
- std::string depstring;
- for (StringToNodeHash::const_iterator i = items_.begin();
- i != items_.end(); ++i) {
- const ItemNode* src = i->second;
-
- if (src->state() == ItemNode::GENERATED) {
- bad_nodes.push_back(src);
-
- // Check dependencies.
- for (ItemNode::ItemNodeSet::const_iterator dest =
- src->unresolved_dependencies().begin();
- dest != src->unresolved_dependencies().end();
- ++dest) {
- if ((*dest)->state() == ItemNode::REFERENCED) {
- depstring += "\"" + src->item()->label().GetUserVisibleName(false) +
- "\" needs " + (*dest)->item()->GetItemTypeName() +
- " \"" + (*dest)->item()->label().GetUserVisibleName(false) +
- "\"\n";
- }
- }
- }
- }
-
- if (!bad_nodes.empty() && depstring.empty()) {
- // Our logic above found a bad node but didn't identify the problem. This
- // normally means a circular dependency.
- depstring = CheckForCircularDependenciesLocked(bad_nodes);
- if (depstring.empty()) {
- // Something's very wrong, just dump out the bad nodes.
- depstring = "I have no idea what went wrong, but these are unresolved, "
- "possible due to an\ninternal error:";
- for (size_t i = 0; i < bad_nodes.size(); i++) {
- depstring += "\n\"" +
- bad_nodes[i]->item()->label().GetUserVisibleName(false) + "\"";
- }
- }
- }
-
- if (depstring.empty())
- return Err();
- return Err(Location(), "Unresolved dependencies.", depstring);
-}
-
-Err ItemTree::MarkItemResolvedLocked(ItemNode* node) {
- node->SetResolved();
- node->item()->OnResolved();
-
- // Now update our waiters, pushing the "resolved" bit.
- ItemNode::ItemNodeSet waiting;
- node->SwapOutWaitingDependencySet(&waiting);
- for (ItemNode::ItemNodeSet::iterator i = waiting.begin();
- i != waiting.end(); ++i) {
- ItemNode* waiter = *i;
-
- // Our node should be unresolved in the waiter.
- DCHECK(waiter->unresolved_dependencies().find(node) !=
- waiter->unresolved_dependencies().end());
- waiter->MarkDirectDependencyResolved(node);
-
- // Recursively mark nodes as resolved.
- if (waiter->state() == ItemNode::GENERATED &&
- waiter->unresolved_dependencies().empty()) {
- Err err = MarkItemResolvedLocked(waiter);
- if (err.has_error())
- return err;
- }
- }
-
- return Err();
-}
-
-std::string ItemTree::CheckForCircularDependenciesLocked(
- const std::vector<const ItemNode*>& bad_nodes) const {
- std::vector<const ItemNode*> cycle;
- if (!RecursiveFindCycle(bad_nodes[0], bad_nodes[0], &cycle))
- return std::string(); // Didn't find a cycle, something else is wrong.
-
- cycle.push_back(bad_nodes[0]);
- std::string ret = "There is a dependency cycle:";
-
- // Walk backwards since the dependency arrows point in the reverse direction.
- for (int i = static_cast<int>(cycle.size()) - 1; i >= 0; i--) {
- ret += "\n \"" + cycle[i]->item()->label().GetUserVisibleName(false) +
- "\"";
- if (i != 0)
- ret += " ->";
- }
-
- return ret;
-}