Jump to page: 1 2
Thread overview
Finding class template instantiations via runtime reflection (for openmethods)
Sep 21, 2017
Jean-Louis Leroy
Sep 22, 2017
Ali Çehreli
Sep 24, 2017
user1234
Sep 25, 2017
Jean-Louis Leroy
Sep 23, 2017
bitwise
Sep 23, 2017
bitwise
Sep 23, 2017
bitwise
Sep 25, 2017
Jean-Louis Leroy
Sep 25, 2017
Biotronic
Sep 25, 2017
Jean-Louis Leroy
Sep 25, 2017
jmh530
Sep 25, 2017
Jacob Carlborg
Sep 25, 2017
Jean-Louis Leroy
Sep 26, 2017
Jacob Carlborg
Sep 26, 2017
Jean-Louis Leroy
Sep 27, 2017
Jacob Carlborg
Sep 26, 2017
b4s1L3
Sep 26, 2017
Jean-Louis Leroy
September 21, 2017
It did not take long! Someone tried to create templatized open methods and it didn't work right of the box. I expected that, but in fact there may be a bit of hope. You cannot have virtual function templates in C++ or in D because the layout of the vtables have to be known at compile time - but openmethods creates its method tables at runtime so maybe it can be made to work.

I stumbled upon a problem very quickly: it seems that classes that come from class template instantiations are not registered in ModuleInfo - see below,

import std.stdio;

class Foo {}

class Bar(T) : Foo
{
  int i;
}

alias BarInt = Bar!int;

const barInt = new BarInt;

void main()
{
  foreach (mod; ModuleInfo) {
    foreach (c; mod.localClasses) {
      writeln(c);
    }
  }
}

...output:
modtemp.Foo
core.exception.RangeError
core.exception.AssertError
etc...

Neither 'Bar!int' nor 'BarInt' appear in 'localClasses'.

Ideas?

September 22, 2017
On 9/21/17 4:32 PM, Jean-Louis Leroy wrote:
> It did not take long! Someone tried to create templatized open methods and it didn't work right of the box. I expected that, but in fact there may be a bit of hope. You cannot have virtual function templates in C++ or in D because the layout of the vtables have to be known at compile time - but openmethods creates its method tables at runtime so maybe it can be made to work.
> 
> I stumbled upon a problem very quickly: it seems that classes that come from class template instantiations are not registered in ModuleInfo - see below,
> 
> import std.stdio;
> 
> class Foo {}
> 
> class Bar(T) : Foo
> {
>    int i;
> }
> 
> alias BarInt = Bar!int;
> 
> const barInt = new BarInt;
> 
> void main()
> {
>    foreach (mod; ModuleInfo) {
>      foreach (c; mod.localClasses) {
>        writeln(c);
>      }
>    }
> }
> 
> ....output:
> modtemp.Foo
> core.exception.RangeError
> core.exception.AssertError
> etc...
> 
> Neither 'Bar!int' nor 'BarInt' appear in 'localClasses'.
> 
> Ideas?
> 

It used to be that classes were always in ModuleInfo (and that ModuleInfo was always generated). That's not so much the case any more, as there has been a push to reduce the runtime footprint and complexity (especially toward -betterC). This makes traditional runtime reflection more difficult and sporadic.

However, I would expect that if ModuleInfo is generated for a file, and some classes are added, then ALL classes instantiated in the module should be added.

I would say it's a bug.

-Steve
September 22, 2017
On 09/22/2017 05:16 AM, Steven Schveighoffer wrote:
> On 9/21/17 4:32 PM, Jean-Louis Leroy wrote:

>> it seems that classes that
>> come from class template instantiations are not registered in
>> ModuleInfo

> I would say it's a bug.
>
> -Steve

I think so too. I wanted to hear it from Steve first. :)

Ali

September 23, 2017
On Thursday, 21 September 2017 at 20:32:38 UTC, Jean-Louis Leroy wrote:
>
> Neither 'Bar!int' nor 'BarInt' appear in 'localClasses'.
>
> Ideas?

The information you can retrieve through localClasses is limited.

AFAIK it only retrieves plain non-template classes declared directly in the module. Last I checked, non-template classes added via mixin were skipped as well.

I'm not sure how much work can be expected in this area. Things related to runtime reflection have slowly been getting removed from druntime and dmd. I don't think there's much left of it.

Your best bet is to scrape the info you need on your own using D's traits:

https://dlang.org/phobos/std_traits.html
https://dlang.org/spec/traits.html

I would recommend trying to work with std.traits first (as opposed to __traits).

If you need to scan entire modules at a time, then start with something like this:

foreach(m; __traits(allMembers, fully.qualified.modulename))
{
    // __traits(getMember, ... , ...)
}


September 23, 2017
On Thursday, 21 September 2017 at 20:32:38 UTC, Jean-Louis Leroy wrote:
>
> Neither 'Bar!int' nor 'BarInt' appear in 'localClasses'.
>
> Ideas?

The information you can retrieve through localClasses is limited.

