提问人:Mar-k 提问时间:8/23/2023 更新时间:8/24/2023 访问量:77
Swift 宏:ReturnClause语法
Swift Macros: ReturnClauseSyntax
问:
我正在对新的 Swift 宏进行一些测试和弄清楚,但我遇到了一个我似乎无法弄清楚的障碍,也是因为还没有很多有用的指南。
因此,首先,如果宏的设备是个好主意,我们暂时将其放在一边。
我试图实现的是创建一个宏,该宏会自动将服务添加到具有所有基本 REST 操作(如 、 、 等)的 服务。@attached(member)
struct
get(id: String)
patch()
getAll()
delete(id: String)
所以我在实现方面走得很远,但我似乎无法弄清楚如何创建它应该只返回添加宏的类型的实例。请参阅下面的代码示例:ReturnClauseSyntax
public struct ServiceMacro: MemberMacro {
public static func expansion(
of node: SwiftSyntax.AttributeSyntax,
providingMembersOf declaration: some SwiftSyntax.DeclGroupSyntax,
in context: some SwiftSyntaxMacros.MacroExpansionContext
) throws -> [SwiftSyntax.DeclSyntax] {
guard let structDecl = declaration.as(StructDeclSyntax.self) else {
// TODO: Emit an error
return []
}
let initializer = try EnumDeclSyntax("enum Service") {
FunctionDeclSyntax(
funcKeyword: "static func",
name: "get",
signature: FunctionSignatureSyntax(
parameterClause: FunctionParameterClauseSyntax(
parameters: FunctionParameterListSyntax(
arrayLiteral: FunctionParameterSyntax(
stringLiteral: "id: String"
)
)
),
trailingTrivia: .init(stringLiteral: " -> \(structDecl.name.trimmed)")
),
bodyBuilder: {
"return \(structDecl.name.trimmed)()"
}
)
}
return [DeclSyntax(initializer)]
}
}
因此,这导致了以下扩展:
@Service
struct Recipe {
enum Service {
static func get(id: String) -> Recipe {
return Recipe()
}
}
}
但是,正如您在宏实现代码中看到的那样,我正在使用 一个感觉不对且可能不对的 来设置尾随琐事。stringLiteral
现在我想知道如何通过使用期望 .我现在只是希望它返回它所应用的结构的实例。returnClause
ReturnClauseSyntax
也许这真的很容易,但我在文档中找不到它,而且这整个语法对我来说都是新的,所以如果有人能为我指出正确的方向,那将非常有帮助。
此外,我们非常欢迎关于实施的其他建议,因为这对我和很多人来说可能是新的。
答:
1赞
La pieuvre
8/24/2023
#1
事实上,这并不难。
您可以像这样检索您正在处理的结构的类型名称
guard let name = declaration.as(StructDeclSyntax.self)?.name.text
else {return []}
然后你可以把它转换成一个TypeSyntax,并将其传递给初始化器的type参数,如下所示:ReturnClauseSyntax
ReturnClauseSyntax(type: TypeSyntax(stringLiteral: name)
现在您可以将所有这些组合在一起:
public struct ServiceMacro: MemberMacro {
public static func expansion(
of node: SwiftSyntax.AttributeSyntax,
providingMembersOf declaration: some SwiftSyntax.DeclGroupSyntax,
in context: some SwiftSyntaxMacros.MacroExpansionContext
) throws -> [SwiftSyntax.DeclSyntax] {
guard let structDecl = declaration.as(StructDeclSyntax.self) else {
// TODO: Emit an error
return []
}
let name = structDecl.name.text
let initializer = try EnumDeclSyntax("enum Service") {
FunctionDeclSyntax(
funcKeyword: "static func",
name: "get",
signature: FunctionSignatureSyntax(
parameterClause: FunctionParameterClauseSyntax(
parameters: FunctionParameterListSyntax(
arrayLiteral: FunctionParameterSyntax(
stringLiteral: "id: String"
)
)
),
returnClause: ReturnClauseSyntax(type: TypeSyntax(stringLiteral: name)
),
bodyBuilder: {
"return \(structDecl.name.trimmed)()"
}
)
}
return [DeclSyntax(initializer)]
}
}
评论