qmltyperegistrar: Record creation method of value types
We need this to tell the compilers how to create value types. Change-Id: Iaef60eef64552df1a155a780aa2c4f4c44533184 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
This commit is contained in:
parent
dba7d84843
commit
97d698f6e7
|
@ -18,7 +18,8 @@ QtObject {
|
||||||
property string valueType
|
property string valueType
|
||||||
property string extension
|
property string extension
|
||||||
property bool isSingleton: false
|
property bool isSingleton: false
|
||||||
property bool isCreatable: name.length > 0
|
property bool isCreatable: accessSemantics === "reference" && name.length > 0
|
||||||
|
property bool isStructured: false
|
||||||
property bool isComposite: false
|
property bool isComposite: false
|
||||||
property bool hasCustomParser: false
|
property bool hasCustomParser: false
|
||||||
property bool extensionIsNamespace: false
|
property bool extensionIsNamespace: false
|
||||||
|
|
|
@ -1286,6 +1286,15 @@ bool QQmlJSScope::isCreatable() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QQmlJSScope::isStructured() const
|
||||||
|
{
|
||||||
|
for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().get()) {
|
||||||
|
if (!scope->isComposite())
|
||||||
|
return scope->hasStructuredFlag();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QQmlSA::Element QQmlJSScope::createQQmlSAElement(const ConstPtr &ptr)
|
QQmlSA::Element QQmlJSScope::createQQmlSAElement(const ConstPtr &ptr)
|
||||||
{
|
{
|
||||||
QQmlSA::Element element;
|
QQmlSA::Element element;
|
||||||
|
|
|
@ -131,6 +131,7 @@ public:
|
||||||
HasBaseTypeError = 0x100,
|
HasBaseTypeError = 0x100,
|
||||||
HasExtensionNamespace = 0x200,
|
HasExtensionNamespace = 0x200,
|
||||||
IsListProperty = 0x400,
|
IsListProperty = 0x400,
|
||||||
|
Structured = 0x800,
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(Flags, Flag)
|
Q_DECLARE_FLAGS(Flags, Flag)
|
||||||
Q_FLAGS(Flags);
|
Q_FLAGS(Flags);
|
||||||
|
@ -531,8 +532,13 @@ QT_WARNING_POP
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSingleton() const { return m_flags & Singleton; }
|
bool isSingleton() const { return m_flags & Singleton; }
|
||||||
|
|
||||||
bool isCreatable() const;
|
bool isCreatable() const;
|
||||||
bool hasCreatableFlag() const { return m_flags & Creatable; }
|
bool hasCreatableFlag() const { return m_flags & Creatable; }
|
||||||
|
|
||||||
|
bool isStructured() const;
|
||||||
|
bool hasStructuredFlag() const { return m_flags & Structured; }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \internal
|
* \internal
|
||||||
*
|
*
|
||||||
|
@ -547,6 +553,7 @@ QT_WARNING_POP
|
||||||
bool extensionIsNamespace() const { return m_flags & HasExtensionNamespace; }
|
bool extensionIsNamespace() const { return m_flags & HasExtensionNamespace; }
|
||||||
void setIsSingleton(bool v) { m_flags.setFlag(Singleton, v); }
|
void setIsSingleton(bool v) { m_flags.setFlag(Singleton, v); }
|
||||||
void setCreatableFlag(bool v) { m_flags.setFlag(Creatable, v); }
|
void setCreatableFlag(bool v) { m_flags.setFlag(Creatable, v); }
|
||||||
|
void setStructuredFlag(bool v) { m_flags.setFlag(Structured, v); }
|
||||||
void setIsComposite(bool v) { m_flags.setFlag(Composite, v); }
|
void setIsComposite(bool v) { m_flags.setFlag(Composite, v); }
|
||||||
void setIsScript(bool v) { m_flags.setFlag(Script, v); }
|
void setIsScript(bool v) { m_flags.setFlag(Script, v); }
|
||||||
void setHasCustomParser(bool v)
|
void setHasCustomParser(bool v)
|
||||||
|
|
|
@ -213,6 +213,8 @@ void QQmlJSTypeDescriptionReader::readComponent(UiObjectDefinition *ast)
|
||||||
scope->setIsSingleton(readBoolBinding(script));
|
scope->setIsSingleton(readBoolBinding(script));
|
||||||
} else if (name == QLatin1String("isCreatable")) {
|
} else if (name == QLatin1String("isCreatable")) {
|
||||||
scope->setCreatableFlag(readBoolBinding(script));
|
scope->setCreatableFlag(readBoolBinding(script));
|
||||||
|
} else if (name == QLatin1String("isStructured")) {
|
||||||
|
scope->setStructuredFlag(readBoolBinding(script));
|
||||||
} else if (name == QLatin1String("isComposite")) {
|
} else if (name == QLatin1String("isComposite")) {
|
||||||
scope->setIsComposite(readBoolBinding(script));
|
scope->setIsComposite(readBoolBinding(script));
|
||||||
} else if (name == QLatin1String("hasCustomParser")) {
|
} else if (name == QLatin1String("hasCustomParser")) {
|
||||||
|
@ -243,8 +245,9 @@ void QQmlJSTypeDescriptionReader::readComponent(UiObjectDefinition *ast)
|
||||||
addWarning(script->firstSourceLocation(),
|
addWarning(script->firstSourceLocation(),
|
||||||
tr("Expected only name, prototype, defaultProperty, attachedType, "
|
tr("Expected only name, prototype, defaultProperty, attachedType, "
|
||||||
"valueType, exports, interfaces, isSingleton, isCreatable, "
|
"valueType, exports, interfaces, isSingleton, isCreatable, "
|
||||||
"isComposite, hasCustomParser, exportMetaObjectRevisions, "
|
"isStructured, isComposite, hasCustomParser, "
|
||||||
"deferredNames, and immediateNames in script bindings, not \"%1\".")
|
"exportMetaObjectRevisions, deferredNames, and immediateNames "
|
||||||
|
"in script bindings, not \"%1\".")
|
||||||
.arg(name));
|
.arg(name));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -88,6 +88,7 @@ static constexpr QLatin1StringView S_CLASSES { "classes" };
|
||||||
static constexpr QLatin1StringView S_CLASS_INFOS { "classInfos" };
|
static constexpr QLatin1StringView S_CLASS_INFOS { "classInfos" };
|
||||||
static constexpr QLatin1StringView S_CLASS_NAME { "className" };
|
static constexpr QLatin1StringView S_CLASS_NAME { "className" };
|
||||||
static constexpr QLatin1StringView S_CONSTANT { "constant" };
|
static constexpr QLatin1StringView S_CONSTANT { "constant" };
|
||||||
|
static constexpr QLatin1StringView S_CONSTRUCT { "construct" };
|
||||||
static constexpr QLatin1StringView S_CONSTRUCTORS { "constructors" };
|
static constexpr QLatin1StringView S_CONSTRUCTORS { "constructors" };
|
||||||
static constexpr QLatin1StringView S_DEFAULT_PROPERTY { "DefaultProperty" };
|
static constexpr QLatin1StringView S_DEFAULT_PROPERTY { "DefaultProperty" };
|
||||||
static constexpr QLatin1StringView S_DEFERRED_PROPERTY_NAMES { "DeferredPropertyNames" };
|
static constexpr QLatin1StringView S_DEFERRED_PROPERTY_NAMES { "DeferredPropertyNames" };
|
||||||
|
@ -123,6 +124,7 @@ static constexpr QLatin1StringView S_RETURN_TYPE { "returnType"
|
||||||
static constexpr QLatin1StringView S_REVISION { "revision" };
|
static constexpr QLatin1StringView S_REVISION { "revision" };
|
||||||
static constexpr QLatin1StringView S_SIGNALS { "signals" };
|
static constexpr QLatin1StringView S_SIGNALS { "signals" };
|
||||||
static constexpr QLatin1StringView S_SLOTS { "slots" };
|
static constexpr QLatin1StringView S_SLOTS { "slots" };
|
||||||
|
static constexpr QLatin1StringView S_STRUCTURED { "structured" };
|
||||||
static constexpr QLatin1StringView S_SUPER_CLASSES { "superClasses" };
|
static constexpr QLatin1StringView S_SUPER_CLASSES { "superClasses" };
|
||||||
static constexpr QLatin1StringView S_TRUE { "true" };
|
static constexpr QLatin1StringView S_TRUE { "true" };
|
||||||
static constexpr QLatin1StringView S_TYPE { "type" };
|
static constexpr QLatin1StringView S_TYPE { "type" };
|
||||||
|
@ -135,6 +137,7 @@ namespace Qml {
|
||||||
static constexpr QLatin1StringView S_ADDED_IN_VERSION { "QML.AddedInVersion" };
|
static constexpr QLatin1StringView S_ADDED_IN_VERSION { "QML.AddedInVersion" };
|
||||||
static constexpr QLatin1StringView S_ATTACHED { "QML.Attached" };
|
static constexpr QLatin1StringView S_ATTACHED { "QML.Attached" };
|
||||||
static constexpr QLatin1StringView S_CREATABLE { "QML.Creatable" };
|
static constexpr QLatin1StringView S_CREATABLE { "QML.Creatable" };
|
||||||
|
static constexpr QLatin1StringView S_CREATION_METHOD { "QML.CreationMethod" };
|
||||||
static constexpr QLatin1StringView S_ELEMENT { "QML.Element" };
|
static constexpr QLatin1StringView S_ELEMENT { "QML.Element" };
|
||||||
static constexpr QLatin1StringView S_EXTENDED { "QML.Extended" };
|
static constexpr QLatin1StringView S_EXTENDED { "QML.Extended" };
|
||||||
static constexpr QLatin1StringView S_EXTENSION_IS_NAMESPACE { "QML.ExtensionIsNamespace" };
|
static constexpr QLatin1StringView S_EXTENSION_IS_NAMESPACE { "QML.ExtensionIsNamespace" };
|
||||||
|
|
|
@ -116,7 +116,7 @@ void QmlTypesClassDescription::collect(
|
||||||
const auto classInfos = classDef->value(S_CLASS_INFOS).toArray();
|
const auto classInfos = classDef->value(S_CLASS_INFOS).toArray();
|
||||||
const QAnyStringView classDefName = toStringView(*classDef, S_CLASS_NAME);
|
const QAnyStringView classDefName = toStringView(*classDef, S_CLASS_NAME);
|
||||||
QAnyStringView foreignTypeName;
|
QAnyStringView foreignTypeName;
|
||||||
bool explicitCreatable = false;
|
bool isConstructible = false;
|
||||||
for (const QCborValue classInfo : classInfos) {
|
for (const QCborValue classInfo : classInfos) {
|
||||||
const QCborMap obj = classInfo.toMap();
|
const QCborMap obj = classInfo.toMap();
|
||||||
const QAnyStringView name = toStringView(obj, S_NAME);
|
const QAnyStringView name = toStringView(obj, S_NAME);
|
||||||
|
@ -151,7 +151,9 @@ void QmlTypesClassDescription::collect(
|
||||||
removedInRevision = QTypeRevision::fromEncodedVersion(toInt(value));
|
removedInRevision = QTypeRevision::fromEncodedVersion(toInt(value));
|
||||||
} else if (name == S_CREATABLE) {
|
} else if (name == S_CREATABLE) {
|
||||||
isCreatable = (value != S_FALSE);
|
isCreatable = (value != S_FALSE);
|
||||||
explicitCreatable = true;
|
} else if (name == S_CREATION_METHOD) {
|
||||||
|
isStructured = (value == S_STRUCTURED);
|
||||||
|
isConstructible = isStructured || (value == S_CONSTRUCT);
|
||||||
} else if (name == S_ATTACHED) {
|
} else if (name == S_ATTACHED) {
|
||||||
attachedType = value;
|
attachedType = value;
|
||||||
collectRelated(value, types, foreign, defaultRevision);
|
collectRelated(value, types, foreign, defaultRevision);
|
||||||
|
@ -270,8 +272,7 @@ void QmlTypesClassDescription::collect(
|
||||||
} else if (classDef && classDef->value(S_OBJECT).toBool()) {
|
} else if (classDef && classDef->value(S_OBJECT).toBool()) {
|
||||||
accessSemantics = DotQmltypes::S_REFERENCE;
|
accessSemantics = DotQmltypes::S_REFERENCE;
|
||||||
} else {
|
} else {
|
||||||
if (!explicitCreatable)
|
isCreatable = isConstructible;
|
||||||
isCreatable = false;
|
|
||||||
|
|
||||||
if (!classDef) {
|
if (!classDef) {
|
||||||
if (elementName.isEmpty() || elementName.front().isLower()) {
|
if (elementName.isEmpty() || elementName.front().isLower()) {
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct QmlTypesClassDescription
|
||||||
QTypeRevision addedInRevision;
|
QTypeRevision addedInRevision;
|
||||||
QTypeRevision removedInRevision;
|
QTypeRevision removedInRevision;
|
||||||
bool isCreatable = true;
|
bool isCreatable = true;
|
||||||
|
bool isStructured = false;
|
||||||
bool isSingleton = false;
|
bool isSingleton = false;
|
||||||
bool hasCustomParser = false;
|
bool hasCustomParser = false;
|
||||||
bool omitFromQmlTypes = false;
|
bool omitFromQmlTypes = false;
|
||||||
|
|
|
@ -115,6 +115,9 @@ void QmlTypesCreator::writeClassProperties(const QmlTypesClassDescription &colle
|
||||||
if (!collector.isCreatable || collector.isSingleton)
|
if (!collector.isCreatable || collector.isSingleton)
|
||||||
m_qml.writeBooleanBinding(S_IS_CREATABLE, false);
|
m_qml.writeBooleanBinding(S_IS_CREATABLE, false);
|
||||||
|
|
||||||
|
if (collector.isStructured)
|
||||||
|
m_qml.writeScriptBinding(QLatin1String("isStructured"), QLatin1String("true"));
|
||||||
|
|
||||||
if (collector.isSingleton)
|
if (collector.isSingleton)
|
||||||
m_qml.writeBooleanBinding(S_IS_SINGLETON, true);
|
m_qml.writeBooleanBinding(S_IS_SINGLETON, true);
|
||||||
|
|
||||||
|
|
|
@ -593,6 +593,20 @@ void tst_qmltyperegistrar::constructibleValueType()
|
||||||
})"));
|
})"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_qmltyperegistrar::structuredValueType()
|
||||||
|
{
|
||||||
|
QVERIFY(qmltypesData.contains(
|
||||||
|
R"(Component {
|
||||||
|
file: "tst_qmltyperegistrar.h"
|
||||||
|
name: "Structured"
|
||||||
|
accessSemantics: "value"
|
||||||
|
exports: ["QmlTypeRegistrarTest/structured 1.0"]
|
||||||
|
isStructured: true
|
||||||
|
exportMetaObjectRevisions: [256]
|
||||||
|
Property { name: "i"; type: "int"; index: 0; isFinal: true }
|
||||||
|
})"));
|
||||||
|
}
|
||||||
|
|
||||||
void tst_qmltyperegistrar::anonymousAndUncreatable()
|
void tst_qmltyperegistrar::anonymousAndUncreatable()
|
||||||
{
|
{
|
||||||
QVERIFY(qmltypesData.contains(
|
QVERIFY(qmltypesData.contains(
|
||||||
|
|
|
@ -513,6 +513,17 @@ private:
|
||||||
int m_i;
|
int m_i;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Structured
|
||||||
|
{
|
||||||
|
Q_GADGET
|
||||||
|
QML_VALUE_TYPE(structured)
|
||||||
|
QML_STRUCTURED_VALUE
|
||||||
|
Q_PROPERTY(int i MEMBER m_i FINAL)
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_i;
|
||||||
|
};
|
||||||
|
|
||||||
class AnonymousAndUncreatable : public QObject
|
class AnonymousAndUncreatable : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -615,6 +626,7 @@ private slots:
|
||||||
void clonedSignal();
|
void clonedSignal();
|
||||||
void baseVersionInQmltypes();
|
void baseVersionInQmltypes();
|
||||||
void constructibleValueType();
|
void constructibleValueType();
|
||||||
|
void structuredValueType();
|
||||||
void anonymousAndUncreatable();
|
void anonymousAndUncreatable();
|
||||||
void omitInvisible();
|
void omitInvisible();
|
||||||
void typedEnum();
|
void typedEnum();
|
||||||
|
|
Loading…
Reference in New Issue