DIP82: static unittest blocks
Jonathan M Davis via Digitalmars-d
digitalmars-d at puremagic.com
Sun Sep 27 08:06:26 PDT 2015
On Sunday, 27 September 2015 at 10:32:00 UTC, Kenji Hara wrote:
> 2015-09-27 14:01 GMT+09:00 Jonathan M Davis via Digitalmars-d <
> digitalmars-d at puremagic.com>:
>
>> This DIP provides a way to handle unittest blocks inside of
>> templates which works with ddoc without compiling the unittest
>> blocks into each instantiation.
>>
>> http://wiki.dlang.org/DIP82
>>
>>
>> At present, we really can't put unittest blocks - including
>> ddoc-ed unittest blocks - inside of templated types, which has
>> been a problem for Phobos and came up again just the other day
>> when someone was helpful and went and tried to turn the
>> examples in std.datetime's *Interval types in ddoc-ed unit
>> tests, but we had to reject the changes, because it would have
>> resulted in those tests being compiled into every
>> instantiation of those templated types, polluting the code of
>> anyone who uses them as well as making the Phobos unit tests
>> take longer to run for no extra benefit whatsoever.
>>
>> So, I wrote up this DIP in the hopes of solving the problem in
>> a clean and simple manner which fits in well with the existing
>> language features.
>
>
> Interesting proposal.
>
> Quick questions:
>
> 1. I think the token `static` should be placed at the immediate
> front of `unittest`
>
> static unittest { ... }
> static nothrow unittest { ... } // NG
>
> It's consistent with the behavior of `static this()` family.
I confess that I've always found it to be inconsistent that
static constructors required that the static be immediately
before rather than being allowed before or after and among other
attributes like would occur with any other function. But if we're
going to retain that inconsistency with static constructors, it
doesn't really make things much worse to do the same with
unnittest blocks.
> 2. Currently the members of template won't be semantically
> analyzed until it's instantiated. So, when the `static
> unittest` is enclosed in other blocks, how it works?
>
> template Foo(T) {
> // inside conditional compilation blocks:
> static if (is(T == int)) {
> static unittest { ... }
> }
> version (UserDefinedVersion) {
> static unittest { ... }
> }
> debug (UserDefinedDebugId) {
> static unittest { ... }
> }
>
> // inside block/labeled attributes
> nothrow {
> static unittest { ... }
> }
> @safe:
> static unittest { ... }
>
> mixin("static unittest { ... }");
> mixin(makeStaticUnittest());
> }
>
> string makeStaticUnittest() { return "static unittest { ...
> }"; }
Well, my first question would be what happens with a ddoc comment
on a symbol within a template? It works to put ddoc comments on
symbols inside of templates, so clearly we have to have rules of
some kind which deal with each of the cases that you have here,
though I'm not as familiar as I probably should be with which of
those results in a symbol having its ddoc comment in the
documentation and which doesn't.
Regardles, it does indeed get a bit interesting. Ideally, I would
think that all of them save for the static if and mixins would
act exactly like they would outside of a template, since nothing
about this is specific to a template instantiation, but if no
semantic analysis is currently done on a template until it's
instantiated, then supporting a static unittest inside of a
version block, debug block, a block for an attribute, or after an
attribute used like a label would mean that at least some amount
of semantic analysis would have to occur that doesn't necessarily
happen now (though again, I wonder how that works with ddoc
comments). Maybe no semantic analysis is done if no static
unittest is found inside of them, and if one or more static
unittest is found inside of them, the minimal amount of semantic
analysis required to determine whether they get compiled in is
done?
As for the static if, I don't see how it can work if it depends
on any template arguments. I would think that it would work
easily enough like the version blocks and debug blocks and
whatnot if the condition did not depend on the template
arguments, but I think that it's clear that if the condition
depends on the template arguments at all, then any static
unittest blocks in there aren't going to work and probably should
be considered errors (even if it's just when the template is
instantiated and the static if's condition is true).
Now, as to the mixins... It would be nice if they worked, but I
have a hard time believing that it's reasonable to make them
work. We would like to be able to have mixins work with ddoc
comments, since without that, we can't put documentation on code
that's mixed in. So, if we ever implement that, then it might be
reasonable to do the same with static unittest blocks. But other
than that, the result would be that every mixin inside of a
template would have to be generated just to see whether it had a
static unittest in it, which is kind of ugly. If the argument to
mixin required a template argument to generate it, then it could
clearly be skipped, but if not, then we'd have to generate it
just to check, which would increase the compilation times for any
template which did that, which wouldn't exactly be pretty. It
probably wouldn't be a big deal in general, since in most cases,
if you're going to mix in code like that, you're probably going
to want to do it based on one or more template arguments, in
which case, the compiler would be able to see that it didn't need
to generate the mixin. Still, it would probably be better to just
not support mixins like this (at least initially) and possibly to
make it an error if a static unittest gets mixed in, since it
would only be mixed in when the template was instantiated.
But even if we did something simple and made it so that static
unittest blocks couldn't legally go inside of a version block,
debug block, etc. and that all attributes on it had to be applied
to it directly in order to have any effect, it would still be an
improvement over what we have now. I would hope though that we
could do something similar to what we do with ddoc comments
inside of a template and that the rules that that uses would work
for this too. But I don't know exactly what those rules are, so I
don't know how well that will work.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list