On Mon, 13 Apr 2015 08:57:26 -0400, rcorre <[email protected]> wrote:

For me, having a solid reflection library like this is one of the most important improvements D can make right now.

At this point, I've kinda hit a wall.

Generating a hierarchical/object-oriented representation of the type system at compile-time using templates seems to be an all-or-nothing procedure.

Below is an example of the base() method of ClassRefl:

const(ClassRefl) base() const {
    static if(!is(T == Object)) {
        alias BaseClassesTuple!T base_type;
        return reflect!(base_type[0]);
    }
}

The method returns "reflect!(base_type[0])", which, when instantiated, will create another ClassRefl for the base class. That ClassRefl will also have a base() method, which will instantiate more reflections/templates, and so on... I also had a parent() method at one point, but since a module can be the parent of a class, it was possible that reflecting a single class using reflect!T could build entire reflection hierarchies for several modules. As soon as you reflect anything right now, all dependent reflections must also be instantiated. The amount of bloat(compiled binary size), and the increase in compile time would most likely be a deal breaker for a lot of people. My approach could probably be optimized, but I'm not sure it would be enough to make it usable.

I'm out of ideas right now, but open to suggestions if you have a solution to the above problem.

How can you get the static type of a reflected field? For example:
alias T = reflect!Foo.fields[0].field_type
doSomethingWithType!T

I don't believe an answer exists with my current design.

How can you get the user-defined attributes of a given ScopeRefl?

I don't think this is possible either with the current design. The current design must also work at runtime, and since UDAs can be any symbol, I'm not sure there is a good way to generalize this. I could wrap all attributes in an AttributeRefl class, but there wouldn't be much to tell about the wrapped attribute beside it's type, and maybe a string representation of it(more bloat).

I'm sure that more could be done to complement __traits and std.traits, but I don't think that includes using my reflection library in it's current state.

I can say that the techniques I used in jsonizer got pretty hacky -- there's a whole lot of __traits and one monstrous
mixin template.

You may want to look at "Orange".
https://github.com/jacob-carlborg/orange

The API is clean, and non-invasive. The only downside for me, is that in order to serialize a class by a base pointer, you have to register it at compile time.

If I understand correctly, more work needs to be done in druntime to better support reflection, but I've read this thread about 3 times and I'm still having a hard time figuring out whats going on :)

The RTInfo(T) template would, in theory, automatically generate some custom metadata for every type. The compiler automatically instantiates the RTInfo(T) template for each type right now. The idea was suggested that a programmer could create their own RTInfo(T) that the compiler would use that instead. This option was thrown out because it doesn't work with separate compilation. Right now, RTInfo(T) is defined in object.d, which is implicitly imported into every module that you compile, but if you had your own RTInfo defined in your own module, it wouldn't be available to any other modules at compile time, nor would it be available to any third party libraries you may be using.

The OffsetTypeInfo thing would be compiler generated. However, the oldest version of DMD I can find on github (2009) says this:

// offTi[]
dtdword(&dt, 0);
dtdword(&dt, 0);            // null for now, fix later

So I'm not sure why it was never implemented. I may eventually attempt a pull request for the above fix.

For the most part, this looks really nice. Thanks for putting it together, bitwise!

Thanks ;)

Reply via email to