File tree 3 files changed +66
-1
lines changed
SwiftSyntaxMacroExpansion
SwiftSyntaxMacros/MacroProtocols
Tests/SwiftSyntaxMacroExpansionTest 3 files changed +66
-1
lines changed Original file line number Diff line number Diff line change @@ -520,7 +520,12 @@ fileprivate extension SyntaxProtocol {
520
520
for macro: Macro . Type ,
521
521
indentationWidth: Trivia ?
522
522
) -> String {
523
- let syntax = Syntax ( self )
523
+ var syntax = Syntax ( self )
524
+
525
+ // Infer nonisolated conformances.
526
+ if macro. inferNonisolatedConformances {
527
+ syntax = syntax. inferNonisolatedConformances ( )
528
+ }
524
529
525
530
// Formatting.
526
531
switch macro. formatMode {
Original file line number Diff line number Diff line change @@ -15,4 +15,29 @@ public protocol Macro {
15
15
/// How the resulting expansion should be formatted, `.auto` by default.
16
16
/// Use `.disabled` for the expansion to be used as is.
17
17
static var formatMode : FormatMode { get }
18
+
19
+ /// Whether to infer "nonisolated" on protocol conformances introduced in
20
+ /// the macro expansion when there are some nonisolated members in the
21
+ /// corresponding declaration group. When true, macro expansion will adjust
22
+ /// expanded code such as
23
+ ///
24
+ /// extension C: P {
25
+ /// nonisolated func f() { }
26
+ /// }
27
+ ///
28
+ /// to
29
+ ///
30
+ /// extension C: nonisolated P {
31
+ /// nonisolated func f() { }
32
+ /// }
33
+ ///
34
+ /// This operation defaults to `true`. Macros can implement it to return
35
+ /// `false` to prevent this adjustment to the macro-expanded code.
36
+ static var inferNonisolatedConformances : Bool { get }
37
+ }
38
+
39
+ extension Macro {
40
+ /// Default implementation of the Macro protocol's
41
+ /// `inferNonisolatedConformances` that returns `true`.
42
+ public static var inferNonisolatedConformances : Bool { true }
18
43
}
Original file line number Diff line number Diff line change @@ -251,6 +251,41 @@ final class ExtensionMacroTests: XCTestCase {
251
251
indentationWidth: indentationWidth
252
252
)
253
253
}
254
+
255
+ func testNonisolatedConformances( ) {
256
+ struct NonisolatedConformanceMacro : ExtensionMacro {
257
+ static func expansion(
258
+ of node: AttributeSyntax ,
259
+ attachedTo declaration: some DeclGroupSyntax ,
260
+ providingExtensionsOf type: some TypeSyntaxProtocol ,
261
+ conformingTo protocols: [ TypeSyntax ] ,
262
+ in context: some MacroExpansionContext
263
+ ) throws -> [ ExtensionDeclSyntax ] {
264
+ return [
265
+ ( """
266
+ extension \( type) : P {
267
+ nonisolated func f() { }
268
+ }
269
+ """ as DeclSyntax ) . cast ( ExtensionDeclSyntax . self)
270
+ ]
271
+ }
272
+ }
273
+
274
+ assertMacroExpansion (
275
+ " @NonisolatedConformance struct Foo {} " ,
276
+ expandedSource: """
277
+ struct Foo {}
278
+
279
+ extension Foo: nonisolated P {
280
+ nonisolated func f() {
281
+ }
282
+ }
283
+ """ ,
284
+ macros: [
285
+ " NonisolatedConformance " : NonisolatedConformanceMacro . self
286
+ ]
287
+ )
288
+ }
254
289
}
255
290
256
291
fileprivate struct SendableExtensionMacro : ExtensionMacro {
You can’t perform that action at this time.
0 commit comments