Thread overview
Fun determining the number of parameters using core reflect
September 11

Hi there,

I've just been wanted to know if a particular local variable has is pointer taken inside a function.
i.e. whether it's aliased.

In order to reflect on that I would have to look at where it is defined i.e. reflect on the lexical parent which is possible but is currently disabled by default since it's expensive.

So I wondered if I could just get the parent function node inside my reflection function, which works since I can get the string of the function I am in.

After a bit of tinkering I arrived at the following code.

Enjoy!

And please feel free to ask questions and suggest improvements!

import core.reflect.reflect;
int f()
{
    int x;
    static assert(nParameters == 0);
    g(&x);
    return x;
}
int f2(int x, float y)
{
    static assert(nParameters == 2);
    return x;
}

void g(int* x) {}

@(core.reflect) uint nParameters(immutable string fName = __FUNCTION__, immutable Scope _scope = currentScope())
{
    auto F = cast(const FunctionDeclaration)
        nodeFromName(fName, ReflectFlags.NoParent | ReflectFlags.NoFunctionbody, _scope);
    uint params = cast(uint)F.type.parameterTypes.length;
    return params;
}
September 11

On Saturday, 11 September 2021 at 08:48:34 UTC, Stefan Koch wrote:

>

Hi there,

Ah one more think I forgot to mention.
If you want to play with this be advised that my core_reflect branch is currently trying to be somewhat stable.
The cutting edge changes you need for this example to work are in the.
core_reflect_newCTFE branch.

September 11

On Saturday, 11 September 2021 at 08:48:34 UTC, Stefan Koch wrote:

>

Hi there,

import core.reflect.reflect;
@(core.reflect) uint nParameters(immutable string fName = __FUNCTION__, immutable Scope _scope = currentScope())
{
    auto F = cast(const FunctionDeclaration)
        nodeFromName(fName, ReflectFlags.NoParent | ReflectFlags.NoFunctionbody, _scope);
    uint params = cast(uint)F.type.parameterTypes.length;
    return params;
}

I can already hear you ask if that supports eponymous templates.
The answers is ... yes it does.

As of a few minutes ago :)

string nArgs(T...)(T args)
{
    static assert(nParameters == 4, "template has to be called with 4 arguments excat>
    return "reflection is cool";
}

pragma(msg, nArgs(1, 2, "trythis", 4.0));

// pragma(msg, nArgs(1, 2, "trythis", 4.0, 1)); // won't compile static assert fails

You can determine the type and names of the parameters passed in.
You can determine how they are used in the function body if there is a body.
I just realized a few minutes ago what interesting things allows you to do.