Since it's a type with sub-classes, we need to use GTypeInstance (at the
very least), otherwise we won't be able to address each sub-class as
such.
This is similar to how GskRenderNode and GdkEvent are handled, with the
added difficulty that GtkExpression is meant to be used in properties,
in order to be deserialised by GtkBuilder. This requires adding a
GParamSpec sub-class that we can match on from within GtkBuilder,
alongside some convenience API for storing a GtkExpression inside a
GValue.
Use a weak ref to invalidate bindings. Make sure that this happens
before creating any watches, so that notifies from the
watched expression about changes will not trigger set_property() calls
during dispose()/finalize().
Invalidating also ensures that the watches aren't removed, which can
trigger warnings if the watches are watching the object itself, and the
weak refs cannot be removed anymore.
GtkExpressions allow looking up values from objects.
There are a few simple expressions, but the main one is the closure
expression that just calls a user-provided closure.