@@ -21,7 +21,9 @@ public struct TestDeclarationMacro: PeerMacro, Sendable {
21
21
providingPeersOf declaration: some DeclSyntaxProtocol ,
22
22
in context: some MacroExpansionContext
23
23
) throws -> [ DeclSyntax ] {
24
- _diagnoseIssues ( with: declaration, testAttribute: node, in: context)
24
+ guard _diagnoseIssues ( with: declaration, testAttribute: node, in: context) else {
25
+ return [ ]
26
+ }
25
27
26
28
guard let function = declaration. as ( FunctionDeclSyntax . self) else {
27
29
return [ ]
@@ -45,6 +47,17 @@ public struct TestDeclarationMacro: PeerMacro, Sendable {
45
47
testAttribute: AttributeSyntax ,
46
48
in context: some MacroExpansionContext
47
49
) -> TypeSyntax ? {
50
+ #if canImport(SwiftSyntax600)
51
+ let types = context. lexicalContext
52
+ . compactMap { $0. asProtocol ( ( any DeclGroupSyntax ) . self) }
53
+ . map ( \. type)
54
+ . reversed ( )
55
+ if types. isEmpty {
56
+ return nil
57
+ }
58
+ let typeName = types. map ( \. trimmedDescription) . joined ( separator: " . " )
59
+ return " \( raw: typeName) "
60
+ #else
48
61
// Find the beginning of the first attribute on the declaration, including
49
62
// those embedded in #if statements, to account for patterns like
50
63
// `@MainActor @Test func` where there's a space ahead of @Test, but the
@@ -79,6 +92,7 @@ public struct TestDeclarationMacro: PeerMacro, Sendable {
79
92
return TypeSyntax ( IdentifierTypeSyntax ( name: . keyword( . Self) ) )
80
93
}
81
94
return nil
95
+ #endif
82
96
}
83
97
84
98
/// Diagnose issues with a `@Test` declaration.
@@ -87,22 +101,30 @@ public struct TestDeclarationMacro: PeerMacro, Sendable {
87
101
/// - declaration: The function declaration to diagnose.
88
102
/// - testAttribute: The `@Test` attribute applied to `declaration`.
89
103
/// - context: The macro context in which the expression is being parsed.
104
+ ///
105
+ /// - Returns: Whether or not macro expansion should continue (i.e. stopping
106
+ /// if a fatal error was diagnosed.)
90
107
private static func _diagnoseIssues(
91
108
with declaration: some DeclSyntaxProtocol ,
92
109
testAttribute: AttributeSyntax ,
93
110
in context: some MacroExpansionContext
94
- ) {
111
+ ) -> Bool {
95
112
var diagnostics = [ DiagnosticMessage] ( )
96
113
defer {
97
- diagnostics . forEach ( context. diagnose)
114
+ context. diagnose ( diagnostics )
98
115
}
99
116
100
117
// The @Test attribute is only supported on function declarations.
101
118
guard let function = declaration. as ( FunctionDeclSyntax . self) else {
102
119
diagnostics. append ( . attributeNotSupported( testAttribute, on: declaration) )
103
- return
120
+ return false
104
121
}
105
122
123
+ #if canImport(SwiftSyntax600)
124
+ // Check if the lexical context is appropriate for a suite or test.
125
+ diagnostics += diagnoseIssuesWithLexicalContext ( containing: declaration, attribute: testAttribute, in: context)
126
+ #endif
127
+
106
128
// Only one @Test attribute is supported.
107
129
let suiteAttributes = function. attributes ( named: " Test " , in: context)
108
130
if suiteAttributes. count > 1 {
@@ -144,6 +166,8 @@ public struct TestDeclarationMacro: PeerMacro, Sendable {
144
166
}
145
167
}
146
168
}
169
+
170
+ return !diagnostics. lazy. map ( \. severity) . contains ( . error)
147
171
}
148
172
149
173
/// Create a function call parameter list used to call a function from its
@@ -406,6 +430,11 @@ public struct TestDeclarationMacro: PeerMacro, Sendable {
406
430
) -> [ DeclSyntax ] {
407
431
var result = [ DeclSyntax] ( )
408
432
433
+ #if canImport(SwiftSyntax600)
434
+ // Get the name of the type containing the function for passing to the test
435
+ // factory function later.
436
+ let typealiasExpr : ExprSyntax = typeName. map { " \( $0) .self " } ?? " nil "
437
+ #else
409
438
// We cannot directly refer to Self here because it will end up being
410
439
// resolved as the __TestContainer type we generate. Create a uniquely-named
411
440
// reference to Self outside the context of the generated type, and use it
@@ -415,7 +444,7 @@ public struct TestDeclarationMacro: PeerMacro, Sendable {
415
444
// inside a static computed property instead of a typealias (where covariant
416
445
// Self is disallowed.)
417
446
//
418
- // This "typealias" will not be necessary when rdar://105470382 is resolved .
447
+ // This "typealias" is not necessary when swift-syntax-6.0.0 is available .
419
448
var typealiasExpr : ExprSyntax = " nil "
420
449
if let typeName {
421
450
let typealiasName = context. makeUniqueName ( thunking: functionDecl)
@@ -430,6 +459,7 @@ public struct TestDeclarationMacro: PeerMacro, Sendable {
430
459
431
460
typealiasExpr = " \( typealiasName) "
432
461
}
462
+ #endif
433
463
434
464
// Parse the @Test attribute.
435
465
let attributeInfo = AttributeInfo ( byParsing: testAttribute, on: functionDecl, in: context)
0 commit comments