Thread overview | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 21, 2017 Finding class template instantiations via runtime reflection (for openmethods) | ||||
---|---|---|---|---|
| ||||
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 Re: Finding class template instantiations via runtime reflection (for openmethods) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jean-Louis Leroy | 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 Re: Finding class template instantiations via runtime reflection (for openmethods) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: Finding class template instantiations via runtime reflection (for openmethods) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jean-Louis Leroy | 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 Re: Finding class template instantiations via runtime reflection (for openmethods) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jean-Louis Leroy | 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 Re: Finding class template instantiations via runtime reflection (for openmethods) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jean-Louis Leroy | 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 Re: Finding class template instantiations via runtime reflection (for openmethods) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: Finding class template instantiations via runtime reflection (for openmethods) | ||||
---|---|---|---|---|
| ||||
Posted in reply to user1234 | 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 Re: Finding class template instantiations via runtime reflection (for openmethods) | ||||
---|---|---|---|---|
| ||||
Posted in reply to user1234 | 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 Re: Finding class template instantiations via runtime reflection (for openmethods) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jean-Louis Leroy | Thank you all for your input. I will file a bug report. |
Copyright © 1999-2021 by the D Language Foundation