aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorSami Shalayel <sami.shalayel@qt.io>2022-09-28 20:04:44 +0200
committerSami Shalayel <sami.shalayel@qt.io>2022-11-23 10:05:30 +0100
commitaa3e01645ddc675c2532c6966c1eae3d1967a73d (patch)
tree3a81b26e35189f8fff05e220ba40190fa6ffd60a /tools
parent9b3813be282ab00d594c48d62f1e13d73f36d514 (diff)
qmltc: add singleton support
Add singleton support to qmltc. Add the QML_SINGLETON annotation to the class, generate a static T* create(QQmlEngine*, QJSEngine*) method for the engine and also add test this new functionality. Fixes: QTBUG-106828 Change-Id: I7b6b39ab0c8a427b3166562c3f04cf4a7eaa20e2 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'tools')
-rw-r--r--tools/qmltc/qmltccodewriter.cpp8
-rw-r--r--tools/qmltc/qmltccompiler.cpp25
-rw-r--r--tools/qmltc/qmltcoutputir.h3
3 files changed, 29 insertions, 7 deletions
diff --git a/tools/qmltc/qmltccodewriter.cpp b/tools/qmltc/qmltccodewriter.cpp
index 7820af5ed8..68bd803b15 100644
--- a/tools/qmltc/qmltccodewriter.cpp
+++ b/tools/qmltc/qmltccodewriter.cpp
@@ -49,6 +49,7 @@ static QString getFunctionCategory(const QmltcMethod &method)
category += u" Q_SLOTS"_s;
break;
case QQmlJSMetaMethod::Method:
+ case QQmlJSMetaMethod::StaticMethod:
break;
}
return category;
@@ -287,6 +288,8 @@ void QmltcCodeWriter::write(QmltcOutputWrapper &code, const QmltcType &type)
// TODO: ignoreInit must be eliminated
QmltcCodeWriter::write(code, type.externalCtor);
+ if (type.staticCreate)
+ QmltcCodeWriter::write(code, *type.staticCreate);
}
// dtor
@@ -384,7 +387,10 @@ void QmltcCodeWriter::write(QmltcOutputWrapper &code, const QmltcMethod &method)
{
const auto [hSignature, cppSignature] = functionSignatures(method);
// Note: augment return type with preambles in declaration
- code.rawAppendToHeader(functionReturnType(method) + u" " + hSignature + u";");
+ code.rawAppendToHeader((method.type == QQmlJSMetaMethod::StaticMethod
+ ? u"static " + functionReturnType(method)
+ : functionReturnType(method))
+ + u" " + hSignature + u";");
// do not generate method implementation if it is a signal
const auto methodType = method.type;
diff --git a/tools/qmltc/qmltccompiler.cpp b/tools/qmltc/qmltccompiler.cpp
index ddb10879db..f7d06d8e9a 100644
--- a/tools/qmltc/qmltccompiler.cpp
+++ b/tools/qmltc/qmltccompiler.cpp
@@ -165,11 +165,6 @@ void QmltcCompiler::compileType(
QmltcType &current, const QQmlJSScope::ConstPtr &type,
std::function<void(QmltcType &, const QQmlJSScope::ConstPtr &)> compileElements)
{
- if (type->isSingleton()) {
- recordError(type->sourceLocation(), u"Singleton types are not supported"_s);
- return;
- }
-
Q_ASSERT(!type->internalName().isEmpty());
current.cppType = type->internalName();
Q_ASSERT(!type->baseType()->internalName().isEmpty());
@@ -182,6 +177,7 @@ void QmltcCompiler::compileType(
const bool documentRoot = (type == rootType);
const bool inlineComponent = type->isInlineComponent();
const bool isAnonymous = !documentRoot || type->internalName().at(0).isLower();
+ const bool isSingleton = type->isSingleton();
QmltcCodeGenerator generator { m_url, m_visitor };
@@ -231,7 +227,7 @@ void QmltcCompiler::compileType(
// add special member functions
current.baselineCtor.access = QQmlJSMetaMethod::Protected;
- if (documentRoot || inlineComponent) {
+ if (documentRoot || inlineComponent || isSingleton) {
current.externalCtor.access = QQmlJSMetaMethod::Public;
} else {
current.externalCtor.access = QQmlJSMetaMethod::Protected;
@@ -318,6 +314,23 @@ void QmltcCompiler::compileType(
+ u"(creator, engine, QQmlData::get(parent)->outerContext);";
}
+ if (isSingleton) {
+ // see https://doc.qt.io/qt-6/qqmlengine.html#QML_SINGLETON for context
+ current.mocCode.append(u"QML_SINGLETON"_s);
+ auto &staticCreate = current.staticCreate.emplace();
+ staticCreate.comments
+ << u"Used by the engine for singleton creation."_s
+ << u"See also \\l {https://doc.qt.io/qt-6/qqmlengine.html#QML_SINGLETON}."_s;
+ staticCreate.type = QQmlJSMetaMethod::StaticMethod;
+ staticCreate.access = QQmlJSMetaMethod::Public;
+ staticCreate.name = u"create"_s;
+ staticCreate.returnType = u"%1 *"_s.arg(current.cppType);
+ QmltcVariable jsEngine(u"QJSEngine*"_s, u"jsEngine"_s);
+ staticCreate.parameterList = { engine, jsEngine };
+ staticCreate.body << u"Q_UNUSED(jsEngine);"_s
+ << u"%1 *result = new %1(engine, nullptr);"_s.arg(current.cppType)
+ << u"return result;"_s;
+ }
auto postponedQmlContextSetup = generator.generate_initCode(current, type);
generator.generate_endInitCode(current, type);
generator.generate_setComplexBindingsCode(current, type);
diff --git a/tools/qmltc/qmltcoutputir.h b/tools/qmltc/qmltcoutputir.h
index 46f8e46ee8..8884ddc3a3 100644
--- a/tools/qmltc/qmltcoutputir.h
+++ b/tools/qmltc/qmltcoutputir.h
@@ -128,6 +128,9 @@ struct QmltcType
// TODO: only needed for binding callables - should not be needed, generally
bool ignoreInit = false; // specifies whether init and externalCtor should be ignored
+
+ // needed for singletons
+ std::optional<QmltcMethod> staticCreate{};
};
// Represents whole QML program, compiled to C++