When suggestions have a known includer target, don't complain that they
don't resolve to a single target.

This made a lot of sense when you had :foo1 and :foo2 both contain foo.cc in their sources,
and you ran `gn suggest foo.cc=bar.h`, but makes less sense when gn
check complains that foo1 doesn't depend on bar and foo2 also doesn't
depend on bar.

Change-Id: I1111e7c1b623015047721cf35e23420d6a6a6964
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/26660
Commit-Queue: Matt Stark <msta@google.com>
Reviewed-by: Takuto Ikuta <tikuta@google.com>
diff --git a/src/gn/command_check.cc b/src/gn/command_check.cc
index f0292a1..c02c106 100644
--- a/src/gn/command_check.cc
+++ b/src/gn/command_check.cc
@@ -310,7 +310,8 @@
       SuggestResult exit_code = OutputSuggestions(
           all_targets, build_settings,
           violation.source_target->label().GetToolchainLabel(),
-          violation.source_file.value(), violation.included_file.value(),
+          violation.source_file.value(), violation.source_target,
+          violation.included_file.value(),
           [&](std::string_view str, TextDecoration dec, HtmlEscaping esc) {
             buf.emplace_back(str, dec, esc);
           },
diff --git a/src/gn/command_suggest.cc b/src/gn/command_suggest.cc
index c6ff2f8..fab7418 100644
--- a/src/gn/command_suggest.cc
+++ b/src/gn/command_suggest.cc
@@ -398,6 +398,7 @@
                                 const BuildSettings* build_settings,
                                 const Label& default_toolchain,
                                 std::string_view includer_name,
+                                const Target* includer_target,
                                 std::string_view included_name,
                                 OutputStringFunc output_fn,
                                 TargetResolutionCache& cache,
@@ -432,7 +433,9 @@
     OutputString("\"", kLabelLike);
   };
 
-  Label current_toolchain = default_toolchain;
+  Label current_toolchain = includer_target
+                                ? includer_target->label().GetToolchainLabel()
+                                : default_toolchain;
 
   auto OutputDefinition = [&](const Target* target) {
     OutputString(":", kLabelLike);
@@ -567,11 +570,16 @@
     return std::make_pair(targets, ok);
   };
 
-  const auto& [includer_targets, includer_ok] =
-      ResolveSuggestion(includer_name);
+  auto [includer_targets, includer_ok] = ResolveSuggestion(includer_name);
   if (!includer_ok)
     return SuggestResult::kFailure;
 
+  if (includer_target) {
+    std::erase_if(includer_targets, [&](const auto& pair) {
+      return pair.first != includer_target;
+    });
+  }
+
   if (includer_targets.empty()) {
     StartError();
     OutputQuoted(includer_name);
@@ -1064,7 +1072,8 @@
 
     SuggestResult res = OutputSuggestions(
         all_targets, &setup->build_settings(),
-        setup->loader()->default_toolchain_label(), includer, included,
+        setup->loader()->default_toolchain_label(), includer,
+        /*includer_target=*/nullptr, included,
         [&](std::string_view str, TextDecoration dec, HtmlEscaping esc) {
           has_suggestions = true;
           ::OutputString(str, dec, esc);
diff --git a/src/gn/command_suggest_unittest.cc b/src/gn/command_suggest_unittest.cc
index 6cee00c..eda3a32 100644
--- a/src/gn/command_suggest_unittest.cc
+++ b/src/gn/command_suggest_unittest.cc
@@ -415,8 +415,9 @@
       output.append(s);
     };
     commands::TargetResolutionCache cache;
-    commands::OutputSuggestions(all_targets, setup_scope.build_settings(),
-                                default_toolchain, from, want, collect, cache);
+    commands::OutputSuggestions(
+        all_targets, setup_scope.build_settings(), default_toolchain, from,
+        /*includer_target=*/nullptr, want, collect, cache);
     return output;
   };
 
@@ -634,8 +635,9 @@
   commands::TargetResolutionCache cache;
   commands::SuggestResult result = commands::OutputSuggestions(
       project.targets(), &project.setup.build_settings(),
-      project.default_toolchain(), "//includer.cc", "//included.h", collect,
-      cache, /*must_be_file=*/false, /*apply=*/true, &project.setup);
+      project.default_toolchain(), "//includer.cc",
+      /*includer_target=*/nullptr, "//included.h", collect, cache,
+      /*must_be_file=*/false, /*apply=*/true, &project.setup);
 
   EXPECT_EQ(commands::SuggestResult::kSuccess, result);
   EXPECT_EQ(
@@ -659,9 +661,9 @@
   commands::TargetResolutionCache same_target_cache;
   commands::SuggestResult same_target_result = commands::OutputSuggestions(
       project.targets(), &project.setup.build_settings(),
-      project.default_toolchain(), "//included.h", "//private.h", collect,
-      same_target_cache, /*must_be_file=*/false, /*apply=*/true,
-      &project.setup);
+      project.default_toolchain(), "//included.h",
+      /*includer_target=*/nullptr, "//private.h", collect, same_target_cache,
+      /*must_be_file=*/false, /*apply=*/true, &project.setup);
 
   EXPECT_EQ(commands::SuggestResult::kUnapplied, same_target_result);
   EXPECT_EQ(
diff --git a/src/gn/commands.h b/src/gn/commands.h
index 98009ee..168cb26 100644
--- a/src/gn/commands.h
+++ b/src/gn/commands.h
@@ -178,6 +178,7 @@
                                 const BuildSettings* build_settings,
                                 const Label& default_toolchain,
                                 std::string_view includer_name,
+                                const Target* includer_target,
                                 std::string_view included_name,
                                 OutputStringFunc output_fn,
                                 TargetResolutionCache& cache,