Getting the names of all the top-level functions in module
Stefan Koch
uplink.coder at googlemail.com
Tue Sep 21 13:29:44 UTC 2021
Hello there,
I was just working on an example for my upcoming library
`core.reflect`
and I wanted to contrast it with the current template way of
doing things.
The issue at hand here is getting all the names of top-level
(free)function in a module in a string[].
The way that I found to do this with templates involves a bit of
knowledge of is expressions here it is
```d
template functionNames (alias M)
{
static const functionNames = ()
{
string[] names;
foreach(m;__traits(derivedMembers, M))
{
alias sym = __traits(getMember, M, m);
static if (is(typeof(sym) T) && is(T F == function))
{
names ~= __traits(identifier, sym);
}
}
return names;
} ();
}
```
Note that on the "callsite" you have to instantiate the helper
template as:
`static const fNames = functionNames!(mixin(__MODULE__))`;
the parens around the mixin are not optional it will not parse
without them.
now comes the way do that with core.reflect.
```d
@(core.reflect) // annotation prevents code-gen since the
`nodeFromName` builtin which is called in there is not a real
function and therefore has no body for the codegenerator to look
at.
const(FunctionDeclaration)[] getFreeFunctionNamesFromModule(
string module_ = __MODULE__,
ReflectFlags flags = ReflectFlags.NoMemberRecursion,
immutable Scope _scope = currentScope()
)
{
string[] result;
auto mod_ = nodeFromName(module_, flags, _scope);
if (auto mod = cast(Module) mod_)
foreach(member;mod.members)
{
if (auto fd = cast(const FunctionDeclaration) member)
{
result ~= fd.name;
}
}
return result;
}
```
and you use it like this.
`static const functionNames = getFreeFunctionNamesFromModule;`
I am using a parenthesis less call to make it look like it's a
magic builtin but in reality the only bits of magic that are used
are the two builtins `nodeFromName` and `currentScope`
whereas the template above used 5 magic constructs.
- 2 different types of pattern matching is expressions.
and
- 3 different __traits expressions.
More information about the Digitalmars-d
mailing list