Thread overview
Examining Members of a module at Compile Time
May 29, 2014
Meta
May 29, 2014
Dicebot
May 29, 2014
Meta
May 29, 2014
I'd like to get a list of all classes in the current module, so I came up with this code:

class Test {}

class TestChild: Test {}

class TestChildChild: TestChild {}

void main()
{
	foreach (item; __traits(allMembers, mixin(__MODULE__)))
	{
		static if (is(mixin(item) == class))
		{
			pragma(msg, item);
 		}
	}
}

This code doesn't work, complaining about `mixin(item)`. So them I thought I'd try:

static if (is(__traits(getMember, mixin(__MODULE__), item) == class))
{
    pragma(msg, item);
}

Which the compiler similarly complains about. I also tried instead assigning the result of the __traits call to an alias, which the compiler didn't like either. Finally I happened on something that worked:

const isModuleClass = mixin("is(" ~ item ~ " == class)");
static if (isModuleClass)
{
    pragma(msg, item);
}

The mixin looks quite ugly, of course, and I'd like to know if there's a better way to turn the string from __traits(allMembers, ...) into a symbol so it can be used in typeof expressions and other things.
May 29, 2014
class Test {}

class TestChild: Test {}

class TestChildChild: TestChild {}

alias Alias(alias Symbol) = Symbol; // this does the trick

void main()
{
	foreach (item; __traits(allMembers, mixin(__MODULE__)))
	{
		alias sym = Alias!(__traits(getMember, mixin(__MODULE__), item));
		static if (is(sym == class))
		{
			pragma(msg, item);
 		}
	}
}

// http://dpaste.dzfl.pl/e3ce615ca188
May 29, 2014
On Thursday, 29 May 2014 at 23:18:32 UTC, Dicebot wrote:
> class Test {}
>
> class TestChild: Test {}
>
> class TestChildChild: TestChild {}
>
> alias Alias(alias Symbol) = Symbol; // this does the trick
>
> void main()
> {
> 	foreach (item; __traits(allMembers, mixin(__MODULE__)))
> 	{
> 		alias sym = Alias!(__traits(getMember, mixin(__MODULE__), item));
> 		static if (is(sym == class))
> 		{
> 			pragma(msg, item);
>  		}
> 	}
> }
>
> // http://dpaste.dzfl.pl/e3ce615ca188

Thanks, that works. It's not a perfect solution, though. It will fail to fail if you pass it something beside a symbol, instead failing silently. But it works okay for my use case.