www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - is `allMembers` useless for modules?

reply FeepingCreature <feepingcreature gmail.com> writes:
It lists imported packages and modules, even though there's no 
way to detect if a symbol is a module and there's no way to go 
from the package to the modules it contains. It does not list 
named imports at all, for basically no reason I can tell.

It's basically impossible at the moment to use templates to 
navigate the import graph.

Is this just a matter of a lack of testcases? Or is this not an 
intended idiom at all?
Jan 13 2019
next sibling parent FeepingCreature <feepingcreature gmail.com> writes:
Oh, here's a fun one:

import std.stdio;

static foreach (member; __traits(allMembers, std))
{
     static assert(__traits(hasMember, std, member));
}

You'd think that __traits(allMembers) would imply 
__traits(hasMember). That would be a dangerous mistake.
Jan 14 2019
prev sibling next sibling parent reply bauss <jj_1337 live.dk> writes:
On Monday, 14 January 2019 at 07:57:34 UTC, FeepingCreature wrote:
 It lists imported packages and modules, even though there's no 
 way to detect if a symbol is a module and there's no way to go 
 from the package to the modules it contains. It does not list 
 named imports at all, for basically no reason I can tell.

 It's basically impossible at the moment to use templates to 
 navigate the import graph.

 Is this just a matter of a lack of testcases? Or is this not an 
 intended idiom at all?
Yes allMembers is useless for modules and packages. It's a long-standing issue for years and will probably never be resolved. It really sucks and I wish there was a solution. The only workaround is to use prebuild commands to execute somekind of code that does what you're trying to acheive by listing modules etc. and importing them in the module you need them etc.
Jan 14 2019
parent aliak <something something.com> writes:
On Monday, 14 January 2019 at 09:57:10 UTC, bauss wrote:
 It's a long-standing issue for years and will probably never be 
 resolved.

 It really sucks and I wish there was a solution.
Because technical reasons? Or is it more red-tape/resources?
Jan 14 2019
prev sibling next sibling parent reply Atila Neves <atila.neves gmail.com> writes:
To answer the question in the title: no. I've written several 
libraries that make use of `allMembers` on modules.

On Monday, 14 January 2019 at 07:57:34 UTC, FeepingCreature wrote:
 It lists imported packages and modules, even though there's no 
 way to detect if a symbol is a module
Sure there is: `enum isModule(string moduleName) = is(typeof(mixin(`{ import `, moduleName, `; }`)))`
 and there's no way to go from the package to the modules it 
 contains.
This is true. There's currently no other way than listing modules to reflect on in a source file somewhere, but this can be automated.
 It does not list named imports at all, for basically no reason 
 I can tell.
I'm not sure what you mean by this.
 It's basically impossible at the moment to use templates to 
 navigate the import graph.
Ah. I'd use dmd as a library for this. I even started writing the code to do exactly this.
Jan 14 2019
parent reply FeepingCreature <feepingcreature gmail.com> writes:
On Monday, 14 January 2019 at 14:06:02 UTC, Atila Neves wrote:
 It lists imported packages and modules, even though there's no 
 way to detect if a symbol is a module
Sure there is: `enum isModule(string moduleName) = is(typeof(mixin(`{ import `, moduleName, `; }`)))`
Right, to restate, there's no non-brute-force way. This should really be a trait; if the compiler offers you a symbol, it should also give you a clean way to determine the nature of that symbol.
 and there's no way to go from the package to the modules it 
 contains.
This is true. There's currently no other way than listing modules to reflect on in a source file somewhere, but this can be automated.
This cannot be automated if you don't know the include path of the source file. You basically have to manually reproduce D's include search logic.
 It does not list named imports at all, for basically no reason 
 I can tell.
I'm not sure what you mean by this.
For instance, if you `import std.string : split`, then split will not be visible in the allMembers list whether or not you imported it public. Though on reflection it's probably more that allMembers specifically excludes imported symbols.
 Ah. I'd use dmd as a library for this. I even started writing 
 the code to do exactly this.
It's silly and disturbing to me to have simple reflection information available in DMD running as a library, its secondary purpose, that is not available when running DMD as a compiler, its primary purpose, for basically no good reason.
Jan 14 2019
parent Neia Neutuladh <neia ikeran.org> writes:
On Mon, 14 Jan 2019 14:22:56 +0000, FeepingCreature wrote:
 On Monday, 14 January 2019 at 14:06:02 UTC, Atila Neves wrote:
 It lists imported packages and modules, even though there's no way to
 detect if a symbol is a module
Sure there is: `enum isModule(string moduleName) = is(typeof(mixin(`{ import `, moduleName, `; }`)))`
Right, to restate, there's no non-brute-force way. This should really be a trait; if the compiler offers you a symbol, it should also give you a clean way to determine the nature of that symbol.
I would have expected this to work: assert(is(std == package)); assert(is(std.stdio == module)); Alas. I didn't think it would be that difficult to add, except the compiler's hard-coded to consider the left-hand side a type. I don't see how to treat something as a reference to either a package or a module or a type in that code. I think the solution is to defer symbol lookup until IsExp semantic.
Jan 14 2019
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/14/19 2:57 AM, FeepingCreature wrote:
 there's no way to 
 detect if a symbol is a module and there's no way to go from the package 
 to the modules it contains.
This needs to be fixed, have you submitted an issue yet?
 It does not list named imports at all, for 
 basically no reason I can tell.
This, too, should be listed as a separate bug.
Jan 15 2019
next sibling parent FeepingCreature <feepingcreature gmail.com> writes:
On Wednesday, 16 January 2019 at 02:05:43 UTC, Andrei 
Alexandrescu wrote:
 On 1/14/19 2:57 AM, FeepingCreature wrote:
 there's no way to detect if a symbol is a module and there's 
 no way to go from the package to the modules it contains.
This needs to be fixed, have you submitted an issue yet?
 It does not list named imports at all, for basically no reason 
 I can tell.
This, too, should be listed as a separate bug.
Thank you, filed as https://issues.dlang.org/show_bug.cgi?id=19589 and https://issues.dlang.org/show_bug.cgi?id=19590 : "Impossible to determine if a symbol returned by __traits(allMembers) is a module, or package" and "Impossible to iterate imported packages with allMembers".
Jan 15 2019
prev sibling next sibling parent Seb <seb wilzba.ch> writes:
On Wednesday, 16 January 2019 at 02:05:43 UTC, Andrei 
Alexandrescu wrote:
 On 1/14/19 2:57 AM, FeepingCreature wrote:
 there's no way to detect if a symbol is a module and there's 
 no way to go from the package to the modules it contains.
This needs to be fixed, have you submitted an issue yet?
FWIW: https://github.com/dlang/dmd/pull/5290
Jan 16 2019
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2019-01-16 03:05, Andrei Alexandrescu wrote:
 On 1/14/19 2:57 AM, FeepingCreature wrote:
 there's no way to detect if a symbol is a module and there's no way to 
 go from the package to the modules it contains.
This needs to be fixed, have you submitted an issue yet?
 It does not list named imports at all, for basically no reason I can 
 tell.
This, too, should be listed as a separate bug.
https://github.com/dlang/dmd/pull/2271 -- /Jacob Carlborg
Jan 16 2019