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 | |
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>
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 29 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/testtypes.h | 2 |
2 files changed, 25 insertions, 6 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); diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index d890668655..bb6e9582c2 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -1392,7 +1392,7 @@ class ScopedEnumsWithNameClash public: enum class ScopedEnum : int { ScopedVal1, ScopedVal2, ScopedVal3, OtherScopedEnum }; - enum class OtherScopedEnum : int { ScopedVal1, ScopedVal2, ScopedVal3 }; + enum class OtherScopedEnum : int { ScopedVal1 = 10, ScopedVal2 = 11, ScopedVal3 = 12 }; }; class ScopedEnumsWithResolvedNameClash |