Skip to content

Commit 35ad12c

Browse files
committed
Generalize the signature of ExpressionMacro's expansion.
Make the signature generic over all freestanding macro expansion syntax nodes (to account for places where we parse as a declaration), and generic over the macro expansion context (lest we cause an existential crisis).
1 parent 52e8020 commit 35ad12c

File tree

4 files changed

+64
-66
lines changed

4 files changed

+64
-66
lines changed

Sources/_SwiftSyntaxMacros/MacroProtocols/ExpressionMacro.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@ import SwiftSyntax
1616
public protocol ExpressionMacro: FreestandingMacro {
1717
/// Expand a macro described by the given macro expansion expression
1818
/// within the given context to produce a replacement expression.
19-
static func expansion(
20-
of node: MacroExpansionExprSyntax,
21-
in context: any MacroExpansionContext
19+
static func expansion<
20+
Node: FreestandingMacroExpansionSyntax,
21+
Context: MacroExpansionContext
22+
>(
23+
of node: Node,
24+
in context: Context
2225
) throws -> ExprSyntax
2326
}

Sources/_SwiftSyntaxMacros/MacroSystem.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ class MacroApplication: SyntaxRewriter {
144144
)
145145
} else if let macro = macro as? ExpressionMacro.Type {
146146
let expandedExpr = try macro.expansion(
147-
of: declExpansion.asMacroExpansionExpr(),
147+
of: declExpansion,
148148
in: context
149149
)
150150
newItems.append(CodeBlockItemSyntax(item: .init(expandedExpr)))

Sources/_SwiftSyntaxMacros/Syntax+MacroEvaluation.swift

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,6 @@ struct ThrownErrorDiagnostic: DiagnosticMessage {
2424
}
2525
}
2626

