swiftlang / swiftlang/swift-syntax
#line macro cannot access original location inside of body macro
- Dominant language
- Swift
- Stars
- 3.7k
- Forks
- 553
- Avg merge
- 5d 13h
- Merged PRs (30d)
- 16
Description
### Description
#line value is wrong inside of body macro, even after using #sourceLocation to fix it.
### Steps to Reproduce
I will use this macro implementation from #2757. It is only online example I can found which uses sourceLocation.
```swift
@attached(body)
public macro SourceLocationMacro(_ properties: String...) =
#externalMacro(module: "MyMacros", type: "SourceLocationMacro")
```
```swift
public 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] {
if let statements = declaration.body?.statements {
var body: [CodeBlockItemSyntax] = []
statements.forEach { statement in
if let location = context.location(of: statement, at: .afterLeadingTrivia, filePathMode: .filePath) {
let transformed = CodeBlockItemListSyntax {
"\n#sourceLocation(file: \(location.file), line: \(location.line))"
statement
"\n#sourceLocation()"
}
body.append(contentsOf: transformed)
}
}
return body
} else {
return []
}
}
}
```
```swift
// this line is 237 on original source code
@SourceLocationMacro
func demo() {
let x: Int = 1
print("demo line", #line)
}
```
Expanded macro
```swift
{
#sourceLocation(file: "/***/AppDelegate.swift", line: 240)
let x: Int = 1
#sourceLocation()
#sourceLocation(file: "/***/AppDelegate.swift", line: 241)
print("demo line", #line)
#sourceLocation()
}
```
On this example sourceLocation does something, it makes Xcode to jump correct line on from the build warning about unused variable. This is the original purpose of the issue #2757. If the macro does not insert sourceLocation lines, the Xcode jumps to a generated code snippet.
My problem is that, sourceLocation does not fix #line value. It prints 239 instead of 241.
Contributor guide
Assessment
This issue has not been assessed yet.