Another big design goal for Metawidget is that it do its work at runtime: I've long had a bee in my bonnett about those who espouse the benefits of static code generation. Yes, static code generation seems to get you started quickly, but in reality it generates volumes of code that is often of poor quality (very verbose, few comments, etc) and still has to be read and understood, documented, handed-over etc.
Runtime frameworks, on the other hand, generate zero code and whilst the frameworks themselves still need to be understood, there is usually lots of documentation how to do so. They also have the benefit of being able to work with the dynamic, runtime nature of a system, which is always richer than the static, compile-time information.
So for example a class Foo might declare a method getBar() which at compile-time is declared to return a Bar, but at runtime turns out (in some instances) to return an ExtendedBar. By examining runtime information, Metawidget can generate better, more accurate interfaces.
Still, this begs the question: if we are traversing objects in favour of classes, what happens if getBar() returns null? Should we stop traversing, or should we fall back to traversing the class heirarchy?
The latter approach is tempting, because it means we can display user interfaces for null objects: it seems a logical way to allow initializing new objects. However, in practice it's awkward because, given we already know the underlying data model is null, we have nowhere to send the data the user interface captures.
So for now I'm going with the first approach: traverse objects, not classes, and stop if we hit null. We'll see how it works out.