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