如何通过全局编译时标记控制Swift宏条件显示/隐藏@available(*, deprecated)
实现条件性为结构体属性添加@available注解的Swift宏
要实现这个根据全局编译标记动态给结构体所有属性添加@available(*, deprecated)的宏,你可以按照以下步骤操作:
定义全局编译标记
首先在项目中设置一个自定义编译标记,比如DEPRECATE_ALL_PROPERTIES。在Xcode中可以通过Build Settings > Swift Compiler - Custom Flags > Other Swift Flags添加-D DEPRECATE_ALL_PROPERTIES来启用这个标记,移除则表示禁用。创建成员宏实现
创建一个遵循MemberMacro协议的宏,在宏的扩展逻辑里根据编译标记判断是否为每个属性添加@available注解:import SwiftSyntax import SwiftSyntaxMacros import SwiftSyntaxBuilder public struct DeprecateAllPropertiesMacro: MemberMacro { public static func expansion( of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, in context: some MacroExpansionContext ) throws -> [DeclSyntax] { // 遍历结构体的所有成员属性 let modifiedMembers = declaration.members.compactMap { member -> DeclSyntax? in guard let variableDecl = member.decl.as(VariableDeclSyntax.self), variableDecl.bindings.count == 1, variableDecl.bindings.first?.pattern.as(IdentifierPatternSyntax.self) != nil else { // 只处理存储属性,跳过计算属性或其他成员 return member.decl } #if DEPRECATE_ALL_PROPERTIES // 标记启用时,为属性添加@available注解 return DeclSyntax( """ @available(*, deprecated) \(variableDecl) """ ) #else // 标记禁用时,返回原属性 return member.decl #endif } return modifiedMembers } } // 宏的注册 public struct DeprecateAllPropertiesMacroPlugin: MacroPlugin { public static let providingMacros: [String: Macro.Type] = [ "MyMacro": DeprecateAllPropertiesMacro.self ] }使用宏
按照你期望的方式使用宏:@MyMacro() struct X { var a: String var b: Int }
效果验证
标记启用时,宏展开后代码为:
struct X { @available(*, deprecated) var a: String @available(*, deprecated) var b: Int }标记禁用时,宏展开后代码与原结构体一致:
struct X { var a: String var b: Int }
注意:这个宏只会处理结构体的存储属性,如果需要支持类的属性,只需要在宏的逻辑里兼容ClassDeclSyntax即可,当前实现默认只处理结构体成员。
内容的提问来源于stack exchange,提问作者bAthi
相关产品推荐
相关产品推荐

