Skip to content

Commit 3a1e653

Browse files
authored
Add support for lexical context (#31)
* Pass lexical context into the BasicMacroExpensionContext. * Add basic tests to ensure lexical context is supplied by assertMacro.
1 parent d9a715b commit 3a1e653

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

Sources/MacroTesting/AssertMacro.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,9 @@ public func assertMacro(
203203
#if canImport(SwiftSyntax600)
204204
var expandedSourceFile = origSourceFile.expand(
205205
macros: macros,
206-
contextGenerator: { _ in context },
206+
contextGenerator: { syntax in
207+
BasicMacroExpansionContext(sharingWith: context, lexicalContext: syntax.allMacroLexicalContexts())
208+
},
207209
indentationWidth: indentationWidth
208210
)
209211
#else
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import MacroTesting
2+
import XCTest
3+
4+
final class EntryMacroTests: BaseTestCase {
5+
override func invokeTest() {
6+
withMacroTesting(
7+
macros: [
8+
EntryMacro.self,
9+
]
10+
) {
11+
super.invokeTest()
12+
}
13+
}
14+
15+
func testWithinEnvironmentValues() {
16+
assertMacro {
17+
"""
18+
extension EnvironmentValues {
19+
@Entry var x: String = ""
20+
}
21+
"""
22+
} expansion: {
23+
"""
24+
extension EnvironmentValues {
25+
var x: String {
26+
get {
27+
fatalError()
28+
}
29+
}
30+
}
31+
"""
32+
}
33+
}
34+
35+
func testNotWithinEnvironmentValues() {
36+
assertMacro {
37+
"""
38+
extension String {
39+
@Entry var x: String = ""
40+
}
41+
"""
42+
} diagnostics: {
43+
"""
44+
extension String {
45+
@Entry var x: String = ""
46+
┬─────
47+
╰─ 🛑 '@Entry' macro can only attach to var declarations inside extensions of EnvironmentValues
48+
}
49+
"""
50+
}
51+
}
52+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import SwiftSyntax
2+
import SwiftSyntaxMacros
3+
4+
// Not complete, just enough to unit test lexical context.
5+
public struct EntryMacro: AccessorMacro {
6+
public static func expansion(
7+
of node: AttributeSyntax,
8+
providingAccessorsOf declaration: some DeclSyntaxProtocol,
9+
in context: some MacroExpansionContext
10+
) throws -> [AccessorDeclSyntax] {
11+
let isInEnvironmentValues = context.lexicalContext.contains { lexicalContext in
12+
lexicalContext.as(ExtensionDeclSyntax.self)?.extendedType.trimmedDescription == "EnvironmentValues"
13+
}
14+
15+
guard isInEnvironmentValues else {
16+
throw MacroExpansionErrorMessage("'@Entry' macro can only attach to var declarations inside extensions of EnvironmentValues")
17+
}
18+
19+
return [
20+
AccessorDeclSyntax(accessorSpecifier: .keyword(.get)) {
21+
"fatalError()"
22+
},
23+
]
24+
}
25+
}

0 commit comments

Comments
 (0)