www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Fun determining the number of parameters using core reflect

reply Stefan Koch <uplink.coder googlemail.com> writes:
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;
}
```
Sep 11 2021
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
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.
Sep 11 2021
prev sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
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.
Sep 11 2021