Source location retrieving doesn't work in body macro expansion assertion
mateusrodriguesxyz opened this issue · 1 comments
mateusrodriguesxyz commented
Description
The location method of BasicMacroExpansionContext
returns nil
when a body macro is expanded using assertMacroExpansion
. This makes it difficult to write tests for macros that depend on non-nil location value.
Steps to Reproduce
Consider the following macro:
struct SourceLocationMacro: BodyMacro {
public static var formatMode: FormatMode { .disabled }
public static func expansion(
of node: AttributeSyntax,
providingBodyFor declaration: some DeclSyntaxProtocol & WithOptionalCodeBlockSyntax,
in context: some MacroExpansionContext
) throws -> [CodeBlockItemSyntax] {
guard let statements = declaration.body?.statements else {
return []
}
let body =
if let location = context.location(of: statements, at: .afterLeadingTrivia, filePathMode: .filePath) {
CodeBlockItemListSyntax {
"#sourceLocation(file: \(location.file), line: \(location.line))"
statements
"#sourceLocation()"
}
} else {
statements
}
return body.map(\.self)
}
}
Assertion of it produces an unexpected expanded source code:
assertMacroExpansion(
"""
@SourceLocationMacro
func f() {
let x: Int = 1
}
""",
expandedSource:
"""
func f() {
#sourceLocation(file: "test.swift", line: 3)
let x: Int = 1
#sourceLocation()
}
""",
macros: ["SourceLocationMacro": SourceLocationMacro.self],
indentationWidth: indentationWidth
)
❌ failed - Macro expansion did not produce the expected expanded source
Actual expanded source:
func f() {
let x: Int = 1
}
ahoppen commented
Synced to Apple’s issue tracker as rdar://133489460