Skip to content

Commit ead17c9

Browse files
authored
Merge pull request #2187 from ahoppen/ahoppen/accessor-return-empty-array
Don’t add any accessors if accessor macro returned an empty array
2 parents 0bd5eef + 46c02e9 commit ead17c9

8 files changed

+228
-1
lines changed

Sources/SwiftSyntaxMacroExpansion/MacroSystem.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,8 @@ private func expandAccessorMacroWithoutExistingAccessors(
267267
conformanceList: nil,
268268
in: context,
269269
indentationWidth: indentationWidth
270-
)
270+
),
271+
!expanded.isEmpty
271272
else {
272273
return nil
273274
}

Tests/SwiftSyntaxMacroExpansionTest/AccessorMacroTests.swift

+59
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
// macros are invoked. //
1919
//==========================================================================//
2020

21+
import SwiftDiagnostics
2122
import SwiftSyntax
23+
import SwiftSyntaxMacroExpansion
2224
import SwiftSyntaxMacros
2325
import SwiftSyntaxMacrosTestSupport
2426
import XCTest
@@ -261,4 +263,61 @@ final class AccessorMacroTests: XCTestCase {
261263
indentationWidth: indentationWidth
262264
)
263265
}
266+
267+
func testEmpty() {
268+
struct TestMacro: AccessorMacro {
269+
static func expansion(
270+
of node: AttributeSyntax,
271+
providingAccessorsOf declaration: some DeclSyntaxProtocol,
272+
in context: some MacroExpansionContext
273+
) throws -> [AccessorDeclSyntax] {
274+
return []
275+
}
276+
}
277+
278+
// The compiler will reject this with
279+
// 'Expansion of macro 'Test()' did not produce a non-observing accessor'
280+
// We consider this a semantic error because swift-syntax doesn't have
281+
// knowledge about which accessors are observing and which ones aren't.
282+
assertMacroExpansion(
283+
"@Test var x: Int",
284+
expandedSource: "var x: Int",
285+
macros: ["Test": TestMacro.self]
286+
)
287+
288+
assertMacroExpansion(
289+
"@Test var x: Int { 1 }",
290+
expandedSource: "var x: Int { 1 }",
291+
macros: ["Test": TestMacro.self]
292+
)
293+
}
294+
295+
func testEmitErrorFromMacro() {
296+
struct TestMacro: AccessorMacro {
297+
static func expansion(
298+
of node: AttributeSyntax,
299+
providingAccessorsOf declaration: some DeclSyntaxProtocol,
300+
in context: some MacroExpansionContext
301+
) throws -> [AccessorDeclSyntax] {
302+
context.diagnose(Diagnostic(node: node, message: MacroExpansionErrorMessage("test")))
303+
return []
304+
}
305+
}
306+
307+
assertMacroExpansion(
308+
"@Test var x: Int",
309+
expandedSource: "var x: Int",
310+
diagnostics: [
311+
DiagnosticSpec(message: "test", line: 1, column: 1)
312+
],
313+
macros: ["Test": TestMacro.self]
314+
)
315+
316+
assertMacroExpansion(
317+
"@Test var x: Int { 1 }",
318+
expandedSource: "var x: Int { 1 }",
319+
diagnostics: [DiagnosticSpec(message: "test", line: 1, column: 1)],
320+
macros: ["Test": TestMacro.self]
321+
)
322+
}
264323
}

Tests/SwiftSyntaxMacroExpansionTest/CodeItemMacroTests.swift

+19
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,23 @@ final class CodeItemMacroTests: XCTestCase {
133133
indentationWidth: indentationWidth
134134
)
135135
}
136+
137+
func testEmpty() {
138+
struct TestMacro: CodeItemMacro {
139+
static func expansion(
140+
of node: some FreestandingMacroExpansionSyntax,
141+
in context: some MacroExpansionContext
142+
) throws -> [CodeBlockItemSyntax] {
143+
return []
144+
}
145+
}
146+
147+
assertMacroExpansion(
148+
"#test",
149+
expandedSource: "",
150+
macros: [
151+
"test": TestMacro.self
152+
]
153+
)
154+
}
136155
}

Tests/SwiftSyntaxMacroExpansionTest/DeclarationMacroTests.swift

+18
Original file line numberDiff line numberDiff line change
@@ -389,4 +389,22 @@ final class DeclarationMacroTests: XCTestCase {
389389
)
390390
}
391391

392+
func testEmpty() {
393+
struct TestMacro: DeclarationMacro {
394+
static func expansion(
395+
of node: some FreestandingMacroExpansionSyntax,
396+
in context: some MacroExpansionContext
397+
) throws -> [DeclSyntax] {
398+
return []
399+
}
400+
}
401+
402+
assertMacroExpansion(
403+
"#test",
404+
expandedSource: "",
405+
macros: [
406+
"test": TestMacro.self
407+
]
408+
)
409+
}
392410
}

