diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2018-10-18 09:29:26 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-10-23 17:23:13 +0000 |
commit | 8a2c182d5941a1d00ac9f7414d1508b7f959d6f3 (patch) | |
tree | 415f85f4d2fd483901cfd9d1d2b71537ae952639 /src | |
parent | ff11568f37999c62e7683b1c21861be63f14567c (diff) |
Fix erroneous enum conflict warnings
Permit enums from sub-classes to overwrite enums from super-classes, but
keep warnings about clashes within a class, provided that the values
differ. The last condition relates to the declaration of enums and a
subsequent declaration of Q_FLAGS, which appear to have the same keys
and values in the meta-object system.
Task-number: QTBUG-71184
Change-Id: I2a00dc90e3714fc4c6fe8add5a6268b88bb9e745
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Rainer Keller <Rainer.Keller@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index ea4a69f05d..ba8d5831ad 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -847,21 +847,40 @@ void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const } } + QSet<QString> localEnums; + const QMetaObject *localMetaObject = nullptr; + // Add any enum values defined by this class, overwriting any inherited values for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) { QMetaEnum e = metaObject->enumerator(ii); const bool isScoped = e.isScoped(); QStringHash<int> *scoped = isScoped ? new QStringHash<int>() : nullptr; + // We allow enums in sub-classes to overwrite enums from base-classes, such as + // ListView.Center (from enum PositionMode) overwriting Item.Center (from enum TransformOrigin). + // This is acceptable because the _use_ of the enum from the QML side requires qualification + // anyway, i.e. ListView.Center vs. Item.Center. + // However if a class defines two enums with the same value, then that must produce a warning + // because it represents a valid conflict. + if (e.enclosingMetaObject() != localMetaObject) { + localEnums.clear(); + localMetaObject = e.enclosingMetaObject(); + } + for (int jj = 0; jj < e.keyCount(); ++jj) { const QString key = QString::fromUtf8(e.key(jj)); const int value = e.value(jj); if (!isScoped || (regType == QQmlType::CppType && extraData.cd->registerEnumClassesUnscoped)) { - if (enums.contains(key)) { - qWarning("Previously registered enum will be overwritten due to name clash: %s.%s", metaObject->className(), key.toUtf8().constData()); - createEnumConflictReport(metaObject, key); - } - enums.insert(key, value); + if (localEnums.contains(key)) { + auto existingEntry = enums.find(key); + if (existingEntry != enums.end() && existingEntry.value() != value) { + qWarning("Previously registered enum will be overwritten due to name clash: %s.%s", metaObject->className(), key.toUtf8().constData()); + createEnumConflictReport(metaObject, key); + } + } else { + localEnums.insert(key); + } + enums.insert(key, value); } if (isScoped) scoped->insert(key, value); |