I've found that the fullyQualifiedName template in std.traits is a good tool for creating mixin code, however, it doesn't always work.

-----
import std.traits;

struct GlobalFoo
{
    int x;
}

// WORKS
mixin(fullyQualifiedName!GlobalFoo ~ " globalFoo;");

unittest
{
    static struct Foo
    {
        int x;
    }
    // Error: no property 'Foo' for type 'void'
    mixin(fullyQualifiedName!Foo ~ " foo;");
}

void main()
{
    static struct Foo
    {
        int x;
    }
    // Error: no property 'Foo' for type 'void'
mixin(fullyQualifiedName!Foo ~ " foo;"); // Error: no property 'Foo' for type 'void'
}
-----

The problem in the example is that you can't access the Foo struct outside the unittest/main function, even if you have a qualified name. I'm wondering if adding support for cases like this should be considered? Should you be able to access types defined inside a unittests/functions?

Another idea to help with this would be to add a new template to phobos, relativeQualifiedName. This would take the current context into account and remove that from the fullyQualifiedName.

module foo;

struct baz
{
     void bar()
     {
         struct bon
         {
         }
         assert(fullyQualifiedName!bon == "foo.baz.bar.bon");
         assert(relativeQualifiedName!bon == "bon");
     }
}

I've thought about how to implement this but haven't figured out a good way. I had something like the following in mind:

template relativeQualifiedName(T)
{
string relativeQualifiedName(string context = __QUALIFIED_NAME_CONTEXT__)
    {
        return fullyQualifiedName!T[context.length+1..$];
    }
}

Of course, __QUALIFIED_NAME_CONTEXT__does not exist in the langauge so this wouldn't work. Any thoughts/suggestions? Can someone think of a way to implement relativeQualifiedName?




Reply via email to