Tests/SwiftSyntaxMacroExpansionTest/ExtensionMacroTests.swift

+22
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,26 @@ final class ExtensionMacroTests: XCTestCase {
106106
indentationWidth: indentationWidth
107107
)
108108
}
109+
110+
func testEmpty() {
111+
struct TestMacro: ExtensionMacro {
112+
static func expansion(
113+
of node: AttributeSyntax,
114+
attachedTo declaration: some DeclGroupSyntax,
115+
providingExtensionsOf type: some TypeSyntaxProtocol,
116+
conformingTo protocols: [TypeSyntax],
117+
in context: some MacroExpansionContext
118+
) throws -> [ExtensionDeclSyntax] {
119+
return []
120+
}
121+
}
122+
123+
assertMacroExpansion(
124+
"@Test struct Foo {}",
125+
expandedSource: "struct Foo {}",
126+
macros: [
127+
"Test": TestMacro.self
128+
]
129+
)
130+
}
109131
}

Tests/SwiftSyntaxMacroExpansionTest/MemberAttributeMacroTests.swift

+44
Original file line numberDiff line numberDiff line change
@@ -354,4 +354,48 @@ final class MemberAttributeMacroTests: XCTestCase {
354354
)
355355
}
356356

357+
func testEmpty() {
358+
struct TestMacro: MemberAttributeMacro {
359+
static func expansion(
360+
of node: AttributeSyntax,
361+
attachedTo declaration: some DeclGroupSyntax,
362+
providingAttributesFor member: some DeclSyntaxProtocol,
363+
in context: some MacroExpansionContext
364+
) throws -> [AttributeSyntax] {
365+
return []
366+
}
367+
}
368+
369+
assertMacroExpansion(
370+
"""
371+
@Test
372+
struct Foo {
373+
var x: Int
374+
}
375+
""",
376+
expandedSource: """
377+
struct Foo {
378+
var x: Int
379+
}
380+
""",
381+
macros: [
382+
"Test": TestMacro.self
383+
]
384+
)
385+
386+
assertMacroExpansion(
387+
"""
388+
@Test
389+
struct Foo {
390+
}
391+
""",
392+
expandedSource: """
393+
struct Foo {
394+
}
395+
""",
396+
macros: [
397+
"Test": TestMacro.self
398+
]
399+
)
400+
}
357401
}

Tests/SwiftSyntaxMacroExpansionTest/MemberMacroTests.swift

+44
Original file line numberDiff line numberDiff line change
@@ -255,4 +255,48 @@ final class MemberMacroTests: XCTestCase {
255255
)
256256
}
257257

258+
func testEmpty() {
259+
struct TestMacro: MemberMacro {
260+
static func expansion(
261+
of node: AttributeSyntax,
262+
providingMembersOf declaration: some DeclGroupSyntax,
263+
conformingTo protocols: [TypeSyntax],
264+
in context: some MacroExpansionContext
265+
) throws -> [DeclSyntax] {
266+
return []
267+
}
268+
}
269+
270+
assertMacroExpansion(
271+
"""
272+
@Test
273+
struct Foo {
274+
var x: Int
275+
}
276+
""",
277+
expandedSource: """
278+
struct Foo {
279+
var x: Int
280+
}
281+
""",
282+
macros: [
283+
"Test": TestMacro.self
284+
]
285+
)
286+
287+
assertMacroExpansion(
288+
"""
289+
@Test
290+
struct Foo {
291+
}
292+
""",
293+
expandedSource: """
294+
struct Foo {
295+
}
296+
""",
297+
macros: [
298+
"Test": TestMacro.self
299+
]
300+
)
301+
}
258302
}

Tests/SwiftSyntaxMacroExpansionTest/PeerMacroTests.swift

+20
Original file line numberDiff line numberDiff line change
@@ -173,4 +173,24 @@ final class PeerMacroTests: XCTestCase {
173173
macros: ["Test": TestMacro.self]
174174
)
175175
}
176+
177+
func testEmpty() {
178+
struct TestMacro: PeerMacro {
179+
static func expansion(
180+
of node: AttributeSyntax,
181+
providingPeersOf declaration: some DeclSyntaxProtocol,
182+
in context: some MacroExpansionContext
183+
) throws -> [DeclSyntax] {
184+
return []
185+
}
186+
}
187+
188+
assertMacroExpansion(
189+
"@Test var x: Int",
190+
expandedSource: "var x: Int",
191+
macros: [
192+
"Test": TestMacro.self
193+
]
194+
)
195+
}
176196
}

0 commit comments

Comments
 (0)