www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Iterate all visible symbols, even from imported modules

reply Lodovico Giaretta <lodovico giaretart.net> writes:
As per title, is it possible to iterate all visible symbols of 
the current module and of all imported modules and packages? My 
aim is to find everything in scope that has a specific UDA.

module foo;

import std.stdio, std.array, std.algorithm;

void bar(){}

struct S{}

void main()
{
     // prints ["object", "std", "bar", "S", "main"]
     // how do I discover that "std" is a package?
     writeln([__traits(allMembers, foo)]);


     // prints ["object", "core", "std", "KeepTerminator", 
"GCC_IO", ... ]
     // strange thing: it looks the same even if I remove all 
imports other than std.stdio
     writeln([__traits(allMembers, foo.std)]);
}

Thank you in advance.
Jul 18 2016
next sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
short answer: no.

there is still no way to write a reliable enumerator like this: 
too much things to hack around.

as for module symbols, it is easy: they has no type. literally: 
`!is(typeof(...))`.

`is(typeof(...))` is a necessary safeguard anyway if you are 
enumerating symbols in module, as you can't do much with module 
names anyway, and you *have* to filter 'em out with top-level 
static if.
Jul 18 2016
parent Lodovico Giaretta <lodovico giaretart.net> writes:
On Monday, 18 July 2016 at 18:21:41 UTC, ketmar wrote:
 short answer: no.

 there is still no way to write a reliable enumerator like this: 
 too much things to hack around.

 as for module symbols, it is easy: they has no type. literally: 
 `!is(typeof(...))`.

 `is(typeof(...))` is a necessary safeguard anyway if you are 
 enumerating symbols in module, as you can't do much with module 
 names anyway, and you *have* to filter 'em out with top-level 
 static if.
Thank you. It looks like the check `is(typeof(T)) || is(T)` is passed by every symbol `T` that is not a module nor a package, so I think I'll use its complementary as a filter.
Jul 18 2016
prev sibling next sibling parent BLM768 <blm768 gmail.com> writes:
On Monday, 18 July 2016 at 13:00:16 UTC, Lodovico Giaretta wrote:
     // how do I discover that "std" is a package?
I've got a DMD pull request that adds __traits(isPackage, someSymbol), but it's stuck waiting for approval. If and when it gets merged, it could be useful for that. https://github.com/dlang/dmd/pull/5290
Jul 18 2016
prev sibling parent reply Meta <jared771 gmail.com> writes:
On Monday, 18 July 2016 at 13:00:16 UTC, Lodovico Giaretta wrote:
 As per title, is it possible to iterate all visible symbols of 
 the current module and of all imported modules and packages? My 
 aim is to find everything in scope that has a specific UDA.

 module foo;

 import std.stdio, std.array, std.algorithm;

 void bar(){}

 struct S{}

 void main()
 {
     // prints ["object", "std", "bar", "S", "main"]
     // how do I discover that "std" is a package?
     writeln([__traits(allMembers, foo)]);


     // prints ["object", "core", "std", "KeepTerminator", 
 "GCC_IO", ... ]
     // strange thing: it looks the same even if I remove all 
 imports other than std.stdio
     writeln([__traits(allMembers, foo.std)]);
 }

 Thank you in advance.
This answer to a similar question on StackOverflow may be useful:
Jul 18 2016
parent Lodovico Giaretta <lodovico giaretart.net> writes:
On Monday, 18 July 2016 at 21:12:38 UTC, Meta wrote:
 On Monday, 18 July 2016 at 13:00:16 UTC, Lodovico Giaretta 
 wrote:
 As per title, is it possible to iterate all visible symbols of 
 the current module and of all imported modules and packages? 
 My aim is to find everything in scope that has a specific UDA.

 module foo;

 import std.stdio, std.array, std.algorithm;

 void bar(){}

 struct S{}

 void main()
 {
     // prints ["object", "std", "bar", "S", "main"]
     // how do I discover that "std" is a package?
     writeln([__traits(allMembers, foo)]);


     // prints ["object", "core", "std", "KeepTerminator", 
 "GCC_IO", ... ]
     // strange thing: it looks the same even if I remove all 
 imports other than std.stdio
     writeln([__traits(allMembers, foo.std)]);
 }

 Thank you in advance.
This answer to a similar question on StackOverflow may be useful:
Wow! Looks exactly what I was looking for. I'll give this a try as soon as possible. Thank you.
Jul 18 2016