Building on Swift macros without requiring swift-syntax I wondered about the bare minimum changes required to persuade swift to export the syntax in a usable form.
How would y'all feel about the following to improve macro plugins that don't use swift-syntax (or may not even be written in Swift)?
This can be acheived by:
- making
SwiftSyntax.SyntaxitselfEncodable(or some other mechanism to make the treeEncodable), - extending
SwiftCompilerPluginMessageHandling.PluginMessage.Syntaxto allow Syntax to be included in the message to macro plugin, - fix
ASTGento handle the extendedSwiftCompilerPluginMessageHandling.PluginMessage.Syntax. (this removes the smelly "loop" ofSwiftSyntax.Syntaxbeing generated only to be stringified externally toSwiftSyntax)
extension Syntax: Encodable {
enum CodingKeys: String, CodingKey{
case kind
case payload
}
public func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(kind.rawValue, forKey: .kind)
if kind == .token {
try container.encode(description, forKey: .payload)
} else {
try container.encode(Array(children(viewMode: .fixedUp)), forKey: .payload)
}
}
}
For Apple's default #stringify example the result is:
{
"kind": "macroExpansionExpr",
"payload": [
{ "kind": "token", "payload": "#" },
{ "kind": "token", "payload": "stringify" },
{ "kind": "token", "payload": "(" },
{
"kind": "labeledExprList",
"payload": [
{
"kind": "labeledExpr",
"payload": [
{
"kind": "infixOperatorExpr",
"payload": [
{
"kind": "declReferenceExpr",
"payload": [
{ "kind": "token", "payload": "a " }
]
},
{
"kind": "binaryOperatorExpr",
"payload": [
{ "kind": "token", "payload": "+ " }
]
},
{
"kind": "declReferenceExpr",
"payload": [
{ "kind": "token", "payload": "b" }
]
}
]
}
]
}
]
},
{ "kind": "token", "payload": ")" },
{
"kind": "multipleTrailingClosureElementList",
"payload": [ ]
}
]
}