I like where this is going with custom attributes, but instead of treating every property delegate type a different attribute and having property delegates as a language feature, could this maybe be implemented as just another static attribute? Doug's custom static attribute suggestion seems to be a good enough abstraction to leverage for this.
A static attribute would be defined in the standard library that describes how the property is to be synthesized.
@staticAttribute(usage: [.property])
struct Delegated<Delegate: PropertyDelegate> {
var delegate: Delegate
var delegateAccess: Access
init(to delegate: Delegate, delegateAccess: Access) { ... }
init(to delegate: Delegate.Type, delegateAccess: Access) { ... }
}
enum Access {
case `public`
case `internal`
case `fileprivate`
case `private`
case hidden
}
PropertyDelegate
would become a normal protocol. Users could then describe the property synthesis by applying the attribute:
class Test {
@Delegated(to: Lazy.self, delegateAccess: .public)
public var data: Data
}
The Swift compiler would interpret the attribute. For the given example, it would synthesize the following:
class Test {
public var $data: Lazy<Data>
public var data: Data {
get {
return $data
}
set {
$data = newValue
}
}
}
Delegated
could be expanded with additional optional properties like delegateName
if the user needs an alternative name, potentially not prefix with $.
The whole idea is very similar to ObjC way of synthesizing properties.