www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - need help about get all public static function name

reply test <test gmail.com> writes:
I try use traits get all public static function of a struct pass 
to template.

Compiler report  " .Function  is not accessible from module " 
with __traits(isStaticFunction, __traits(getMember, Type , name)).

If I add " __traits(getProtection, __traits(getMember, Type, 
name)) == "public" before "__traits(isStaticFunction, 
__traits(getMember, Type , name))", it report " argument void 
function(void*) nothrow  nogc has no protection".



If I add "isFunction!(typeof(__traits(getMember, Type, name)))" 
before all this, It report type State is not an expression.

If I use "isFunction!(__traits(getMember, BaseType, name)) ", it 
report again "argument void function(void*) nothrow  nogc has no 
protection"


how to do this ?
Oct 22 2018
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Monday, 22 October 2018 at 10:16:22 UTC, test wrote:
 I try use traits get all public static function of a struct 
 pass to template...
 how to do this ?
void allFunctions(T)() { import std.stdio; foreach (name; __traits(allMembers, T)) { static foreach (overload; __traits(getOverloads, T, name)) { static if (__traits(getProtection, overload) == "public" && __traits(isStaticFunction, overload)) { // 'overload' is an alias to a T's public static function writeln(name, ": ", typeof(overload).stringof); } } } }
Oct 22 2018
parent reply test <test gmail.com> writes:
On Monday, 22 October 2018 at 10:29:56 UTC, Stanislav Blinov 
wrote:
 On Monday, 22 October 2018 at 10:16:22 UTC, test wrote:
 I try use traits get all public static function of a struct 
 pass to template...
 how to do this ?
void allFunctions(T)() { import std.stdio; foreach (name; __traits(allMembers, T)) { static foreach (overload; __traits(getOverloads, T, name)) { static if (__traits(getProtection, overload) == "public" && __traits(isStaticFunction, overload)) { // 'overload' is an alias to a T's public static function writeln(name, ": ", typeof(overload).stringof); } } } }
On the line: static foreach (overload; __traits(getOverloads, Type, name)) , throw error: is not accessible from module and
Oct 22 2018
parent reply test <test gmail.com> writes:
On Monday, 22 October 2018 at 10:45:07 UTC, test wrote:
 On Monday, 22 October 2018 at 10:29:56 UTC, Stanislav Blinov 
 wrote:
 On Monday, 22 October 2018 at 10:16:22 UTC, test wrote:
and
On Monday, 22 October 2018 at 10:45:07 UTC, test wrote: test1.d ===================== alias Fn1 = void function(); struct XX { alias Fn = Fn1; enum Y { aa } static void Test(){} int id; } test2.d ===================== import test1; void GetPub(BaseType)(){ static foreach (name; __traits(allMembers, BaseType)) static if( name[0] !is '_' && __traits(getProtection, __traits(getMember, BaseType, name)) == "public" ) { static assert( hasMember!(BaseType.init, name)); static if( __traits(isStaticFunction, __traits(getMember, BaseType, name)) ) { pragma(msg, typeof(BaseType.init).stringof ~ "." ~ name); } } } extern(C) void main(){ GetPub!XX; }
Oct 22 2018
next sibling parent test <test gmail.com> writes:
On Monday, 22 October 2018 at 10:49:10 UTC, test wrote:
 On Monday, 22 October 2018 at 10:45:07 UTC, test wrote:
 On Monday, 22 October 2018 at 10:29:56 UTC, Stanislav Blinov 
 wrote:
extern(C) void main(){ GetPub!XX; }
https://run.dlang.io/is/f295qE
Oct 22 2018
prev sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Monday, 22 October 2018 at 10:49:10 UTC, test wrote:

 test1.d
 =====================
 alias Fn1       = void function();
 struct XX {
         alias Fn        = Fn1;
         // ...
 }
'Fn' is not a static function, it's a type. I.e. you can declare a function pointer with it: Fn func;
 test2.d
 =====================
 import test1;
 void GetPub(BaseType)(){
     // ...
 }
My code works fine with your struct XX, with dmd 2.082. std.traits.hasMember expects an aggregate *type*, but you're trying to pass as instance. A revised GetPub: void GetPub(BaseType)(){ static foreach (name; __traits(allMembers, BaseType)) static if( name[0] !is '_' && is(typeof(__traits(getMember, BaseType, name))) && __traits(getProtection, __traits(getMember, BaseType, name)) == "public" ) { //static assert( hasMember!(BaseType.init, name)); static assert(hasMember!(BaseType, name)); static if( __traits(isStaticFunction, __traits(getMember, BaseType, name)) ) { pragma(msg, BaseType.stringof ~ "." ~ name); } } } note the added check that the member is not a type: is(typeof(__traits(getMember, BaseType, name))). You'll still need to iterate overloads if you want to get all static functions.
Oct 22 2018
parent reply test <test gmail.com> writes:
On Monday, 22 October 2018 at 11:18:20 UTC, Stanislav Blinov 
wrote:
 On Monday, 22 October 2018 at 10:49:10 UTC, test wrote:


 note the added check that the member is not a type: 
 is(typeof(__traits(getMember, BaseType, name))).
 You'll still need to iterate overloads if you want to get all 
 static functions.
Thanks for this. some how when I call "is(typeof(__traits(getMember, BaseType, name))) " in the template, my code report others error like: Error: no property fromPointer for type void Error: template instance TypeTemplate!(BaseType) is used as a type Error: template instance `TypeTemplate!(BaseType)` error instantiating
Oct 22 2018
next sibling parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Monday, 22 October 2018 at 11:42:59 UTC, test wrote:

 some how when I call "is(typeof(__traits(getMember, BaseType, 
 name))) " in the template, my code report others error like:

 Error: no property fromPointer for type void
 Error: template instance TypeTemplate!(BaseType) is used as a 
 type

 Error: template instance `TypeTemplate!(BaseType)` error 
 instantiating
That would be hard to diagnose without actually seeing the code, it seems there's something else going on.
Oct 22 2018
prev sibling parent reply test <test gmail.com> writes:
On Monday, 22 October 2018 at 11:42:59 UTC, test wrote:
 On Monday, 22 October 2018 at 11:18:20 UTC, Stanislav Blinov 
 wrote:

 Error: template instance `TypeTemplate!(BaseType)` error 
 instantiating
I use alias this to allow call static method on proxyType. It work some time, but on other case it report: The code throw error is: struct TcpStream { void read(ubyte[] data){ auto id2 = Fiber.getThis(); // Error: this for getBoxPayload needs to be type BoxedTypeNode not type TcpStream } } If the read is static method, then there is no error. I can not fix this so I try use static method alias, but it work on normal case not my code (100KB+). I try made a simple example but it has no error:
Oct 22 2018
parent reply test <test gmail.com> writes:
On Monday, 22 October 2018 at 11:59:21 UTC, test wrote:
 On Monday, 22 October 2018 at 11:42:59 UTC, test wrote:
 I try made a simple example but it has no error:
I find the way to show the error: https://run.dlang.io/is/f8cULz import std.traits; struct FiberS { static auto getThis(){ return Fiber.getId(); } } struct Proxy(T){ T* ptr; alias getPayload this; property ref auto getPayload() inout return { return * ptr ; } static auto getId(){ return 1; } } alias Fiber = Proxy!(FiberS); extern(C) void main(){ auto id = Fiber.getThis(); // work here } struct TcpStream { void read(ubyte[] data){ auto id = Fiber.getThis(); // not work here in my case } }
Oct 22 2018
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Monday, 22 October 2018 at 12:03:22 UTC, test wrote:
 On Monday, 22 October 2018 at 11:59:21 UTC, test wrote:
 On Monday, 22 October 2018 at 11:42:59 UTC, test wrote:
 I try made a simple example but it has no error:
I find the way to show the error: https://run.dlang.io/is/f8cULz import std.traits; struct FiberS { static auto getThis(){ return Fiber.getId(); } } struct Proxy(T){ T* ptr; alias getPayload this; property ref auto getPayload() inout return { return * ptr ; } static auto getId(){ return 1; } } alias Fiber = Proxy!(FiberS); extern(C) void main(){ auto id = Fiber.getThis(); // work here } struct TcpStream { void read(ubyte[] data){ auto id = Fiber.getThis(); // not work here in my case } }
Let's analyze this call: auto id = Fiber.getThis(); You're trying to call a static function 'getThis' on Fiber. The type 'Fiber' is really a Proxy!FiberS. Proxy doesn't have a static getThis() function. So the compiler tries an 'alias this', which forwards to a non-static member function getPayload(). To call that function, you need an instance of 'Proxy', which you don't have. I guess the first error message ("this for getPayload needs to be type Proxy not type TcpStream") just doesn't report that clearly.
Oct 22 2018
parent reply test <test gmail.com> writes:
On Monday, 22 October 2018 at 12:16:50 UTC, Stanislav Blinov 
wrote:
 On Monday, 22 October 2018 at 12:03:22 UTC, test wrote:
 You're trying to call a static function 'getThis' on Fiber.
 The type 'Fiber' is really a Proxy!FiberS. Proxy doesn't have a 
 static getThis() function. So the compiler tries an 'alias 
 this', which forwards to a non-static member function 
 getPayload(). To call that function, you need an instance of 
 'Proxy', which you don't have.
 I guess the first error message ("this for getPayload needs to 
 be type Proxy not type TcpStream") just doesn't report that 
 clearly.
But this work:
 extern(C) void main(){
        auto id = Fiber.getThis(); // work here
 }
here also dont have Fiber instance.
Oct 22 2018
parent test <test gmail.com> writes:
On Monday, 22 October 2018 at 12:32:57 UTC, test wrote:
 On Monday, 22 October 2018 at 12:16:50 UTC, Stanislav Blinov 
 wrote:
 On Monday, 22 October 2018 at 12:03:22 UTC, test wrote:
 You're trying to call a static function 'getThis' on Fiber.
 The type 'Fiber' is really a Proxy!FiberS. Proxy doesn't have 
 a static getThis() function. So the compiler tries an 'alias 
 this', which forwards to a non-static member function 
 getPayload(). To call that function, you need an instance of 
 'Proxy', which you don't have.
 I guess the first error message ("this for getPayload needs to 
 be type Proxy not type TcpStream") just doesn't report that 
 clearly.
But this work:
 extern(C) void main(){
        auto id = Fiber.getThis(); // work here
 }
here also dont have Fiber instance.
I think this is a bug. If I use "alias this " with a FiberS instance tuple memebr, it will work. but if I use alias this with propery , it only work on static method, on delegate method it will use delegate this. This is kind like Javascript method this is come from caller place. I think it is a bug. please help me confirm this. If so please made a bug report for me.
Oct 22 2018