From 8dbe8280aac13766687462a5b3f78f21d7485c7d Mon Sep 17 00:00:00 2001 From: Stuart Montgomery Date: Wed, 10 Jul 2024 12:45:38 -0500 Subject: [PATCH 1/2] Include try and await expressions which are parents of a freestanding expression macro in lexicalContext Resolves rdar://109470248 --- .../SwiftSyntaxMacros/Syntax+LexicalContext.swift | 14 ++++++++++++++ .../LexicalContextTests.swift | 8 +++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Sources/SwiftSyntaxMacros/Syntax+LexicalContext.swift b/Sources/SwiftSyntaxMacros/Syntax+LexicalContext.swift index 0ba6ddb9216..3a7cb8c7d1b 100644 --- a/Sources/SwiftSyntaxMacros/Syntax+LexicalContext.swift +++ b/Sources/SwiftSyntaxMacros/Syntax+LexicalContext.swift @@ -67,6 +67,20 @@ extension SyntaxProtocol { case let freestandingMacro as FreestandingMacroExpansionSyntax: return Syntax(freestandingMacro.detached) as Syntax + // Try and await are preserved: A freestanding expression macro preceded + // by try or await may need to know whether those keywords are present so it + // can propagate them to any expressions in its expansion which were passed + // as arguments to the macro. The expression of the try or await is replaced + // with a trivial placeholder, though. + case var tryExpr as TryExprSyntax: + tryExpr = tryExpr.detached + tryExpr.expression = "()" + return Syntax(tryExpr) + case var awaitExpr as AwaitExprSyntax: + awaitExpr = awaitExpr.detached + awaitExpr.expression = "()" + return Syntax(awaitExpr) + default: return nil } diff --git a/Tests/SwiftSyntaxMacroExpansionTest/LexicalContextTests.swift b/Tests/SwiftSyntaxMacroExpansionTest/LexicalContextTests.swift index 533a2a4d19f..0d94a828b2e 100644 --- a/Tests/SwiftSyntaxMacroExpansionTest/LexicalContextTests.swift +++ b/Tests/SwiftSyntaxMacroExpansionTest/LexicalContextTests.swift @@ -531,7 +531,7 @@ final class LexicalContextTests: XCTestCase { struct S { let arg: C var contextDescription: String { - #lexicalContextDescription + try await #lexicalContextDescription } } return S(arg: c) @@ -542,7 +542,9 @@ final class LexicalContextTests: XCTestCase { struct S { let arg: C var contextDescription: String { - """ + try await """ + await () + try () contextDescription: String struct S {} { c in @@ -551,7 +553,7 @@ final class LexicalContextTests: XCTestCase { struct S { let arg: C var contextDescription: String { - #lexicalContextDescription + try await #lexicalContextDescription } } return S(arg: c) From 76d026c102177f87aaa86ea98e908d0f727f88b4 Mon Sep 17 00:00:00 2001 From: Stuart Montgomery Date: Wed, 10 Jul 2024 13:02:12 -0500 Subject: [PATCH 2/2] Use a wildcard token instead --- Sources/SwiftSyntaxMacros/Syntax+LexicalContext.swift | 4 ++-- Tests/SwiftSyntaxMacroExpansionTest/LexicalContextTests.swift | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/SwiftSyntaxMacros/Syntax+LexicalContext.swift b/Sources/SwiftSyntaxMacros/Syntax+LexicalContext.swift index 3a7cb8c7d1b..1f6ef803179 100644 --- a/Sources/SwiftSyntaxMacros/Syntax+LexicalContext.swift +++ b/Sources/SwiftSyntaxMacros/Syntax+LexicalContext.swift @@ -74,11 +74,11 @@ extension SyntaxProtocol { // with a trivial placeholder, though. case var tryExpr as TryExprSyntax: tryExpr = tryExpr.detached - tryExpr.expression = "()" + tryExpr.expression = ExprSyntax(TypeExprSyntax(type: IdentifierTypeSyntax(name: .wildcardToken()))) return Syntax(tryExpr) case var awaitExpr as AwaitExprSyntax: awaitExpr = awaitExpr.detached - awaitExpr.expression = "()" + awaitExpr.expression = ExprSyntax(TypeExprSyntax(type: IdentifierTypeSyntax(name: .wildcardToken()))) return Syntax(awaitExpr) default: diff --git a/Tests/SwiftSyntaxMacroExpansionTest/LexicalContextTests.swift b/Tests/SwiftSyntaxMacroExpansionTest/LexicalContextTests.swift index 0d94a828b2e..6b426aa7431 100644 --- a/Tests/SwiftSyntaxMacroExpansionTest/LexicalContextTests.swift +++ b/Tests/SwiftSyntaxMacroExpansionTest/LexicalContextTests.swift @@ -543,8 +543,8 @@ final class LexicalContextTests: XCTestCase { let arg: C var contextDescription: String { try await """ - await () - try () + await _ + try _ contextDescription: String struct S {} { c in