diff --git a/Sources/FoundationMacros/BundleMacro.swift b/Sources/FoundationMacros/BundleMacro.swift new file mode 100644 index 000000000..bd45c8ca4 --- /dev/null +++ b/Sources/FoundationMacros/BundleMacro.swift @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +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 + }() + """ + } +} diff --git a/Sources/FoundationMacros/CMakeLists.txt b/Sources/FoundationMacros/CMakeLists.txt index 98b90c0df..2cd1a338e 100644 --- a/Sources/FoundationMacros/CMakeLists.txt +++ b/Sources/FoundationMacros/CMakeLists.txt @@ -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 diff --git a/Sources/FoundationMacros/FoundationMacros.swift b/Sources/FoundationMacros/FoundationMacros.swift index dedf6f386..78e6696f1 100644 --- a/Sources/FoundationMacros/FoundationMacros.swift +++ b/Sources/FoundationMacros/FoundationMacros.swift @@ -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 diff --git a/Tests/FoundationMacrosTests/BundleMacroTests.swift b/Tests/FoundationMacrosTests/BundleMacroTests.swift new file mode 100644 index 000000000..5b466f422 --- /dev/null +++ b/Tests/FoundationMacrosTests/BundleMacroTests.swift @@ -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 BundleMacroTests: 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 + }() + """ + ) + } +}