[xcode] Fix detection of XCTests by Xcode 12.0+

For Xcode to detect the XCTests automatically in a project, the
source files used by the tests needs to be listed in the project.
However, if the files are listed, then Xcode tries to build them.

With version of Xcode prior to 12.0, the project was configured
so that Xcode would do nothing while trying to compile them (by
passing `--help` flag to the compiler). This stopped working with
Xcode 12.0 which started to expect the compilation to produce
some output.

Instead of configuring the compilation to be a no-op, instead
configure Xcode so that those files are not compiled by setting
a pattern matching all files for "Excluded Source File Names".
This works with all version of Xcode and both "legacy" and "new"
build system.

Bug: chromium:1103230
Change-Id: I44eb0df32ca9c8d57b2dc5b378878c5eb308bf38
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/11162
Reviewed-by: Justin Cohen <justincohen@google.com>
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: Sylvain Defresne <sdefresne@chromium.org>
diff --git a/src/gn/xcode_object.cc b/src/gn/xcode_object.cc
index b56f6a9..0761b4f 100644
--- a/src/gn/xcode_object.cc
+++ b/src/gn/xcode_object.cc
@@ -192,18 +192,6 @@
   out << value->Reference();
 }
 
-void PrintValue(std::ostream& out, IndentRules rules, CompilerFlags flags) {
-  out << "{COMPILER_FLAGS = \"";
-  switch (flags) {
-    case CompilerFlags::HELP:
-      out << "--help";
-      break;
-    case CompilerFlags::NONE:
-      break;
-  }
-  out << "\"; }";
-}
-
 template <typename ObjectClass>
 void PrintValue(std::ostream& out,
                 IndentRules rules,
@@ -463,11 +451,8 @@
 // PBXBuildFile ---------------------------------------------------------------
 
 PBXBuildFile::PBXBuildFile(const PBXFileReference* file_reference,
-                           const PBXBuildPhase* build_phase,
-                           const CompilerFlags compiler_flag)
-    : file_reference_(file_reference),
-      build_phase_(build_phase),
-      compiler_flag_(compiler_flag) {
+                           const PBXBuildPhase* build_phase)
+    : file_reference_(file_reference), build_phase_(build_phase) {
   DCHECK(file_reference_);
   DCHECK(build_phase_);
 }
@@ -488,9 +473,6 @@
   out << indent_str << Reference() << " = {";
   PrintProperty(out, rules, "isa", ToString(Class()));
   PrintProperty(out, rules, "fileRef", file_reference_);
-  if (compiler_flag_ != CompilerFlags::NONE) {
-    PrintProperty(out, rules, "settings", compiler_flag_);
-  }
   out << "};\n";
 }
 
@@ -731,15 +713,15 @@
 
 void PBXNativeTarget::AddResourceFile(const PBXFileReference* file_reference) {
   DCHECK(file_reference);
-  resource_build_phase_->AddBuildFile(std::make_unique<PBXBuildFile>(
-      file_reference, resource_build_phase_, CompilerFlags::NONE));
+  resource_build_phase_->AddBuildFile(
+      std::make_unique<PBXBuildFile>(file_reference, resource_build_phase_));
 }
 