27-
extension MacroExpansionDeclSyntax {
28-
/// Macro expansion declarations are parsed in some positions where an
29-
/// expression is also warranted, so
30-
public func asMacroExpansionExpr() -> MacroExpansionExprSyntax {
31-
MacroExpansionExprSyntax(
32-
unexpectedBeforePoundToken,
33-
poundToken: poundToken,
34-
unexpectedBetweenPoundTokenAndMacro,
35-
macro: macro,
36-
genericArguments: genericArguments,
37-
unexpectedBetweenGenericArgumentsAndLeftParen,
38-
leftParen: leftParen,
39-
unexpectedBetweenLeftParenAndArgumentList,
40-
argumentList: argumentList,
41-
unexpectedBetweenArgumentListAndRightParen,
42-
rightParen: rightParen,
43-
unexpectedBetweenRightParenAndTrailingClosure,
44-
trailingClosure: trailingClosure,
45-
unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures,
46-
additionalTrailingClosures: additionalTrailingClosures,
47-
unexpectedAfterAdditionalTrailingClosures
48-
)
49-
}
50-
}
51-
5227
extension SyntaxProtocol {
5328
/// Detach the current node and inform the macro expansion context,
5429
/// if it needs to know.

Tests/SwiftSyntaxMacrosTest/MacroSystemTests.swift

Lines changed: 57 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,28 @@ import _SwiftSyntaxMacros
1818
import _SwiftSyntaxTestSupport
1919
import XCTest
2020

21+
enum CustomError: Error, CustomStringConvertible {
22+
case message(String)
23+
24+
var description: String {
25+
switch self {
26+
case .message(let text):
27+
return text
28+
}
29+
}
30+
}
31+
2132
// MARK: Example macros
2233
public struct StringifyMacro: ExpressionMacro {
23-
public static func expansion(
24-
of macro: MacroExpansionExprSyntax,
25-
in context: any MacroExpansionContext
26-
) -> ExprSyntax {
34+
public static func expansion<
35+
Node: FreestandingMacroExpansionSyntax,
36+
Context: MacroExpansionContext
37+
>(
38+
of macro: Node,
39+
in context: Context
40+
) throws -> ExprSyntax {
2741
guard let argument = macro.argumentList.first?.expression else {
28-
// FIXME: Create a diagnostic for the missing argument?
29-
return ExprSyntax(macro)
42+
throw CustomError.message("missing argument")
3043
}
3144

3245
return "(\(argument), \(StringLiteralExprSyntax(content: argument.description)))"
@@ -50,9 +63,12 @@ private func replaceFirstLabel(
5063
}
5164

5265
public struct ColorLiteralMacro: ExpressionMacro {
53-
public static func expansion(
54-
of macro: MacroExpansionExprSyntax,
55-
in context: any MacroExpansionContext
66+
public static func expansion<
67+
Node: FreestandingMacroExpansionSyntax,
68+
Context: MacroExpansionContext
69+
>(
70+
of macro: Node,
71+
in context: Context
5672
) -> ExprSyntax {
5773
let argList = replaceFirstLabel(
5874
of: macro.argumentList,
@@ -67,9 +83,12 @@ public struct ColorLiteralMacro: ExpressionMacro {
6783
}
6884

6985
public struct FileLiteralMacro: ExpressionMacro {
70-
public static func expansion(
71-
of macro: MacroExpansionExprSyntax,
72-
in context: any MacroExpansionContext
86+
public static func expansion<
87+
Node: FreestandingMacroExpansionSyntax,
88+
Context: MacroExpansionContext
89+
>(
90+
of macro: Node,
91+
in context: Context
7392
) -> ExprSyntax {
7493
let argList = replaceFirstLabel(
7594
of: macro.argumentList,
@@ -84,9 +103,12 @@ public struct FileLiteralMacro: ExpressionMacro {
84103
}
85104

86105
public struct ImageLiteralMacro: ExpressionMacro {
87-
public static func expansion(
88-
of macro: MacroExpansionExprSyntax,
89-
in context: any MacroExpansionContext
106+
public static func expansion<
107+
Node: FreestandingMacroExpansionSyntax,
108+
Context: MacroExpansionContext
109+
>(
110+
of macro: Node,
111+
in context: Context
90112
) -> ExprSyntax {
91113
let argList = replaceFirstLabel(
92114
of: macro.argumentList,
@@ -101,9 +123,12 @@ public struct ImageLiteralMacro: ExpressionMacro {
101123
}
102124

103125
public struct ColumnMacro: ExpressionMacro {
104-
public static func expansion(
105-
of macro: MacroExpansionExprSyntax,
106-
in context: any MacroExpansionContext
126+
public static func expansion<
127+
Node: FreestandingMacroExpansionSyntax,
128+
Context: MacroExpansionContext
129+
>(
130+
of macro: Node,
131+
in context: Context
107132
) throws -> ExprSyntax {
108133
guard let sourceLoc = context.location(of: macro),
109134
let column = sourceLoc.column else {
@@ -120,9 +145,12 @@ public struct ColumnMacro: ExpressionMacro {
120145
}
121146

122147
public struct FileIDMacro: ExpressionMacro {
123-
public static func expansion(
124-
of macro: MacroExpansionExprSyntax,
125-
in context: any MacroExpansionContext
148+
public static func expansion<
149+
Node: FreestandingMacroExpansionSyntax,
150+
Context: MacroExpansionContext
151+
>(
152+
of macro: Node,
153+
in context: Context
126154
) throws -> ExprSyntax {
127155
guard let sourceLoc = context.location(of: macro),
128156
let fileID = sourceLoc.file else {
@@ -141,9 +169,12 @@ public struct FileIDMacro: ExpressionMacro {
141169
/// Macro whose only purpose is to ensure that we cannot see "out" of the
142170
/// macro expansion syntax node we were given.
143171
struct CheckContextIndependenceMacro: ExpressionMacro {
144-
static func expansion(
145-
of macro: MacroExpansionExprSyntax,
146-
in context: any MacroExpansionContext
172+
static func expansion<
173+
Node: FreestandingMacroExpansionSyntax,
174+
Context: MacroExpansionContext
175+
>(
176+
of macro: Node,
177+
in context: Context
147178
) -> ExprSyntax {
148179

149180
// Should not have a parent.
@@ -152,18 +183,7 @@ struct CheckContextIndependenceMacro: ExpressionMacro {
152183
// Absolute starting position should be zero.
153184
XCTAssertEqual(macro.position.utf8Offset, 0)
154185

155-
return ExprSyntax(macro)
156-
}
157-
}
158-
159-
enum CustomError: Error, CustomStringConvertible {
160-
case message(String)
161-
162-
var description: String {
163-
switch self {
164-
case .message(let text):
165-
return text
166-
}
186+
return "()"
167187
}
168188
}
169189

@@ -701,7 +721,7 @@ final class MacroSystemTests: XCTestCase {
701721
let b = #checkContext
702722
""",
703723
"""
704-
let b = #checkContext
724+
let b = ()
705725
"""
706726
)
707727
}

0 commit comments

Comments
 (0)