Propagate Swift module name for simple test targets

This allows simple test targets (those with only a single `swift_library`
dependency) to support running individual tests in Xcode.

Xcode uses the PRODUCT_MODULE_NAME setting to filter which tests to run
during execution. Since the PRODUCT_MODULE_NAME was previously set to the
name of the test target rather than the name of the library target, the
filter would be invalid and no tests would execute.

PiperOrigin-RevId: 212869062
diff --git a/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl b/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
index ce1b467..f43833c 100644
--- a/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
+++ b/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
@@ -798,10 +798,12 @@
         swift_transitive_modules = _depset_to_file_metadata_list(provider.swift_modules)
         objc_module_maps = _depset_to_file_metadata_list(provider.module_maps)
         test_deps = provider.deps.to_list()
+        module_name = provider.module_name
     else:
         swift_transitive_modules = swift_transitive_modules.to_list()
         objc_module_maps = objc_module_maps.to_list()
         test_deps = None
+        module_name = None
 
     info = _struct_omitting_none(
         artifacts = artifacts,
@@ -825,6 +827,7 @@
         srcs = srcs,
         swift_transitive_modules = swift_transitive_modules,
         objc_module_maps = objc_module_maps,
+        module_name = module_name,
         type = target_kind,
         infoplist = infoplist.basename if infoplist else None,
         platform_type = platform_type,
diff --git a/src/TulsiGenerator/BazelAspectInfoExtractor.swift b/src/TulsiGenerator/BazelAspectInfoExtractor.swift
index 3486ba4..31e4500 100644
--- a/src/TulsiGenerator/BazelAspectInfoExtractor.swift
+++ b/src/TulsiGenerator/BazelAspectInfoExtractor.swift
@@ -346,6 +346,7 @@
       let swiftToolchain = dict["swift_toolchain"] as? String
       let swiftTransitiveModules = MakeBazelFileInfos("swift_transitive_modules")
       let objCModuleMaps = MakeBazelFileInfos("objc_module_maps")
+      let moduleName = dict["module_name"] as? String
       let extensions: Set<BuildLabel>?
       if let extensionList = dict["extensions"] as? [String] {
         extensions = Set(extensionList.map({ BuildLabel($0) }))
@@ -415,6 +416,7 @@
                                 swiftToolchain: swiftToolchain,
                                 swiftTransitiveModules: swiftTransitiveModules,
                                 objCModuleMaps: objCModuleMaps,
+                                moduleName: moduleName,
                                 extensionType: extensionType,
                                 xcodeVersion: xcodeVersion)
       progressNotifier?.incrementValue()
diff --git a/src/TulsiGenerator/PBXTargetGenerator.swift b/src/TulsiGenerator/PBXTargetGenerator.swift
index 46ffcd6..092d4ac 100644
--- a/src/TulsiGenerator/PBXTargetGenerator.swift
+++ b/src/TulsiGenerator/PBXTargetGenerator.swift
@@ -1329,6 +1329,10 @@
       testSettings["OTHER_SWIFT_FLAGS"] = "$(inherited) " + otherSwiftFlagsArr.joined(separator: " ")
     }
 
+    if let moduleName = ruleEntry.moduleName {
+      testSettings["PRODUCT_MODULE_NAME"] = moduleName
+    }
+
     return testSettings
   }
 
diff --git a/src/TulsiGenerator/RuleEntry.swift b/src/TulsiGenerator/RuleEntry.swift
index 48c7fce..7a0fb57 100644
--- a/src/TulsiGenerator/RuleEntry.swift
+++ b/src/TulsiGenerator/RuleEntry.swift
@@ -221,6 +221,9 @@
   /// List containing the transitive ObjC modulemaps on which this rule depends.
   public let objCModuleMaps: [BazelFileInfo]
 
+  /// Module name to use in Xcode instead of the default.
+  public let moduleName: String?
+
   /// The deployment platform target for this target.
   public let deploymentTarget: DeploymentTarget?
 
@@ -343,6 +346,7 @@
        swiftToolchain: String? = nil,
        swiftTransitiveModules: [BazelFileInfo] = [],
        objCModuleMaps: [BazelFileInfo] = [],
+       moduleName: String? = nil,
        extensionType: String? = nil,
        xcodeVersion: String? = nil) {
 
@@ -390,6 +394,7 @@
     self.deploymentTarget = deploymentTarget
     self.buildFilePath = buildFilePath
     self.objcDefines = objcDefines
+    self.moduleName = moduleName
     self.swiftDefines = swiftDefines
     self.includePaths = includePaths
     self.swiftLanguageVersion = swiftLanguageVersion
@@ -460,6 +465,7 @@
                    swiftToolchain: String? = nil,
                    swiftTransitiveModules: [BazelFileInfo] = [],
                    objCModuleMaps: [BazelFileInfo] = [],
+                   moduleName: String? = nil,
                    extensionType: String? = nil,
                    xcodeVersion: String? = nil) {
     self.init(label: BuildLabel(label),
@@ -488,6 +494,7 @@
               swiftToolchain: swiftToolchain,
               swiftTransitiveModules: swiftTransitiveModules,
               objCModuleMaps: objCModuleMaps,
+              moduleName: moduleName,
               extensionType: extensionType,
               xcodeVersion: xcodeVersion)
   }