-void PBXNativeTarget::AddFileForIndexing(const PBXFileReference* file_reference,
-                                         const CompilerFlags compiler_flag) {
+void PBXNativeTarget::AddFileForIndexing(
+    const PBXFileReference* file_reference) {
   DCHECK(file_reference);
-  source_build_phase_->AddBuildFile(std::make_unique<PBXBuildFile>(
-      file_reference, source_build_phase_, compiler_flag));
+  source_build_phase_->AddBuildFile(
+      std::make_unique<PBXBuildFile>(file_reference, source_build_phase_));
 }
 
 PBXObjectClass PBXNativeTarget::Class() const {
@@ -785,18 +767,15 @@
 
 void PBXProject::AddSourceFileToIndexingTarget(
     const std::string& navigator_path,
-    const std::string& source_path,
-    const CompilerFlags compiler_flag) {
+    const std::string& source_path) {
   if (!target_for_indexing_) {
     AddIndexingTarget();
   }
-  AddSourceFile(navigator_path, source_path, compiler_flag,
-                target_for_indexing_);
+  AddSourceFile(navigator_path, source_path, target_for_indexing_);
 }
 
 void PBXProject::AddSourceFile(const std::string& navigator_path,
                                const std::string& source_path,
-                               const CompilerFlags compiler_flag,
                                PBXNativeTarget* target) {
   PBXFileReference* file_reference =
       sources_->AddSourceFile(navigator_path, source_path);
@@ -805,7 +784,7 @@
     return;
 
   DCHECK(target);
-  target->AddFileForIndexing(file_reference, compiler_flag);
+  target->AddFileForIndexing(file_reference);
 }
 
 void PBXProject::AddAggregateTarget(const std::string& name,
@@ -870,6 +849,7 @@
   attributes["CODE_SIGNING_REQUIRED"] = "NO";
   attributes["CONFIGURATION_BUILD_DIR"] = output_dir;
   attributes["PRODUCT_NAME"] = product_name;
+  attributes["EXCLUDED_SOURCE_FILE_NAMES"] = "*.*";
 
   targets_.push_back(std::make_unique<PBXNativeTarget>(
       name, shell_script, config_name_, attributes, output_type, product_name,
diff --git a/src/gn/xcode_object.h b/src/gn/xcode_object.h
index 78bdc92..82dec5e 100644
--- a/src/gn/xcode_object.h
+++ b/src/gn/xcode_object.h
@@ -23,11 +23,6 @@
 // https://chromium.googlesource.com/external/gyp/+/master/pylib/gyp/xcodeproj_file.py
 // for more information on Xcode project file format.
 
-enum class CompilerFlags {
-  NONE,
-  HELP,
-};
-
 // PBXObjectClass -------------------------------------------------------------
 
 enum PBXObjectClass {
@@ -193,8 +188,7 @@
 class PBXBuildFile : public PBXObject {
  public:
   PBXBuildFile(const PBXFileReference* file_reference,
-               const PBXBuildPhase* build_phase,
-               const CompilerFlags compiler_flag);
+               const PBXBuildPhase* build_phase);
   ~PBXBuildFile() override;
 
   // PBXObject implementation.
@@ -205,7 +199,6 @@
  private:
   const PBXFileReference* file_reference_ = nullptr;
   const PBXBuildPhase* build_phase_ = nullptr;
-  const CompilerFlags compiler_flag_;
 
   DISALLOW_COPY_AND_ASSIGN(PBXBuildFile);
 };
@@ -329,8 +322,7 @@
 
   void AddResourceFile(const PBXFileReference* file_reference);
 
-  void AddFileForIndexing(const PBXFileReference* file_reference,
-                          const CompilerFlags compiler_flag);
+  void AddFileForIndexing(const PBXFileReference* file_reference);
 
   // PBXObject implementation.
   PBXObjectClass Class() const override;
@@ -355,11 +347,9 @@
   ~PBXProject() override;
 
   void AddSourceFileToIndexingTarget(const std::string& navigator_path,
-                                     const std::string& source_path,
-                                     const CompilerFlags compiler_flag);
+                                     const std::string& source_path);
   void AddSourceFile(const std::string& navigator_path,
                      const std::string& source_path,
-                     const CompilerFlags compiler_flag,
                      PBXNativeTarget* target);
   void AddAggregateTarget(const std::string& name,
                           const std::string& shell_script);
diff --git a/src/gn/xcode_object_unittest.cc b/src/gn/xcode_object_unittest.cc
index 70a14df..0498c3f 100644
--- a/src/gn/xcode_object_unittest.cc
+++ b/src/gn/xcode_object_unittest.cc
@@ -54,7 +54,7 @@
     const PBXFileReference* file_reference,
     const PBXSourcesBuildPhase* build_phase) {
   std::unique_ptr<PBXBuildFile> pbx_build_file(
-      new PBXBuildFile(file_reference, build_phase, CompilerFlags::NONE));
+      new PBXBuildFile(file_reference, build_phase));
   return pbx_build_file;
 }
 
diff --git a/src/gn/xcode_writer.cc b/src/gn/xcode_writer.cc
index 44f0c25..a5650fa 100644
--- a/src/gn/xcode_writer.cc
+++ b/src/gn/xcode_writer.cc
@@ -37,8 +37,6 @@
 #include "gn/variables.h"
 #include "gn/xcode_object.h"
 
-#include <iostream>
-
 namespace {
 
 // This is the template of the script used to build the target. It invokes
@@ -101,10 +99,7 @@
 };
 
 const char* kXCTestFileSuffixes[] = {
-    "egtest.m",
-    "egtest.mm",
-    "xctest.m",
-    "xctest.mm",
+    "egtest.m", "egtest.mm", "xctest.m", "xctest.mm", "UITests.m", "UITests.mm",
 };
 
 const char kXCTestModuleTargetNamePostfix[] = "_module";
@@ -305,15 +300,9 @@
                                       SourceDir source_dir,
                                       const BuildSettings* build_settings) {
   for (const SourceFile& source : sources) {
-    std::string source_path = RebasePath(source.value(), source_dir,
-                                         build_settings->root_path_utf8());
-
-    // Test files need to be known to Xcode for proper indexing and for
-    // discovery of tests function for XCTest and XCUITest, but the compilation
-    // is done via ninja and thus must prevent Xcode from compiling the files by
-    // adding '-help' as per file compiler flag.
-    project->AddSourceFile(source_path, source_path, CompilerFlags::HELP,
-                           native_target);
+    const std::string source_path = RebasePath(
+        source.value(), source_dir, build_settings->root_path_utf8());
+    project->AddSourceFile(source_path, source_path, native_target);
   }
 }
 
@@ -700,8 +689,7 @@
   for (const SourceFile& source : sorted_sources) {
     const std::string source_file = RebasePath(
         source.value(), source_dir, build_settings_->root_path_utf8());
-    project_.AddSourceFileToIndexingTarget(source_file, source_file,
-                                           CompilerFlags::NONE);
+    project_.AddSourceFileToIndexingTarget(source_file, source_file);
   }
 
   return true;
@@ -776,12 +764,6 @@
 bool XcodeProject::AddCXTestSourceFilesForTestModuleTargets(
     const std::map<const Target*, PBXNativeTarget*>& bundle_targets,
     Err* err) {
-  // With the New Build System, the hack of calling clang with --help to get
-  // Xcode to see and parse the file without building them no longer work so
-  // disable it for the moment. See https://crbug.com/1103230 for details.
-  if (options_.build_system == XcodeBuildSystem::kNew)
-    return true;
-
   const SourceDir source_dir("//");
 
   // Needs to search for xctest files under the application targets, and this