swiftlang / swiftlang/swift-syntax

#line macro cannot access original location inside of body macro

Open
#3,253 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.