How/where to hack DMD to generate docs for string mixed members.
Hey, How/where to hack DMD to generate docs for string mixed members? struct S { mixin(" /// auto bar() {} "); } Best regards, Ilya Yaroshenko
Re: Why is the error message coming by the end of the compilation?
On Saturday, 14 April 2018 at 17:58:20 UTC, Steven Schveighoffer wrote: On 4/14/18 4:16 AM, bauss wrote: I tried to use __traits(compiles) but it always returns false for the code I'm going to mixin, even though it's valid, that was my initial go to, so this is really a second attempt on something to give meaningful error messages when certain mixins don't compile. Hm.. that seems annoying. I'd guess you'd get simple tests to work, maybe it's the way you are using __traits(compiles). If all else fails, back out to the place where you are using it. At some point, it is a function call. Just wrap that call, and check if it compiles or not. e.g.: static assert(__traits(compiles, theFunction(theItem), "this code won't compile: " ~ theItem.source); // if we get here, it will compile theFunction(theItem); D can be quite perplexing when you have so much meta in it :) -Steve All I mixin is a class, but the class itself can be pretty big and have all kinds of complexity. What I first tried was using __traits(compiles, source) without anything, then I tried to make a wrapper function that simply did it but nothing works with it. I know there are a few things that you can't test directly with __traits(compiles) since it has its limits, but a class shouldn't be one of them. I think it's kind of hard to demonstrate what exactly I'm doing unless you have the code, but even so I don't see a way around it. What I'm trying to achieve is getting a way from one big mixin with all the source code using join() on an array of strings, so I can give sensible error messages to the user, since right now you have to know which file you made an error in, because you have no information like that except for what line in the mixin the error is. That is okay when you have let's say 10 lines of code, but in my case each mixin can span well over hundreds of lines of code or even more. And the code the user see is not the same code that is within the mixin, so you can't use the line numbers for anything, because the code the user made is parsed and translated into other pieces of D code which is put into the function of a class and then that class is what the mixin actually is. It's kind of complex. I wish there was a way to give a mixin some kind of identity like: mixin("mymixin", "somecode"); Where an error message would print something like: Error in mixin("mymixin"): ... That would completely solve this issue and I wouldn't have to have pragma(msg) all over the place. I'm not sure whether such a proposal would be worth it, but in my case that would help a lot, but I'd guess it would need a DIP?
Re: Why is the error message coming by the end of the compilation?
On 4/14/18 4:16 AM, bauss wrote: I tried to use __traits(compiles) but it always returns false for the code I'm going to mixin, even though it's valid, that was my initial go to, so this is really a second attempt on something to give meaningful error messages when certain mixins don't compile. Hm.. that seems annoying. I'd guess you'd get simple tests to work, maybe it's the way you are using __traits(compiles). If all else fails, back out to the place where you are using it. At some point, it is a function call. Just wrap that call, and check if it compiles or not. e.g.: static assert(__traits(compiles, theFunction(theItem), "this code won't compile: " ~ theItem.source); // if we get here, it will compile theFunction(theItem); D can be quite perplexing when you have so much meta in it :) -Steve
Re: template evaluation
Ok, trying to reduce my example a little bit, I arrived at this: ´´´ void main(){} struct D { size_t dummy; auto static s = S!D.init; } struct S(alias container = null) { pragma(msg, container); static if(__traits(compiles, __traits(allMembers, container))) { static foreach(m; __traits(allMembers, container)) { pragma(msg, m); pragma(msg, is(typeof(__traits(getMember, container, m; /* for D.dummy this yields "true" for D.s this yields "false" */ } } } ´´´ What I clearly have, is a circular reference, now I'm aware of this. So, am I trying something illegal? It seems, I can't get the type of the according member of the template parameter, even then (or should I say "especially because") the analyzing type has the same type. But if this would be the only member, which I can't get the type of, the information would be enough, to ensure what I want. Is it like this?
template evaluation
Hi all, I must overlook something, but given this: ´´´ void main(){} static assert(isMatching!(D, S!(D, true))); // place 1: works as expected. struct D { auto static s = S!(typeof(this), true).init; } enum bool isMatching(T, U) = (){ bool b; static foreach(i, m; __traits(allMembers, T)) { static if(is(typeof(__traits(getMember, T, m)) == U)) { if(b) return false; else b = true; } } return b; }(); struct S(T, bool c = false) //if(isMatching!(T, S!(T, true))) // place 2: does not work {} ´´´ While "place 1" works as expected: it static asserts to true, if type D has a single coinciding member to the checked one and static asserts to false if it doesn't or if there are more of them then one; Why I can't use the same template in "place 2"? PS: Taken the (){}() pattern from here: https://p0nce.github.io/d-idioms/#Precomputed-tables-at-compile-time-through-CTFE
Re: Why is the error message coming by the end of the compilation?
On Friday, 13 April 2018 at 21:20:26 UTC, Ikeran wrote: On Friday, 13 April 2018 at 20:50:38 UTC, bauss wrote: What I'm doing is basically this: static foreach (viewResult; generateViewsResult) { pragma(msg, "Compiling: " ~ viewResult.name); mixin(viewResult.source); pragma(msg, "Compiled: " ~ viewResult.name); } I would've expect the compiling to be before the error message, but the compiled after the error message. However it seems like it doesn't do that, but as I can't reproduce it I'm just wondering what causes it. The compiler is free to examine your source code in any order that produces the same artifacts on success and self-consistent error messages otherwise. In this case, it evaluated the pragmas and the `mixin` in one pass, then the function body in a separate pass. The best way I've found to debug mixins is to pragma(msg) the code I wanted to mix in, then insert it myself. The problem is I can't pragma(msg) the code I want to mixin manually since all mixins are dynamically generated. That's why my only way is to do it within that static foreach. I have no control over how many mixins there are and only to an extend what they contains. Basically what I'n doing is I have a file named views.config in which each like contains something like: name|file.dd The name is what's in viewResult.name and the content of file.dd is what's in viewResult.source (But parsed and wrapped into a valid D class) I initially tried to just use __traits(compiles) but it fails even on the valid generated D code.
Re: Why is the error message coming by the end of the compilation?
On Friday, 13 April 2018 at 21:22:13 UTC, Steven Schveighoffer wrote: On 4/13/18 4:50 PM, bauss wrote: I can't seem to reproduce this with any other smaller projects, so my question is really what could trigger this behavior. See: https://i.imgur.com/OmqJ8Sr.png Whenever I try to just do this kind of thing by itself then it behaves correctly. Ex: (As you can see it prints the error messages in the order it should.) https://run.dlang.io/ What I'm doing is basically this: static foreach (viewResult; generateViewsResult) { pragma(msg, "Compiling: " ~ viewResult.name); mixin(viewResult.source); pragma(msg, "Compiled: " ~ viewResult.name); } I would've expect the compiling to be before the error message, but the compiled after the error message. It may be on a later semantic pass that the error occurs, I'm not sure. Only thing I can think of. However it seems like it doesn't do that, but as I can't reproduce it I'm just wondering what causes it. I'm suspecting that it's something to do with dub and that it's within a dependency that's compiled as a source library, but I've yet to test it out completely. Try verbose output maybe? It's really impossible to debug mixins when you have no idea which mixin the error actually come from, which is what I'm trying to solve. You may want to try using __traits(compiles) in a debug version to see whether it will compile or not, and if not, print the thing you are trying to compile. -Steve I tried to use __traits(compiles) but it always returns false for the code I'm going to mixin, even though it's valid, that was my initial go to, so this is really a second attempt on something to give meaningful error messages when certain mixins don't compile.