[swift] List all outputs as deps of "source_set" stamp file

Since a swift target generates more than object files, and since
some of those outputs are input dependencies for other .swift
files, explicitly list them as part of the "source_set" stamp
file dependencies.

Also change NinjaBinaryTargetWriter::AddSourceSetFiles() to use
the shared code from SwiftValues to compute the outputs instead
of duplicating the effort (incorrectly).

Bug: none
Change-Id: I6e6c9091aaa34369fda20ba3cbae37df88454374
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/16880
Reviewed-by: David Turner <digit@google.com>
Commit-Queue: Sylvain Defresne <sdefresne@chromium.org>
diff --git a/src/gn/ninja_binary_target_writer.cc b/src/gn/ninja_binary_target_writer.cc
index b47c2e4..7dc6ea8 100644
--- a/src/gn/ninja_binary_target_writer.cc
+++ b/src/gn/ninja_binary_target_writer.cc
@@ -206,12 +206,8 @@
   // Swift files may generate one object file per module or one per source file
   // depending on how the compiler is invoked (whole module optimization).
   if (source_set->source_types_used().SwiftSourceUsed()) {
-    const Tool* tool = source_set->toolchain()->GetToolForSourceTypeAsC(
-        SourceFile::SOURCE_SWIFT);
-
     std::vector<OutputFile> outputs;
-    SubstitutionWriter::ApplyListToLinkerAsOutputFile(
-        source_set, tool, tool->outputs(), &outputs);
+    source_set->swift_values().GetOutputs(source_set, &outputs);
 
     for (const OutputFile& output : outputs) {
       SourceFile output_as_source =
diff --git a/src/gn/ninja_c_binary_target_writer.cc b/src/gn/ninja_c_binary_target_writer.cc
index 9b656bf..5e2be80 100644
--- a/src/gn/ninja_c_binary_target_writer.cc
+++ b/src/gn/ninja_c_binary_target_writer.cc
@@ -195,12 +195,15 @@
   //  - GCC .gch files are not object files, therefore they are not added to the
   //    object file list.
   std::vector<OutputFile> obj_files;
+  std::vector<OutputFile> extra_files;
   std::vector<SourceFile> other_files;
+  std::vector<OutputFile>* stamp_files = &obj_files;  // default
   if (!target_->source_types_used().SwiftSourceUsed()) {
     WriteSources(*pch_files, input_deps, order_only_deps, module_dep_info,
                  &obj_files, &other_files);
   } else {
-    WriteSwiftSources(input_deps, order_only_deps, &obj_files);
+    stamp_files = &extra_files;  // Swift generates more than object files
+    WriteSwiftSources(input_deps, order_only_deps, &obj_files, &extra_files);
   }
 
   // Link all MSVC pch object files. The vector will be empty on GCC toolchains.
@@ -209,7 +212,7 @@
     return;
 
   if (target_->output_type() == Target::SOURCE_SET) {
-    WriteSourceSetStamp(obj_files);
+    WriteSourceSetStamp(*stamp_files);
 #ifndef NDEBUG
     // Verify that the function that separately computes a source set's object
     // files match the object files just computed.
@@ -503,14 +506,13 @@
 void NinjaCBinaryTargetWriter::WriteSwiftSources(
     const std::vector<OutputFile>& input_deps,
     const std::vector<OutputFile>& order_only_deps,
-    std::vector<OutputFile>* object_files) {
+    std::vector<OutputFile>* object_files,
+    std::vector<OutputFile>* output_files) {
   DCHECK(target_->builds_swift_module());
-
-  std::vector<OutputFile> outputs;
-  target_->swift_values().GetOutputs(target_, &outputs);
+  target_->swift_values().GetOutputs(target_, output_files);
 
   const BuildSettings* build_settings = settings_->build_settings();
-  for (const OutputFile& output : outputs) {
+  for (const OutputFile& output : *output_files) {
     const SourceFile output_as_source = output.AsSourceFile(build_settings);
     if (output_as_source.IsObjectType()) {
       object_files->push_back(output);
@@ -528,7 +530,8 @@
 
   const Tool* tool = target_->swift_values().GetTool(target_);
   WriteCompilerBuildLine(target_->sources(), input_deps,
-                         swift_order_only_deps.vector(), tool->name(), outputs,
+                         swift_order_only_deps.vector(), tool->name(),
+                         *output_files,
                          /*can_write_source_info=*/false,
                          /*restat_output_allowed=*/true);
 
diff --git a/src/gn/ninja_c_binary_target_writer.h b/src/gn/ninja_c_binary_target_writer.h
index 17615cc..a50d8c9 100644
--- a/src/gn/ninja_c_binary_target_writer.h
+++ b/src/gn/ninja_c_binary_target_writer.h
@@ -82,7 +82,8 @@
                     std::vector<SourceFile>* other_files);
   void WriteSwiftSources(const std::vector<OutputFile>& input_deps,
                          const std::vector<OutputFile>& order_only_deps,
-                         std::vector<OutputFile>* object_files);
+                         std::vector<OutputFile>* object_files,
+                         std::vector<OutputFile>* output_files);
 
   // Writes the stamp line for a source set. These are not linked.
   void WriteSourceSetStamp(const std::vector<OutputFile>& object_files);
diff --git a/src/gn/ninja_c_binary_target_writer_unittest.cc b/src/gn/ninja_c_binary_target_writer_unittest.cc
index 3815ab4..9fb8ff3 100644
--- a/src/gn/ninja_c_binary_target_writer_unittest.cc
+++ b/src/gn/ninja_c_binary_target_writer_unittest.cc
@@ -2336,6 +2336,7 @@
         "  restat = 1\n"
         "\n"
         "build obj/foo/foo.stamp: stamp"
+        " gen/foo/foo.h obj/foo/Foo.swiftmodule"
         " obj/foo/file1.o obj/foo/file2.o\n";
 
     const std::string out_str = out.str();
@@ -2372,7 +2373,8 @@
         "../../bar/bar.swift || obj/foo/foo.stamp\n"
         "  restat = 1\n"
         "\n"
-        "build obj/bar/bar.stamp: stamp obj/bar/bar.o "
+        "build obj/bar/bar.stamp: stamp"
+        " gen/bar/bar.h obj/bar/Bar.swiftmodule obj/bar/bar.o "
         "|| obj/foo/foo.stamp\n";
 
     const std::string out_str = out.str();
@@ -2417,7 +2419,8 @@
         "../../bar/bar.swift || obj/bar/group.stamp obj/foo/foo.stamp\n"
         "  restat = 1\n"
         "\n"
-        "build obj/bar/bar.stamp: stamp obj/bar/bar.o "
+        "build obj/bar/bar.stamp: stamp"
+        " gen/bar/bar.h obj/bar/Bar.swiftmodule obj/bar/bar.o "
         "|| obj/bar/group.stamp obj/foo/foo.stamp\n";
 
     const std::string out_str = out.str();