Consider application bundle as executable for phony targets

When generating phony short names for target, consider that targets
creating bundle with type "com.apple.product-type.application" as
executables.

This will help ensure that when targeting the iOS platform, it is
possible to build the application bundle using their short name
even if some third-party dependency use the same name.

Recently building Chrome on iOS from the command-line using
`ninja -C out/Debug chrome` was broken for the second time due
to a change in perfetto adding a target named "chrome".

Note that on iOS it is not possible to run an executable that is
not in an application bundle, so the rule that prefer executable
target was not working there.

Bug: chromium:1383100
Change-Id: Iab62336fa37db8fab0dc84affa2cfab65e0e60f9
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/14920
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: Brett Wilson <brettw@chromium.org>
diff --git a/docs/reference.md b/docs/reference.md
index 09417a5..9fb18db 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -7799,6 +7799,10 @@
        short name. Use "ninja doom_melon" to compile the
        "//tools/fruit:doom_melon" executable.
 
+       Note that for Apple platforms, create_bundle targets with a product_type
+       of "com.apple.product-type.application" are considered as executable
+       for this rule (as they define application bundles).
+
     5. The short names of all targets if there is only one target with that
        short name.
 
diff --git a/src/gn/bundle_data.h b/src/gn/bundle_data.h
index 527e078..5b3bca6 100644
--- a/src/gn/bundle_data.h
+++ b/src/gn/bundle_data.h
@@ -162,6 +162,11 @@
   // Recursive collection of all bundle_data that the target depends on.
   const UniqueTargets& bundle_deps() const { return bundle_deps_; }
 
+  // Returns whether the bundle is an application bundle.
+  bool is_application() const {
+    return product_type_ == "com.apple.product-type.application";
+  }
+
   // Returns whether the bundle is a framework bundle.
   bool is_framework() const {
     return product_type_ == "com.apple.product-type.framework";
diff --git a/src/gn/ninja_build_writer.cc b/src/gn/ninja_build_writer.cc
index eb135ea..e39e559 100644
--- a/src/gn/ninja_build_writer.cc
+++ b/src/gn/ninja_build_writer.cc
@@ -487,6 +487,10 @@
        short name. Use "ninja doom_melon" to compile the
        "//tools/fruit:doom_melon" executable.
 
+       Note that for Apple platforms, create_bundle targets with a product_type
+       of "com.apple.product-type.application" are considered as executable
+       for this rule (as they define application bundles).
+
     5. The short names of all targets if there is only one target with that
        short name.
 
@@ -550,6 +554,13 @@
       exes_counts.last_seen = target;
     }
 
+    if (target->output_type() == Target::CREATE_BUNDLE &&
+        target->bundle_data().is_application()) {
+      Counts& exes_counts = exes[short_name];
+      exes_counts.count++;
+      exes_counts.last_seen = target;
+    }
+
     // Find targets in "important" directories.
     const std::string& dir_string = label.dir().value();
     if (dir_string.size() == 2 && dir_string[0] == '/' &&