More accurate swift attr handling

Swift copts map to OTHER_SWIFT_FLAGS and SWIFT_INCLUDE_PATHS.

PiperOrigin-RevId: 189069646
diff --git a/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl b/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
index 4626de8..92b76a9 100644
--- a/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
+++ b/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
@@ -608,11 +608,15 @@
                       _collect_asset_catalogs(rule_attr) +
                       _collect_bundle_imports(rule_attr))
 
+  copts_attr = _get_opt_attr(rule_attr, 'copts')
+  is_swift = target_kind == 'swift_library'
+
   # Keys for attribute and inheritable_attributes keys must be kept in sync
   # with defines in Tulsi's RuleEntry.
   attributes = _dict_omitting_none(
       binary=_get_label_attr(binary_rule, 'label'),
-      copts=_get_opt_attr(rule_attr, 'copts'),
+      copts=None if is_swift else copts_attr,
+      swiftc_opts=copts_attr if is_swift else None,
       datamodels=_collect_xcdatamodeld_files(rule_attr, 'datamodels'),
       supporting_files=supporting_files,
       xctest_app=_get_label_attr(rule_attr, 'xctest_app.label'),
diff --git a/src/TulsiGenerator/PBXTargetGenerator.swift b/src/TulsiGenerator/PBXTargetGenerator.swift
index bdf41e5..df769c1 100644
--- a/src/TulsiGenerator/PBXTargetGenerator.swift
+++ b/src/TulsiGenerator/PBXTargetGenerator.swift
@@ -550,7 +550,13 @@
       var localPreprocessorDefines = defines
       let localIncludes = includes.mutableCopy() as! NSMutableOrderedSet
       let otherCFlags = NSMutableOrderedSet()
-      addLocalSettings(ruleEntry, localDefines: &localPreprocessorDefines, localIncludes: localIncludes, otherCFlags: otherCFlags)
+      let swiftIncludePaths = NSMutableOrderedSet()
+      let otherSwiftFlags = NSMutableOrderedSet()
+      addLocalSettings(ruleEntry, localDefines: &localPreprocessorDefines, localIncludes: localIncludes,
+                       otherCFlags: otherCFlags, swiftIncludePaths: swiftIncludePaths, otherSwiftFlags: otherSwiftFlags)
+
+      addOtherSwiftFlags(ruleEntry, toSet: otherSwiftFlags)
+      addSwiftIncludes(ruleEntry, toSet: swiftIncludePaths)
 
       let pchFile = BazelFileInfo(info: ruleEntry.attributes[.pch])
       if let pchFile = pchFile, includeFileInProject(pchFile) {
@@ -592,12 +598,6 @@
         var resolvedIncludes = localIncludes.array as! [String]
         resolvedIncludes.append("$(\(PBXTargetGenerator.BazelWorkspaceSymlinkVarName))/tools/cpp/gcc3")
 
-        let swiftIncludePaths = NSMutableOrderedSet()
-        addSwiftIncludes(ruleEntry, toSet: swiftIncludePaths)
-
-        let otherSwiftFlags = NSMutableOrderedSet()
-        addOtherSwiftFlags(ruleEntry, toSet: otherSwiftFlags)
-
         let deploymentTarget: DeploymentTarget
         if let ruleDeploymentTarget = ruleEntry.deploymentTarget {
           deploymentTarget = ruleDeploymentTarget
@@ -1202,7 +1202,22 @@
   private func addLocalSettings(_ ruleEntry: RuleEntry,
                                 localDefines: inout Set<String>,
                                 localIncludes: NSMutableOrderedSet,
-                                otherCFlags: NSMutableOrderedSet) {
+                                otherCFlags: NSMutableOrderedSet,
+                                swiftIncludePaths: NSMutableOrderedSet,
+                                otherSwiftFlags: NSMutableOrderedSet) {
+    if let swiftc_opts = ruleEntry.attributes[.swiftc_opts] as? [String], !swiftc_opts.isEmpty {
+      for opt in swiftc_opts {
+        if opt.hasPrefix("-I") {
+          var path = opt.substring(from: opt.index(opt.startIndex, offsetBy: 2))
+          if !path.hasPrefix("/") {
+            path = "$(\(PBXTargetGenerator.BazelWorkspaceSymlinkVarName))/\(path)"
+          }
+          swiftIncludePaths.add(path)
+        } else {
+          otherSwiftFlags.add(opt)
+        }
+      }
+    }
     guard let copts = ruleEntry.attributes[.copts] as? [String], !copts.isEmpty else {
       return
     }
@@ -1255,7 +1270,9 @@
 
     includes.add("$(\(PBXTargetGenerator.BazelWorkspaceSymlinkVarName))/tools/cpp/gcc3")
     addIncludes(ruleEntry, toSet: includes)
-    addLocalSettings(ruleEntry, localDefines: &defines, localIncludes: includes, otherCFlags: NSMutableOrderedSet())
+    addLocalSettings(ruleEntry, localDefines: &defines, localIncludes: includes,
+                     otherCFlags: NSMutableOrderedSet(), swiftIncludePaths: NSMutableOrderedSet(),
+                     otherSwiftFlags: NSMutableOrderedSet())
     addSwiftIncludes(ruleEntry, toSet: swiftIncludePaths)
     addOtherSwiftFlags(ruleEntry, toSet: otherSwiftFlags)
 
diff --git a/src/TulsiGenerator/RuleEntry.swift b/src/TulsiGenerator/RuleEntry.swift
index 2b1f87e..edb88b3 100644
--- a/src/TulsiGenerator/RuleEntry.swift
+++ b/src/TulsiGenerator/RuleEntry.swift
@@ -159,6 +159,7 @@
     case pch
     case swift_language_version
     case swift_toolchain
+    case swiftc_opts
     // Contains various files that are used as part of the build process but need no special
     // handling in the generated Xcode project. For example, asset_catalog, storyboard, and xibs
     // attributes all end up as supporting_files.
diff --git a/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/SwiftProject.xcodeproj/project.pbxproj b/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/SwiftProject.xcodeproj/project.pbxproj
index dbaaaf1..dd813c9 100644
--- a/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/SwiftProject.xcodeproj/project.pbxproj
+++ b/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/SwiftProject.xcodeproj/project.pbxproj
@@ -384,7 +384,7 @@
 				GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
 				HEADER_SEARCH_PATHS = "$(inherited) $(TULSI_BWRS)/tools/cpp/gcc3 ";
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
-				OTHER_CFLAGS = "-swift-version 3";
+				OTHER_SWIFT_FLAGS = "$(inherited) -swift-version 3";
 				PRODUCT_NAME = _idx_SwiftLibraryV3_56AA3A57_ios_min8.0;
 				SDKROOT = iphoneos;
 				SWIFT_INCLUDE_PATHS = "$(inherited) $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_swift/SwiftLibraryV3/_objs";
@@ -397,7 +397,7 @@
 				GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
 				HEADER_SEARCH_PATHS = "$(inherited) $(TULSI_BWRS)/tools/cpp/gcc3 ";
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
-				OTHER_CFLAGS = "-swift-version 4";
+				OTHER_SWIFT_FLAGS = "$(inherited) -swift-version 4";
 				PRODUCT_NAME = _idx_SwiftLibraryV4_56AA3A59_ios_min8.0;
 				SDKROOT = iphoneos;
 				SWIFT_INCLUDE_PATHS = "$(inherited) $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_swift/SwiftLibraryV4/_objs";
@@ -477,7 +477,7 @@
 				GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1";
 				HEADER_SEARCH_PATHS = "$(inherited) $(TULSI_BWRS)/tools/cpp/gcc3 ";
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
-				OTHER_CFLAGS = "-swift-version 3";
+				OTHER_SWIFT_FLAGS = "$(inherited) -swift-version 3";
 				PRODUCT_NAME = _idx_SwiftLibraryV3_56AA3A57_ios_min8.0;
 				SDKROOT = iphoneos;
 				SWIFT_INCLUDE_PATHS = "$(inherited) $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_swift/SwiftLibraryV3/_objs";
@@ -490,7 +490,7 @@
 				GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1";
 				HEADER_SEARCH_PATHS = "$(inherited) $(TULSI_BWRS)/tools/cpp/gcc3 ";
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
-				OTHER_CFLAGS = "-swift-version 4";
+				OTHER_SWIFT_FLAGS = "$(inherited) -swift-version 4";
 				PRODUCT_NAME = _idx_SwiftLibraryV4_56AA3A59_ios_min8.0;
 				SDKROOT = iphoneos;
 				SWIFT_INCLUDE_PATHS = "$(inherited) $(TULSI_BWRS)/_tulsi-includes/x/x/tulsi_e2e_swift/SwiftLibraryV4/_objs";
diff --git a/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift b/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
index e363bc0..2194f7c 100644
--- a/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
+++ b/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
@@ -2607,6 +2607,35 @@
     assertTarget(expectedTarget, inTargets: targets)
   }
 
+  func testSwiftTargetIndexerCompilerFlags() {
+    let package = "test/package"
+
+    let swiftTargetName = "SwiftTarget"
+    let swiftTargetBuildLabel = BuildLabel("\(package):\(swiftTargetName)")
+    let swiftTargetOpts = ["-I/include/foobar",  "-DCOMPILER_DEFINE"] as AnyObject
+
+    let swiftLibraryRule = makeTestRuleEntry(swiftTargetBuildLabel,
+                                             type: "swift_library",
+                                             attributes: ["swiftc_opts": swiftTargetOpts],
+                                             sourceFiles: sourceFileNames)
+
+    var proccessedEntries = [RuleEntry: (NSOrderedSet)]()
+    let indexerTargetName = String(format: "_idx_\(swiftTargetName)_%08X_ios_min9.0", swiftTargetBuildLabel.hashValue)
+    targetGenerator.registerRuleEntryForIndexer(swiftLibraryRule,
+                                                ruleEntryMap: RuleEntryMap(),
+                                                pathFilters: pathFilters,
+                                                processedEntries: &proccessedEntries)
+    targetGenerator.generateIndexerTargets()
+
+    let targets = project.targetByName
+    XCTAssertEqual(targets.count, 1)
+    validateIndexerTarget(indexerTargetName,
+                          sourceFileNames: sourceFileNames,
+                          swiftIncludePaths: "$(inherited) /include/foobar",
+                          otherSwiftFlags: "$(inherited) -DCOMPILER_DEFINE",
+                          inTargets: targets)
+  }
+
   // MARK: - Helper methods
 
   private func debugBuildSettingsFromSettings(_ settings: [String: String]) -> [String: String] {
@@ -2877,6 +2906,8 @@
                                      pchFile: PBXFileReference? = nil,
                                      bridgingHeader: String? = nil,
                                      swiftLanguageVersion: String? = nil,
+                                     swiftIncludePaths: String? = nil,
+                                     otherSwiftFlags: String? = nil,
                                      inTargets targets: Dictionary<String, PBXTarget> = Dictionary<String, PBXTarget>(),
                                      line: UInt = #line) {
     var expectedBuildSettings = [
@@ -2885,15 +2916,21 @@
         "SDKROOT": "iphoneos",
         "IPHONEOS_DEPLOYMENT_TARGET": "9.0",
     ]
-    if pchFile != nil {
-      expectedBuildSettings["GCC_PREFIX_HEADER"] = "$(TULSI_BWRS)/\(pchFile!.path!)"
+    if let pchFile = pchFile {
+      expectedBuildSettings["GCC_PREFIX_HEADER"] = "$(TULSI_BWRS)/\(pchFile.path!)"
     }
-    if bridgingHeader != nil {
-        expectedBuildSettings["SWIFT_OBJC_BRIDGING_HEADER"] = bridgingHeader!
+    if let bridgingHeader = bridgingHeader {
+      expectedBuildSettings["SWIFT_OBJC_BRIDGING_HEADER"] = bridgingHeader
     }
     if let swiftLanguageVersion = swiftLanguageVersion {
       expectedBuildSettings["SWIFT_VERSION"] = swiftLanguageVersion
     }
+    if let swiftIncludePaths = swiftIncludePaths {
+      expectedBuildSettings["SWIFT_INCLUDE_PATHS"] = swiftIncludePaths
+    }
+    if let otherSwiftFlags = otherSwiftFlags {
+      expectedBuildSettings["OTHER_SWIFT_FLAGS"] = otherSwiftFlags
+    }
 
     var expectedBuildPhases = [BuildPhaseDefinition]()
     if sourceFileNames != nil {