@@ -109,6 +109,15 @@ public struct ObservableMacro {
109109 trailingTrivia: . space
110110 )
111111 }
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+ }
112121}
113122
114123struct ObservationDiagnostic : DiagnosticMessage {
@@ -142,8 +151,13 @@ extension DiagnosticsError {
142151 }
143152}
144153
154+
155+ struct LocalMacroExpansionContext < Context: MacroExpansionContext > {
156+ var context : Context
157+ }
158+
145159extension DeclModifierListSyntax {
146- func privatePrefixed( _ prefix: String ) -> DeclModifierListSyntax {
160+ func privatePrefixed( _ prefix: String , in context : LocalMacroExpansionContext < some MacroExpansionContext > ) -> DeclModifierListSyntax {
147161 let modifier : DeclModifierSyntax = DeclModifierSyntax ( name: " private " , trailingTrivia: . space)
148162 return [ modifier] + filter {
149163 switch $0. name. tokenKind {
@@ -170,7 +184,7 @@ extension DeclModifierListSyntax {
170184}
171185
172186extension TokenSyntax {
173- func privatePrefixed( _ prefix: String ) -> TokenSyntax {
187+ func privatePrefixed( _ prefix: String , in context : LocalMacroExpansionContext < some MacroExpansionContext > ) -> TokenSyntax {
174188 switch tokenKind {
175189 case . identifier( let identifier) :
176190 return TokenSyntax ( . identifier( prefix + identifier) , leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia, presence: presence)
@@ -180,8 +194,58 @@ extension TokenSyntax {
180194 }
181195}
182196
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+
183247extension PatternBindingListSyntax {
184- func privatePrefixed( _ prefix: String ) -> PatternBindingListSyntax {
248+ func privatePrefixed( _ prefix: String , in context : LocalMacroExpansionContext < some MacroExpansionContext > ) -> PatternBindingListSyntax {
185249 var bindings = self . map { $0 }
186250 for index in 0 ..< bindings. count {
187251 let binding = bindings [ index]
@@ -190,12 +254,12 @@ extension PatternBindingListSyntax {
190254 leadingTrivia: binding. leadingTrivia,
191255 pattern: IdentifierPatternSyntax (
192256 leadingTrivia: identifier. leadingTrivia,
193- identifier: identifier. identifier. privatePrefixed ( prefix) ,
257+ identifier: identifier. identifier. privatePrefixed ( prefix, in : context ) ,
194258 trailingTrivia: identifier. trailingTrivia
195259 ) ,
196260 typeAnnotation: binding. typeAnnotation,
197261 initializer: binding. initializer,
198- accessorBlock: binding. accessorBlock,
262+ accessorBlock: binding. accessorBlock? . locationAnnotated ( in : context ) ,
199263 trailingComma: binding. trailingComma,
200264 trailingTrivia: binding. trailingTrivia)
201265
@@ -207,14 +271,20 @@ extension PatternBindingListSyntax {
207271}
208272
209273extension 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) ]
212282 return VariableDeclSyntax (
213283 leadingTrivia: leadingTrivia,
214284 attributes: newAttributes,
215- modifiers: modifiers. privatePrefixed ( prefix) ,
285+ modifiers: modifiers. privatePrefixed ( prefix, in : context ) ,
216286 bindingSpecifier: TokenSyntax ( bindingSpecifier. tokenKind, leadingTrivia: . space, trailingTrivia: . space, presence: . present) ,
217- bindings: bindings. privatePrefixed ( prefix) ,
287+ bindings: bindings. privatePrefixed ( prefix, in : context ) ,
218288 trailingTrivia: trailingTrivia
219289 )
220290 }
@@ -417,12 +487,12 @@ extension ObservationTrackedMacro: PeerMacro {
417487 return [ ]
418488 }
419489
420- if property. hasMacroApplication ( ObservableMacro . ignoredMacroName) ||
421- property. hasMacroApplication ( ObservableMacro . trackedMacroName) {
490+ if property. hasMacroApplication ( ObservableMacro . ignoredMacroName) {
422491 return [ ]
423492 }
424493
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) )
426496 return [ storage]
427497 }
428498}
0 commit comments