This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
To allow the user to customize the C++ code that QDoc sees, so as to be
able to work-around some limitations on QDoc itself, QDoc defines two
symbols: Q_QDOC and Q_CLANG_QDOC, both of which are "true" during an
entire execution of QDoc.
At a certain point in time, QDoc allowed the user the choice between a
custom C++ parser and a Clang based one.
The Q_QDOC symbol would always be defined while the Q_CLANG_QDOC symbol
would be defined only when the Clang based parser was chosen.
In more recent times, QDoc always uses a Clang based parser, such that
both Q_CLANG_QDOC and Q_QDOC are always defined, making them equivalent.
To avoid using different symbols, and the possible confusion and
fragmentation that derives from it, all usages of Q_CLANG_QDOC are now
replaced by the equivalent usages of Q_QDOC.
Change-Id: I5810abb9ad1016a4c5bbea99acd03381b8514b3f
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
Some tests in corelib/kernel need threading support, but they are not
guarded against compilation if Qt is built without threading.
Such tests have been disabled in this case.
Change-Id: I2f5dc9582f2a59b6af2a9e56638b045dca06193d
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
CMakeLists.txt and .cmake files of significant size
(more than 2 lines according to our check in tst_license.pl)
now have the copyright and license header.
Existing copyright statements remain intact
Task-number: QTBUG-88621
Change-Id: I3b98cdc55ead806ec81ce09af9271f9b95af97fa
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
Problem description:
--------------------
Assume we have two properties, P1 and P2. Assume further that we assign
a binding to P2, so that it depends on P1. Let the binding additionally
capture some (non-QProperty) boolean, and only create the dependency to
P1 if the boolean is true.
The state afterwards is
P1:[p1vaue|firstObserver]
|
|
v
---[p2binding]
/
P2:[p2value|binding]
If the boolean is set to false, and P1 changes its value, we still
correctly re-evaluate the binding and update P2's value. However, during
binding evaluation we will notice that there is no further dependency
from P2 on P1, and remove its observer.
The state afterwards is
P1:[p1vaue|firstObserver=nullptr]
---[p2binding]
/
P2:[p2value|binding]
Then, during the notify phase, we traverse the observer's again,
starting from P1's firstObserver. Given that it is nullptr now, we never
reach P2's binding, and thus won't send a notification from it.
Fix:
----
We store a list of all visited binding-observers (in a QVarLengthArray,
to avoid allocations as long as possible). After the binding evaluation
phase, we then use that list to send notifications from every binding
that we visited. As we already have a list of all bindings, we no longer
need to recurse on binding-observes during the notification process;
instead, we only need to deal with static callbacks and ChangeHandlers.
The pre-existing notification logic is still kept for the grouped update
case, where we already have a list of all delayed properties, and should
therefore not encounter the same issue. Unifying its codepath with the
existing logic is left as an exercise for a later patch.
Fixes: QTBUG-105204
Task-number: QTBUG-104982
Pick-to: 6.4 6.3 6.2
Change-Id: I2951f7d9597f4da0b8560a64dfb834f7ad86e757
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Set it to nullptr on clear, and deal with possibly null bindingStatus.
Task-number: QTBUG-101177
Task-number: QTBUG-102403
Pick-to: 6.4
Change-Id: I66cb4d505a4f7b377dc90b45ac13834fca19d399
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
Files that have to be modified by hand are modified.
License files are organized under LICENSES directory.
Task-number: QTBUG-67283
Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
In some situation we want to notify even if the value didn't change.
Task-number: QTBUG-101771
Pick-to: 6.2 6.3
Change-Id: I7d82a9f6e0f7d5eb48065e3f428b814939181ea8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
QObject's cache the binding status pointer to avoid TLS lookups.
However, when an object is moved to a different thread, we need to
update the cached pointer (as the original thread might stop and thus no
longer exist, and to correctly allow setting up bindings in the object's
thread).
Fix this by also storing the binding status in QThreadPrivate and
updating the object's binding status when moved. This does only work
when the thread is already running, though. If it is not running, we
instead treat the QThreadPrivate's status pointer as a pointer to a
vector of pending objects. Once the QThread has been started, we check
if there are pending objects, and update them at this point.
Pick-to: 6.2 6.3
Fixes: QTBUG-101177
Change-Id: I0490bbbdc1a17cb5f85044ad6eb2e1a8c759d4b7
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Add additional template argument to QObjectCompatProperty to specify
a custom getter. This may be useful for classes like
QAbstractProxyModelPrivate the need to customize property getters.
Task-number: QTBUG-89655
Change-Id: I34fe4bdebbbf1446aff60bd20a946454607f52d5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
- getgrgid/getpwuid are not supported
- the default constructor of "ObserverOrUninit" must be referenced for GHS compiler
Task-number: QTBUG-96176
Pick-to: 6.2
Change-Id: I24093da76e116aba4b87a8f5c5763b03d082a2cd
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Qt requires a compiler that support C++17 thus __cplusplus
is always 201703L or higher. This patch removes checks
for __cplusplus value that always succeed.
Change-Id: I4b830683ecefab8f913d8b09604086d53209d2e3
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
As QPropertyAlias was public by accident in 6.0, we have to ensure that
it still works in 6.2.
This re-adds some tests for it, and reimplements the unlinking
functionality. To avoid performance regressions in hot-paths,
a new unlink_fast function is added, which behaves like the old unlink:
It ignores the special handling for QPropertyAlias, so that we can skip
the tag check. It is only used in QPropertyObserverNodeProtector and
clearDependencyObservers, where we already know the type of the
observer.
Fixes: QTBUG-95846
Pick-to: 6.2
Change-Id: Ifb405b8327c4d61c673b1a912ed6e169d27c2d8f
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
We call evaluateRecursive_inline in setBinding, which in turns runs the
noSelfDependecies check. However, creating a binding resuting in a
binding loop must not crash, but instead result in the binding entering
an error state. To prevent a crash caused by the assert in debug builds
of Qt, we replace the assert with a warning for now.
A better approach in the future would be to ensure that we only run the
check in cases where we are sure that a self-dependency is really a
fatal error.
Pick-to: 6.2
Change-Id: I58158864ed81fa907132a4e7d6667c9b529e7e64
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
Directly writing to the underlying property storage has the potential of
breaking all kinds of internal invariants. As we return QBindable in
the public interface, we should not grant callers access to the
internals of the object.
Pick-to: 6.2 6.1
Change-Id: I737ff293b9d921b7de861da5ae23356c17690b78
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Andreas Buhr <andreas.buhr@qt.io>
Once we're in ~QObject, only methods of QObject are still valid.
Notably, no setter of any derived class is still valid. Thus, to be safe
we must no longer react to binding changes of those properties. To
ensure that this happens for QObjectCompatProperty properties, we
explicitly clear the binding storage.
Fixes a particles3d example crash.
Change-Id: I10d2bfa5e96621ce039d751cffaf3ac41893623e
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
QPropertyChangeHandler is a templated class and it's argument is
a functor. That makes it inherently cumbersome to use the class
in any context where the change handler needs to be stored.
Introduce a QPropertyNotifier class that stores the functor
in a std::function<void()>, and add a QProperty::addNotifier()
method that can be used instead of onValueChanged().
Also make QPropertyNotifier default constructible.
This significantly simplifies the code that needs to be written
and makes it possible to store notifications as class members
without major hassle.
Fixes: QTBUG-92980
Change-Id: Id5b7baec093b9ac0467946cded943d92ad21030b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Since we changed binding evaluation to be always eager, we notify and
evaluate all bindings as soon as any dependency changes. This includes
bindings which have been initially installed on a property, but which
were later removed.
With lazy evaluation, we would only notify those bindings and mark them
as dirty, which is unproblematic. With eager evalution, we attempt to
evaluate the binding, though. While that part is still fine, afterwards
we would attempt to write the new value into the property. However,
there is no property at that point, as the binding is not installed.
Instead of adding a check whether the propertydataptr is null, we skip
the reevaluation completely by removing the bindings observers - and
thus the cause for the binding function's reevaluation. As soon as the
binding is set, we reevaluate the function anyway, at which point we
also capture the observers again.
Task-number: QTBUG-89505
Change-Id: Ie1885ccd8be519fb96f6fde658275810b54f445a
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This removes traces of QPropertyAlias which is internal API which is
a) not really working even before this change (no compatibility with
QBindableInterface due to QPropertyAlias not being derived from
QUntypedPropertyData)
b) not used anywhere
For BIC reasons, we need to keep some methods still around until Qt 7,
though.
Change-Id: I5bb4735a4c88cba275dc2cc6e29a46ca09622059
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Instead of silently failing, we now print an explanatory warning to aid
with debugging.
Task-number: QTBUG-89512
Change-Id: I36dd2ce452af12d0523c19286919095e366bd390
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
With C++20 standard, src/corelib/kernel/qproperty.h of Qt Base cannot be
compiled at line 100:
QPropertyBindingSourceLocation(
const std::experimental::source_location &cppLocation
)
The reason is that source_location has been merged into namespace std
since C++20, and the header file has also been change from
<experimental/source_location> to <source_location>.
The problem can be avoided by define a constant.
Fixes: QTBUG-93270
Change-Id: I46b4daac6ea20f9623b43746880500d41396afb2
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
If the signal takes a value, we pass the current value of the property
to it.
As we now use eager evaluation, accessing the current value is now
possible.
Change-Id: I5e6947a6575bfa8ca5143f56620c645d4750a686
Reviewed-by: Andreas Buhr <andreas.buhr@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This mirrors the functionality of QObjectCompatProperty::notify, and can
be useful to delay notifications until a class invariant has been
restored.
Change-Id: I1c16a0b1537a1b53d144c8abe48e546553edf877
Reviewed-by: Andreas Buhr <andreas.buhr@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
A sticky QPropertyBinding is a binding that does not get removed when a
write occurs. This is used in the QML engine to implement support for
the QQmlPropertyData::DontRemoveBinding flag.
Task-number: QTBUG-91689
Change-Id: Ib575b49abe634215318ccc7ba46212cc21eb4dad
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Add Qt::begin/endPropertyUpdateGroup() methods.
These methods will group a set of property updates together and delay
bindings evaluations or change notifications until the end of the update
group.
In cases where many properties get updated, this can avoid duplicated
recalculations and change notifications.
Change-Id: Ia78ae1d46abc6b7e5da5023442e081cb5c5ae67b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Andreas Buhr <andreas.buhr@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
When a property value changes, first update all dependent bindings to
their new value. Only once that is done send out all the notifications
and changed signals.
This way, if a property depends on multiple other properties, which all
get changed, there will only be one notification; and (potentially
invalid) intermediate values will not be observed.
Fixes: QTBUG-89844
Change-Id: I086077934aee6dc940705f08a87bf8448708881f
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Andreas Buhr <andreas.buhr@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Too much of the existing code in Qt requires eager evaluation without
large scale modifications. Combined with the fact that supporting both
eager and lazy evaluation has a high maintenance burden, keeping lazy
evaluation, at least in its current state, is not worth it.
This does not diminish other benefits of the new property system, which
include
- a C++ API to setup and modify bindings and
- faster execution compared to QML's existing bindings and the ability
to use them without having a QML engine.
We do no longer benefit from doing less work thanks to laziness. A later
commit will introduce grouping support to recapture some of this
benefit.
[ChangeLog][Import Behavior Change][QProperty] QProperty uses always
eager evaluation now when a dependency in a binding changes.
Change-Id: I34694fd5c7bcb1d31a0052d2e3da8b68d016671b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Andreas Buhr <andreas.buhr@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
A few methods in QBindable which do not modify anything were not marked
as const so far. This adds the missing const, and a test to verify that
they work.
As all methods are fully inline, this does not cause any binary
compatibility issues.
Fixes: QTBUG-89508
Change-Id: If06d33bc405232887b8c371c268840ba34dbadf6
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit amends 4ceaf22bed.
Signal parameter was not actually used, even is the signal was
specified.
This patch fixes it and also introduces unit-tests for this issue.
Change-Id: I029d413644eb6a72af3bdce27cc5f5bcadfe946a
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
There is no need to write emit and notify at the same time, as not
emitting after notify does not make sense.
This naturally only applies to properties with a changed signal.
Change-Id: I99ff7863a509262ad9d4f7c9c5afbc66fd37001c
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
For QObjectCompatProperty, which allows to do basically anything in its
setter, it is actually easier to manually specify when the change should
become visible. This is in line with manually writing emit calls in the
old property system, and allows the preservation of class invariants.
Change-Id: I585bd3f25d722ca3fd721ead85fe73dbee26c5f6
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Introduction of QObjectCompatProperty requires every write to
the property to be examined whether it is OK or should be replaced
by a setValueBypassingBindings/markDirty combination. The existence
of operator= make this difficult as it is easy to miss places where
it is written. By not having operator=, we can help developers
make sure they had a conscious decision about each write to the
property.
Change-Id: Ia61ea4722eb0bab26ce7684b85dd03d710cd1751
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This is in line with QML where
import QtQuick 2.15
Rectangle {
width: 100
height: 100
color: "red"
Rectangle {
id: inner
x: 10
y: x
width: 50
height: 50
onYChanged: { console.log("hey"); inner.x = 10}
TapHandler {
onTapped: inner.x = 20
}
}
}
results in a binding loop warning when the tap handler triggers. While
the change handler would only run once, we cannot statically determine
if we need to loop once, twice, or if there actually is a diverging
loop. Thus we unconditionally warn about the binding loop and stop
executing the binding.
As a drive-by, verify in the related test that a change handler which
overwrites its properties binding itself removes the binding.
Change-Id: I5372019c2389ab724c49cd7489ecbd3ebced1c69
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
We missed takeBinding as a supported operation on Q(Untyped)Bindable.
To avoid adding version checks to code dealing with QBindableInterface,
we simply synthesize takeBinding as a combination of binding to retrieve
the binding and setBinding with a default-constructed
QUntypedPropertyBinding.
Change-Id: I43803a0dfe210353d0235f0373d2257f75ffe534
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
To optimize certain operations, it can be useful to know whether we are
currently evaluating a binding. For instance, we have properties whose
storage is only alloctaed on-demand when they are set. However, we would
also allocate them if they are used in a binding context, as we would
otherwise not properly track the dependency. Using
isAnyBindingEvaluating in the getter, we can detect this
situation, and avoid the allocation if it returns false.
This API is private for now, as it exposes some internals of the
property system and should be used with care. As it needs to access the
TLS variable, it also has a non-negligible cost.
Change-Id: I373aabee644fe7020b2ffba7d6a0ad9a1e1b4ec0
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
If we create a QBindable from a const property, we should obtain a
read-only interface. Besides implementing this feature, this patch adds
a isReadOnly method to Q(Untyped)Bindable which can be used to check
whether one can modify the property via the bindable interface.
Task-number: QTBUG-89505
Task-number: QTBUG-89469
Change-Id: Ic36949a5b84c5119e0060ed0a1cf4ac94a66f341
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Remove the qmake project files for most of Qt.
Leave the qmake project files for examples, because we still test those
in the CI to ensure qmake does not regress.
Also leave the qmake project files for utils and other minor parts that
lack CMake project files.
Task-number: QTBUG-88742
Change-Id: I6cdf059e6204816f617f9624f3ea9822703f73cc
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
This adds functionality for marking properties (QProperty and related
classes) manually as dirty. This facilliates the integration of bindable
properties with non-binable properties and makes it possible for
bindable properties to change due to external events.
Fixes: QTBUG-89167
Change-Id: I256cf154d914149dacb6cadaba92b13c88c9d027
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
When an eager binding triggers a setBinding call, we end up with a
special kind of binding loop:
setBinding() -> evaluate -> notifyObserver
^ |
| /
----------------------------
We now catch set condition, and set the binding status to BindingLoop
(with a distinct description).
Task-number: QTBUG-87153
Task-number: QTBUG-87733
Pick-to: 6.0
Change-Id: I9f9915797d82eab820fc279baceaf89d7e5a3f4a
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
The intention was always that you can define properties that do
not require a changed signal. But having to explicitly pass
a nullptr as signal parameter into the macro is ugly, so
use the cool QT_OVERLOADED_MACRO to make it optional.
Pick-to: 6.0
Change-Id: I0ce366d043850f983c968d73c544d89933c48df9
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
If a QBindable is created from a computed property, it is not possible
to actually set a value or a binding. If we try to do it anyway, we'd
get a crash. Thus we now check whether the function pointer is null
before invoking it.
Pick-to: 6.0
Task-number: QTBUG-87153
Change-Id: I5bedb9080ccf79d9b8166b80d5733d095ed76f8d
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Avoid spurious bindings by resetting the binding state before calling
the setter of eager properties.
Fixes: QTBUG-88999
Pick-to: 6.0
Change-Id: I1e3b5662307d906598335a21d306be9c606529d4
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This ensurse that we do not do dobule notifications in setValue.
Moerover we avoid needless notifications in markDirtyAndNotifyObservers
when the value did not change. Lastly, if the value did actually change,
we pass that information along to notify, so that we do not evaluate the
eager property twice.
Fixes a test-case which errorneously relied on the old behavior, and
adds a new test which verifies that the fix works.
Change-Id: I8ec6fa2fe8611565dfc603ceab3ba5f92999b26c
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>