Skip to content

Commit 3f3e923

Browse files
committed
Adapt pattern binding into VariableDeclSyntax for lexical context
1 parent b4c601c commit 3f3e923

3 files changed

Lines changed: 40 additions & 18 deletions

File tree

Sources/SwiftSyntaxMacroExpansion/MacroExpansion.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,10 @@ public func expandAttachedMacroWithoutCollapsing<Context: MacroExpansionContext>
415415
)
416416
)
417417

418-
// Insert the enclosing `VariableDeclSyntax` into the lexical context
418+
// Insert the enclosing `PatternBindingSyntax`'s var decl context
419+
// into the lexical context
419420
var context: MacroExpansionContext = context
420-
if let varDeclLexicalContext = varDecl.asMacroLexicalContext() {
421+
if let varDeclLexicalContext = binding.asMacroLexicalContext() {
421422
context = PrependLexicalContextWrapperContext(
422423
prependLexicalContext: [varDeclLexicalContext],
423424
wrapping: context

Sources/SwiftSyntaxMacros/Syntax+LexicalContext.swift

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,24 @@ extension SyntaxProtocol {
5555
case is EnumCaseElementSyntax:
5656
return Syntax(self.detached)
5757

58-
// Pattern bindings have their accessors and initializer removed.
58+
// Pattern bindings have their accessors and initializer removed, and wrapped in the parent variable decl.
5959
case var patternBinding as PatternBindingSyntax:
60+
let varDecl = patternBinding.parent?.as(PatternBindingListSyntax.self)?.parent?.as(VariableDeclSyntax.self)?
61+
.detached
6062
patternBinding = patternBinding.detached
6163
patternBinding.accessorBlock = nil
6264
patternBinding.initializer = nil
63-
return Syntax(patternBinding)
64-
65-
// Variable declarations have their accessor blocks removed from bindings.
66-
case var varDecl as VariableDeclSyntax:
67-
varDecl = varDecl.detached
68-
varDecl.bindings = PatternBindingListSyntax(
69-
varDecl.bindings.map {
70-
var binding = $0.detached
71-
binding.accessorBlock = nil
72-
binding.initializer = nil
73-
return binding
74-
}
75-
)
76-
return Syntax(varDecl)
65+
if var varDecl {
66+
varDecl.bindings = [patternBinding]
67+
return Syntax(varDecl)
68+
} else {
69+
return Syntax(
70+
VariableDeclSyntax(
71+
bindingSpecifier: .keyword(.var),
72+
bindings: [patternBinding]
73+
)
74+
)
75+
}
7776

7877
// Freestanding macros are fine as-is because if any arguments change
7978
// the whole macro would have to be re-evaluated.

Tests/SwiftSyntaxMacroExpansionTest/LexicalContextTests.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,14 @@ extension SyntaxProtocol {
151151
return singleVarName
152152
}
153153

154+
// Variable declarations with a single binding.
155+
if let varDecl = self.as(VariableDeclSyntax.self),
156+
varDecl.bindings.count == 1,
157+
let singleVarName = varDecl.bindings.first?.singleBindingName
158+
{
159+
return singleVarName
160+
}
161+
154162
return nil
155163
}
156164
}
@@ -303,6 +311,21 @@ final class LexicalContextTests: XCTestCase {
303311
indentationWidth: indentationWidth
304312
)
305313

314+
assertMacroExpansion(
315+
"""
316+
extension A {
317+
static var staticProp = #function, secondProp = #function
318+
}
319+
""",
320+
expandedSource: """
321+
extension A {
322+
static var staticProp = "staticProp", secondProp = "secondProp"
323+
}
324+
""",
325+
macros: ["function": FunctionMacro.self],
326+
indentationWidth: indentationWidth
327+
)
328+
306329
assertMacroExpansion(
307330
"""
308331
func f(a: Int, _: Double, c: Int) {
@@ -546,7 +569,6 @@ final class LexicalContextTests: XCTestCase {
546569
await _
547570
try _
548571
unsafe _
549-
contextDescription: String
550572
var contextDescription: String
551573
struct S {}
552574
{ c in

0 commit comments

Comments
 (0)