Nun*_*ves 8 macros swift swift-macro
我正在摆弄新的 Swift 5.9 宏。
我有以下宏:
鉴于以下枚举
@associatedValues
enum Fruit {
case banana(Banana)
case grape(Grape)
}
Run Code Online (Sandbox Code Playgroud)
我想
@associatedValues
enum Fruit {
case banana(Banana)
case grape(Grape)
var bananaValue: Banana? { if ... return ... } }
var grapeValue: Grape? { if ... return ... } }
}
Run Code Online (Sandbox Code Playgroud)
我的实现是这样的:
public static func expansion<Declaration, Context>(
of node: SwiftSyntax.AttributeSyntax,
providingMembersOf declaration: Declaration,
in context: Context
) throws -> [SwiftSyntax.DeclSyntax]
where Declaration: SwiftSyntax.DeclGroupSyntax,
Context: SwiftSyntaxMacros.MacroExpansionContext
{
guard let enumDeclaration = declaration.as(EnumDeclSyntax.self) else {
throw AssociatedValuesMacroError.onlyApplicableToEnum
}
return enumDeclaration.memberBlock.members
.compactMap { $0.decl.as(EnumCaseDeclSyntax.self) }
.map { (_case: EnumCaseDeclSyntax) in
let _element: EnumCaseElementListSyntax.Element = _case.elements.first!
let caseName = _element.identifier
let typeName = _element.associatedValue!.parameterList.first!.description
return
"""
var \(raw: caseName)Value: \(raw: typeName)? {
if case let .\(raw: caseName)(value) = self {
return value
} else {
return nil
}
}
"""
}
}
Run Code Online (Sandbox Code Playgroud)
现在,自动完成功能检测到新属性,但编译器告诉我:
Declaration name 'bananaValue' is not covered by macro 'associatedValues'
Declaration name 'grapeValue' is not covered by macro 'associatedValues'
测试会运行并验证输出,但不会在编译时验证。
我缺少什么?谢谢
Nun*_*ves 19
我们需要添加names: arbitrary宏观作用。
@attached(member, names: arbitrary)
public macro AssociatedValues() = #externalMacro(module: "MyMacrosModule", type: "AssociatedValuesMacro")
Run Code Online (Sandbox Code Playgroud)
注意:就我而言,我需要任意名称,因为名称是动态的。但如果您确实知道要添加哪些属性,则应该使用names: myCustomName。
另外,虽然不是特定问题的答案,但请确保将宏类型添加到CompilerPlugin.
#if canImport(SwiftCompilerPlugin)
import SwiftCompilerPlugin
import SwiftSyntaxMacros
@main
struct MacrosPlugin: CompilerPlugin {
let providingMacros: [Macro.Type] = [
AssociatedValueMacro.self
]
}
Run Code Online (Sandbox Code Playgroud)