Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
42 changes: 42 additions & 0 deletions Sources/FoundationMacros/BundleMacro.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import SwiftSyntax
import SwiftSyntaxMacros
import Foundation

#if FOUNDATION_FRAMEWORK
/// Returns the bundle most likely to contain resources for the calling code.
///
/// Code in an app, app extension, framework, etc. will return the bundle associated with that target.
/// Code in a Swift Package target will return the resource bundle associated with that target.
@available(macOS 10.0, iOS 2.0, tvOS 9.0, watchOS 2.0, *)
@freestanding(expression)
public macro bundle() -> Bundle = #externalMacro(module: "FoundationMacros", type: "BundleMacro")
#endif


public struct BundleMacro: SwiftSyntaxMacros.ExpressionMacro, Sendable {
public static func expansion(of node: some FreestandingMacroExpansionSyntax, in context: some MacroExpansionContext) throws -> ExprSyntax {
"""
{
#if SWIFT_MODULE_RESOURCE_BUNDLE_AVAILABLE
return Bundle.module
#elseif SWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE
#error("No resource bundle is available for this module. If resources are included elsewhere, specify the bundle manually.")
#else
return Bundle(_dsoHandle: #dsohandle) ?? .main
#endif
}()
"""
}
}
1 change: 1 addition & 0 deletions Sources/FoundationMacros/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ target_compile_options(FoundationMacros PRIVATE -parse-as-library)

target_sources(FoundationMacros PRIVATE
FoundationMacros.swift
BundleMacro.swift
PredicateMacro.swift)

target_compile_options(FoundationMacros PRIVATE
Expand Down
6 changes: 5 additions & 1 deletion Sources/FoundationMacros/FoundationMacros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import SwiftCompilerPlugin

@main
struct FoundationMacros: CompilerPlugin {
var providingMacros: [Macro.Type] = [PredicateMacro.self, ExpressionMacro.self]
var providingMacros: [Macro.Type] = [
PredicateMacro.self,
ExpressionMacro.self,
BundleMacro.self
]
}

#endif
57 changes: 57 additions & 0 deletions Tests/FoundationMacrosTests/BundleTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2022-2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import XCTest
import FoundationMacros

final class BundleTests: XCTestCase {

func testSimple() {
AssertMacroExpansion(
macros: ["bundle": BundleMacro.self],
"""
#bundle
""",
"""
{
#if SWIFT_MODULE_RESOURCE_BUNDLE_AVAILABLE
return Bundle.module
#elseif SWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE
#error("No resource bundle is available for this module. If resources are included elsewhere, specify the bundle manually.")
#else
return Bundle(_dsoHandle: #dsohandle) ?? .main
#endif
}()
"""
)
}

func testUsingParenthesis() {
AssertMacroExpansion(
macros: ["bundle": BundleMacro.self],
"""
#bundle()
""",
"""
{
#if SWIFT_MODULE_RESOURCE_BUNDLE_AVAILABLE
return Bundle.module
#elseif SWIFT_MODULE_RESOURCE_BUNDLE_UNAVAILABLE
#error("No resource bundle is available for this module. If resources are included elsewhere, specify the bundle manually.")
#else
return Bundle(_dsoHandle: #dsohandle) ?? .main
#endif
}()
"""
)
}
}