Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2021,8 +2021,18 @@ package final class SourcesTaskProducer: FilesBasedBuildPhaseTaskProducerBase, F
private func generatePackageTargetBundleAccessorForSwift(_ scope: MacroEvaluationScope, bundleName: String) async -> GeneratedSourceCodeResult {
let filePath = scope.evaluate(BuiltinMacros.DERIVED_SOURCES_DIR).join("resource_bundle_accessor.swift")

// Emit an explicit access level on imports if access-level-on-import is part of the language mode (>= 6.0).
// Without this, targets that use access levels on imports will fail to compile.
let importPrefix: String = {
guard let swiftVersion = try? Version(scope.evaluate(BuiltinMacros.SWIFT_VERSION)),
swiftVersion >= Version(6) else {
return ""
}
return "public "
}()

let contents = bundleName.isEmpty ? """
import class Foundation.Bundle
\(importPrefix)import class Foundation.Bundle

extension Foundation.Bundle {
static let module = {
Expand All @@ -2031,9 +2041,9 @@ package final class SourcesTaskProducer: FilesBasedBuildPhaseTaskProducerBase, F
}()
}
""" : """
import class Foundation.Bundle
import class Foundation.ProcessInfo
import struct Foundation.URL
\(importPrefix)import class Foundation.Bundle
\(importPrefix)import class Foundation.ProcessInfo
\(importPrefix)import struct Foundation.URL

private class BundleFinder {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,9 @@ fileprivate struct PackageProductConstructionTests: CoreBasedTests {
results.checkWriteAuxiliaryFileTask(.matchTarget(target), .matchRuleType("WriteAuxiliaryFile"), .matchRuleItemBasename("resource_bundle_accessor.swift")) { task, contents in
XCTAssertMatch(contents.unsafeStringValue, .contains("static nonisolated let module: Bundle"))
XCTAssertMatch(contents.unsafeStringValue, .contains("let bundleName = \"tool_resources\""))
// For SWIFT_VERSION < 6.0, access-level-on-import is not part of the language mode.
// Imports in the generated file must not specify an access level in this case.
XCTAssertMatch(contents.unsafeStringValue, (.regex(#/^import class Foundation\.Bundle/#)))
}
}

Expand Down Expand Up @@ -1129,6 +1132,58 @@ fileprivate struct PackageProductConstructionTests: CoreBasedTests {
}
}

/// For SWIFT_VERSION >= 6.0, access-level-on-import is part of the language mode.
/// If any source file in the target uses an access level on an import, then
/// every import in the module must specify an access level, including imports
/// in generated files.
@Test(.requireSDKs(.macOS))
func resourceBundleAccessorEmitsAccessLevelImportForSwift6() async throws {
let testProject = try await TestPackageProject(
"aProject",
groupTree: TestGroup(
"SomeFiles",
children: [
TestFile("main.swift"),
]),
buildConfigurations: [
TestBuildConfiguration("Debug", buildSettings: [
"SWIFT_EXEC": swiftCompilerPath.str,
"SWIFT_VERSION": "6",
"GENERATE_INFOPLIST_FILE": "YES",
"PRODUCT_NAME": "$(TARGET_NAME)",
"GENERATE_RESOURCE_ACCESSORS": "YES",
"USE_HEADERMAP": "NO",
]),
],
targets: [
TestStandardTarget(
"tool", type: .application,
buildConfigurations: [
TestBuildConfiguration("Debug", buildSettings: [
"PRODUCT_NAME": "$(TARGET_NAME)",
"USE_HEADERMAP": "NO",
"DEFINES_MODULE": "YES",
"PACKAGE_RESOURCE_BUNDLE_NAME": "tool_resources",
"CODE_SIGNING_ALLOWED": "NO",
]),
],
buildPhases: [
TestSourcesBuildPhase(["main.swift"]),
]
),
])
let tester = try await TaskConstructionTester(getCore(), testProject)

await tester.checkBuild(runDestination: .macOS) { results in
results.checkNoDiagnostics()
results.checkTarget("tool") { target in
results.checkWriteAuxiliaryFileTask(.matchTarget(target), .matchRuleType("WriteAuxiliaryFile"), .matchRuleItemBasename("resource_bundle_accessor.swift")) { task, contents in
XCTAssertMatch(contents.unsafeStringValue, .contains("public import class Foundation.Bundle"))
}
}
}
}

@Test(.requireSDKs(.macOS, .iOS))
func packageResourceBundleEmbedding() async throws {
let testProject = try await TestProject(
Expand Down
Loading