aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-05-26 13:06:50 +0200
committerUlf Hermann <ulf.hermann@qt.io>2023-05-30 13:42:35 +0200
commit79f811dd09a1ecf31b8649eaf0fe3ef940bcf403 (patch)
treeae1b4319c8f8b8812a8aebc24bffb3fcafebfd90 /src
parentbd845c2050204eadbac76d35e5f8b012aade4b52 (diff)
QtQml: Index inline components by name rather than ID
The ID can only be determined once the compilation unit is present. It depends on the order of objects in the compiled data. The name is always available. Indexing by name increases the overhead. However, since we don't have to "amend" the ID later on and since we only need one lookup table rather than two per type now, it's probably worth it. Change-Id: I478de505a1934b5b6ab340b4be4fa5da4e95aeb3 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/inlinecomponentutils_p.h3
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit.cpp78
-rw-r--r--src/qml/jsruntime/qv4executablecompilationunit_p.h6
-rw-r--r--src/qml/jsruntime/qv4function.cpp3
-rw-r--r--src/qml/qml/qqmlimport.cpp39
-rw-r--r--src/qml/qml/qqmlmetatype.cpp2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp21
-rw-r--r--src/qml/qml/qqmlpropertycachecreator_p.h12
-rw-r--r--src/qml/qml/qqmltype.cpp59
-rw-r--r--src/qml/qml/qqmltype_p.h9
-rw-r--r--src/qml/qml/qqmltype_p_p.h4
-rw-r--r--src/qml/qml/qqmltypecompiler.cpp4
-rw-r--r--src/qml/qml/qqmltypecompiler_p.h2
-rw-r--r--src/qml/qml/qqmltypedata.cpp53
-rw-r--r--src/qml/qml/qqmltypedata_p.h4
15 files changed, 143 insertions, 156 deletions
diff --git a/src/qml/inlinecomponentutils_p.h b/src/qml/inlinecomponentutils_p.h
index 5a4d8272e5..92ae719750 100644
--- a/src/qml/inlinecomponentutils_p.h
+++ b/src/qml/inlinecomponentutils_p.h
@@ -77,7 +77,8 @@ void fillAdjacencyListForInlineComponents(ObjectContainer *objectContainer,
if (targetType.isInlineComponentType()
&& targetType.containingType() == currentICTypeRef->type().containingType()) {
auto icIt = std::find_if(allICs.cbegin(), allICs.cend(), [&](const QV4::CompiledData::InlineComponent &icSearched){
- return int(icSearched.objectIndex) == targetType.inlineComponentObjectId();
+ return objectContainer->stringAt(icSearched.nameIndex)
+ == targetType.elementName();
});
Q_ASSERT(icIt != allICs.cend());
Node& target = nodes[i];
diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp
index a4293310c4..0bdf5acba4 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit.cpp
+++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp
@@ -357,6 +357,31 @@ IdentifierHash ExecutableCompilationUnit::createNamedObjectsPerComponent(int com
return *namedObjectsPerComponentCache.insert(componentObjectIndex, namedObjectCache);
}
+template<typename F>
+void processInlinComponentType(
+ const QQmlType &type, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
+ F &&populateIcData)
+{
+ if (type.isInlineComponentType()) {
+ QString icRootName;
+ if (compilationUnit->icRootName) {
+ icRootName = type.elementName();
+ std::swap(*compilationUnit->icRootName, icRootName);
+ } else {
+ compilationUnit->icRootName = std::make_unique<QString>(type.elementName());
+ }
+
+ populateIcData();
+
+ if (icRootName.isEmpty())
+ compilationUnit->icRootName.reset();
+ else
+ std::swap(*compilationUnit->icRootName, icRootName);
+ } else {
+ populateIcData();
+ }
+}
+
void ExecutableCompilationUnit::finalizeCompositeType(CompositeMetaTypeIds types)
{
// Add to type registry of composites
@@ -402,7 +427,7 @@ void ExecutableCompilationUnit::finalizeCompositeType(CompositeMetaTypeIds types
// and in that case we need to add its object count
for (auto nodeIt = nodesSorted.rbegin(); nodeIt != nodesSorted.rend(); ++nodeIt) {
const auto &ic = allICs.at(nodeIt->index());
- int lastICRoot = ic.objectIndex;
+ const int lastICRoot = ic.objectIndex;
for (int i = ic.objectIndex; i<objectCount(); ++i) {
const QV4::CompiledData::Object *obj = objectAt(i);
bool leftCurrentInlineComponent
@@ -411,24 +436,24 @@ void ExecutableCompilationUnit::finalizeCompositeType(CompositeMetaTypeIds types
|| !obj->hasFlag(QV4::CompiledData::Object::IsPartOfInlineComponent);
if (leftCurrentInlineComponent)
break;
- inlineComponentData[lastICRoot].totalBindingCount += obj->nBindings;
+ const QString lastICRootName = stringAt(ic.nameIndex);
+ inlineComponentData[lastICRootName].totalBindingCount += obj->nBindings;
if (auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
const auto type = typeRef->type();
if (type.isValid() && type.parserStatusCast() != -1)
- ++inlineComponentData[lastICRoot].totalParserStatusCount;
+ ++inlineComponentData[lastICRootName].totalParserStatusCount;
- ++inlineComponentData[lastICRoot].totalObjectCount;
+ ++inlineComponentData[lastICRootName].totalObjectCount;
if (const auto compilationUnit = typeRef->compilationUnit()) {
// if the type is an inline component type, we have to extract the information from it
// This requires that inline components are visited in the correct order
- auto icRoot = compilationUnit->icRoot;
- if (type.isInlineComponentType())
- icRoot = type.inlineComponentId();
- QScopedValueRollback<int> rollback {compilationUnit->icRoot, icRoot};
- inlineComponentData[lastICRoot].totalBindingCount += compilationUnit->totalBindingsCount();
- inlineComponentData[lastICRoot].totalParserStatusCount += compilationUnit->totalParserStatusCount();
- inlineComponentData[lastICRoot].totalObjectCount += compilationUnit->totalObjectCount();
+ processInlinComponentType(type, compilationUnit, [&]() {
+ auto &icData = inlineComponentData[lastICRootName];
+ icData.totalBindingCount += compilationUnit->totalBindingsCount();
+ icData.totalParserStatusCount += compilationUnit->totalParserStatusCount();
+ icData.totalObjectCount += compilationUnit->totalObjectCount();
+ });
}
}
}
@@ -448,13 +473,11 @@ void ExecutableCompilationUnit::finalizeCompositeType(CompositeMetaTypeIds types
++parserStatusCount;
++objectCount;
if (const auto compilationUnit = typeRef->compilationUnit()) {
- auto icRoot = compilationUnit->icRoot;
- if (type.isInlineComponentType())
- icRoot = type.inlineComponentId();
- QScopedValueRollback<int> rollback {compilationUnit->icRoot, icRoot};
- bindingCount += compilationUnit->totalBindingsCount();
- parserStatusCount += compilationUnit->totalParserStatusCount();
- objectCount += compilationUnit->totalObjectCount();
+ processInlinComponentType(type, compilationUnit, [&](){
+ bindingCount += compilationUnit->totalBindingsCount();
+ parserStatusCount += compilationUnit->totalParserStatusCount();
+ objectCount += compilationUnit->totalObjectCount();
+ });
}
}
}
@@ -465,21 +488,21 @@ void ExecutableCompilationUnit::finalizeCompositeType(CompositeMetaTypeIds types
}
int ExecutableCompilationUnit::totalBindingsCount() const {
- if (icRoot == -1)
+ if (!icRootName)
return m_totalBindingsCount;
- return inlineComponentData[icRoot].totalBindingCount;
+ return inlineComponentData[*icRootName].totalBindingCount;
}
int ExecutableCompilationUnit::totalObjectCount() const {
- if (icRoot == -1)
+ if (!icRootName)
return m_totalObjectCount;
- return inlineComponentData[icRoot].totalObjectCount;
+ return inlineComponentData[*icRootName].totalObjectCount;
}
int ExecutableCompilationUnit::totalParserStatusCount() const {
- if (icRoot == -1)
+ if (!icRootName)
return m_totalParserStatusCount;
- return inlineComponentData[icRoot].totalParserStatusCount;
+ return inlineComponentData[*icRootName].totalParserStatusCount;
}
bool ExecutableCompilationUnit::verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const
@@ -497,11 +520,12 @@ bool ExecutableCompilationUnit::verifyChecksum(const CompiledData::DependentType
sizeof(data->dependencyMD5Checksum)) == 0;
}
-CompositeMetaTypeIds ExecutableCompilationUnit::typeIdsForComponent(int objectid) const
+CompositeMetaTypeIds ExecutableCompilationUnit::typeIdsForComponent(
+ const QString &inlineComponentName) const
{
- if (objectid == 0)
+ if (inlineComponentName.isEmpty())
return typeIds;
- return inlineComponentData[objectid].typeIds;
+ return inlineComponentData[inlineComponentName].typeIds;
}
QStringList ExecutableCompilationUnit::moduleRequests() const
diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h
index 3a0efa467e..b110ea3fd1 100644
--- a/src/qml/jsruntime/qv4executablecompilationunit_p.h
+++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h
@@ -131,7 +131,7 @@ public:
int m_totalBindingsCount = 0; // Number of bindings used in this type
int m_totalParserStatusCount = 0; // Number of instantiated types that are QQmlParserStatus subclasses
int m_totalObjectCount = 0; // Number of objects explicitly instantiated
- int icRoot = -1;
+ std::unique_ptr<QString> icRootName;
int totalBindingsCount() const;
int totalParserStatusCount() const;
@@ -143,12 +143,12 @@ public:
bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const;
- CompositeMetaTypeIds typeIdsForComponent(int objectid = 0) const;
+ CompositeMetaTypeIds typeIdsForComponent(const QString &inlineComponentName = QString()) const;
CompositeMetaTypeIds typeIds;
bool isRegistered = false;
- QHash<int, InlineComponentData> inlineComponentData;
+ QHash<QString, InlineComponentData> inlineComponentData;
int inlineComponentId(const QString &inlineComponentName) const
{
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 5edccafa3c..42f952ff19 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -163,8 +163,7 @@ Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit,
if (!qmltype.isComposite()) {
if (!qmltype.isInlineComponentType())
return QMetaType();
- const CompositeMetaTypeIds typeIds
- = unit->typeIdsForComponent(qmltype.inlineComponentId());
+ const CompositeMetaTypeIds typeIds = unit->typeIdsForComponent(qmltype.elementName());
return param.isList() ? typeIds.listId : typeIds.id;
}
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 874f642283..65fbd498c9 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -584,10 +584,10 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
Q_ASSERT(!type_return->isValid());
auto createICType = [&]() {
auto typePriv = new QQmlTypePrivate {QQmlType::RegistrationType::InlineComponentType};
- bool ok = false;
- typePriv->extraData.id->objectId = QUrl(this->url).fragment().toInt(&ok);
- Q_ASSERT(ok);
- typePriv->extraData.id->url = QUrl(this->url);
+ const QUrl ownUrl = QUrl(url);
+ typePriv->elementName = ownUrl.fragment();
+ Q_ASSERT(!typePriv->elementName.isEmpty());
+ typePriv->extraData.id->url = ownUrl;
auto icType = QQmlType(typePriv);
typePriv->release();
return icType;
@@ -595,12 +595,13 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
if (containingType.isValid()) {
// we currently cannot reference a Singleton inside itself
// in that case, containingType is still invalid
- if (int icID = containingType.lookupInlineComponentIdByName(typeStr); icID != -1) {
- *type_return = containingType.lookupInlineComponentById(icID);
+ if (QQmlType icID = containingType.lookupInlineComponentByName(typeStr);
+ icID.isValid()) {
+ *type_return = icID;
} else {
auto icType = createICType();
- int placeholderId = containingType.generatePlaceHolderICId();
- const_cast<QQmlImportInstance*>(this)->containingType.associateInlineComponent(typeStr, placeholderId, CompositeMetaTypeIds {}, icType);
+ const_cast<QQmlImportInstance*>(this)->containingType.associateInlineComponent(
+ typeStr, CompositeMetaTypeIds {}, icType);
*type_return = QQmlType(icType);
}
} else {
@@ -766,18 +767,17 @@ bool QQmlImports::resolveType(
if (resolveTypeInNamespace(splitName.at(0), &m_unqualifiedset, nullptr)) {
// either simple type + inline component
auto const icName = splitName.at(1).toString();
- auto objectIndex = type_return->lookupInlineComponentIdByName(icName);
- if (objectIndex != -1) {
- *type_return = type_return->lookupInlineComponentById(objectIndex);
+ auto ic = type_return->lookupInlineComponentByName(icName);
+ if (ic.isValid()) {
+ *type_return = ic;
} else {
auto icTypePriv = new QQmlTypePrivate(QQmlType::RegistrationType::InlineComponentType);
icTypePriv->setContainingType(type_return);
icTypePriv->extraData.id->url = type_return->sourceUrl();
- int placeholderId = type_return->generatePlaceHolderICId();
- icTypePriv->extraData.id->url.setFragment(QString::number(placeholderId));
+ icTypePriv->extraData.id->url.setFragment(icName);
auto icType = QQmlType(icTypePriv);
icTypePriv->release();
- type_return->associateInlineComponent(icName, placeholderId, CompositeMetaTypeIds {}, icType);
+ type_return->associateInlineComponent(icName, CompositeMetaTypeIds {}, icType);
*type_return = icType;
}
Q_ASSERT(type_return->containingType().isValid());
@@ -803,18 +803,17 @@ bool QQmlImports::resolveType(
} else {
if (resolveTypeInNamespace(splitName.at(1), s, nullptr)) {
auto const icName = splitName.at(2).toString();
- auto objectIndex = type_return->lookupInlineComponentIdByName(icName);
- if (objectIndex != -1)
- *type_return = type_return->lookupInlineComponentById(objectIndex);
+ QQmlType ic = type_return->lookupInlineComponentByName(icName);
+ if (ic.isValid())
+ *type_return = ic;
else {
auto icTypePriv = new QQmlTypePrivate(QQmlType::RegistrationType::InlineComponentType);
icTypePriv->setContainingType(type_return);
icTypePriv->extraData.id->url = type_return->sourceUrl();
- int placeholderId = type_return->generatePlaceHolderICId();
- icTypePriv->extraData.id->url.setFragment(QString::number(placeholderId));
+ icTypePriv->extraData.id->url.setFragment(icName);
auto icType = QQmlType(icTypePriv);
icTypePriv->release();
- type_return->associateInlineComponent(icName, placeholderId, CompositeMetaTypeIds {}, icType);
+ type_return->associateInlineComponent(icName, CompositeMetaTypeIds {}, icType);
*type_return = icType;
}
type_return->setPendingResolutionName(icName);
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index d1123f3c4e..415bee061c 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -1440,7 +1440,7 @@ void QQmlMetaType::registerMetaObjectForType(const QMetaObject *metaobject, QQml
static bool hasActiveInlineComponents(const QQmlTypePrivate *d)
{
- for (const QQmlType &ic : std::as_const(d->objectIdToICType)) {
+ for (const QQmlType &ic : std::as_const(d->namesToInlineComponentType)) {
const QQmlTypePrivate *icPriv = ic.priv();
if (icPriv && icPriv->count() > 1)
return true;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index f7d2b94059..ea31ff0b56 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1275,11 +1275,26 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
return nullptr;
}
} else {
- int subObjectId = type.inlineComponentId();
- QScopedValueRollback<int> rollback {compilationUnit->icRoot, subObjectId};
+ QString subObjectName;
+ if (compilationUnit->icRootName) {
+ subObjectName = type.elementName();
+ std::swap(*compilationUnit->icRootName, subObjectName);
+ } else {
+ compilationUnit->icRootName = std::make_unique<QString>(type.elementName());
+ }
+
+ const auto guard = qScopeGuard([&] {
+ if (subObjectName.isEmpty())
+ compilationUnit->icRootName.reset();
+ else
+ std::swap(*compilationUnit->icRootName, subObjectName);
+ });
+
QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data(),
isContextObject);
- instance = subCreator.create(subObjectId, nullptr, nullptr, CreationFlags::InlineComponent);
+ instance = subCreator.create(
+ compilationUnit->inlineComponentId(*compilationUnit->icRootName),
+ nullptr, nullptr, CreationFlags::InlineComponent);
if (!instance) {
errors += subCreator.errors;
return nullptr;
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h
index 7c6c54c611..d8f22a06ba 100644
--- a/src/qml/qml/qqmlpropertycachecreator_p.h
+++ b/src/qml/qml/qqmlpropertycachecreator_p.h
@@ -628,16 +628,16 @@ inline QQmlError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(
if (qmltype.isComposite() || qmltype.isInlineComponentType()) {
CompositeMetaTypeIds typeIds;
if (qmltype.isInlineComponentType()) {
- auto objectId = qmltype.inlineComponentId();
+ const QString icName = qmltype.elementName();
auto containingType = qmltype.containingType();
if (containingType.isValid()) {
- auto icType = containingType.lookupInlineComponentById(objectId);
+ auto icType = containingType.lookupInlineComponentByName(icName);
typeIds = {icType.typeId(), icType.qListTypeId()};
} else {
typeIds = {};
}
if (!typeIds.isValid()) // type has not been registered yet, we must be in containing type
- typeIds = objectContainer->typeIdsForComponent(objectId);
+ typeIds = objectContainer->typeIdsForComponent(icName);
Q_ASSERT(typeIds.isValid());
} else if (selfReference) {
typeIds = objectContainer->typeIdsForComponent();
@@ -713,8 +713,7 @@ inline QMetaType QQmlPropertyCacheCreator<ObjectContainer>::metaTypeForParameter
if (!qmltype.isComposite()) {
const QMetaType typeId = param.isList() ? qmltype.qListTypeId() : qmltype.typeId();
if (!typeId.isValid() && qmltype.isInlineComponentType()) {
- const int objectId = qmltype.inlineComponentId();
- const auto typeIds = objectContainer->typeIdsForComponent(objectId);
+ const auto typeIds = objectContainer->typeIdsForComponent(qmltype.elementName());
return param.isList() ? typeIds.listId : typeIds.id;
} else {
return typeId;
@@ -825,8 +824,7 @@ inline QQmlError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataFor
if (referencedType.isValid()) {
*type = referencedType.typeId();
if (!type->isValid() && referencedType.isInlineComponentType()) {
- int objectId = referencedType.inlineComponentId();
- *type = objectContainer->typeIdsForComponent(objectId).id;
+ *type = objectContainer->typeIdsForComponent(referencedType.elementName()).id;
Q_ASSERT(type->isValid());
}
} else {
diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp
index d01aa5ba11..85e3f8295a 100644
--- a/src/qml/qml/qqmltype.cpp
+++ b/src/qml/qml/qqmltype.cpp
@@ -743,24 +743,9 @@ bool QQmlType::isInlineComponentType() const {
return d ? d->regType == QQmlType::InlineComponentType : false;
}
-int QQmlType::inlineComponentId() const {
- bool ok = false;
- if (d->regType == QQmlType::RegistrationType::InlineComponentType) {
- Q_ASSERT(d->extraData.id->objectId != -1);
- return d->extraData.id->objectId;
- }
- int subObjectId = sourceUrl().fragment().toInt(&ok);
- return ok ? subObjectId : -1;
-}
-
QUrl QQmlType::sourceUrl() const
{
- auto url = d ? d->sourceUrl() : QUrl();
- if (url.isValid() && d->regType == QQmlType::RegistrationType::InlineComponentType && d->extraData.id->objectId) {
- Q_ASSERT(url.hasFragment());
- url.setFragment(QString::number(inlineComponentId()));
- }
- return url;
+ return d ? d->sourceUrl() : QUrl();
}
int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &name, bool *ok) const
@@ -926,19 +911,6 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, QStringView scopedEnumN
return -1;
}
-int QQmlType::inlineComponentObjectId() const
-{
- if (!isInlineComponentType())
- return -1;
- return d->extraData.id->objectId;
-}
-
-void QQmlType::setInlineComponentObjectId(int id) const
-{
- Q_ASSERT(d && d->regType == QQmlType::InlineComponentType);
- d->extraData.id->objectId = id;
-}
-
void QQmlType::refHandle(const QQmlTypePrivate *priv)
{
if (priv)
@@ -958,10 +930,10 @@ int QQmlType::refCount(const QQmlTypePrivate *priv)
return -1;
}
-int QQmlType::lookupInlineComponentIdByName(const QString &name) const
+QQmlType QQmlType::lookupInlineComponentByName(const QString &name) const
{
Q_ASSERT(d);
- return d->namesToInlineComponentObjectIndex.value(name, -1);
+ return d->namesToInlineComponentType.value(name);
}
QQmlType QQmlType::containingType() const
@@ -972,37 +944,20 @@ QQmlType QQmlType::containingType() const
return ret;
}
-QQmlType QQmlType::lookupInlineComponentById(int objectid) const
-{
- Q_ASSERT(d);
- return d->objectIdToICType.value(objectid, QQmlType(nullptr));
-}
-
-int QQmlType::generatePlaceHolderICId() const
-{
- Q_ASSERT(d);
- int id = -2;
- for (auto it = d->objectIdToICType.keyBegin(); it != d->objectIdToICType.keyEnd(); ++it)
- if (*it < id)
- id = *it;
- return id;
-}
-
-void QQmlType::associateInlineComponent(const QString &name, int objectID, const CompositeMetaTypeIds &metaTypeIds, QQmlType existingType)
+void QQmlType::associateInlineComponent(
+ const QString &name, const CompositeMetaTypeIds &metaTypeIds, QQmlType existingType)
{
bool const reuseExistingType = existingType.isValid();
auto priv = reuseExistingType ? const_cast<QQmlTypePrivate *>(existingType.d.data()) : new QQmlTypePrivate { RegistrationType::InlineComponentType } ;
priv->setName( QString::fromUtf8(typeName()), name);
auto icUrl = QUrl(sourceUrl());
- icUrl.setFragment(QString::number(objectID));
+ icUrl.setFragment(name);
priv->extraData.id->url = icUrl;
priv->extraData.id->containingType = d.data();
- priv->extraData.id->objectId = objectID;
priv->typeId = metaTypeIds.id;
priv->listId = metaTypeIds.listId;
- d->namesToInlineComponentObjectIndex.insert(name, objectID);
QQmlType icType(priv);
- d->objectIdToICType.insert(objectID, icType);
+ d->namesToInlineComponentType.insert(name, icType);
if (!reuseExistingType)
priv->release();
}
diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h
index c2c85c9c2e..a92381b803 100644
--- a/src/qml/qml/qqmltype_p.h
+++ b/src/qml/qml/qqmltype_p.h
@@ -119,7 +119,6 @@ public:
int index() const;
bool isInlineComponentType() const;
- int inlineComponentId() const;
struct Q_QML_PRIVATE_EXPORT SingletonInstanceInfo
{
@@ -143,8 +142,6 @@ public:
int scopedEnumValue(QQmlEnginePrivate *engine, int index, const QString &, bool *ok) const;
int scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &, const QByteArray &, bool *ok) const;
int scopedEnumValue(QQmlEnginePrivate *engine, QStringView, QStringView, bool *ok) const;
- int inlineComponentObjectId() const;
- void setInlineComponentObjectId(int id) const; // TODO: const setters are BAD
const QQmlTypePrivate *priv() const { return d.data(); }
static void refHandle(const QQmlTypePrivate *priv);
@@ -163,11 +160,9 @@ public:
};
QQmlType containingType() const;
- int lookupInlineComponentIdByName(const QString &name) const;
- QQmlType lookupInlineComponentById(int objectid) const;
- int generatePlaceHolderICId() const;
+ QQmlType lookupInlineComponentByName(const QString &name) const;
- void associateInlineComponent(const QString &name, int objectID, const CompositeMetaTypeIds &metaTypeIds, QQmlType existingType);
+ void associateInlineComponent(const QString &name, const CompositeMetaTypeIds &metaTypeIds, QQmlType existingType);
void setPendingResolutionName(const QString &name);
QString pendingResolutionName() const;
diff --git a/src/qml/qml/qqmltype_p_p.h b/src/qml/qml/qqmltype_p_p.h
index d2b282955f..d5ef381299 100644
--- a/src/qml/qml/qqmltype_p_p.h
+++ b/src/qml/qml/qqmltype_p_p.h
@@ -117,7 +117,6 @@ public:
// this should still be fine
QQmlTypePrivate const * containingType = nullptr;
QString inlineComponentName = QString();
- int objectId = -1;
};
using QQmlSequenceTypeData = QMetaSequence;
@@ -153,8 +152,7 @@ public:
mutable QList<QStringHash<int>*> scopedEnums;
void setName(const QString &uri, const QString &element);
- mutable QHash<QString, int> namesToInlineComponentObjectIndex;
- mutable QHash<int, QQmlType> objectIdToICType;
+ mutable QHash<QString, QQmlType> namesToInlineComponentType;
private:
~QQmlTypePrivate() override;
diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp
index 9e6b88ba96..7b9ee544ea 100644
--- a/src/qml/qml/qqmltypecompiler.cpp
+++ b/src/qml/qml/qqmltypecompiler.cpp
@@ -259,9 +259,9 @@ void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier
document->imports.append(import);
}
-CompositeMetaTypeIds QQmlTypeCompiler::typeIdsForComponent(int objectId) const
+CompositeMetaTypeIds QQmlTypeCompiler::typeIdsForComponent(const QString &inlineComponentName) const
{
- return typeData->typeIds(objectId);
+ return typeData->typeIds(inlineComponentName);
}
QQmlCompilePass::QQmlCompilePass(QQmlTypeCompiler *typeCompiler)
diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h
index d07f42fb47..54c5710ecd 100644
--- a/src/qml/qml/qqmltypecompiler_p.h
+++ b/src/qml/qml/qqmltypecompiler_p.h
@@ -108,7 +108,7 @@ public:
return resolvedTypes->value(id);
}
- CompositeMetaTypeIds typeIdsForComponent(int objectId = 0) const;
+ CompositeMetaTypeIds typeIdsForComponent(const QString &inlineComponentName = QString()) const;
private:
QList<QQmlError> errors;
diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp
index faab11a9ae..643824a20e 100644
--- a/src/qml/qml/qqmltypedata.cpp
+++ b/src/qml/qml/qqmltypedata.cpp
@@ -74,11 +74,11 @@ void QQmlTypeData::unregisterCallback(TypeDataCallback *callback)
Q_ASSERT(!m_callbacks.contains(callback));
}
-CompositeMetaTypeIds QQmlTypeData::typeIds(int objectId) const
+CompositeMetaTypeIds QQmlTypeData::typeIds(const QString &inlineComponentName) const
{
- if (objectId != 0)
- return m_inlineComponentData[objectId].typeIds;
- return m_typeIds;
+ if (inlineComponentName.isEmpty())
+ return m_typeIds;
+ return m_inlineComponentData[inlineComponentName].typeIds;
}
bool QQmlTypeData::tryLoadFromDiskCache()
@@ -166,7 +166,7 @@ bool QQmlTypeData::tryLoadFromDiskCache()
for (auto&& ic: ics) {
QString const nameString = m_compiledData->stringAt(ic.nameIndex);
auto importUrl = finalUrl();
- importUrl.setFragment(QString::number(ic.objectIndex));
+ importUrl.setFragment(nameString);
auto import = new QQmlImportInstance();
m_importCache->addInlineComponentImport(import, nameString, importUrl, QQmlType());
}
@@ -287,14 +287,16 @@ static bool addTypeReferenceChecksumsToHash(
// local helper function for inline components
namespace {
template<typename ObjectContainer>
-void setupICs(const ObjectContainer &container, QHash<int, InlineComponentData> *icData, const QUrl &finalUrl) {
+void setupICs(
+ const ObjectContainer &container, QHash<QString, InlineComponentData> *icData,
+ const QUrl &finalUrl) {
Q_ASSERT(icData->empty());
for (int i = 0; i != container->objectCount(); ++i) {
auto root = container->objectAt(i);
for (auto it = root->inlineComponentsBegin(); it != root->inlineComponentsEnd(); ++it) {
const QByteArray &className = QQmlPropertyCacheCreatorBase::createClassNameForInlineComponent(finalUrl, it->objectIndex);
InlineComponentData icDatum(CompositeMetaTypeIds::fromCompositeName(className), int(it->objectIndex), int(it->nameIndex), 0, 0, 0);
- icData->insert(it->objectIndex, icDatum);
+ icData->insert(container->stringAt(it->nameIndex), icDatum);
}
}
};
@@ -370,14 +372,14 @@ void QQmlTypeData::done()
Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError() || type.type.isInlineComponentType());
if (type.type.isInlineComponentType() && !type.type.pendingResolutionName().isEmpty()) {
auto containingType = type.type.containingType();
- auto objectId = containingType.lookupInlineComponentIdByName(type.type.pendingResolutionName());
- if (objectId < 0) { // can be any negative number if we tentatively resolved it in QQmlImport but it actually was not an inline component
+ auto ic = containingType.lookupInlineComponentByName(type.type.pendingResolutionName());
+
+ // Only if we create the IC from an actual CU, we have valid metatypes.
+ if (!ic.typeId().isValid()) {
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.pendingResolutionName()));
return;
- } else {
- type.type.setInlineComponentObjectId(objectId);
}
}
if (type.typeData && type.typeData->isError()) {
@@ -533,9 +535,9 @@ void QQmlTypeData::done()
if (type.isValid()) {
for (auto const &icDatum : std::as_const(m_inlineComponentData)) {
Q_ASSERT(icDatum.typeIds.isValid());
- QQmlType existingType = type.lookupInlineComponentById(type.lookupInlineComponentIdByName(m_compiledData->stringAt(icDatum.nameIndex)));
- type.associateInlineComponent(m_compiledData->stringAt(icDatum.nameIndex),
- icDatum.objectIndex, icDatum.typeIds, existingType);
+ const QString icName = m_compiledData->stringAt(icDatum.nameIndex);
+ QQmlType existingType = type.lookupInlineComponentByName(icName);
+ type.associateInlineComponent(icName, icDatum.typeIds, existingType);
}
}
}
@@ -698,7 +700,7 @@ void QQmlTypeData::continueLoadFromIR()
for (auto it = object->inlineComponentsBegin(); it != object->inlineComponentsEnd(); ++it) {
QString const nameString = m_document->stringAt(it->nameIndex);
auto importUrl = finalUrl();
- importUrl.setFragment(QString::number(it->objectIndex));
+ importUrl.setFragment(nameString);
auto import = new QQmlImportInstance(); // Note: The cache takes ownership of the QQmlImportInstance
m_importCache->addInlineComponentImport(import, nameString, importUrl, containingType);
}
@@ -955,15 +957,16 @@ QQmlError QQmlTypeData::buildTypeResolutionCaches(
ref->setCompilationUnit(resolvedType->typeData->compilationUnit());
if (resolvedType->type.isInlineComponentType()) {
// Inline component which is part of an already resolved type
- int objectId = -1;
- if (qmlType.containingType().isValid()) {
- objectId = qmlType.containingType().lookupInlineComponentIdByName(QString::fromUtf8(qmlType.typeName()));
- qmlType.setInlineComponentObjectId(objectId);
- } else {
- objectId = resolvedType->type.inlineComponentId();
- }
- Q_ASSERT(objectId != -1);
- ref->setTypePropertyCache(resolvedType->typeData->compilationUnit()->propertyCaches.at(objectId));
+ QString icName;
+ if (qmlType.containingType().isValid())
+ icName = qmlType.elementName();
+ else
+ icName = resolvedType->type.elementName();
+ Q_ASSERT(!icName.isEmpty());
+
+ const auto compilationUnit = resolvedType->typeData->compilationUnit();
+ ref->setTypePropertyCache(compilationUnit->propertyCaches.at(
+ compilationUnit->inlineComponentId(icName)));
ref->setType(qmlType);
Q_ASSERT(ref->type().isInlineComponentType());
}
@@ -972,7 +975,7 @@ QQmlError QQmlTypeData::buildTypeResolutionCaches(
ref->setType(qmlType);
if (qmlType.isValid()) {
// this is required for inline components in singletons
- auto type = qmlType.lookupInlineComponentById(qmlType.inlineComponentId()).typeId();
+ auto type = qmlType.lookupInlineComponentByName(qmlType.elementName()).typeId();
auto exUnit = QQmlMetaType::obtainExecutableCompilationUnit(type);
if (exUnit) {
ref->setCompilationUnit(exUnit);
diff --git a/src/qml/qml/qqmltypedata_p.h b/src/qml/qml/qqmltypedata_p.h
index 9e4f85974b..2c9058dc26 100644
--- a/src/qml/qml/qqmltypedata_p.h
+++ b/src/qml/qml/qqmltypedata_p.h
@@ -68,7 +68,7 @@ public:
void registerCallback(TypeDataCallback *);
void unregisterCallback(TypeDataCallback *);
- CompositeMetaTypeIds typeIds(int objectId = 0) const;
+ CompositeMetaTypeIds typeIds(const QString &inlineComponentName = QString()) const;
QByteArray typeClassName() const { return m_typeClassName; }
SourceCodeData backupSourceCode() const { return m_backupSourceCode; }
@@ -126,7 +126,7 @@ private:
using ExecutableCompilationUnitPtr = QQmlRefPointer<QV4::ExecutableCompilationUnit>;
- QHash<int, InlineComponentData> m_inlineComponentData;
+ QHash<QString, InlineComponentData> m_inlineComponentData;
ExecutableCompilationUnitPtr m_compiledData;