On 4 June 2013 18:23, Jacob Carlborg <doob@me.com> wrote:
In the thread "Slow performance compared to C++, ideas?" Manu is arguing that methods should be non-virtual by default. The problem he is having is that developers will forget to declare methods as final.

This issue got me think if there's a way to automatically detect that a method is virtual that shouldn't be.

If one modifies druntime to take advantage out of RTInfo. If I understand everything correctly RTInfo will be instantiated once for each user defined type. With that and the help of a UDA you can check that all methods that should be final really are final. Something like:

struct virtual {} // the UDA

class Foo
{
    void a () {} // static assert, not declared as @virtual
    @virtual void b () {} // ok
    @virtual final void c () {} // static assert, declared as final and @virtual
    final d () {} // ok
}

checkVirtual!(Foo);

import std.typetuple;

void checkVirtual (T) ()
{
    static if (!is(T == class))
        return;

    foreach (m ; __traits(derivedMembers, T))
    {
        alias TypeTuple!(__traits(getAttributes, mixin("T." ~ m))) attrs;
        enum methodName = T.stringof ~ "." ~ m.stringof;

        static if (staticIndexOf!(virtual, attrs) != -1)
        {
            static if (!__traits(isVirtualMethod, mixin("T." ~ m)))
                static assert (false, "Method " ~ methodName ~ " marked as @virtual is not virtual");
        }

        else
        {
            static if (__traits(isVirtualMethod, mixin("T." ~ m)))
                static assert (false, "Method " ~ methodName ~ " is virtual but not marked as @virtual");
        }
    }
}

--
/Jacob Carlborg

This is a great idea. If final-by-default is ultimately rejected, I'll definitely try this out.
That said, it only solves half the problem, that is, internal programmers forgetting to mark their functions final (and assuming they also remember 'checkVirtual!' in their moules).
It offers nothing to address the 3rd party library problem.