@@ -200,6 +200,21 @@ public struct AllLexicalContextsMacro: DeclarationMacro {
200
200
}
201
201
}
202
202
203
+ public struct LexicalContextDescriptionMacro : ExpressionMacro {
204
+ public static func expansion(
205
+ of node: some FreestandingMacroExpansionSyntax ,
206
+ in context: some MacroExpansionContext
207
+ ) throws -> ExprSyntax {
208
+ let descriptions = context. lexicalContext. reduce ( into: " " ) { descriptions, syntax in
209
+ descriptions += " \( syntax. trimmed) \n "
210
+ }
211
+ return """
212
+ \" \" \"
213
+ \( raw: descriptions) \" \" \"
214
+ """
215
+ }
216
+ }
217
+
203
218
final class LexicalContextTests : XCTestCase {
204
219
private let indentationWidth : Trivia = . spaces( 2 )
205
220
@@ -505,5 +520,49 @@ final class LexicalContextTests: XCTestCase {
505
520
// Test closures separately, because they don't fit as declaration macros.
506
521
let closure : ExprSyntax = " { (a, b) in print(a + b) } "
507
522
XCTAssertEqual ( closure. asMacroLexicalContext ( ) !. description, " { (a, b) in } " )
523
+
524
+ // Test freestanding macros separately, because since the context contains
525
+ // the full body of the macro, including each decl from the context as a new
526
+ // decl in the expansion results in a cycle. So we instead use a macro that
527
+ // generates a description of the lexical context.
528
+ assertMacroExpansion (
529
+ """
530
+ #M(a: 1, b: 2) { c in
531
+ struct S {
532
+ let arg: C
533
+ var contextDescription: String {
534
+ #lexicalContextDescription
535
+ }
536
+ }
537
+ return S(arg: c)
538
+ }
539
+ """ ,
540
+ expandedSource: #"""
541
+ #M(a: 1, b: 2) { c in
542
+ struct S {
543
+ let arg: C
544
+ var contextDescription: String {
545
+ """
546
+ contextDescription: String
547
+ struct S {}
548
+ { c in
549
+ }
550
+ #M(a: 1, b: 2) { c in
551
+ struct S {
552
+ let arg: C
553
+ var contextDescription: String {
554
+ #lexicalContextDescription
555
+ }
556
+ }
557
+ return S(arg: c)
558
+ }
559
+ """
560
+ }
561
+ }
562
+ return S(arg: c)
563
+ }
564
+ """# ,
565
+ macros: [ " lexicalContextDescription " : LexicalContextDescriptionMacro . self]
566
+ )
508
567
}
509
568
}
0 commit comments