When accessing properties of a QObject* property in QML, then we currently cannot determine which property is being read even if we do know the exact object type. This is because properties can be overridden by specifying another property of the same name in some subclass. The QML engine will pick up the overridden property and access that. qmlcachegenplus-generated code will use the declared property or even crash.
Additionally, the QML engine will recognize properties added in subclasses, while qmlcachegenplus does not. This is commonly seen with the "parent" property of QQuickItem. If a specific Item with additional properties is used as parent, then the QML engine has no problems accessing the parent's extra properties. qmlcachegenplus will reject them, though.
We can leverage the "final" attribute of properties for fixing this. Final properties cannot be overridden.
To fix this, the following steps have to be taken:
- Reject property lookups on QObject* properties in qmlcachegenplus-generated code for now.
- Pass the "final" attribute through metatypes and qmltypes to qmlcachegenplus. Allow access to final properties of QObject* properties.
- Properly implement "as" casts. They need to be enforced.
- Add an attribute to classes that tells us which one is the "parent", like the current DefaultProperty.
- Add another attribute to classes that tells us whether a class rejects to be a parent. For example, a Repeater is never the parent of its children.
- Add a pragma that introduces a keyword "parent". That keyword as-casts the parent property to the document parent, unless the document parent does not want to be a parent.
- Warn in qmllint if the new pragma is not given. Assume it to be set in direct mode, even if it isn't.
This way, most parent access will be safe.