format: Ensure that formatting always reaches a fixedpoint in one run

The .golden for this is ugly, but follows existing sources formatting e.g. in
https://gn.googlesource.com/gn/+/master/tools/gn/format_test_data/062.golden#25
This at least causes formatting to reach a fixed point in one step, which is
the more annoying bug.

In practice, the user will probably fix the sorting to the actual desired
formatting by manually sorting as was done in
https://chromium-review.googlesource.com/c/chromium/src/+/1403177.

Bug: gn:40

Test: CQ
Change-Id: Id3fea2564ae34156ac77e7445acd3f18bb4d161f
Reviewed-on: https://gn-review.googlesource.com/c/3720
Reviewed-by: Nico Weber <thakis@chromium.org>
Reviewed-by: Scott Graham <scottmg@chromium.org>
Commit-Queue: Scott Graham <scottmg@chromium.org>
diff --git a/tools/gn/command_format.cc b/tools/gn/command_format.cc
index 0f7b7b2..10e22ef 100644
--- a/tools/gn/command_format.cc
+++ b/tools/gn/command_format.cc
@@ -428,6 +428,8 @@
       const PARSENODE* node = statements[i].get();
       int line_number =
           prev ? prev->GetRange().end().line_number() + 1 : start_line;
+      if (node->comments() && !node->comments()->before().empty())
+        line_number++;
       const_cast<FunctionCallNode*>(node->AsFunctionCall())
           ->SetNewLocation(line_number);
       prev = node;
diff --git a/tools/gn/command_format_unittest.cc b/tools/gn/command_format_unittest.cc
index f5e0c35..bad12ee 100644
--- a/tools/gn/command_format_unittest.cc
+++ b/tools/gn/command_format_unittest.cc
@@ -31,6 +31,10 @@
                                FILE_PATH_LITERAL(".golden")),               \
         &expected));                                                        \
     EXPECT_EQ(expected, out);                                               \
+    /* Make sure formatting the output doesn't cause further changes. */    \
+    std::string out_again;                                                  \
+    EXPECT_TRUE(commands::FormatStringToString(out, false, &out_again));    \
+    ASSERT_EQ(out, out_again);                                              \
   }
 
 // These are expanded out this way rather than a runtime loop so that
@@ -110,3 +114,4 @@
 FORMAT_TEST(072)
 FORMAT_TEST(073)
 FORMAT_TEST(074)
+FORMAT_TEST(075)
diff --git a/tools/gn/format_test_data/075.gn b/tools/gn/format_test_data/075.gn
new file mode 100644
index 0000000..8a3c327
--- /dev/null
+++ b/tools/gn/format_test_data/075.gn
@@ -0,0 +1,11 @@
+# This tests for a case where formatting did not reach a fixed point after a
+# single run of formatting.
+
+import("stuff.gni")
+
+# Subprojects need to override arguments in {mac,ios}_sdk_overrides.gni in their
+# .gn config, but those arguments are only used on macOS. Including
+# mac_sdk_overrides.gni insures that this doesn't trigger an unused argument
+# warning.
+import("//build/config/mac/mac_sdk_overrides.gni")
+import("//build/config/ios/ios_sdk_overrides.gni")
diff --git a/tools/gn/format_test_data/075.golden b/tools/gn/format_test_data/075.golden
new file mode 100644
index 0000000..d181bd6
--- /dev/null
+++ b/tools/gn/format_test_data/075.golden
@@ -0,0 +1,12 @@
+# This tests for a case where formatting did not reach a fixed point after a
+# single run of formatting.
+
+import("stuff.gni")
+
+import("//build/config/ios/ios_sdk_overrides.gni")
+
+# Subprojects need to override arguments in {mac,ios}_sdk_overrides.gni in their
+# .gn config, but those arguments are only used on macOS. Including
+# mac_sdk_overrides.gni insures that this doesn't trigger an unused argument
+# warning.
+import("//build/config/mac/mac_sdk_overrides.gni")