@@ -109,6 +109,15 @@ public struct ObservableMacro {
109
109
trailingTrivia: . space
110
110
)
111
111
}
112
+
113
+ static var trackedAttribute : AttributeSyntax {
114
+ AttributeSyntax (
115
+ leadingTrivia: . space,
116
+ atSign: . atSignToken( ) ,
117
+ attributeName: IdentifierTypeSyntax ( name: . identifier( trackedMacroName) ) ,
118
+ trailingTrivia: . space
119
+ )
120
+ }
112
121
}
113
122
114
123
struct ObservationDiagnostic : DiagnosticMessage {
@@ -142,8 +151,13 @@ extension DiagnosticsError {
142
151
}
143
152
}
144
153
154
+
155
+ struct LocalMacroExpansionContext < Context: MacroExpansionContext > {
156
+ var context : Context
157
+ }
158
+
145
159
extension DeclModifierListSyntax {
146
- func privatePrefixed( _ prefix: String ) -> DeclModifierListSyntax {
160
+ func privatePrefixed( _ prefix: String , in context : LocalMacroExpansionContext < some MacroExpansionContext > ) -> DeclModifierListSyntax {
147
161
let modifier : DeclModifierSyntax = DeclModifierSyntax ( name: " private " , trailingTrivia: . space)
148
162
return [ modifier] + filter {
149
163
switch $0. name. tokenKind {
@@ -170,7 +184,7 @@ extension DeclModifierListSyntax {
170
184
}
171
185
172
186
extension TokenSyntax {
173
- func privatePrefixed( _ prefix: String ) -> TokenSyntax {
187
+ func privatePrefixed( _ prefix: String , in context : LocalMacroExpansionContext < some MacroExpansionContext > ) -> TokenSyntax {
174
188
switch tokenKind {
175
189
case . identifier( let identifier) :
176
190
return TokenSyntax ( . identifier( prefix + identifier) , leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia, presence: presence)
@@ -180,8 +194,58 @@ extension TokenSyntax {
180
194
}
181
195
}
182
196
197
+ extension CodeBlockSyntax {
198
+ func locationAnnotated( in context: LocalMacroExpansionContext < some MacroExpansionContext > ) -> CodeBlockSyntax {
199
+ guard let firstStatement = statements. first, let loc = context. context. location ( of: firstStatement) else {
200
+ return self
201
+ }
202
+
203
+ return CodeBlockSyntax (
204
+ leadingTrivia: leadingTrivia,
205
+ leftBrace: leftBrace,
206
+ statements: CodeBlockItemListSyntax {
207
+ " #sourceLocation(file: \( loc. file) , line: \( loc. line) ) "
208
+ statements
209
+ " #sourceLocation() "
210
+ } ,
211
+ rightBrace: rightBrace,
212
+ trailingTrivia: trailingTrivia
213
+ )
214
+ }
215
+ }
216
+
217
+
218
+ extension AccessorDeclSyntax {
219
+ func locationAnnotated( in context: LocalMacroExpansionContext < some MacroExpansionContext > ) -> AccessorDeclSyntax {
220
+ return AccessorDeclSyntax (
221
+ leadingTrivia: leadingTrivia,
222
+ attributes: attributes,
223
+ modifier: modifier,
224
+ accessorSpecifier: accessorSpecifier,
225
+ parameters: parameters,
226
+ effectSpecifiers: effectSpecifiers,
227
+ body: body? . locationAnnotated ( in: context) ,
228
+ trailingTrivia: trailingTrivia
229
+ )
230
+ }
231
+ }
232
+
233
+ extension AccessorBlockSyntax {
234
+ func locationAnnotated( in context: LocalMacroExpansionContext < some MacroExpansionContext > ) -> AccessorBlockSyntax {
235
+ switch accessors {
236
+ case . accessors( let accessorList) :
237
+ let remapped = AccessorDeclListSyntax {
238
+ accessorList. map { $0. locationAnnotated ( in: context) }
239
+ }
240
+ return AccessorBlockSyntax ( accessors: . accessors( remapped) )
241
+ case . getter( let codeBlockList) :
242
+ return AccessorBlockSyntax ( accessors: . getter( codeBlockList) )
243
+ }
244
+ }
245
+ }
246
+
183
247
extension PatternBindingListSyntax {
184
- func privatePrefixed( _ prefix: String ) -> PatternBindingListSyntax {
248
+ func privatePrefixed( _ prefix: String , in context : LocalMacroExpansionContext < some MacroExpansionContext > ) -> PatternBindingListSyntax {
185
249
var bindings = self . map { $0 }
186
250
for index in 0 ..< bindings. count {
187
251
let binding = bindings [ index]
@@ -190,12 +254,12 @@ extension PatternBindingListSyntax {
190
254
leadingTrivia: binding. leadingTrivia,
191
255
pattern: IdentifierPatternSyntax (
192
256
leadingTrivia: identifier. leadingTrivia,
193
- identifier: identifier. identifier. privatePrefixed ( prefix) ,
257
+ identifier: identifier. identifier. privatePrefixed ( prefix, in : context ) ,
194
258
trailingTrivia: identifier. trailingTrivia
195
259
) ,
196
260
typeAnnotation: binding. typeAnnotation,
197
261
initializer: binding. initializer,
198
- accessorBlock: binding. accessorBlock,
262
+ accessorBlock: binding. accessorBlock? . locationAnnotated ( in : context ) ,
199
263
trailingComma: binding. trailingComma,
200
264
trailingTrivia: binding. trailingTrivia)
201
265
@@ -207,14 +271,20 @@ extension PatternBindingListSyntax {
207
271
}
208
272
209
273
extension VariableDeclSyntax {
210
- func privatePrefixed( _ prefix: String , addingAttribute attribute: AttributeSyntax ) -> VariableDeclSyntax {
211
- let newAttributes = attributes + [ . attribute( attribute) ]
274
+ func privatePrefixed( _ prefix: String , addingAttribute attribute: AttributeSyntax , removingAttribute toRemove: AttributeSyntax , in context: LocalMacroExpansionContext < some MacroExpansionContext > ) -> VariableDeclSyntax {
275
+ let newAttributes = attributes. filter { attribute in
276
+ switch attribute {
277
+ case . attribute( let attr) :
278
+ attr. attributeName. identifier != toRemove. attributeName. identifier
279
+ default : true
280
+ }
281
+ } + [ . attribute( attribute) ]
212
282
return VariableDeclSyntax (
213
283
leadingTrivia: leadingTrivia,
214
284
attributes: newAttributes,
215
- modifiers: modifiers. privatePrefixed ( prefix) ,
285
+ modifiers: modifiers. privatePrefixed ( prefix, in : context ) ,
216
286
bindingSpecifier: TokenSyntax ( bindingSpecifier. tokenKind, leadingTrivia: . space, trailingTrivia: . space, presence: . present) ,
217
- bindings: bindings. privatePrefixed ( prefix) ,
287
+ bindings: bindings. privatePrefixed ( prefix, in : context ) ,
218
288
trailingTrivia: trailingTrivia
219
289
)
220
290
}
@@ -417,12 +487,12 @@ extension ObservationTrackedMacro: PeerMacro {
417
487
return [ ]
418
488
}
419
489
420
- if property. hasMacroApplication ( ObservableMacro . ignoredMacroName) ||
421
- property. hasMacroApplication ( ObservableMacro . trackedMacroName) {
490
+ if property. hasMacroApplication ( ObservableMacro . ignoredMacroName) {
422
491
return [ ]
423
492
}
424
493
425
- let storage = DeclSyntax ( property. privatePrefixed ( " _ " , addingAttribute: ObservableMacro . ignoredAttribute) )
494
+ let localContext = LocalMacroExpansionContext ( context: context)
495
+ let storage = DeclSyntax ( property. privatePrefixed ( " _ " , addingAttribute: ObservableMacro . ignoredAttribute, removingAttribute: ObservableMacro . trackedAttribute, in: localContext) )
426
496
return [ storage]
427
497
}
428
498
}
0 commit comments