| // Copyright 2018 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/metadata.h" |
| |
| bool Metadata::WalkStep(const BuildSettings* settings, |
| const std::vector<std::string>& keys_to_extract, |
| const std::vector<std::string>& keys_to_walk, |
| bool rebase_files, |
| std::vector<Value>* next_walk_keys, |
| std::vector<Value>* result, |
| Err* err) const { |
| // If there's no metadata, there's nothing to find, so quick exit. |
| if (contents_.empty()) { |
| next_walk_keys->emplace_back(nullptr, ""); |
| return true; |
| } |
| |
| // Pull the data from each specified key. |
| for (const auto& key : keys_to_extract) { |
| auto iter = contents_.find(key); |
| if (iter == contents_.end()) |
| continue; |
| assert(iter->second.type() == Value::LIST); |
| |
| if (rebase_files) { |
| for (const auto& val : iter->second.list_value()) { |
| if (!val.VerifyTypeIs(Value::STRING, err)) |
| return false; |
| // TODO(juliehockett): Do we want to consider absolute paths here? In |
| // which case we'd need to propagate the root_path_utf8 from |
| // build_settings as well. |
| std::string filename = source_dir_.ResolveRelativeAs( |
| /*as_file = */ true, val, err, settings->root_path_utf8()); |
| if (err->has_error()) |
| return false; |
| result->emplace_back(val.origin(), std::move(filename)); |
| } |
| } else { |
| result->insert(result->end(), iter->second.list_value().begin(), |
| iter->second.list_value().end()); |
| } |
| } |
| |
| // Get the targets to look at next. If no keys_to_walk are present, we push |
| // the empty string to the list so that the target knows to include its deps |
| // and data_deps. The values used here must be lists of strings. |
| bool found_walk_key = false; |
| for (const auto& key : keys_to_walk) { |
| auto iter = contents_.find(key); |
| if (iter != contents_.end()) { |
| found_walk_key = true; |
| assert(iter->second.type() == Value::LIST); |
| for (const auto& val : iter->second.list_value()) { |
| if (!val.VerifyTypeIs(Value::STRING, err)) |
| return false; |
| next_walk_keys->emplace_back(val); |
| } |
| } |
| } |
| |
| if (!found_walk_key) |
| next_walk_keys->emplace_back(nullptr, ""); |
| |
| return true; |
| } |