[swift] Set `restat = 1` to swift build rules

The swift compiler may leave output file untouched if they are
identical when performing an incremental build. This results
in what should be "no-op" builds to be considered dirty.

Set `restat = 1` on the swift buidl rules to tell ninja that
the compiler perform this optimization and that it should stat
the outputs again and use the result to decide maybe prune the
build graph.

Bug: 362
Change-Id: I97d5096d1541d3f33c7378a7881214f11fece14d
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/16860
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 62e01eb..b47c2e4 100644
--- a/src/gn/ninja_binary_target_writer.cc
+++ b/src/gn/ninja_binary_target_writer.cc
@@ -264,7 +264,8 @@
     const std::vector<OutputFile>& order_only_deps,
     const char* tool_name,
     const std::vector<OutputFile>& outputs,
-    bool can_write_source_info) {
+    bool can_write_source_info,
+    bool restat_output_allowed) {
   out_ << "build";
   WriteOutputs(outputs);
 
@@ -289,6 +290,10 @@
          << FindFilenameNoExtension(&sources[0].value());
     out_ << std::endl;
   }
+
+  if (restat_output_allowed) {
+    out_ << "  restat = 1" << std::endl;
+  }
 }
 
 void NinjaBinaryTargetWriter::WriteCustomLinkerFlags(std::ostream& out,
diff --git a/src/gn/ninja_binary_target_writer.h b/src/gn/ninja_binary_target_writer.h
index 92ac5ee..c013cf8 100644
--- a/src/gn/ninja_binary_target_writer.h
+++ b/src/gn/ninja_binary_target_writer.h
@@ -58,7 +58,8 @@
                               const std::vector<OutputFile>& order_only_deps,
                               const char* tool_name,
                               const std::vector<OutputFile>& outputs,
-                              bool can_write_source_info = true);
+                              bool can_write_source_info = true,
+                              bool restat_output_allowed = false);
 
   void WriteLinkerFlags(std::ostream& out,
                         const Tool* tool,
diff --git a/src/gn/ninja_c_binary_target_writer.cc b/src/gn/ninja_c_binary_target_writer.cc
index aa5345c..5be23d8 100644
--- a/src/gn/ninja_c_binary_target_writer.cc
+++ b/src/gn/ninja_c_binary_target_writer.cc
@@ -546,7 +546,8 @@
 
   WriteCompilerBuildLine(target_->sources(), input_deps,
                          swift_order_only_deps.vector(), tool->name(), outputs,
-                         false);
+                         /*can_write_source_info=*/false,
+                         /*restat_output_allowed=*/true);
 
   out_ << std::endl;
 }
diff --git a/src/gn/ninja_c_binary_target_writer_unittest.cc b/src/gn/ninja_c_binary_target_writer_unittest.cc
index 085914a..d64e4a6 100644
--- a/src/gn/ninja_c_binary_target_writer_unittest.cc
+++ b/src/gn/ninja_c_binary_target_writer_unittest.cc
@@ -2300,6 +2300,7 @@
         "\n"
         "build obj/foo/Foo.swiftmodule obj/foo/file1.o obj/foo/file2.o: swift"
         " ../../foo/file1.swift ../../foo/file2.swift\n"
+        "  restat = 1\n"
         "\n"
         "build obj/foo/foo.stamp: stamp"
         " obj/foo/file1.o obj/foo/file2.o\n";
@@ -2335,6 +2336,7 @@
         "\n"
         "build obj/bar/Bar.swiftmodule obj/bar/bar.o: swift ../../bar/bar.swift"
         " || obj/foo/foo.stamp\n"
+        "  restat = 1\n"
         "\n"
         "build obj/bar/bar.stamp: stamp obj/bar/bar.o "
         "|| obj/foo/foo.stamp\n";
@@ -2378,6 +2380,7 @@
         "\n"
         "build obj/bar/Bar.swiftmodule obj/bar/bar.o: swift ../../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 "
         "|| obj/bar/group.stamp obj/foo/foo.stamp\n";