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>
This commit is contained in:
Simon Hausmann 2018-10-18 09:29:26 +02:00
parent ff11568f37
commit 8a2c182d59
2 changed files with 25 additions and 6 deletions

View File

@ -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);

View File

@ -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