aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/labs/stylekit/qqstylekitcontrolproperties.cpp50
-rw-r--r--src/labs/stylekit/qqstylekitcontrolproperties_p.h3
-rw-r--r--src/labs/stylekit/qqstylekitdebug.cpp37
-rw-r--r--src/labs/stylekit/qqstylekitglobal_p.h1
-rw-r--r--src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp4
-rw-r--r--src/qml/qml/qqmlmetatype.cpp30
-rw-r--r--src/qml/qml/qqmlmetatypedata.cpp23
-rw-r--r--src/qml/qml/qqmlmetatypedata_p.h12
-rw-r--r--src/qml/qml/qqmltypedata.cpp30
9 files changed, 108 insertions, 82 deletions
diff --git a/src/labs/stylekit/qqstylekitcontrolproperties.cpp b/src/labs/stylekit/qqstylekitcontrolproperties.cpp
index d44bf6050d..d35935860f 100644
--- a/src/labs/stylekit/qqstylekitcontrolproperties.cpp
+++ b/src/labs/stylekit/qqstylekitcontrolproperties.cpp
@@ -11,6 +11,8 @@ QT_BEGIN_NAMESPACE
// ************* QQStyleKitPropertyGroup ****************
+QHash<PropertyPathId_t, QString> QQStyleKitPropertyGroup::s_pathStrings;
+
QQStyleKitPropertyGroup::QQStyleKitPropertyGroup(QQSK::PropertyGroup, QObject *parent)
: QObject(parent)
{
@@ -27,6 +29,51 @@ PropertyPathId QQStyleKitPropertyGroup::propertyPathId(QQSK::Property property,
return PropertyPathId(property, m_groupSpace.start, QQSK::PropertyGroup::DelegateSubtype0);
}
+QString QQStyleKitPropertyGroup::pathToString() const
+{
+ /* Start from the root of the path and build the path down to this group. This
+ * mirrors how the groups were originally created and avoids rounding issues
+ * that can arise if attempting to reconstruct the path “backwards”.
+ * Note: For each group, m_groupSpace.start is stored relative to the root,
+ * while m_groupSpace.size is relative to the parent group. However, when
+ * calculating the group index, the group-space start must be computed
+ * relative to the parent group.
+ * We cache the requested paths, as the same paths are typically requested
+ * repeatedly. The number of possible paths (and thus leaf groups) is well below
+ * 100, and in practice the cache usually ends up with fewer than 20 entries. */
+ if (s_pathStrings.contains(m_groupSpace.start))
+ return s_pathStrings[m_groupSpace.start];
+
+ constexpr PropertyPathId_t rootGroupsSize = nestedGroupsStartSize / nestedGroupCount;
+ const auto metaEnum = QMetaEnum::fromType<QQSK::PropertyGroup>();
+
+ PropertyPathId_t nestedGroupStart = m_groupSpace.start;
+ PropertyPathId_t nestedGroupSize = rootGroupsSize;
+ PropertyPathId_t nestedGroupIndex = nestedGroupStart / nestedGroupSize;
+ auto groupType = QQSK::PropertyGroup(nestedGroupIndex);
+ if (groupType == QQSK::PropertyGroup::Control)
+ return {};
+
+ QString groupName = QString::fromLatin1(metaEnum.valueToKey(static_cast<int>(groupType)));
+ groupName[0] = groupName[0].toLower();
+ QString pathString = groupName;
+
+ while (true) {
+ nestedGroupStart -= nestedGroupIndex * nestedGroupSize;
+ nestedGroupSize /= nestedGroupCount;
+ nestedGroupIndex = nestedGroupStart / nestedGroupSize;
+ groupType = QQSK::PropertyGroup(nestedGroupIndex);
+ if (groupType == QQSK::PropertyGroup::Control)
+ break;
+
+ QString groupName = QString::fromLatin1(metaEnum.valueToKey(static_cast<int>(groupType)));
+ groupName[0] = groupName[0].toLower();
+ pathString += '.'_L1 + groupName;
+ }
+
+ return pathString;
+}
+
QQStyleKitControlProperties *QQStyleKitPropertyGroup::controlProperties() const
{
if (isControlProperties()) {
@@ -63,9 +110,8 @@ T *QQStyleKitPropertyGroup::lazyCreateGroup(T * const &ptr, QQSK::PropertyGroup
/* Calculate the available property ID space for the nested group. This is done by
* dividing the available space inside _this_ group on the number of potential groups
* that _this_ group can potentially contain. */
- constexpr PropertyPathId_t groupCount = PropertyPathId_t(QQSK::PropertyGroup::PATH_ID_GROUP_COUNT);
const PropertyPathId_t nestedGroupIndex = PropertyPathId_t(group);
- const PropertyPathId_t nestedGroupSize = m_groupSpace.size / groupCount;
+ const PropertyPathId_t nestedGroupSize = m_groupSpace.size / nestedGroupCount;
nestedGroup->m_groupSpace.size = nestedGroupSize;
nestedGroup->m_groupSpace.start = m_groupSpace.start + (nestedGroupIndex * nestedGroupSize);
/* Ensure that we haven’t exhausted the available PropertyPathId space. There must be
diff --git a/src/labs/stylekit/qqstylekitcontrolproperties_p.h b/src/labs/stylekit/qqstylekitcontrolproperties_p.h
index f2c7f35216..fb6df9fb81 100644
--- a/src/labs/stylekit/qqstylekitcontrolproperties_p.h
+++ b/src/labs/stylekit/qqstylekitcontrolproperties_p.h
@@ -45,6 +45,7 @@ public:
QQStyleKitPropertyGroup(QQSK::PropertyGroup group, QObject *parent);
PropertyPathId propertyPathId(QQSK::Property property, PropertyPathId::Flag flag) const;
+ QString pathToString() const;
template<typename T>
inline T styleProperty(
@@ -101,6 +102,8 @@ protected:
private:
bool shouldEmitLocally();
bool shouldEmitGlobally();
+
+ static QHash<PropertyPathId_t, QString> s_pathStrings;
};
// ************* QQStyleKitImageProperties ****************
diff --git a/src/labs/stylekit/qqstylekitdebug.cpp b/src/labs/stylekit/qqstylekitdebug.cpp
index dcd191959d..4f6cd78b61 100644
--- a/src/labs/stylekit/qqstylekitdebug.cpp
+++ b/src/labs/stylekit/qqstylekitdebug.cpp
@@ -52,37 +52,12 @@ QString QQStyleKitDebug::styleReaderToString(const QQStyleKitReader *reader)
QString QQStyleKitDebug::propertyPath(const QQStyleKitPropertyGroup *group, const PropertyPathId property)
{
- QString path = enumToString(property.property());
- path[0] = path[0].toLower();
- const QQStyleKitPropertyGroup *childGroup = group;
- const int startIndex = QQStyleKitPropertyGroup::staticMetaObject.propertyOffset();
-
- while (childGroup) {
- if (childGroup->isControlProperties())
- break;
- const QQStyleKitPropertyGroup *parentGroup =
- qobject_cast<const QQStyleKitPropertyGroup *>(childGroup->parent());
- if (!parentGroup)
- break;
-
- // Resolve group name by inspecting which property in the parent group it belongs to
- const QMetaObject* parentMeta = parentGroup->metaObject();
- for (int i = startIndex; i < parentMeta->propertyCount(); ++i) {
- const QMetaProperty prop = parentMeta->property(i);
- const QMetaObject* typeMeta = QMetaType::fromName(prop.typeName()).metaObject();
- if (!typeMeta || !typeMeta->inherits(&QQStyleKitPropertyGroup::staticMetaObject))
- continue;
- QObject *propGroup = prop.read(parentGroup).value<QQStyleKitPropertyGroup *>();
- if (propGroup == childGroup) {
- path.prepend(QString::fromUtf8(prop.name()) + kDot);
- break;
- }
- }
-
- childGroup = parentGroup;
- }
-
- return path;
+ const QString path = group->pathToString();
+ QString propertyName = enumToString(property.property());
+ propertyName[0] = propertyName[0].toLower();
+ if (path.isEmpty())
+ return propertyName;
+ return path + kDot + propertyName;
}
QString QQStyleKitDebug::controlToString(const QQStyleKitControlProperties *control)
diff --git a/src/labs/stylekit/qqstylekitglobal_p.h b/src/labs/stylekit/qqstylekitglobal_p.h
index 3808def107..e4d6a151dc 100644
--- a/src/labs/stylekit/qqstylekitglobal_p.h
+++ b/src/labs/stylekit/qqstylekitglobal_p.h
@@ -171,6 +171,7 @@ using QQStyleKitExtendableControlType = quint32;
using QQStyleKitPropertyStorage = QHash<PropertyStorageId, QVariant>;
constexpr PropertyPathId_t maxPropertyStorageSpaceSize = std::numeric_limits<PropertyPathId_t>::max();
+constexpr PropertyPathId_t nestedGroupCount = PropertyPathId_t(QQSK::PropertyGroup::PATH_ID_GROUP_COUNT);
constexpr PropertyPathId_t maxStateCombinationCount = PropertyPathId_t(QQSK::StateFlag::MAX_STATE);
constexpr PropertyPathId_t stateStorageSpaceSize = maxPropertyStorageSpaceSize / maxStateCombinationCount;
constexpr PropertyPathId_t subtypeCount = PropertyPathId_t(QQSK::PropertyPathFlag::DelegateSubtype2) - PropertyPathId_t(QQSK::PropertyPathFlag::DelegateSubtype0) + 1;
diff --git a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp
index 14eabef68a..b9f13f52a7 100644
--- a/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp
+++ b/src/plugins/qmltooling/qmldbg_preview/qqmlpreviewposition.cpp
@@ -162,8 +162,6 @@ void QQmlPreviewPosition::readLastPositionFromByteArray(const QByteArray &array)
QPoint nativePosition;
stream >> nativePosition;
- if (nativePosition.isNull())
- return;
QSize size;
stream >> size;
@@ -174,8 +172,6 @@ void QQmlPreviewPosition::readLastPositionFromByteArray(const QByteArray &array)
void QQmlPreviewPosition::setPosition(const QQmlPreviewPosition::Position &position,
QWindow *window)
{
- if (position.nativePosition.isNull())
- return;
if (QScreen *screen = findScreen(position.screenName)) {
window->setScreen(screen);
const auto point = QHighDpiScaling::mapPositionFromNative(position.nativePosition,
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 5e2e5eb488..01da4ef485 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -329,7 +329,6 @@ void QQmlMetaType::clearTypeRegistrations()
data->idToType.clear();
data->nameToType.clear();
data->urlToType.clear();
- data->typePropertyCaches.clear();
data->metaObjectToType.clear();
data->undeletableTypes.clear();
data->propertyCaches.clear();
@@ -350,7 +349,7 @@ void QQmlMetaType::clearTypeRegistrations()
void QQmlMetaType::registerTypeAlias(int typeIndex, const QString &name)
{
QQmlMetaTypeDataPtr data;
- const QQmlType type = data->types.value(typeIndex);
+ const QQmlType type = data->types.value(typeIndex).type;
const QQmlTypePrivate *priv = type.priv();
data->nameToType.insert(name, priv);
}
@@ -928,7 +927,8 @@ static bool namespaceContainsRegistrations(const QQmlMetaTypeData *data, const Q
{
// Has any type previously been installed to this namespace?
QHashedString nameSpace(uri);
- for (const QQmlType &type : data->types) {
+ for (const auto &typeAndCaches : std::as_const(data->types)) {
+ const QQmlType &type = typeAndCaches.type;
if (type.module() == nameSpace && type.version().majorVersion() == version.majorVersion())
return true;
}
@@ -1328,10 +1328,7 @@ QQmlType QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStrin
QQmlType QQmlMetaType::qmlTypeById(int qmlTypeId)
{
const QQmlMetaTypeDataPtr data;
- QQmlType type = data->types.value(qmlTypeId);
- if (type.isValid())
- return type;
- return QQmlType();
+ return data->types.value(qmlTypeId).type;
}
/*!
@@ -1519,7 +1516,7 @@ QQmlPropertyCache::ConstPtr QQmlMetaType::rawPropertyCacheForType(
void QQmlMetaType::unregisterType(int typeIndex)
{
QQmlMetaTypeDataPtr data;
- const QQmlType type = data->types.value(typeIndex);
+ const QQmlType type = data->types.value(typeIndex).type;
if (const QQmlTypePrivate *d = type.priv()) {
if (d->regType == QQmlType::CompositeType || d->regType == QQmlType::CompositeSingletonType)
removeFromInlineComponents(data->urlToType, d);
@@ -1529,8 +1526,7 @@ void QQmlMetaType::unregisterType(int typeIndex)
removeQQmlTypePrivate(data->metaObjectToType, d);
for (auto & module : data->uriToModule)
module->remove(d);
- data->clearPropertyCachesForVersion(typeIndex);
- data->types[typeIndex] = QQmlType();
+ data->types[typeIndex] = QQmlMetaTypeData::Type();
data->undeletableTypes.remove(type);
}
}
@@ -1607,9 +1603,9 @@ void QQmlMetaType::freeUnusedTypesAndCaches()
bool deletedAtLeastOneType;
do {
deletedAtLeastOneType = false;
- QList<QQmlType>::Iterator it = data->types.begin();
+ auto it = data->types.begin();
while (it != data->types.end()) {
- const QQmlTypePrivate *d = (*it).priv();
+ const QQmlTypePrivate *d = it->type.priv();
if (d && d->count() == 1 && !hasActiveInlineComponents(data, d)) {
deletedAtLeastOneType = true;
@@ -1625,8 +1621,7 @@ void QQmlMetaType::freeUnusedTypesAndCaches()
for (auto &module : data->uriToModule)
module->remove(d);
- data->clearPropertyCachesForVersion(d->index);
- *it = QQmlType();
+ *it = QQmlMetaTypeData::Type();
} else {
++it;
}
@@ -1687,7 +1682,12 @@ QList<QQmlType> QQmlMetaType::qmlTypes()
QList<QQmlType> QQmlMetaType::qmlAllTypes()
{
const QQmlMetaTypeDataPtr data;
- return data->types;
+ QList<QQmlType> types;
+ types.reserve(data->types.size());
+ std::transform(
+ data->types.constBegin(), data->types.constEnd(),
+ std::back_inserter(types), [](const auto &type) { return type.type; });
+ return types;
}
/*!
diff --git a/src/qml/qml/qqmlmetatypedata.cpp b/src/qml/qml/qqmlmetatypedata.cpp
index 30838c73a0..13170a47e1 100644
--- a/src/qml/qml/qqmlmetatypedata.cpp
+++ b/src/qml/qml/qqmlmetatypedata.cpp
@@ -28,14 +28,15 @@ QQmlMetaTypeData::~QQmlMetaTypeData()
void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
{
for (int i = 0; i < types.size(); ++i) {
- if (!types.at(i).isValid()) {
- types[i] = QQmlType(priv);
+ Type &type = types[i];
+ if (!type.type.isValid()) {
+ type.type = QQmlType(priv);
priv->index = i;
priv->release();
return;
}
}
- types.append(QQmlType(priv));
+ types.append({QQmlType(priv), {}});
priv->index = types.size() - 1;
priv->release();
}
@@ -85,23 +86,17 @@ bool QQmlMetaTypeData::registerModuleTypes(const QString &uri)
QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCacheForVersion(
int index, QTypeRevision version) const
{
- return (index < typePropertyCaches.size())
- ? typePropertyCaches.at(index).value(version)
+ return (index < types.size())
+ ? types[index].propertyCaches.value(version)
: QQmlPropertyCache::ConstPtr();
}
void QQmlMetaTypeData::setPropertyCacheForVersion(int index, QTypeRevision version,
const QQmlPropertyCache::ConstPtr &cache)
{
- if (index >= typePropertyCaches.size())
- typePropertyCaches.resize(index + 1);
- typePropertyCaches[index][version] = cache;
-}
-
-void QQmlMetaTypeData::clearPropertyCachesForVersion(int index)
-{
- if (index < typePropertyCaches.size())
- typePropertyCaches[index].clear();
+ if (index >= types.size())
+ types.resize(index + 1);
+ types[index].propertyCaches[version] = cache;
}
QQmlPropertyCache::ConstPtr QQmlMetaTypeData::propertyCache(
diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h
index 6b6bae64f2..44eebb93fe 100644
--- a/src/qml/qml/qqmlmetatypedata_p.h
+++ b/src/qml/qml/qqmlmetatypedata_p.h
@@ -32,8 +32,16 @@ struct QQmlMetaTypeData
QQmlMetaTypeData();
~QQmlMetaTypeData();
void registerType(QQmlTypePrivate *priv);
- QList<QQmlType> types;
+
+ struct Type
+ {
+ QQmlType type;
+ QHash<QTypeRevision, QQmlPropertyCache::ConstPtr> propertyCaches;
+ };
+
+ QList<Type> types;
QSet<QQmlType> undeletableTypes;
+
typedef QHash<int, QQmlTypePrivate *> Ids;
Ids idToType;
@@ -45,7 +53,6 @@ struct QQmlMetaTypeData
typedef QMultiHash<const QMetaObject *, const QQmlTypePrivate *> MetaObjects;
MetaObjects metaObjectToType;
- QVector<QHash<QTypeRevision, QQmlPropertyCache::ConstPtr>> typePropertyCaches;
QHash<int, QQmlValueType *> metaTypeToValueType;
// This has to be a multihash because a user can create a compilation unit using arbitrary
@@ -110,7 +117,6 @@ struct QQmlMetaTypeData
QQmlPropertyCache::ConstPtr propertyCacheForVersion(int index, QTypeRevision version) const;
void setPropertyCacheForVersion(
int index, QTypeRevision version, const QQmlPropertyCache::ConstPtr &cache);
- void clearPropertyCachesForVersion(int index);
QQmlPropertyCache::ConstPtr propertyCache(const QMetaObject *metaObject, QTypeRevision version);
QQmlPropertyCache::ConstPtr propertyCache(const QQmlType &type, QTypeRevision version);
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
index 44e1635afc..e3947d15df 100644
--- a/src/qml/qml/qqmltypedata.cpp
+++ b/src/qml/qml/qqmltypedata.cpp
@@ -418,24 +418,28 @@ bool QQmlTypeData::checkDependencies()
|| type.typeData->isCompleteOrError()
|| type.type.isInlineComponentType());
- if (type.type.isInlineComponentType()) {
- const QUrl url = type.type.sourceUrl();
- if (!QQmlMetaType::equalBaseUrls(url, finalUrl())
- && !QQmlMetaType::obtainCompilationUnit(type.type.typeId())) {
- const QString &typeName = stringAt(it.key());
- int lastDot = typeName.lastIndexOf(u'.');
- createError(
- type,
- QQmlTypeLoader::tr("Type %1 has no inline component type called %2")
- .arg(QStringView{typeName}.left(lastDot), type.type.elementName()));
- return false;
- }
- }
if (type.typeData && type.typeData->isError()) {
const QString &typeName = stringAt(it.key());
createError(type, QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName));
return false;
}
+
+ if (!type.selfReference && type.type.isInlineComponentType()) {
+ const QString icName = type.type.elementName();
+ Q_ASSERT(!icName.isEmpty());
+
+ // We have a CU here. Check if the inline component exists.
+ if (type.typeData && type.typeData->compilationUnit()->inlineComponentId(icName) >= 0)
+ return true;
+
+ const QString typeName = stringAt(it.key());
+ const qsizetype lastDot = typeName.lastIndexOf(u'.');
+ createError(
+ type,
+ QQmlTypeLoader::tr("Type %1 has no inline component type called %2")
+ .arg(QStringView{typeName}.left(lastDot), icName));
+ return false;
+ }
}
return true;