It makes sense to simplify this proposal by relegating runtime access to a future proposal, but I think its still important that we think about them. For example, I've always really liked the fact that C# Custom Attributes are defined as standard types and their constructors:
- it doesn't introduce a new syntax
- those types serve both as definition and as runtime metadata
- behaviour can be attached to them
Here's what it could look like in Swift:
@attribute(name: "codingKey", usage: .variables)
internal struct CodingKeyAttribute {
let key: String
init(key: String = "key") {
self.key = key
}
var snakeCase: String {
// ...
}
}
@attribute(name: "ignoreRules", usage: [.functions, .variables, .classes])
internal struct IgnoreRulesAttribute {
private let rules: [String]
private let printWarnings: Bool
init(_ rules: [String], printWarnings: Bool = false) {
self.rules = rules
self.printWarnings = printWarnings
}
}
Once we allow accessing them at runtime, we could reuse the type as metadata:
for attribute in myObject.reflectionMetadata.attributes {
if let codingKey = attribute as? CodingKeyAttribute {
print(codingKey.snakeCase)
} else if let ignoreRules = attribute as? IgnoreRulesAttribute {
// Ignore
}
}