digitalmars.D.learn - using __traits to get line number of a member
- forkit (34/34) Nov 12 2021 Code below is self explanatory.
- Stanislav Blinov (3/5) Nov 12 2021 https://dlang.org/spec/traits.html#getLocation
- forkit (9/15) Nov 12 2021 Thanks. That seems to be the one, except:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (16/17) Nov 12 2021 mixin(m) seems to solve the issue, which I think necessitates 'static if...
- forkit (44/48) Nov 13 2021 Thanks. Really appreciate the help provided in this thread :-)
- Stanislav Blinov (15/19) Nov 13 2021 What you really should be doing is this:
- forkit (50/69) Nov 13 2021 static import mod = mixin(__MODULE__);
- Stanislav Blinov (9/11) Nov 13 2021 ```
- forkit (6/18) Nov 13 2021 thanks :-)
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/6) Nov 14 2021 I don't understand myself but all of it as a single string works:
Code below is self explanatory. Any assistance on how to get the line number is welcome ;-) // ++++++++++++++++++++++++++ module test; import std; class myClass{ void foo(){}} void myFunction1(){} void main() { // list the first user defined member of this module (other than main) int i; foreach(m; __traits(allMembers, mixin(__MODULE__))) { // we can ignore these members // "std" and "object" are created by the compiler, and "main" I'm not interested in. if(m == "std" || m == "object" || m == "main") { i = 1; continue; } writefln("The name of the first user member is: %s", m); // On this next line, m.lineNumber is just a stub holder till an actual solution is found //writefln("The line number on which that member begins, is: %s, m.lineNumber); if(i == 1) break; } //writeln("Nothing to see here."); } void myFunction2(){} // +++++++++++++++++++++++++
Nov 12 2021
On Saturday, 13 November 2021 at 05:31:51 UTC, forkit wrote:Code below is self explanatory. Any assistance on how to get the line number is welcome ;-)https://dlang.org/spec/traits.html#getLocation That?
Nov 12 2021
On Saturday, 13 November 2021 at 06:05:37 UTC, Stanislav Blinov wrote:On Saturday, 13 November 2021 at 05:31:51 UTC, forkit wrote:Thanks. That seems to be the one, except: writeln(__traits(getLocation, m)[1]); // nope. writes the line no. of the foreach loop writeln(__traits(getLocation, myClass)[1]); // yes, but I have to provide the name manually here, which i would not know. I would have thought m referred to myClass at this point in the loop. But that doesn't seem to be the case.Code below is self explanatory. Any assistance on how to get the line number is welcome ;-)https://dlang.org/spec/traits.html#getLocation That?
Nov 12 2021
On 11/12/21 11:00 PM, forkit wrote:// nope. writes the line no. of the foreach loopmixin(m) seems to solve the issue, which I think necessitates 'static if': static foreach(m; __traits(allMembers, mixin(__MODULE__))) { static if(m == "std" || m == "object" || m == "main") { // Ignore } else { writefln("The name of the first user member is: %s", m); writeln(__traits(getLocation, mixin(m))[1]); // <-- HERE } } It works because we mix-in the value of the string 'm', which becomes a symbol. ('foreach' instead of 'static foreach' works as well.) Ali
Nov 12 2021
On Saturday, 13 November 2021 at 07:20:14 UTC, Ali Çehreli wrote:It works because we mix-in the value of the string 'm', which becomes a symbol. ('foreach' instead of 'static foreach' works as well.) AliThanks. Really appreciate the help provided in this thread :-) Final working code below: //=================================== module test; import std; class myClass{ void foo(){}} void myFunction1(){} void main() { // list the first user defined member of this module (other than main) int i; foreach(m; __traits(allMembers, mixin(__MODULE__))) { // ignore these members static if(m == "std" || m == "object" || m == "main" || m == "_d_run_main" || m == "_Dmain" ) { i = 1; continue; } else { writefln("The name of the first user member is: %s", m); // getLocation returns a tuple. See note below writefln("%s begins on line number: %s", m, __traits(getLocation, mixin(m))[1]); } if(i == 1) break; } } void myFunction2(){} /* https://dlang.org/spec/traits.html#getLocation get the location of a symbol where the argument was declared. getLocation Returns a tuple(string, int, int) whose entries correspond to [0] string -> the filename [1] int -> line number [2] int -> column number */ // ======================================
Nov 13 2021
On Saturday, 13 November 2021 at 08:04:56 UTC, forkit wrote:int i; foreach(m; __traits(allMembers, mixin(__MODULE__))) // ... __traits(getLocation, mixin(m))[1]);What you really should be doing is this: ```d static import mod = mixin(__MODULE__); foreach (i, name; __traits(allMembers, mod)) { // ... __traits(getLocation, __traits(getMember, mod, i)); // ... } ``` Otherwise you might run into name conflicts, and get location of a wrong symbol. Also if you really want to be generic you should couple it with `__traits(getOverloads)`, like the docs for getLocation suggest.
Nov 13 2021
On Saturday, 13 November 2021 at 17:22:16 UTC, Stanislav Blinov wrote:On Saturday, 13 November 2021 at 08:04:56 UTC, forkit wrote:static import mod = mixin(__MODULE__); That statement above would not compile. After spending way too much time trying to work out, I gave up, and used what i have, which works. I just want to know, which members in my module are functions, and which are classes. I got the isFunction (that method exists) However, there is no isClass method. Why not? How do I determine if a member is a class.. I wonder... e.g. //========================= module test; import std; class myClass{} // nothing to see here void main() { alias allMembersOfThisModule = __traits(allMembers, mixin(__MODULE__)); string memberFile() { return `__traits(getLocation, mixin(member))[0]`; } string memberLocation() { return `__traits(getLocation, mixin(member))[1]`; } foreach(member; allMembersOfThisModule) { static if(member == "std" || member == "object") { continue; } else { writefln("\nHere is a member: %s", member); // what kind of member is it? if(isFunction!(mixin(member))) writeln("This is a function."); //else //if(isClass!(mixin(member))) //writeln("This is a class."); else writeln("Not really sure what type of member this is.."); writefln("%s is located in file: %s", member, mixin(memberFile)); writefln("%s begins on line number: %s", member, mixin(memberLocation)); } } } void myFunction(){} // nothing to see here // =========================================int i; foreach(m; __traits(allMembers, mixin(__MODULE__))) // ... __traits(getLocation, mixin(m))[1]);What you really should be doing is this: ```d static import mod = mixin(__MODULE__); foreach (i, name; __traits(allMembers, mod)) { // ... __traits(getLocation, __traits(getMember, mod, i)); // ... } ``` Otherwise you might run into name conflicts, and get location of a wrong symbol. Also if you really want to be generic you should couple it with `__traits(getOverloads)`, like the docs for getLocation suggest.
Nov 13 2021
On Sunday, 14 November 2021 at 04:05:45 UTC, forkit wrote:However, there is no isClass method. Why not? How do I determine if a member is a class.. I wonder...``` static if (is(something == class)) { /* ... */ } ``` or, if member is an instance ``` static if (is(typeof(something) == class)) { /* ... */ } ``` Ditto for interfaces, structs, unions.
Nov 13 2021
On Sunday, 14 November 2021 at 04:24:09 UTC, Stanislav Blinov wrote:On Sunday, 14 November 2021 at 04:05:45 UTC, forkit wrote:thanks :-) works now... if((is(mixin(member) == class))) writeln("This is a class.");However, there is no isClass method. Why not? How do I determine if a member is a class.. I wonder...``` static if (is(something == class)) { /* ... */ } ``` or, if member is an instance ``` static if (is(typeof(something) == class)) { /* ... */ } ``` Ditto for interfaces, structs, unions.
Nov 13 2021
On 11/13/21 8:05 PM, forkit wrote:static import mod = mixin(__MODULE__); That statement above would not compile.I don't understand myself but all of it as a single string works: mixin("static import mod = " ~ __MODULE__ ~ ";"); Ali
Nov 14 2021