Update `gn format` to always insert newlines before targets.

Change-Id: Ie1d0e3be4ee053d4a742bb3dfd2266b96a6a6964
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/25621
Reviewed-by: Takuto Ikuta <tikuta@google.com>
Commit-Queue: Matt Stark <msta@google.com>
diff --git a/src/gn/command_format.cc b/src/gn/command_format.cc
index e00b271..b015718 100644
--- a/src/gn/command_format.cc
+++ b/src/gn/command_format.cc
@@ -790,9 +790,21 @@
 
   // If they're already separated by 1 or more lines, then we want to keep a
   // blank line.
-  return (b_range.begin().line_number() > a_end + 1) ||
-         // Always put a blank line before a block comment.
-         b->AsBlockComment();
+  // Always put a blank line before a block comment.
+  if ((b_range.begin().line_number() > a_end + 1) || b->AsBlockComment()) {
+    return true;
+  }
+
+  const FunctionCallNode* func_call = b->AsFunctionCall();
+  // We have several types of function call nodes with blocks:
+  // * Target-like builtins (eg. static_library, config, toolchain)
+  // * Template invocations
+  // * tool
+  // * declare_args
+  // * foreach
+  // All of these except foreach should enforce a blank line before them.
+  return func_call && func_call->block() &&
+         func_call->function().value() != "foreach";
 }
 
 int Printer::CurrentColumn() const {
diff --git a/src/gn/edit_command_unittest.cc b/src/gn/edit_command_unittest.cc
index 9467e92..ff16d3b 100644
--- a/src/gn/edit_command_unittest.cc
+++ b/src/gn/edit_command_unittest.cc
@@ -114,6 +114,7 @@
 executable("foo") {
   testonly = true
 }
+
 executable("bar") {
   testonly = false
 }
@@ -306,6 +307,7 @@
 executable("foo") {
   sources = [ "foo.cc" ]
 }
+
 source_set("bar") {
 }
 )"));
@@ -320,6 +322,7 @@
                  Edited(R"(
 source_set("bar") {
 }
+
 executable("foo") {
   sources = [ "foo.cc" ]
 }
@@ -340,6 +343,7 @@
 executable("foo") {
   sources = [ "foo.cc" ]
 }
+
 source_set("bar") {
 }
 
@@ -363,8 +367,10 @@
 executable("foo") {
   sources = [ "foo.cc" ]
 }
+
 source_set("bar") {
 }
+
 source_set("qux") {
 }
 
diff --git a/src/gn/format_test_data/072.golden b/src/gn/format_test_data/072.golden
index b4e5a4b..01787c6 100644
--- a/src/gn/format_test_data/072.golden
+++ b/src/gn/format_test_data/072.golden
@@ -4,6 +4,7 @@
 import("d")
 
 import("z")
+
 declare_args() {
 }
 
diff --git a/src/gn/format_test_data/073.golden b/src/gn/format_test_data/073.golden
index e32977b..9dd168f 100644
--- a/src/gn/format_test_data/073.golden
+++ b/src/gn/format_test_data/073.golden
@@ -21,6 +21,7 @@
     }
 
     import("d")
+
     template("wee") {
       import("5")
       import("6")