jarod
(Jarod Long)
1
I'm trying to write a macro that will replace a stored property with a computed property similar to how the Observable macro works. But I can't get this to work for properties that define initial values. I have something like this:
extension Foo {
@Bar static let someFoo = Foo()
}
Which I want to translate into something like this:
extension Foo {
static var someFoo: Foo {
// some extra logic here
return _someFoo
}
private static var _someFoo = Foo()
}
However, it seems like the annotated property can only be modified in the specific ways that the macro system allows. So I can add the private stored property, and I can add an accessor to the original property, but the property remains as it was written, so I end up with this:
extension Foo {
static let someFoo = Foo() {
// some extra logic here
return _someFoo
}
private static var _someFoo = Foo()
}
Which is invalid because the computed property is a let and has an initial value.
I could require writing var instead (though I'd prefer to keep using let), but I'd still need to somehow replace the initial value with a type annotation.
Am I overlooking something? How does the Observable macro accomplish this?
bbrk24
2
Isn’t this the exact thing that property wrappers are for? I don’t see why you’d need a full-fledged macro for this.
jarod
(Jarod Long)
3
The particular use case I have involves generating a string based on the name of the property which is why I'm using a macro. But your comment made me realize that I should be able to accomplish what I'm trying to do by using a macro to apply a property wrapper, so thanks for the suggestion!
I'm still curious about the original question though. I took a closer look at the proposal, and it has this to say about accessor macros:
A side effect of the expansion is to remove any initializer from the stored property itself; it is up to the implementation of the accessor macro to either diagnose the presence of the initializer (if it cannot be used) or incorporate it in the result.
Now I'm wondering if there's a bug, because I don't actually see the initializer being removed from the property.
5 Likes
For everyone coming across this issue via search engines:
There has already been filed a bug report on GitHub apple/swift (#63731)
See here: GitHub Issue 63731 on apple/swift
2 Likes