Thread overview
Inspecting __traits(isDeprecated) and deprecation warnings
Sep 24, 2019
Anonymouse
Sep 25, 2019
Tobias Pankrath
Sep 25, 2019
Anonymouse
Sep 25, 2019
Boris Carvajal
Sep 26, 2019
drug
Sep 26, 2019
Anonymouse
September 24, 2019
I want to write a piece of code that reflects on the names of members of a passed struct, where some are depreacted.

https://run.dlang.io/is/P9EtRG

struct Foo
{
    string s;
    int ii;
    bool bbb;

    deprecated("Use `s`")
    string zzzz;
}

template longestMemberLength(T)
{
    enum longestMemberLength = ()
    {
        size_t maxLength;

        foreach (immutable i, immutable name; __traits(allMembers, T))
        {
            static if (!__traits(isDeprecated, __traits(getMember, T, name)))
            {
                maxLength = max(maxLength, name.length);
            }
        }

        return maxLength;
    }();
}

static assert (longestMemberLength!Foo == "bbb".length);

> onlineapp.d(23): Deprecation: variable `onlineapp.Foo.zzzz` is deprecated - Use s

Is there any way to inspect the deprecated-ness of a member this way? I only have what __traits(allMembers) gives me.
September 25, 2019
On Tuesday, 24 September 2019 at 17:01:46 UTC, Anonymouse wrote:
> I want to write a piece of code that reflects on the names of members of a passed struct, where some are depreacted.
>
> https://run.dlang.io/is/P9EtRG
>
> struct Foo
> {
>     string s;
>     int ii;
>     bool bbb;
>
>     deprecated("Use `s`")
>     string zzzz;
> }
>
> template longestMemberLength(T)
> {
>     enum longestMemberLength = ()
>     {
>         size_t maxLength;
>
>         foreach (immutable i, immutable name; __traits(allMembers, T))
>         {
>             static if (!__traits(isDeprecated, __traits(getMember, T, name)))
>             {
>                 maxLength = max(maxLength, name.length);
>             }
>         }
>
>         return maxLength;
>     }();
> }
>
> static assert (longestMemberLength!Foo == "bbb".length);
>
>> onlineapp.d(23): Deprecation: variable `onlineapp.Foo.zzzz` is deprecated - Use s
>
> Is there any way to inspect the deprecated-ness of a member this way? I only have what __traits(allMembers) gives me.

Does your code work or does it not? I don't seem to unterstand neither what the question here is nor what the desired result is. Is the problem that the static reflections triggers the deprecation warning?
September 25, 2019
On Wednesday, 25 September 2019 at 05:57:19 UTC, Tobias Pankrath wrote:
> Does your code work or does it not? I don't seem to unterstand neither what the question here is nor what the desired result is. Is the problem that the static reflections triggers the deprecation warning?

I added some deprecations in my project and am going through my templates trying to silence the warnings that suddenly popped up. This template works, but it triggers deprecation warnings when I am actively trying to avoid them.

getMember in _traits(isDeprecated, __traits(getMember, T, name)) causes a warning on deprecated symbols, which I wanted to avoid with isDeprecated, but I couldn't without first calling getMember to get the symbol to evaluate it. There's no way to combine isDeprecated with getMember without getting a warning.

I worked around the issue by using .tupleof instead of getMember, which breaks it for classes (.tupleof needs a `this` and SomeClass.init can't be it) but silences warnings for structs.

https://run.dlang.io/is/TVR8Cb

import std;

void main()
{
    static assert(longestMemberName!Foo == "bbb".length);
}

struct Foo
{
    string s;
    int ii;
    bool bbb;

    deprecated("Use `s`")
    string zzzz;
}

template longestMemberName(T)
if (is(T == struct))
{
    enum longestMemberName = ()
    {
        size_t maxLength;
        T thing;  // need a `this`

        foreach (immutable i, member; thing.tupleof)
        {
            static if (!__traits(isDeprecated, thing.tupleof[i]) &&
                       !isType!(thing.tupleof[i]))
            {
                enum name = __traits(identifier, thing.tupleof[i]);
                maxLength = max(maxLength, name.length);
            }
        }

        return maxLength;
    }();
}
September 25, 2019
On Wednesday, 25 September 2019 at 14:20:00 UTC, Anonymouse wrote:
> I added some deprecations in my project and am going through my templates trying to silence the warnings that suddenly popped up. This template works, but it triggers deprecation warnings when I am actively trying to avoid them.

This code seems to work for classes too and even with DMD "-de" compiler switch.

template isMemberDeprecated(T, string name)
{
    enum isMemberDeprecated = mixin(q{__traits(isDeprecated, }, T, ".", name, q{)});
}

https://run.dlang.io/is/iQbxOC


September 26, 2019
On 9/25/19 11:35 PM, Boris Carvajal wrote:
> On Wednesday, 25 September 2019 at 14:20:00 UTC, Anonymouse wrote:
>> I added some deprecations in my project and am going through my templates trying to silence the warnings that suddenly popped up. This template works, but it triggers deprecation warnings when I am actively trying to avoid them.
> 
> This code seems to work for classes too and even with DMD "-de" compiler switch.
> 
> template isMemberDeprecated(T, string name)
> {
>      enum isMemberDeprecated = mixin(q{__traits(isDeprecated, }, T, ".", name, q{)});
> }
> 
> https://run.dlang.io/is/iQbxOC
> 
> 
It's really nice! Thank you.
September 26, 2019
On Wednesday, 25 September 2019 at 20:35:55 UTC, Boris Carvajal wrote:
> On Wednesday, 25 September 2019 at 14:20:00 UTC, Anonymouse wrote:
>> I added some deprecations in my project and am going through my templates trying to silence the warnings that suddenly popped up. This template works, but it triggers deprecation warnings when I am actively trying to avoid them.
>
> This code seems to work for classes too and even with DMD "-de" compiler switch.
>
> template isMemberDeprecated(T, string name)
> {
>     enum isMemberDeprecated = mixin(q{__traits(isDeprecated, }, T, ".", name, q{)});
> }
>
> https://run.dlang.io/is/iQbxOC

I think I can work with this, thanks!