Pitch: Introduce custom attributes

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
    }
}
7 Likes