Skip to content

Commit 1481235

Browse files
authored
Add an accessor macro example (#2565)
1 parent 05a06ed commit 1481235

File tree

6 files changed

+150
-0
lines changed

6 files changed

+150
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftSyntax
14+
import SwiftSyntaxMacros
15+
16+
public struct EnvironmentValueMacro: AccessorMacro {
17+
public static func expansion(
18+
of node: AttributeSyntax,
19+
providingAccessorsOf declaration: some DeclSyntaxProtocol,
20+
in context: some MacroExpansionContext
21+
) throws -> [AccessorDeclSyntax] {
22+
guard
23+
case let .argumentList(arguments) = node.arguments,
24+
let argument = arguments.first
25+
else { return [] }
26+
27+
return [
28+
"""
29+
get { self[\(argument.expression)] }
30+
""",
31+
"""
32+
set { self[\(argument.expression)] = newValue }
33+
""",
34+
]
35+
}
36+
}

Examples/Sources/MacroExamples/Implementation/Plugin.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct MyPlugin: CompilerPlugin {
2626
DefaultFatalErrorImplementationMacro.self,
2727
DictionaryStorageMacro.self,
2828
DictionaryStoragePropertyMacro.self,
29+
EnvironmentValueMacro.self,
2930
EquatableExtensionMacro.self,
3031
FontLiteralMacro.self,
3132
FuncUniqueMacro.self,
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#if canImport(SwiftUI)
14+
15+
import SwiftUI
16+
17+
// MARK: - EnvironmentValue Accessor
18+
19+
/// Adds getter / setter to an attached environment value with specified EnvironmentKey
20+
@attached(accessor)
21+
public macro EnvironmentValue(for key: any EnvironmentKey.Type) =
22+
#externalMacro(module: "MacroExamplesImplementation", type: "EnvironmentValueMacro")
23+
24+
#endif
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
// MARK: - EnvironmentValue Accessor
14+
15+
import MacroExamplesInterface
16+
17+
#if canImport(SwiftUI)
18+
19+
import SwiftUI
20+
21+
private struct MyEnvironmentKey: EnvironmentKey {
22+
static let defaultValue: String = "Default value"
23+
}
24+
25+
extension EnvironmentValues {
26+
@EnvironmentValue(for: MyEnvironmentKey.self)
27+
var myCustomValue: String
28+
}
29+
30+
func runEnvironmentValueAccessorMacroPlayground() {
31+
var environmentValues = EnvironmentValues()
32+
print("Default myCustomValue: \(environmentValues.myCustomValue)")
33+
environmentValues.myCustomValue = "New value"
34+
print("New myCustomValue: \(environmentValues.myCustomValue)")
35+
}
36+
37+
#endif

Examples/Sources/MacroExamples/Playground/main.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ runMemberMacrosPlayground()
4747
// MARK: - Peer Macros
4848

4949
runPeerMacrosPlayground()
50+
51+
// MARK: - Accessor Macros
52+
53+
#if canImport(SwiftUI)
54+
55+
runEnvironmentValueAccessorMacroPlayground()
56+
57+
#endif
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import MacroExamplesImplementation
14+
import SwiftSyntaxMacros
15+
import SwiftSyntaxMacrosTestSupport
16+
import XCTest
17+
18+
final class EnvironmentValueMacroMacroTests: XCTestCase {
19+
private let macros = ["EnvironmentValue": EnvironmentValueMacro.self]
20+
21+
func testEnvironmentValue() {
22+
assertMacroExpansion(
23+
"""
24+
extension EnvironmentValues {
25+
@EnvironmentValue(for: MyEnvironmentKey.self)
26+
var myCustomValue: String
27+
}
28+
""",
29+
expandedSource: """
30+
extension EnvironmentValues {
31+
var myCustomValue: String {
32+
get {
33+
self[MyEnvironmentKey.self]
34+
}
35+
set {
36+
self[MyEnvironmentKey.self] = newValue
37+
}
38+
}
39+
}
40+
""",
41+
macros: macros
42+
)
43+
}
44+
}

0 commit comments

Comments
 (0)