@@ -14,6 +14,7 @@ import SwiftBasicFormat
14
14
import SwiftDiagnostics
15
15
import SwiftSyntax
16
16
import SwiftSyntaxMacros
17
+ import SwiftSyntaxMacroExpansion
17
18
18
19
extension CompilerPluginMessageHandler {
19
20
/// Get concrete macro type from a pair of module name and type name.
@@ -35,7 +36,7 @@ extension CompilerPluginMessageHandler {
35
36
expansionDiscriminator: discriminator
36
37
)
37
38
38
- let expandedSource : String
39
+ let expandedSource : String ?
39
40
do {
40
41
guard let macroSyntax = syntax. asProtocol ( FreestandingMacroExpansionSyntax . self) else {
41
42
throw MacroExpansionError . freestandingMacroSyntaxIsNotMacro
@@ -44,34 +45,14 @@ extension CompilerPluginMessageHandler {
44
45
throw MacroExpansionError . macroTypeNotFound
45
46
}
46
47
47
- switch macroDefinition {
48
- case let exprMacroDef as ExpressionMacro . Type :
49
- func _expand( node: some FreestandingMacroExpansionSyntax ) throws -> ExprSyntax {
50
- try exprMacroDef. expansion ( of: node, in: context)
51
- }
52
- let rewritten = try _openExistential ( macroSyntax, do: _expand)
53
- expandedSource = rewritten. formattedExpansion ( macroDefinition. formatMode)
54
-
55
- case let declMacroDef as DeclarationMacro . Type :
56
- func _expand( node: some FreestandingMacroExpansionSyntax ) throws -> [ DeclSyntax ] {
57
- try declMacroDef. expansion ( of: node, in: context)
58
- }
59
- let rewritten = try _openExistential ( macroSyntax, do: _expand)
60
- expandedSource = CodeBlockItemListSyntax ( rewritten. map { CodeBlockItemSyntax ( item: . decl( $0) ) } ) . formattedExpansion ( macroDefinition. formatMode)
61
-
62
- case let codeItemMacroDef as CodeItemMacro . Type :
63
- func _expand( node: some FreestandingMacroExpansionSyntax ) throws -> [ CodeBlockItemSyntax ] {
64
- try codeItemMacroDef. expansion ( of: node, in: context)
65
- }
66
- let rewritten = try _openExistential ( macroSyntax, do: _expand)
67
- expandedSource = CodeBlockItemListSyntax ( rewritten) . formattedExpansion ( macroDefinition. formatMode)
68
-
69
- default :
70
- throw MacroExpansionError . unmathedMacroRole
71
- }
48
+ expandedSource = SwiftSyntaxMacroExpansion . expandFreestandingMacro (
49
+ definition: macroDefinition,
50
+ node: macroSyntax,
51
+ in: context
52
+ )
72
53
} catch {
73
54
context. addDiagnostics ( from: error, node: syntax)
74
- expandedSource = " "
55
+ expandedSource = nil
75
56
}
76
57
77
58
let diagnostics = context. diagnostics. map {
@@ -99,132 +80,25 @@ extension CompilerPluginMessageHandler {
99
80
100
81
let attributeNode = sourceManager. add ( attributeSyntax) . cast ( AttributeSyntax . self)
101
82
let declarationNode = sourceManager. add ( declSyntax) . cast ( DeclSyntax . self)
83
+ let parentDeclNode = parentDeclSyntax. map { sourceManager. add ( $0) . cast ( DeclSyntax . self) }
102
84
103
- let expandedSources : [ String ]
85
+ let expandedSources : [ String ] ?
104
86
do {
105
87
guard let macroDefinition = resolveMacro ( macro) else {
106
88
throw MacroExpansionError . macroTypeNotFound
107
89
}
108
90
109
- switch ( macroDefinition, macroRole) {
110
- case ( let attachedMacro as AccessorMacro . Type , . accessor) :
111
- let accessors = try attachedMacro. expansion (
112
- of: attributeNode,
113
- providingAccessorsOf: declarationNode,
114
- in: context
115
- )
116
- expandedSources = accessors. map {
117
- $0. formattedExpansion ( macroDefinition. formatMode)
118
- }
119
-
120
- case ( let attachedMacro as MemberAttributeMacro . Type , . memberAttribute) :
121
- guard
122
- let parentDeclSyntax = parentDeclSyntax,
123
- let parentDeclGroup = sourceManager. add ( parentDeclSyntax) . asProtocol ( DeclGroupSyntax . self)
124
- else {
125
- // Compiler error: 'parentDecl' is mandatory for MemberAttributeMacro.
126
- throw MacroExpansionError . invalidExpansionMessage
127
- }
128
-
129
- // Local function to expand a member atribute macro once we've opened up
130
- // the existential.
131
- func expandMemberAttributeMacro(
132
- _ node: some DeclGroupSyntax
133
- ) throws -> [ AttributeSyntax ] {
134
- return try attachedMacro. expansion (
135
- of: attributeNode,
136
- attachedTo: node,
137
- providingAttributesFor: declarationNode,
138
- in: context
139
- )
140
- }
141
-
142
- let attributes = try _openExistential (
143
- parentDeclGroup,
144
- do: expandMemberAttributeMacro
145
- )
146
-
147
- // Form a buffer containing an attribute list to return to the caller.
148
- expandedSources = attributes. map {
149
- $0. formattedExpansion ( macroDefinition. formatMode)
150
- }
151
-
152
- case ( let attachedMacro as MemberMacro . Type , . member) :
153
- guard let declGroup = declarationNode. asProtocol ( DeclGroupSyntax . self)
154
- else {
155
- // Compiler error: declNode for member macro must be DeclGroupSyntax.
156
- throw MacroExpansionError . invalidExpansionMessage
157
- }
158
-
159
- // Local function to expand a member macro once we've opened up
160
- // the existential.
161
- func expandMemberMacro(
162
- _ node: some DeclGroupSyntax
163
- ) throws -> [ DeclSyntax ] {
164
- return try attachedMacro. expansion (
165
- of: attributeNode,
166
- providingMembersOf: node,
167
- in: context
168
- )
169
- }
170
-
171
- let members = try _openExistential ( declGroup, do: expandMemberMacro)
172
-
173
- // Form a buffer of member declarations to return to the caller.
174
- expandedSources = members. map { $0. formattedExpansion ( macroDefinition. formatMode) }
175
-
176
- case ( let attachedMacro as PeerMacro . Type , . peer) :
177
- let peers = try attachedMacro. expansion (
178
- of: attributeNode,
179
- providingPeersOf: declarationNode,
180
- in: context
181
- )
182
-
183
- // Form a buffer of peer declarations to return to the caller.
184
- expandedSources = peers. map {
185
- $0. formattedExpansion ( macroDefinition. formatMode)
186
- }
187
-
188
- case ( let attachedMacro as ConformanceMacro . Type , . conformance) :
189
- guard
190
- let declGroup = declarationNode. asProtocol ( DeclGroupSyntax . self) ,
191
- let identified = declarationNode. asProtocol ( IdentifiedDeclSyntax . self)
192
- else {
193
- // Compiler error: type mismatch.
194
- throw MacroExpansionError . invalidExpansionMessage
195
- }
196
-
197
- // Local function to expand a conformance macro once we've opened up
198
- // the existential.
199
- func expandConformanceMacro(
200
- _ node: some DeclGroupSyntax
201
- ) throws -> [ ( TypeSyntax , GenericWhereClauseSyntax ? ) ] {
202
- return try attachedMacro. expansion (
203
- of: attributeNode,
204
- providingConformancesOf: node,
205
- in: context
206
- )
207
- }
208
-
209
- let conformances = try _openExistential (
210
- declGroup,
211
- do: expandConformanceMacro
212
- )
213
-
214
- // Form a buffer of extension declarations to return to the caller.
215
- expandedSources = conformances. map { typeSyntax, whereClause in
216
- let typeName = identified. identifier. trimmedDescription
217
- let protocolName = typeSyntax. trimmedDescription
218
- let whereClause = whereClause? . trimmedDescription ?? " "
219
- return " extension \( typeName) : \( protocolName) \( whereClause) {} "
220
- }
221
-
222
- default :
223
- throw MacroExpansionError . unmathedMacroRole
224
- }
91
+ expandedSources = SwiftSyntaxMacroExpansion . expandAttachedMacro (
92
+ definition: macroDefinition,
93
+ macroRole: MacroRole ( messageMacroRole: macroRole) ,
94
+ attributeNode: attributeNode,
95
+ declarationNode: declarationNode,
96
+ parentDeclNode: parentDeclNode,
97
+ in: context
98
+ )
225
99
} catch {
226
100
context. addDiagnostics ( from: error, node: attributeNode)
227
- expandedSources = [ ]
101
+ expandedSources = nil
228
102
}
229
103
230
104
let diagnostics = context. diagnostics. map {
@@ -236,17 +110,17 @@ extension CompilerPluginMessageHandler {
236
110
}
237
111
}
238
112
239
- fileprivate extension SyntaxProtocol {
240
- /// Perform a format if required and then trim any leading/trailing
241
- /// whitespace.
242
- func formattedExpansion( _ mode: FormatMode ) -> String {
243
- let formatted : Syntax
244
- switch mode {
245
- case . auto:
246
- formatted = self . formatted ( )
247
- case . disabled:
248
- formatted = Syntax ( self )
113
+ private extension MacroRole {
114
+ init ( messageMacroRole: PluginMessage . MacroRole ) {
115
+ switch messageMacroRole {
116
+ case . expression: self = . expression
117
+ case . declaration: self = . declaration
118
+ case . accessor: self = . accessor
119
+ case . memberAttribute: self = . memberAttribute
120
+ case . member: self = . member
121
+ case . peer: self = . peer
122
+ case . conformance: self = . conformance
123
+ case . codeItem: self = . codeItem
249
124
}
250
- return formatted. trimmedDescription ( matching: { $0. isWhitespace } )
251
125
}
252
126
}
0 commit comments