Skip to content

Commit 9f76064

Browse files
Fallback to root node lookup for detached node
1 parent 28794d2 commit 9f76064

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

Sources/SwiftSyntaxMacroExpansion/BasicMacroExpansionContext.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,9 @@ extension BasicMacroExpansionContext: MacroExpansionContext {
210210
// The syntax node came from the source file itself.
211211
rootSourceFile = directRootSourceFile
212212
offsetAdjustment = .zero
213-
} else if let nodeInOriginalTree = sharedState.detachedNodes[Syntax(node)] {
213+
} else if let nodeInOriginalTree = sharedState.detachedNodes[Syntax(node)]
214+
?? sharedState.detachedNodes[Syntax(node.root)]
215+
{
214216
// The syntax node came from a disconnected root, so adjust for that.
215217
rootSourceFile = nodeInOriginalTree.root.as(SourceFileSyntax.self)
216218
offsetAdjustment = SourceLength(utf8Length: nodeInOriginalTree.position.utf8Offset)

Tests/SwiftSyntaxMacroExpansionTest/BodyMacroTests.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,51 @@ final class BodyMacroTests: XCTestCase {
125125
indentationWidth: indentationWidth
126126
)
127127
}
128+
129+
func testBodyNodeLocationFromContext() {
130+
131+
struct SourceLocationMacro: BodyMacro {
132+
public static var formatMode: FormatMode { .disabled }
133+
134+
public static func expansion(
135+
of node: AttributeSyntax,
136+
providingBodyFor declaration: some DeclSyntaxProtocol & WithOptionalCodeBlockSyntax,
137+
in context: some MacroExpansionContext
138+
) throws -> [CodeBlockItemSyntax] {
139+
guard let statements = declaration.body?.statements else {
140+
return []
141+
}
142+
let body =
143+
if let location = context.location(of: statements, at: .afterLeadingTrivia, filePathMode: .filePath) {
144+
CodeBlockItemListSyntax {
145+
"#sourceLocation(file: \(location.file), line: \(location.line))"
146+
statements
147+
"#sourceLocation()"
148+
}
149+
} else {
150+
statements
151+
}
152+
return body.map(\.self)
153+
}
154+
}
155+
156+
assertMacroExpansion(
157+
"""
158+
@SourceLocationMacro
159+
func f() {
160+
let x: Int = 1
161+
}
162+
""",
163+
expandedSource:
164+
"""
165+
func f() {
166+
#sourceLocation(file: "test.swift", line: 3)
167+
let x: Int = 1
168+
#sourceLocation()
169+
}
170+
""",
171+
macros: ["SourceLocationMacro": SourceLocationMacro.self],
172+
indentationWidth: indentationWidth
173+
)
174+
}
128175
}

0 commit comments

Comments
 (0)