Hi-

Inside an init function in a generic protocol extension, I am currently using a 
Mirror reflecting an instance of “Self" to iterate through all the Child 
properties of the type adopting the protocol (Self). 

Now, I want to be able to determine how many of Self's properties have a 
default value prior to any init methods being called. I also would like to know 
other metadata about these properties, such as what their access level 
(private/internal/public/open) is, what their ownership is (weak, unowned, 
etc.), whether they are declared on a parent class or on the existing 
class/struct/enum, and ideally, get the highest access-level KeyPath to each 
property under the current scope (since it’s in the type’s own init method now, 
that scope should be “everything”).

However, so far I am finding Child to be extremely limiting. You can’t get any 
children of Self.self; you have to reflect an instance. And then, all you get 
is a string for the key of the property, which evidently cannot even be used to 
form a KeyPath—not even using the #keypath(String) argument! You don’t get any 
of the metadata I want via this method, from what I can tell. Am I missing 
something…? 

Forgetting about generic protocols for a second, even with a concrete type, I 
can’t seem to figure out how one would be able to use KeyPaths in the manner 
that I’m trying to do. Here is an example showing some of these limitations:

struct Foo {
    private(set) var hasDefaultValue = true
    private(set) var doesNotHaveDefaultValue: Bool
    var default = Foo(hasDefaultValue: true, doesNotHaveDefaultValue: false)
}

init() {
    for child in Mirror(reflecting: Foo.default) {
        let key = #keypath(“Foo.” + child.label) // won’t compile; worthless
        let path: WritableKeyPath<Foo, Bool> = \Foo.doesNotHaveDefaultValue // 
compiles, so far so good… (false hope)
        self[keyPath: path] = false // crashes even though it’s a 
WritableKeyPath; worthless
        … etc. etc.
    }
}

Are these just bugs? Or is keyPath really this limited? Is there really no way 
in Swift to use reflection to get all the information on a type’s properties, 
not even from within the type’s own init method?

So far it seems that Mirror just returns for each property<T> a (label: String, 
value: T) tuple where label is just a String, and value is whatever type the 
property is. Meanwhile, in the C++ of the open source Swift compiler code, they 
have a method allowing the compiler to determine whether or not a property has 
a default value. I just want to know if there’s a way to do it from within 
Swift, or if all these goodies are still only available in C++. If I need to 
submit a PR to mod the compiler then I will, I just want to make sure I’m not 
missing something here.

Thanks,

Jon
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to