aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljsregistercontent.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2024-11-15 13:52:25 +0100
committerUlf Hermann <ulf.hermann@qt.io>2024-11-20 10:00:56 +0100
commit1e095058e165b1c2f244799ca1928ae4cc046a2c (patch)
treee85ad67398f6724d723cf3c3b40f602db6f37193 /src/qmlcompiler/qqmljsregistercontent.cpp
parent55c3b94035787ea265c5ff6e3c271d7154186def (diff)
QmlCompiler: Split QQmlJSRegisterContent in public and private classes
We want an easy way to hold pointers to other QQmlJSRegisterContents in QQmlJSRegisterContent. Furthermore, copying a QQmlJSRegisterContent so far is very expensive. Solve both problems by introducing the PIMPL pattern with a shared d-pointer. This also changes the equality semantics of QQmlJSRegisterContent. Two QQmlJSRegisterContents are only equal if they contain the same d-pointer now, not if their contents are otherwise equal. However, since we generally don't rely on immediate equality of QQmlJSRegisterContent anyway, this is not a problem. QQmlJSTypeResolver::equals() still works. There is one place where the equality was used, though. That one is adapted. Furthermore, we now want to keep the register contents in a pool that's automatically cleared when we're done with our analysis. Therefore the creation methods cannot be static anymore and storedIn() as well as castTo() need to go through the pool as well. Task-number: QTBUG-124670 Change-Id: I0a51b609fc769ccb33c1d82930bda83c2a40e1a5 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
Diffstat (limited to 'src/qmlcompiler/qqmljsregistercontent.cpp')
-rw-r--r--src/qmlcompiler/qqmljsregistercontent.cpp427
1 files changed, 375 insertions, 52 deletions
diff --git a/src/qmlcompiler/qqmljsregistercontent.cpp b/src/qmlcompiler/qqmljsregistercontent.cpp
index cc5d92eff7..04cc547f22 100644
--- a/src/qmlcompiler/qqmljsregistercontent.cpp
+++ b/src/qmlcompiler/qqmljsregistercontent.cpp
@@ -3,22 +3,171 @@
#include "qqmljsregistercontent_p.h"
+#include <variant>
+
QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
-QQmlJSRegisterContent::QQmlJSRegisterContent() = default;
+struct QQmlJSRegisterContentPrivate
+{
+public:
+
+ using ContentVariant = QQmlJSRegisterContent::ContentVariant;
+
+ enum class Kind : size_t {
+ Type, Property, Enum, Method, ImportNamespace, Conversion, MethodCall
+ };
+
+ struct ConvertedTypes
+ {
+ QList<QQmlJSRegisterContent> origins;
+ QQmlJSScope::ConstPtr result;
+ QQmlJSRegisterContent resultScope;
+
+ friend size_t qHash(const ConvertedTypes &types, size_t seed = 0)
+ {
+ return qHashMulti(seed, types.origins, types.result, types.resultScope);
+ }
+
+ friend bool operator==(const ConvertedTypes &a, const ConvertedTypes &b)
+ {
+ return a.origins == b.origins && a.result == b.result && a.resultScope == b.resultScope;
+ }
+
+ friend bool operator!=(const ConvertedTypes &a, const ConvertedTypes &b)
+ {
+ return !(a == b);
+ }
+ };
+
+ struct PropertyLookup
+ {
+ QQmlJSMetaProperty property;
+ int baseLookupIndex = QQmlJSRegisterContent::InvalidLookupIndex;
+ int resultLookupIndex = QQmlJSRegisterContent::InvalidLookupIndex;
+
+ friend size_t qHash(const PropertyLookup &property, size_t seed = 0)
+ {
+ return qHashMulti(
+ seed, property.property, property.baseLookupIndex, property.resultLookupIndex);
+ }
+
+ friend bool operator==(const PropertyLookup &a, const PropertyLookup &b)
+ {
+ return a.baseLookupIndex == b.baseLookupIndex
+ && a.resultLookupIndex == b.resultLookupIndex
+ && a.property == b.property;
+ }
+
+ friend bool operator!=(const PropertyLookup &a, const PropertyLookup &b)
+ {
+ return !(a == b);
+ }
+ };
+
+ using Content = std::variant<
+ std::pair<QQmlJSScope::ConstPtr, int>,
+ PropertyLookup,
+ std::pair<QQmlJSMetaEnum, QString>,
+ std::pair<QList<QQmlJSMetaMethod>, QQmlJSScope::ConstPtr>,
+ std::pair<uint, QQmlJSScope::ConstPtr>,
+ ConvertedTypes,
+ QQmlJSMetaMethod
+ >;
+
+ friend size_t qHash(const QQmlJSRegisterContentPrivate &registerContent, size_t seed = 0)
+ {
+ seed = qHashMulti(
+ seed, registerContent.m_storedType, registerContent.m_content.index(),
+ registerContent.m_variant, registerContent.m_scope);
+
+ switch (Kind(registerContent.m_content.index())) {
+ case Kind::Type:
+ return qHash(std::get<std::pair<QQmlJSScope::ConstPtr, int>>(registerContent.m_content),
+ seed);
+ case Kind::Property:
+ return qHash(std::get<PropertyLookup>(registerContent.m_content), seed);
+ case Kind::Enum:
+ return qHash(std::get<std::pair<QQmlJSMetaEnum, QString>>(registerContent.m_content),
+ seed);
+ case Kind::Method:
+ return qHash(std::get<std::pair<QList<QQmlJSMetaMethod>, QQmlJSScope::ConstPtr>>(
+ registerContent.m_content), seed);
+ case Kind::ImportNamespace:
+ return qHash(std::get<std::pair<uint, QQmlJSScope::ConstPtr>>(
+ registerContent.m_content), seed);
+ case Kind::Conversion:
+ return qHash(std::get<ConvertedTypes>(registerContent.m_content), seed);
+ case Kind::MethodCall:
+ return qHash(std::get<QQmlJSMetaMethod>(registerContent.m_content), seed);
+ }
+
+ Q_UNREACHABLE_RETURN(seed);
+ }
+
+ friend bool operator==(
+ const QQmlJSRegisterContentPrivate &a, const QQmlJSRegisterContentPrivate &b)
+ {
+ return a.m_storedType == b.m_storedType && a.m_variant == b.m_variant
+ && a.m_scope == b.m_scope && a.m_content == b.m_content;
+ }
+
+ friend bool operator!=(
+ const QQmlJSRegisterContentPrivate &a, const QQmlJSRegisterContentPrivate &b)
+ {
+ return !(a == b);
+ }
+
+ QQmlJSScope::ConstPtr m_storedType;
+ QQmlJSRegisterContent m_scope;
+ Content m_content;
+ ContentVariant m_variant = ContentVariant::Unknown;
+
+ int resultLookupIndex() const
+ {
+ switch (Kind(m_content.index())) {
+ case Kind::Type:
+ return std::get<std::pair<QQmlJSScope::ConstPtr, int>>(m_content).second;
+ case Kind::Property:
+ return std::get<PropertyLookup>(m_content).resultLookupIndex;
+ default:
+ return QQmlJSRegisterContent::InvalidLookupIndex;
+ }
+ }
+
+private:
+ friend class QQmlJSRegisterContentPool;
+
+ QQmlJSRegisterContentPrivate() = default;
+ ~QQmlJSRegisterContentPrivate() = default;
+ QQmlJSRegisterContentPrivate(const QQmlJSRegisterContentPrivate &) = default;
+ QQmlJSRegisterContentPrivate(QQmlJSRegisterContentPrivate &&) = default;
+ QQmlJSRegisterContentPrivate &operator=(const QQmlJSRegisterContentPrivate &) = default;
+ QQmlJSRegisterContentPrivate &operator=(QQmlJSRegisterContentPrivate &&) = default;
+};
+
+QQmlJSRegisterContent::QQmlJSRegisterContent()
+ : d(QQmlJSRegisterContentPool::invalid())
+{}
+
+bool QQmlJSRegisterContent::isValid() const
+{
+ return !containedType().isNull();
+};
QString QQmlJSRegisterContent::descriptiveName() const
{
- if (m_storedType.isNull() && containedType().isNull())
+ using Kind = QQmlJSRegisterContentPrivate::Kind;
+
+ if (d->m_storedType.isNull() && containedType().isNull())
return u"(invalid type)"_s;
const auto scope = [this]() -> QString {
- if (m_scope.isNull())
+ if (!d->m_scope.isValid())
return u"(invalid type)::"_s;
- const QQmlJSScope::ConstPtr scopeContained = m_scope->containedType();
+ const QQmlJSScope::ConstPtr scopeContained = d->m_scope.containedType();
if (scopeContained.isNull())
return u"(invalid type)::"_s;
@@ -31,19 +180,19 @@ QString QQmlJSRegisterContent::descriptiveName() const
};
QString result;
- switch (Kind(m_content.index())) {
+ switch (Kind(d->m_content.index())) {
case Kind::Type: {
const QQmlJSScope::ConstPtr contained = type();
result += contained->internalName();
- if (m_storedType && m_storedType->internalName() != contained->internalName())
- result += u" stored as "_s + m_storedType->internalName();
+ if (d->m_storedType && d->m_storedType->internalName() != contained->internalName())
+ result += u" stored as "_s + d->m_storedType->internalName();
return result;
}
case Kind::Property: {
const QQmlJSMetaProperty prop = property();
result += scope() + prop.propertyName() + u" with type "_s + prop.typeName();
- if (m_storedType && m_storedType->internalName() != prop.typeName())
- result += u" (stored as "_s + m_storedType->internalName() + u")";
+ if (d->m_storedType && d->m_storedType->internalName() != prop.typeName())
+ result += u" (stored as "_s + d->m_storedType->internalName() + u")";
return result;
}
case Kind::Method: {
@@ -52,8 +201,8 @@ QString QQmlJSRegisterContent::descriptiveName() const
result = scope() + u"(unknown method)"_s;
else
result = scope() + methods[0].methodName() + u"(...)"_s;
- if (m_storedType)
- return result + u" (stored as "_s + m_storedType->internalName() + u")";
+ if (d->m_storedType)
+ return result + u" (stored as "_s + d->m_storedType->internalName() + u")";
return result;
}
case Kind::Enum: {
@@ -63,8 +212,8 @@ QString QQmlJSRegisterContent::descriptiveName() const
result = scope() + enumName;
else
result = scope() + enumName + u"::"_s + memberName;
- if (m_storedType)
- return result + u" (stored as "_s + m_storedType->internalName() + u")";
+ if (d->m_storedType)
+ return result + u" (stored as "_s + d->m_storedType->internalName() + u")";
return result;
}
case Kind::ImportNamespace: {
@@ -74,7 +223,7 @@ QString QQmlJSRegisterContent::descriptiveName() const
return u"conversion to %1"_s.arg(conversionResult()->internalName());
}
case Kind::MethodCall: {
- const QQmlJSMetaMethod &method = std::get<QQmlJSMetaMethod>(m_content);
+ const QQmlJSMetaMethod &method = std::get<QQmlJSMetaMethod>(d->m_content);
return u"call to method %1, returning %2"_s.arg(
method.methodName(), method.returnTypeName());
}
@@ -100,21 +249,58 @@ QString QQmlJSRegisterContent::containedTypeName() const
type->internalName().isEmpty() ? type->baseTypeName() : type->internalName());
}
+bool QQmlJSRegisterContent::isType() const
+{
+ return d->m_content.index() == size_t(QQmlJSRegisterContentPrivate::Kind::Type);
+}
+
+bool QQmlJSRegisterContent::isProperty() const
+{
+ return d->m_content.index() == size_t(QQmlJSRegisterContentPrivate::Kind::Property);
+}
+
+bool QQmlJSRegisterContent::isEnumeration() const
+{
+ return d->m_content.index() == size_t(QQmlJSRegisterContentPrivate::Kind::Enum);
+}
+
+bool QQmlJSRegisterContent::isMethod() const
+{
+ return d->m_content.index() == size_t(QQmlJSRegisterContentPrivate::Kind::Method);
+}
+
+bool QQmlJSRegisterContent::isImportNamespace() const
+{
+ return d->m_content.index() == size_t(QQmlJSRegisterContentPrivate::Kind::ImportNamespace);
+}
+
+bool QQmlJSRegisterContent::isConversion() const
+{
+ return d->m_content.index() == size_t(QQmlJSRegisterContentPrivate::Kind::Conversion);
+}
+
+bool QQmlJSRegisterContent::isMethodCall() const
+{
+ return d->m_content.index() == size_t(QQmlJSRegisterContentPrivate::Kind::MethodCall);
+}
+
bool QQmlJSRegisterContent::isList() const
{
- switch (Kind(m_content.index())) {
+ using Kind = QQmlJSRegisterContentPrivate::Kind;
+
+ switch (Kind(d->m_content.index())) {
case Kind::Type:
- return std::get<std::pair<QQmlJSScope::ConstPtr, int>>(m_content).first->accessSemantics()
- == QQmlJSScope::AccessSemantics::Sequence;
+ return std::get<std::pair<QQmlJSScope::ConstPtr, int>>(d->m_content).first
+ ->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence;
case Kind::Property:
- return std::get<PropertyLookup>(m_content).property.type()->accessSemantics()
- == QQmlJSScope::AccessSemantics::Sequence;
+ return std::get<QQmlJSRegisterContentPrivate::PropertyLookup>(d->m_content).property.type()
+ ->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence;
case Kind::Conversion:
- return std::get<ConvertedTypes>(m_content).result->accessSemantics()
- == QQmlJSScope::AccessSemantics::Sequence;
+ return std::get<QQmlJSRegisterContentPrivate::ConvertedTypes>(d->m_content).result
+ ->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence;
case Kind::MethodCall:
- return std::get<QQmlJSMetaMethod>(m_content).returnType()->accessSemantics()
- == QQmlJSScope::AccessSemantics::Sequence;
+ return std::get<QQmlJSMetaMethod>(d->m_content).returnType()
+ ->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence;
default:
return false;
}
@@ -122,9 +308,12 @@ bool QQmlJSRegisterContent::isList() const
bool QQmlJSRegisterContent::isWritable() const
{
- switch (Kind(m_content.index())) {
+ using Kind = QQmlJSRegisterContentPrivate::Kind;
+
+ switch (Kind(d->m_content.index())) {
case Kind::Property:
- return std::get<PropertyLookup>(m_content).property.isWritable();
+ return std::get<QQmlJSRegisterContentPrivate::PropertyLookup>(d->m_content)
+ .property.isWritable();
// TODO: What can we actually write?
default:
@@ -134,6 +323,11 @@ bool QQmlJSRegisterContent::isWritable() const
return true;
}
+bool QQmlJSRegisterContent::isJavaScriptReturnValue() const
+{
+ return isMethodCall() && std::get<QQmlJSMetaMethod>(d->m_content).isJavaScriptFunction();
+}
+
/*!
* \internal
* Precondition: This is an attachment.
@@ -141,7 +335,7 @@ bool QQmlJSRegisterContent::isWritable() const
*/
QQmlJSRegisterContent QQmlJSRegisterContent::attacher() const
{
- Q_ASSERT(m_variant == Attachment);
+ Q_ASSERT(d->m_variant == Attachment);
return scopeType();
}
@@ -152,21 +346,26 @@ QQmlJSRegisterContent QQmlJSRegisterContent::attacher() const
*/
QQmlJSRegisterContent QQmlJSRegisterContent::attachee() const
{
- Q_ASSERT(m_variant == Attachment);
+ Q_ASSERT(d->m_variant == Attachment);
QQmlJSRegisterContent attachee = attacher().scopeType();
while (attachee.variant() == ModulePrefix)
attachee = attachee.scopeType();
return attachee;
}
+QQmlJSScope::ConstPtr QQmlJSRegisterContent::storedType() const
+{
+ return d->m_storedType;
+}
+
QQmlJSScope::ConstPtr QQmlJSRegisterContent::containedType() const
{
if (isType())
return type();
if (isProperty())
- return std::get<PropertyLookup>(m_content).property.type();
+ return std::get<QQmlJSRegisterContentPrivate::PropertyLookup>(d->m_content).property.type();
if (isEnumeration())
- return std::get<std::pair<QQmlJSMetaEnum, QString>>(m_content).first.type();
+ return std::get<std::pair<QQmlJSMetaEnum, QString>>(d->m_content).first.type();
if (isMethod())
return methodType();
if (isImportNamespace())
@@ -174,86 +373,210 @@ QQmlJSScope::ConstPtr QQmlJSRegisterContent::containedType() const
if (isConversion())
return conversionResult();
if (isMethodCall())
- return std::get<QQmlJSMetaMethod>(m_content).returnType();
+ return std::get<QQmlJSMetaMethod>(d->m_content).returnType();
Q_UNREACHABLE_RETURN({});
}
-QQmlJSRegisterContent QQmlJSRegisterContent::create(
+QQmlJSRegisterContent QQmlJSRegisterContent::scopeType() const
+{
+ return d->m_scope;
+}
+
+QQmlJSScope::ConstPtr QQmlJSRegisterContent::type() const
+{
+ return std::get<std::pair<QQmlJSScope::ConstPtr, int>>(d->m_content).first;
+}
+
+QQmlJSMetaProperty QQmlJSRegisterContent::property() const
+{
+ return std::get<QQmlJSRegisterContentPrivate::PropertyLookup>(d->m_content).property;
+}
+
+int QQmlJSRegisterContent::baseLookupIndex() const
+{
+ return std::get<QQmlJSRegisterContentPrivate::PropertyLookup>(d->m_content).baseLookupIndex;
+}
+
+int QQmlJSRegisterContent::resultLookupIndex() const
+{
+ return d->resultLookupIndex();
+}
+
+QQmlJSMetaEnum QQmlJSRegisterContent::enumeration() const
+{
+ return std::get<std::pair<QQmlJSMetaEnum, QString>>(d->m_content).first;
+}
+
+QString QQmlJSRegisterContent::enumMember() const
+{
+ return std::get<std::pair<QQmlJSMetaEnum, QString>>(d->m_content).second;
+}
+
+QList<QQmlJSMetaMethod> QQmlJSRegisterContent::method() const
+{
+ return std::get<std::pair<QList<QQmlJSMetaMethod>, QQmlJSScope::ConstPtr>>(d->m_content).first;
+}
+
+QQmlJSScope::ConstPtr QQmlJSRegisterContent::methodType() const
+{
+ return std::get<std::pair<QList<QQmlJSMetaMethod>, QQmlJSScope::ConstPtr>>(d->m_content).second;
+}
+
+uint QQmlJSRegisterContent::importNamespace() const
+{
+ return std::get<std::pair<uint, QQmlJSScope::ConstPtr>>(d->m_content).first;
+}
+
+QQmlJSScope::ConstPtr QQmlJSRegisterContent::importNamespaceType() const
+{
+ return std::get<std::pair<uint, QQmlJSScope::ConstPtr>>(d->m_content).second;
+}
+
+QQmlJSScope::ConstPtr QQmlJSRegisterContent::conversionResult() const
+{
+ return std::get<QQmlJSRegisterContentPrivate::ConvertedTypes>(d->m_content).result;
+}
+
+QQmlJSRegisterContent QQmlJSRegisterContent::conversionResultScope() const
+{
+ return std::get<QQmlJSRegisterContentPrivate::ConvertedTypes>(d->m_content).resultScope;
+}
+
+QList<QQmlJSRegisterContent> QQmlJSRegisterContent::conversionOrigins() const
+{
+ return std::get<QQmlJSRegisterContentPrivate::ConvertedTypes>(d->m_content).origins;
+}
+
+QQmlJSMetaMethod QQmlJSRegisterContent::methodCall() const
+{
+ return std::get<QQmlJSMetaMethod>(d->m_content);
+}
+
+QQmlJSRegisterContent::ContentVariant QQmlJSRegisterContent::variant() const
+{
+ return d->m_variant;
+}
+
+QQmlJSRegisterContentPool::QQmlJSRegisterContentPool() = default;
+QQmlJSRegisterContentPool::~QQmlJSRegisterContentPool() = default;
+
+const QQmlJSRegisterContentPrivate QQmlJSRegisterContentPool::s_invalid;
+
+QQmlJSRegisterContent QQmlJSRegisterContentPool::create(
const QQmlJSScope::ConstPtr &type, int resultLookupIndex,
QQmlJSRegisterContent::ContentVariant variant, const QQmlJSRegisterContent &scope)
{
- QQmlJSRegisterContent result(scope, variant);
- result.m_content = std::make_pair(type, resultLookupIndex);
+ QQmlJSRegisterContentPrivate *result = create(scope, variant);
+ result->m_content = std::make_pair(type, resultLookupIndex);
return result;
}
-QQmlJSRegisterContent QQmlJSRegisterContent::create(
+QQmlJSRegisterContent QQmlJSRegisterContentPool::create(
const QQmlJSMetaProperty &property, int baseLookupIndex, int resultLookupIndex,
QQmlJSRegisterContent::ContentVariant variant, const QQmlJSRegisterContent &scope)
{
- QQmlJSRegisterContent result(scope, variant);
- result.m_content = PropertyLookup { property, baseLookupIndex, resultLookupIndex};
+ QQmlJSRegisterContentPrivate *result = create(scope, variant);
+ result->m_content = QQmlJSRegisterContentPrivate::PropertyLookup {
+ property,
+ baseLookupIndex,
+ resultLookupIndex
+ };
return result;
}
-QQmlJSRegisterContent QQmlJSRegisterContent::create(
+QQmlJSRegisterContent QQmlJSRegisterContentPool::create(
const QQmlJSMetaEnum &enumeration, const QString &enumMember,
QQmlJSRegisterContent::ContentVariant variant, const QQmlJSRegisterContent &scope)
{
- QQmlJSRegisterContent result(scope, variant);
- result.m_content = std::make_pair(enumeration, enumMember);
+ QQmlJSRegisterContentPrivate *result = create(scope, variant);
+ result->m_content = std::make_pair(enumeration, enumMember);
return result;
}
-QQmlJSRegisterContent QQmlJSRegisterContent::create(
+QQmlJSRegisterContent QQmlJSRegisterContentPool::create(
const QList<QQmlJSMetaMethod> &methods, const QQmlJSScope::ConstPtr &methodType,
QQmlJSRegisterContent::ContentVariant variant, const QQmlJSRegisterContent &scope)
{
// Methods can only be stored in QJSValue.
Q_ASSERT(methodType->internalName() == u"QJSValue"_s);
- QQmlJSRegisterContent result(scope, variant);
- result.m_content = std::make_pair(methods, methodType);
+ QQmlJSRegisterContentPrivate *result = create(scope, variant);
+ result->m_content = std::make_pair(methods, methodType);
return result;
}
-QQmlJSRegisterContent QQmlJSRegisterContent::create(
+QQmlJSRegisterContent QQmlJSRegisterContentPool::create(
const QQmlJSMetaMethod &method, const QQmlJSScope::ConstPtr &returnType,
const QQmlJSRegisterContent &scope)
{
- QQmlJSRegisterContent result(scope, MethodCall);
+ QQmlJSRegisterContentPrivate *result = create(scope, ContentVariant::MethodCall);
QQmlJSMetaMethod resultMethod = method;
resultMethod.setReturnType({ returnType });
resultMethod.setReturnTypeName(returnType->internalName());
- result.m_content = std::move(resultMethod);
+ result->m_content = std::move(resultMethod);
return result;
}
-QQmlJSRegisterContent QQmlJSRegisterContent::create(
+QQmlJSRegisterContent QQmlJSRegisterContentPool::create(
uint importNamespaceStringId, const QQmlJSScope::ConstPtr &importNamespaceType,
QQmlJSRegisterContent::ContentVariant variant, const QQmlJSRegisterContent &scope)
{
- QQmlJSRegisterContent result(scope, variant);
- result.m_content = std::make_pair(importNamespaceStringId, importNamespaceType);
+ QQmlJSRegisterContentPrivate *result = create(scope, variant);
+ result->m_content = std::make_pair(importNamespaceStringId, importNamespaceType);
return result;
}
-QQmlJSRegisterContent QQmlJSRegisterContent::create(
+QQmlJSRegisterContent QQmlJSRegisterContentPool::create(
const QList<QQmlJSRegisterContent> &origins, const QQmlJSScope::ConstPtr &conversion,
const QQmlJSRegisterContent &conversionScope, ContentVariant variant,
const QQmlJSRegisterContent &scope)
{
- QQmlJSRegisterContent result(scope, variant);
+ QQmlJSRegisterContentPrivate *result = create(scope, variant);
- result.m_content = ConvertedTypes {
+ result->m_content = QQmlJSRegisterContentPrivate::ConvertedTypes {
origins,
conversion,
- QSharedPointer<QQmlJSRegisterContent>::create(conversionScope)
+ conversionScope
};
return result;
}
+QQmlJSRegisterContent QQmlJSRegisterContentPool::storedIn(
+ const QQmlJSRegisterContent &content, const QQmlJSScope::ConstPtr &newStoredType)
+{
+ QQmlJSRegisterContentPrivate *result = clone(content.d);
+ result->m_storedType = newStoredType;
+ return result;
+}
+
+QQmlJSRegisterContent QQmlJSRegisterContentPool::castTo(
+ const QQmlJSRegisterContent &content, const QQmlJSScope::ConstPtr &newContainedType)
+{
+ // This is not a conversion but a run time cast. It may result in null or undefined.
+ QQmlJSRegisterContentPrivate *result = clone(content.d);
+ result->m_content = std::make_pair(newContainedType, result->resultLookupIndex());
+ return result;
+}
+
+QQmlJSRegisterContentPrivate *QQmlJSRegisterContentPool::clone(
+ const QQmlJSRegisterContentPrivate *from)
+{
+ m_pool.push_back(std::unique_ptr<QQmlJSRegisterContentPrivate, Deleter>(from
+ ? new QQmlJSRegisterContentPrivate(*from)
+ : new QQmlJSRegisterContentPrivate));
+ return m_pool.back().get();
+}
+
+QQmlJSRegisterContentPrivate *QQmlJSRegisterContentPool::create(
+ const QQmlJSRegisterContent &scope, ContentVariant variant)
+{
+ QQmlJSRegisterContentPrivate *result = create();
+ result->m_scope = scope;
+ result->m_variant = variant;
+ return result;
+}
+
QT_END_NAMESPACE