std.reflection prototype

bitwise via Digitalmars-d digitalmars-d at puremagic.com
Mon Apr 13 22:03:37 PDT 2015


On Mon, 13 Apr 2015 08:57:26 -0400, rcorre <ryan at rcorre.net> 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 ;)


More information about the Digitalmars-d mailing list