aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp2
16 files changed, 144 insertions, 157 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;
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index f171d55d03..25dc754826 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -6767,7 +6767,7 @@ void tst_qqmllanguage::bareInlineComponent()
if (type.elementName() == QStringLiteral("Tab1")) {
QVERIFY(type.module().isEmpty());
tab1Found = true;
- const auto ics = type.priv()->objectIdToICType;
+ const auto ics = type.priv()->namesToInlineComponentType;
QVERIFY(ics.size() > 0);
for (const QQmlType &ic : ics)
QVERIFY(ic.containingType() == type);