[swift] Consider swift bridge_header as a source file

The target that builds .swift files may use an optional bridge header.
This header is used to import Objective-C types in Swift when modules
are not used (which Chromium currently does not support).

As this header may include any file from the project, it needs to be
considered as a source file (it cannot be listed in sources directly
as mixed languages is not supported for .swift files).

This fixes `gn check` for the target that uses .swift with a bridge
header (which happens in Chromium).

Bug: 305
Change-Id: Iac64c88258302b4f39d8feafc5eb020cfea8efa8
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/14660
Commit-Queue: Sylvain Defresne <sdefresne@chromium.org>
Reviewed-by: Takuto Ikuta <tikuta@google.com>
diff --git a/src/gn/header_checker.cc b/src/gn/header_checker.cc
index 8d2d313..7bad781 100644
--- a/src/gn/header_checker.cc
+++ b/src/gn/header_checker.cc
@@ -214,6 +214,16 @@
     files_to_public[source].is_public = default_public;
   }
 
+  // If the target includes some .swift files, it may also use a header file
+  // to provide bridging Objective-C code. This header needs to be considered
+  // as a source file with the default visibility.
+  if (target->has_swift_values()) {
+    const SourceFile& bridge_header = target->swift_values().bridge_header();
+    if (!bridge_header.is_null()) {
+      files_to_public[bridge_header].is_public = default_public;
+    }
+  }
+
   // Add in the public files, forcing them to public. This may overwrite some
   // entries, and it may add new ones.
   if (default_public)  // List only used when default is not public.
diff --git a/src/gn/header_checker.h b/src/gn/header_checker.h
index d4d2f9f..55c9259 100644
--- a/src/gn/header_checker.h
+++ b/src/gn/header_checker.h
@@ -77,6 +77,8 @@
   FRIEND_TEST_ALL_PREFIXES(HeaderCheckerTest, SourceFileForInclude);
   FRIEND_TEST_ALL_PREFIXES(HeaderCheckerTest,
                            SourceFileForInclude_FileNotFound);
+  FRIEND_TEST_ALL_PREFIXES(HeaderCheckerTest,
+                           SourceFileForInclude_SwiftBridgeHeader);
   FRIEND_TEST_ALL_PREFIXES(HeaderCheckerTest, Friend);
 
   ~HeaderChecker();
diff --git a/src/gn/header_checker_unittest.cc b/src/gn/header_checker_unittest.cc
index a290d45..2a168fd 100644
--- a/src/gn/header_checker_unittest.cc
+++ b/src/gn/header_checker_unittest.cc
@@ -391,6 +391,16 @@
   EXPECT_FALSE(err.has_error());
 }
 
+TEST_F(HeaderCheckerTest, SourceFileForInclude_SwiftBridgeHeader) {
+  const SourceFile bridge_header("//a/bridge_header.h");
+  a_.swift_values().bridge_header() = bridge_header;
+  auto checker = CreateChecker();
+
+  HeaderChecker::FileMap file_map;
+  checker->AddTargetToFileMap(&a_, &file_map);
+  EXPECT_NE(file_map.find(bridge_header), file_map.end());
+}
+
 TEST_F(HeaderCheckerTest, Friend) {
   // Note: we have a public dependency chain A -> B -> C set up already.
   InputFile input_file(SourceFile("//some_file.cc"));