@@ -13,17 +13,18 @@ import SwiftSyntaxMacros
13
13
public struct AssociatedObjectMacro { }
14
14
15
15
extension AssociatedObjectMacro : PeerMacro {
16
- public static func expansion<
17
- Context: MacroExpansionContext ,
18
- Declaration: DeclSyntaxProtocol
19
- > (
16
+ public static func expansion< Context: MacroExpansionContext , Declaration: DeclSyntaxProtocol > (
20
17
of node: AttributeSyntax ,
21
18
providingPeersOf declaration: Declaration ,
22
19
in context: Context
23
20
) throws -> [ DeclSyntax ] {
21
+
24
22
guard let varDecl = declaration. as ( VariableDeclSyntax . self) ,
25
23
let binding = varDecl. bindings. first,
26
- let identifier = binding. pattern. as ( IdentifierPatternSyntax . self) ? . identifier else { return [ ] }
24
+ let identifier = binding. pattern. as ( IdentifierPatternSyntax . self) ? . identifier else {
25
+ context. diagnose ( AssociatedObjectMacroDiagnostic . requiresVariableDeclaration. diagnose ( at: declaration) )
26
+ return [ ]
27
+ }
27
28
28
29
let keyDecl = VariableDeclSyntax (
29
30
bindingKeyword: . identifier( " static var " ) ,
@@ -49,23 +50,28 @@ extension AssociatedObjectMacro: AccessorMacro {
49
50
in context: Context
50
51
) throws -> [ AccessorDeclSyntax ] {
51
52
52
- guard let varDecl = declaration. as ( VariableDeclSyntax . self) else {
53
+ guard let varDecl = declaration. as ( VariableDeclSyntax . self) ,
54
+ let binding = varDecl. bindings. first,
55
+ let identifier = binding. pattern. as ( IdentifierPatternSyntax . self) ? . identifier
56
+ else {
57
+ // Probably can't add a diagnose here, since this is an Accessor macro
53
58
context. diagnose ( AssociatedObjectMacroDiagnostic . requiresVariableDeclaration. diagnose ( at: declaration) )
54
59
return [ ]
55
60
}
56
61
57
- guard let binding = varDecl. bindings. first,
58
- let identifier = binding. pattern. as ( IdentifierPatternSyntax . self) ? . identifier,
59
- let type = binding. typeAnnotation? . type
60
- else {
62
+ // Explicit specification of type is required
63
+ guard let type = binding. typeAnnotation? . type else {
64
+ context. diagnose ( AssociatedObjectMacroDiagnostic . specifyTypeExplicitly. diagnose ( at: identifier) )
61
65
return [ ]
62
66
}
63
67
64
- guard binding. accessor == nil else {
65
- context. diagnose ( AssociatedObjectMacroDiagnostic . accessorShouldBeNil. diagnose ( at: declaration) )
68
+ // Error if accessor already exists
69
+ if let accessor = binding. accessor {
70
+ context. diagnose ( AssociatedObjectMacroDiagnostic . accessorShouldBeNil. diagnose ( at: accessor) )
66
71
return [ ]
67
72
}
68
73
74
+ // Initial value required
69
75
guard let defaultValue = binding. initializer? . value else {
70
76
context. diagnose ( AssociatedObjectMacroDiagnostic . requiresInitialValue. diagnose ( at: declaration) )
71
77
return [ ]
@@ -79,9 +85,8 @@ extension AssociatedObjectMacro: AccessorMacro {
79
85
80
86
return [
81
87
"""
82
-
83
88
get {
84
- return objc_getAssociatedObject(
89
+ objc_getAssociatedObject(
85
90
self,
86
91
&Self.__associated_ \( identifier) Key
87
92
) as? \( type)
0 commit comments