AFAIK it only retrieves plain non-template classes declared directly in the module. Last I checked, non-template classes added via mixin were skipped as well.

I'm not sure how much work can be expected in this area. Things related to runtime reflection have slowly been getting removed from druntime and dmd. I don't think there's much left of it.

Your best bet is to scrape the info you need on your own using D's traits:

https://dlang.org/phobos/std_traits.html
https://dlang.org/spec/traits.html

I would recommend trying to work with std.traits first (as opposed to __traits).

If you need to scan entire modules at a time, then start with something like this:

foreach(m; __traits(allMembers, fully.qualified.modulename))
{
    // __traits(getMember, ... , ...)
}


September 23, 2017
On Thursday, 21 September 2017 at 20:32:38 UTC, Jean-Louis Leroy wrote:
>
> Neither 'Bar!int' nor 'BarInt' appear in 'localClasses'.
>
> Ideas?

The information you can retrieve through localClasses is limited.

AFAIK it only retrieves plain non-template classes declared directly in the module. Last I checked, non-template classes added via mixin were skipped as well.

I'm not sure how much work can be expected in this area. Things related to runtime reflection have slowly been getting removed from druntime and dmd. I don't think there's much left of it.

Your best bet is to scrape the info you need on your own using D's traits:

https://dlang.org/phobos/std_traits.html
https://dlang.org/spec/traits.html

I would recommend trying to work with std.traits first (as opposed to __traits).

If you need to scan entire modules at a time, then start with something like this:

foreach(m; __traits(allMembers, fully.qualified.modulename))
{
    // __traits(getMember, ... , ...)
}


September 24, 2017
On Friday, 22 September 2017 at 12:16:52 UTC, Steven Schveighoffer wrote:
> On 9/21/17 4:32 PM, Jean-Louis Leroy wrote:
>> It did not take long! Someone tried to create templatized open methods and it didn't work right of the box. I expected that, but in fact there may be a bit of hope. You cannot have virtual function templates in C++ or in D because the layout of the vtables have to be known at compile time - but openmethods creates its method tables at runtime so maybe it can be made to work.
>> 
>> I stumbled upon a problem very quickly: it seems that classes that come from class template instantiations are not registered in ModuleInfo - see below,
>> 
>> import std.stdio;
>> 
>> class Foo {}
>> 
>> class Bar(T) : Foo
>> {
>>    int i;
>> }
>> 
>> alias BarInt = Bar!int;
>> 
>> const barInt = new BarInt;
>> 
>> void main()
>> {
>>    foreach (mod; ModuleInfo) {
>>      foreach (c; mod.localClasses) {
>>        writeln(c);
>>      }
>>    }
>> }
>> 
>> ....output:
>> modtemp.Foo
>> core.exception.RangeError
>> core.exception.AssertError
>> etc...
>> 
>> Neither 'Bar!int' nor 'BarInt' appear in 'localClasses'.
>> 
>> Ideas?
>> 
>
> It used to be that classes were always in ModuleInfo (and that ModuleInfo was always generated). That's not so much the case any more, as there has been a push to reduce the runtime footprint and complexity (especially toward -betterC). This makes traditional runtime reflection more difficult and sporadic.
>
> However, I would expect that if ModuleInfo is generated for a file, and some classes are added, then ALL classes instantiated in the module should be added.
>
> I would say it's a bug.
>
> -Steve

aliases are not symbol so it's expected that 'BarInt' doesn't appear in the items.
Would "Bar!int" be usable in Object.factory ?
September 25, 2017
On 9/24/17 12:30 AM, user1234 wrote:
> On Friday, 22 September 2017 at 12:16:52 UTC, Steven Schveighoffer wrote:
>> It used to be that classes were always in ModuleInfo (and that ModuleInfo was always generated). That's not so much the case any more, as there has been a push to reduce the runtime footprint and complexity (especially toward -betterC). This makes traditional runtime reflection more difficult and sporadic.
>>
>> However, I would expect that if ModuleInfo is generated for a file, and some classes are added, then ALL classes instantiated in the module should be added.
>>
>> I would say it's a bug.
>>
> 
> aliases are not symbol so it's expected that 'BarInt' doesn't appear in the items.

Correct, even with a fixed compiler, BarInt would not appear.

> Would "Bar!int" be usable in Object.factory ?

I'm not sure what the name of the class might be, as this capability depends completely on the compiler.

As it stands, no entry for the class type is made in the ModuleInfo, so there's no way to know what the "right name" is -- someone needs to add the capability, and that may be when the decision is made.

Note to readers, Object.factory uses exactly the mechanism Jean-Louis has used, so if his code can't find it, neither can Object.factory.

-Steve
September 25, 2017
On Sunday, 24 September 2017 at 04:30:26 UTC, user1234 wrote:
> aliases are not symbol so it's expected that 'BarInt' doesn't appear in the items.

I didn't really expect that either.


September 25, 2017
Thank you all for your input. I will file a bug report.

« First   ‹ Prev
1 2