Include validations when collecting metadata

Some Fuchsia tests depend on metadata to collect clippy output. This
failed because validations were not considered when collecting metadata.

Bug: 478798763
Change-Id: Id213821800144a14c8113f13caf7833748679f0c
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/20981
Reviewed-by: Takuto Ikuta <tikuta@google.com>
Commit-Queue: Neri Marschik <nerima@google.com>
diff --git a/src/gn/target.cc b/src/gn/target.cc
index e3c95f3..062beba 100644
--- a/src/gn/target.cc
+++ b/src/gn/target.cc
@@ -1313,6 +1313,14 @@
             return false;
         }
       }
+      for (const auto& dep : validations_) {
+        // If we haven't walked this dep yet, go down into it.
+        if (targets_walked->add(dep.ptr)) {
+          if (!dep.ptr->GetMetadata(keys_to_extract, keys_to_walk, rebase_dir,
+                                    false, result, targets_walked, err))
+            return false;
+        }
+      }
 
       // Any other walk keys are superfluous, as they can only be a subset of
       // all deps.
@@ -1345,6 +1353,22 @@
         break;
       }
     }
+    if (!found_next) {
+      for (const auto& dep : validations_) {
+        // Match against the label with the toolchain.
+        if (dep.label.GetUserVisibleName(true) == canonicalize_next_label) {
+          // If we haven't walked this dep yet, go down into it.
+          if (targets_walked->add(dep.ptr)) {
+            if (!dep.ptr->GetMetadata(keys_to_extract, keys_to_walk, rebase_dir,
+                                      false, result, targets_walked, err))
+              return false;
+          }
+          // We found it, so we can exit this search now.
+          found_next = true;
+          break;
+        }
+      }
+    }
     // If we didn't find the specified dep in the target, that's an error.
     // Propagate it back to the user.
     if (!found_next) {
diff --git a/src/gn/target_unittest.cc b/src/gn/target_unittest.cc
index ebe40be..b920c26 100644
--- a/src/gn/target_unittest.cc
+++ b/src/gn/target_unittest.cc
@@ -1538,3 +1538,31 @@
   ASSERT_EQ(1u, output.size());
   EXPECT_EQ("input.modulemap.pcm", output[0].value()) << output[0].value();
 }
+
+TEST(TargetTest, CollectMetadataWithValidation) {
+  TestWithScope setup;
+
+  TestTarget a(setup, "//foo:a", Target::SOURCE_SET);
+  Value a_expected(nullptr, Value::LIST);
+  a_expected.list_value().push_back(Value(nullptr, "foo"));
+  a.metadata().contents().emplace("walk", a_expected);
+
+  TestTarget b(setup, "//foo:b", Target::SOURCE_SET);
+  Value b_expected(nullptr, Value::LIST);
+  b_expected.list_value().push_back(Value(nullptr, "bar"));
+  b.metadata().contents().emplace("walk", b_expected);
+
+  a.validations().push_back(LabelTargetPair(&b));
+
+  std::vector<std::string> data_keys = {"walk"};
+  std::vector<std::string> walk_keys;
+  std::vector<Value> result;
+  TargetSet targets;
+  Err err;
+  a.GetMetadata(data_keys, walk_keys, SourceDir(), false, &result, &targets,
+                &err);
+  EXPECT_FALSE(err.has_error());
+
+  std::vector<Value> expected = {Value(nullptr, "bar"), Value(nullptr, "foo")};
+  EXPECT_EQ(result, expected);
+}