Skip to content

Commit 954a493

Browse files
authored
Merge pull request #2188 from ahoppen/ahoppen/509/accessor-return-empty-array
[509] Don’t add any accessors if accessor macro returned an empty array
2 parents 7bb5231 + 47c846c commit 954a493

File tree

2 files changed

+228
-1
lines changed

2 files changed

+228
-1
lines changed

Sources/SwiftSyntaxMacroExpansion/MacroSystem.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,8 @@ private func expandAccessorMacroWithoutExistingAccessors(
259259
conformanceList: nil,
260260
in: context,
261261
indentationWidth: indentationWidth
262-
)
262+
),
263+
!expanded.isEmpty
263264
else {
264265
return nil
265266
}

Tests/SwiftSyntaxMacroExpansionTest/MacroSystemTests.swift

+226
Original file line numberDiff line numberDiff line change
@@ -2088,4 +2088,230 @@ final class MacroSystemTests: XCTestCase {
20882088
macros: ["Test": DiagnoseFirstArgument.self]
20892089
)
20902090
}
2091+
2092+
func testEmptyAccessorMacro() {
2093+
struct TestMacro: AccessorMacro {
2094+
static func expansion(
2095+
of node: AttributeSyntax,
2096+
providingAccessorsOf declaration: some DeclSyntaxProtocol,
2097+
in context: some MacroExpansionContext
2098+
) throws -> [AccessorDeclSyntax] {
2099+
return []
2100+
}
2101+
}
2102+
2103+
// The compiler will reject this with
2104+
// 'Expansion of macro 'Test()' did not produce a non-observing accessor'
2105+
// We consider this a semantic error because swift-syntax doesn't have
2106+
// knowledge about which accessors are observing and which ones aren't.
2107+
assertMacroExpansion(
2108+
"@Test var x: Int",
2109+
expandedSource: "var x: Int",
2110+
macros: ["Test": TestMacro.self]
2111+
)
2112+
2113+
assertMacroExpansion(
2114+
"@Test var x: Int { 1 }",
2115+
expandedSource: "var x: Int { 1 }",
2116+
macros: ["Test": TestMacro.self]
2117+
)
2118+
}
2119+
2120+
func testEmitErrorFromAccessorMacro() {
2121+
struct TestMacro: AccessorMacro {
2122+
static func expansion(
2123+
of node: AttributeSyntax,
2124+
providingAccessorsOf declaration: some DeclSyntaxProtocol,
2125+
in context: some MacroExpansionContext
2126+
) throws -> [AccessorDeclSyntax] {
2127+
context.diagnose(Diagnostic(node: node, message: MacroExpansionErrorMessage("test")))
2128+
return []
2129+
}
2130+
}
2131+
2132+
assertMacroExpansion(
2133+
"@Test var x: Int",
2134+
expandedSource: "var x: Int",
2135+
diagnostics: [
2136+
DiagnosticSpec(message: "test", line: 1, column: 1)
2137+
],
2138+
macros: ["Test": TestMacro.self]
2139+
)
2140+
2141+
assertMacroExpansion(
2142+
"@Test var x: Int { 1 }",
2143+
expandedSource: "var x: Int { 1 }",
2144+
diagnostics: [DiagnosticSpec(message: "test", line: 1, column: 1)],
2145+
macros: ["Test": TestMacro.self]
2146+
)
2147+
}
2148+
2149+
func testEmptyCodeItemMacro() {
2150+
struct TestMacro: CodeItemMacro {
2151+
static func expansion(
2152+
of node: some FreestandingMacroExpansionSyntax,
2153+
in context: some MacroExpansionContext
2154+
) throws -> [CodeBlockItemSyntax] {
2155+
return []
2156+
}
2157+
}
2158+
2159+
assertMacroExpansion(
2160+
"#test",
2161+
expandedSource: "",
2162+
macros: [
2163+
"test": TestMacro.self
2164+
]
2165+
)
2166+
}
2167+
2168+
func testEmptyDeclarationMacro() {
2169+
struct TestMacro: DeclarationMacro {
2170+
static func expansion(
2171+
of node: some FreestandingMacroExpansionSyntax,
2172+
in context: some MacroExpansionContext
2173+
) throws -> [DeclSyntax] {
2174+
return []
2175+
}
2176+
}
2177+
2178+
assertMacroExpansion(
2179+
"#test",
2180+
expandedSource: "",
2181+
macros: [
2182+
"test": TestMacro.self
2183+
]
2184+
)
2185+
}
2186+
2187+
func testEmptyExtensionMacro() {
2188+
struct TestMacro: ExtensionMacro {
2189+
static func expansion(
2190+
of node: AttributeSyntax,
2191+
attachedTo declaration: some DeclGroupSyntax,
2192+
providingExtensionsOf type: some TypeSyntaxProtocol,
2193+
conformingTo protocols: [TypeSyntax],
2194+
in context: some MacroExpansionContext
2195+
) throws -> [ExtensionDeclSyntax] {
2196+
return []
2197+
}
2198+
}
2199+
2200+
assertMacroExpansion(
2201+
"@Test struct Foo {}",
2202+
expandedSource: "struct Foo {}",
2203+
macros: [
2204+
"Test": TestMacro.self
2205+
]
2206+
)
2207+
}
2208+
2209+
func testEmptyMemberAttributeMacro() {
2210+
struct TestMacro: MemberAttributeMacro {
2211+
static func expansion(
2212+
of node: AttributeSyntax,
2213+
attachedTo declaration: some DeclGroupSyntax,
2214+
providingAttributesFor member: some DeclSyntaxProtocol,
2215+
in context: some MacroExpansionContext
2216+
) throws -> [AttributeSyntax] {
2217+
return []
2218+
}
2219+
}
2220+
2221+
assertMacroExpansion(
2222+
"""
2223+
@Test
2224+
struct Foo {
2225+
var x: Int
2226+
}
2227+
""",
2228+
expandedSource: """
2229+
struct Foo {
2230+
var x: Int
2231+
}
2232+
""",
2233+
macros: [
2234+
"Test": TestMacro.self
2235+
]
2236+
)
2237+
2238+
assertMacroExpansion(
2239+
"""
2240+
@Test
2241+
struct Foo {
2242+
}
2243+
""",
2244+
expandedSource: """
2245+
struct Foo {
2246+
}
2247+
""",
2248+
macros: [
2249+
"Test": TestMacro.self
2250+
]
2251+
)
2252+
}
2253+
2254+
func testEmptyMemberMacro() {
2255+
struct TestMacro: MemberMacro {
2256+
static func expansion(
2257+
of node: AttributeSyntax,
2258+
providingMembersOf declaration: some DeclGroupSyntax,
2259+
in context: some MacroExpansionContext
2260+
) throws -> [DeclSyntax] {
2261+
return []
2262+
}
2263+
}
2264+
2265+
assertMacroExpansion(
2266+
"""
2267+
@Test
2268+
struct Foo {
2269+
var x: Int
2270+
}
2271+
""",
2272+
expandedSource: """
2273+
struct Foo {
2274+
var x: Int
2275+
}
2276+
""",
2277+
macros: [
2278+
"Test": TestMacro.self
2279+
]
2280+
)
2281+
2282+
assertMacroExpansion(
2283+
"""
2284+
@Test
2285+
struct Foo {
2286+
}
2287+
""",
2288+
expandedSource: """
2289+
struct Foo {
2290+
}
2291+
""",
2292+
macros: [
2293+
"Test": TestMacro.self
2294+
]
2295+
)
2296+
}
2297+
2298+
func testEmptyPeerMacro() {
2299+
struct TestMacro: PeerMacro {
2300+
static func expansion(
2301+
of node: AttributeSyntax,
2302+
providingPeersOf declaration: some DeclSyntaxProtocol,
2303+
in context: some MacroExpansionContext
2304+
) throws -> [DeclSyntax] {
2305+
return []
2306+
}
2307+
}
2308+
2309+
assertMacroExpansion(
2310+
"@Test var x: Int",
2311+
expandedSource: "var x: Int",
2312+
macros: [
2313+
"Test": TestMacro.self
2314+
]
2315+
)
2316+
}
20912317
}

0 commit comments

Comments
 (0)