Details
-
Task
-
Resolution: Unresolved
-
P2: Important
-
None
-
2cc30828a (dev), 25e1f9b89 (dev)
Description
We have a FINAL modifier for Q_PROPERTY. It is supposed to prevent definitions of further properties of the same name in derived classes. It is enforced only by the QML engine.
Shadowing of properties is a major problem for QML tooling. We can rarely determine the type of a property with certainty without executing the code that manipulates it. This is because the object holding the property can often be of a derived type. In a derived type any non-FINAL properties can be overridden with properties of different type (and different ID in the meta object).
Shadowing of properties is also rare. Often it's accidental, and most of the time the effects are quite confusing. Code that our QML tooling stumbles over is generally rather hard to read for the developer, too. If you manipulate a property of a given name that exist on the class of the object at hand, you do not expect to actually manipulate a different property of a derived class.
All of this suggests that simply attaching a FINAL attribute to every single property is not a sufficient solution. It's error prone because you can easily forget it and it's a lot of boiler plate. Rather, we should mimic the C++ way of handing this:
- VIRTUAL (or lower case "virtual" in QML) denotes that a property can be overridden. If it's not VIRTUAL and you still override you get a warning for now. Later we can turn it into an error. However, you can only override VIRTUAL properties explicitly, with OVERRIDE or FINAL. Any attempt to override a VIRTUAL property with a non-OVERRIDE and non-FINAL property is an error.
- OVERRIDE (or "override") denotes that the property does override a VIRTUAL one. If you override a VIRTUAL property without OVERRIDE, that is an error. If you OVERRIDE a property that's not VIRTUAL, that's also an error. OVERRIDE on a property that doesn't override anything is also an error.
- FINAL (and "final") denotes that you override a VIRTUAL property and that it cannot be further overridden. FINAL properties that actually don't override anything are fine for now, but eventually we should also warn on those and teach people to remove the boiler plate. FINAL properties that override a non-VIRTUAL property are a warning for now, but can become an error later.
The same thing should be done to Q_INVOKABLE methods. Overriding Q_INVOKABLE methods is even rarer than overriding properties. Before taking any action we need to determine the current behavior of the QML engine regarding how they are handled. We might then introduce Q_VIRTUAL, Q_OVERRIDE, and Q_FINAL if necessary. Those would imply Q_INVOKABLE with the added semantics detailed above.
Mind that non-Q_VIRTUAL methods could still be virtual in C++, as long as none of their overrides are Q_INVOKABLE, and similar for override and final. The meta object call will do the right thing there.
Methods can also be overloaded on argument types, which is its own can of worms that has to be addressed separately. A solution purely for overriding on the same set of argument types would be a big step forward, though.
Attachments
Issue Links
- covers
-
QTBUG-108739 Most properties in QtQuick are not FINAL and can be shadowed
-
- Closed
-
- relates to
-
QTBUG-116636 qmltc: Add ability to mark Q_PROPERTY() as FINAL
-
- Reported
-
-
QTBUG-125002 QML: Treat "required property" as FINAL
-
- Reported
-
- resulted from
-
QTBUG-96588 Allow "final" modifier on QML properties
-
- Closed
-
- mentioned in
-
Page Loading...
Gerrit Reviews
For Gerrit Dashboard: QTBUG-98320 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
381599,14 | QML: Add final property attribute | dev | qt/qtdeclarative | Status: MERGED | +2 | 0 |
628978,8 | qmlformat: Support the final property attribute | dev | qt/qtdeclarative | Status: MERGED | +2 | 0 |