www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to get the UDAs for a function parameter correctly?

reply Heromyth <bitworld qq.com> writes:
I want to get the UDAs for for a function parameter. Here the 
test code and I got some errors:

source/app.d(29,33): Error: first argument is not a symbol
source/app.d(39,15): Error: template instance app.test!(ClassA) 
error instantiating

How can I fix this? Would this be a bug? Thanks.

=====================
import std.stdio;
import std.traits;
import std.meta;


struct Length {
     int a;
     int b;
}

class ClassA {
     void test( Length(1, 9) int len,  Length(2, 4) int size) {
         writeln("It's OK");
     }

     void test(string name) {
         writeln("Can't be compiled");
     }
}

string test(T)() {
     string str;
     alias currentMembers = __traits(getOverloads, T, "test");

     static foreach(member; currentMembers) {{
         alias Params = Parameters!(member);
         static foreach(i; 0 .. Params.length)
         {{
             alias ThisParameter =  Params[i .. i + 1];
             static foreach(uda; __traits(getAttributes, 
ThisParameter)) {
                 str ~= uda.stringof ~  "\n";
             }
         }}
     }}

     return str;
}

void main() {
     enum aa = test!(ClassA);
     writeln(aa);
}
May 10 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 11 May 2020 at 02:25:39 UTC, Heromyth wrote:
 I want to get the UDAs for for a function parameter. Here the 
 test code and I got some errors:
I think my blog aside is one of the few if only write-ups on how to do this: http://dpldocs.info/this-week-in-d/Blog.Posted_2019_02_11.html#how-to-get-uda-on-a-function-param the library will not help much, you need to slice the parameters yourself. (It might work combine lib stuff with slice though, e.g. getUDA!(Parameters!F[1 .. 2]) maybe, i have never tried). but this does work: static if(is(typeof(method) P == __parameters)) foreach(idx, _; P) {{ // alias for convenience later alias param = P[idx .. idx + 1]; // this slice is the trick // can get the identifier now string ident = __traits(identifier, param); // and the attributes foreach(attr; __traits(getAttributes, param)) {} }}
May 10 2020
parent Heromyth <bitworld qq.com> writes:
On Monday, 11 May 2020 at 02:34:32 UTC, Adam D. Ruppe wrote:
 On Monday, 11 May 2020 at 02:25:39 UTC, Heromyth wrote:
 I want to get the UDAs for for a function parameter. Here the 
 test code and I got some errors:
I think my blog aside is one of the few if only write-ups on how to do this: http://dpldocs.info/this-week-in-d/Blog.Posted_2019_02_11.html#how-to-get-uda-on-a-function-param the library will not help much, you need to slice the parameters yourself. (It might work combine lib stuff with slice though, e.g. getUDA!(Parameters!F[1 .. 2]) maybe, i have never tried). but this does work: static if(is(typeof(method) P == __parameters)) foreach(idx, _; P) {{ // alias for convenience later alias param = P[idx .. idx + 1]; // this slice is the trick // can get the identifier now string ident = __traits(identifier, param); // and the attributes foreach(attr; __traits(getAttributes, param)) {} }}
That's great! It should use static if(is(typeof(method) P == __parameters)) to get all the parameters instead of using: alias Params = Parameters!(member); Here is the adjusted code: ================================= import std.stdio; import std.traits; import std.meta; struct Length { int a; int b; } class ClassA { void test( Length(1, 9) int len, Length(2, 4) int size) { writeln("It's OK"); } void test(string name, Length(3, 5) int len) { writeln("Works now"); } void test() { } } string test(T)() { string str; alias currentMembers = __traits(getOverloads, T, "test"); static foreach(member; currentMembers) {{ static if(is(typeof(member) Params == __parameters)) { static foreach(i, _; Params) {{ alias ThisParameter = Params[i .. i + 1]; static foreach(uda; __traits(getAttributes, ThisParameter)) { str ~= uda.stringof ~ "\n"; } }} } }} return str; } void main() { enum aa = test!(ClassA); writeln(aa); }
May 10 2020