aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Golubev <andrei.golubev@qt.io>2021-10-29 12:43:44 +0200
committerAndrei Golubev <andrei.golubev@qt.io>2021-11-17 18:04:41 +0100
commit590dd43c4d1bdb67a2db66081357390458f87de8 (patch)
tree3236800c2538b1940eb727d5498156588e9768b1
parent06d99e4032ecd0611513d500d7c099ad9cb5d872 (diff)
qmltc: Compile QML enums into C++
Task-number: QTBUG-84368 Change-Id: Idf6c724496c807477ce0914ab0d32a80a9b90b5a Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--tests/auto/qml/qmltc/CMakeLists.txt1
-rw-r--r--tests/auto/qml/qmltc/data/typeWithEnums.qml10
-rw-r--r--tests/auto/qml/qmltc/tst_qmltc.cpp34
-rw-r--r--tests/auto/qml/qmltc/tst_qmltc.h1
-rw-r--r--tools/qmltc/qmltccodewriter.cpp1
-rw-r--r--tools/qmltc/qmltccompiler.cpp26
-rw-r--r--tools/qmltc/qmltccompiler.h1
-rw-r--r--tools/qmltc/qmltcoutputir.h5
8 files changed, 77 insertions, 2 deletions
diff --git a/tests/auto/qml/qmltc/CMakeLists.txt b/tests/auto/qml/qmltc/CMakeLists.txt
index 66d1e4bf01..f7f33fe214 100644
--- a/tests/auto/qml/qmltc/CMakeLists.txt
+++ b/tests/auto/qml/qmltc/CMakeLists.txt
@@ -9,6 +9,7 @@ set(qml_sources
data/HelloWorld.qml
data/NameConflict.qml
data/simpleQtQuickTypes.qml
+ data/typeWithEnums.qml
)
set_source_files_properties(data/NameConflict.qml PROPERTIES
diff --git a/tests/auto/qml/qmltc/data/typeWithEnums.qml b/tests/auto/qml/qmltc/data/typeWithEnums.qml
new file mode 100644
index 0000000000..7aaad03562
--- /dev/null
+++ b/tests/auto/qml/qmltc/data/typeWithEnums.qml
@@ -0,0 +1,10 @@
+import QtQml
+QtObject {
+ enum NoValuesSpecified {
+ A, B, C, D
+ }
+
+ enum ValuesSpecified {
+ A_ = 1, B_, B2_, C_ = 41, D_
+ }
+}
diff --git a/tests/auto/qml/qmltc/tst_qmltc.cpp b/tests/auto/qml/qmltc/tst_qmltc.cpp
index d9a5ca06e1..19e32e7941 100644
--- a/tests/auto/qml/qmltc/tst_qmltc.cpp
+++ b/tests/auto/qml/qmltc/tst_qmltc.cpp
@@ -32,6 +32,7 @@
#include "ResolvedNameConflict.h"
#include "helloworld.h"
#include "simpleqtquicktypes.h"
+#include "typewithenums.h"
// Qt:
#include <QtCore/qstring.h>
@@ -72,6 +73,8 @@ void tst_qmltc::initTestCase()
QUrl urls[] = {
QUrl("qrc:/QmltcTests/data/NameConflict.qml"),
QUrl("qrc:/QmltcTests/data/HelloWorld.qml"),
+ QUrl("qrc:/QmltcTests/data/simpleQtQuickTypes.qml"),
+ QUrl("qrc:/QmltcTests/data/typeWithEnums.qml"),
};
QQmlEngine e;
@@ -109,4 +112,35 @@ void tst_qmltc::qtQuickIncludes()
QCOMPARE(mo->classInfo(mo->indexOfClassInfo("QML.Element")).value(), "anonymous");
}
+void tst_qmltc::enumerations()
+{
+ QQmlEngine e;
+ PREPEND_NAMESPACE(typeWithEnums) created(&e);
+
+ // sanity
+ QCOMPARE(PREPEND_NAMESPACE(typeWithEnums)::NoValuesSpecified::A, 0);
+ QCOMPARE(PREPEND_NAMESPACE(typeWithEnums)::NoValuesSpecified::B, 1);
+ QCOMPARE(PREPEND_NAMESPACE(typeWithEnums)::NoValuesSpecified::C, 2);
+ QCOMPARE(PREPEND_NAMESPACE(typeWithEnums)::NoValuesSpecified::D, 3);
+
+ QCOMPARE(PREPEND_NAMESPACE(typeWithEnums)::ValuesSpecified::A_, 1);
+ QCOMPARE(PREPEND_NAMESPACE(typeWithEnums)::ValuesSpecified::B_, 2);
+ QCOMPARE(PREPEND_NAMESPACE(typeWithEnums)::ValuesSpecified::B2_, 3);
+ QCOMPARE(PREPEND_NAMESPACE(typeWithEnums)::ValuesSpecified::C_, 41);
+ QCOMPARE(PREPEND_NAMESPACE(typeWithEnums)::ValuesSpecified::D_, 42);
+
+ const QMetaObject *mo = created.metaObject();
+ const QMetaEnum enumerator1 = mo->enumerator(mo->indexOfEnumerator("NoValuesSpecified"));
+ QCOMPARE(enumerator1.enumName(), "NoValuesSpecified");
+ QCOMPARE(enumerator1.keyCount(), 4);
+ QCOMPARE(enumerator1.key(2), "C");
+ QCOMPARE(enumerator1.value(2), PREPEND_NAMESPACE(typeWithEnums)::NoValuesSpecified::C);
+
+ const QMetaEnum enumerator2 = mo->enumerator(mo->indexOfEnumerator("ValuesSpecified"));
+ QCOMPARE(enumerator2.enumName(), "ValuesSpecified");
+ QCOMPARE(enumerator2.keyCount(), 5);
+ QCOMPARE(enumerator2.key(2), "B2_");
+ QCOMPARE(enumerator2.value(2), PREPEND_NAMESPACE(typeWithEnums)::ValuesSpecified::B2_);
+}
+
QTEST_MAIN(tst_qmltc)
diff --git a/tests/auto/qml/qmltc/tst_qmltc.h b/tests/auto/qml/qmltc/tst_qmltc.h
index 2680aefac8..23c2d383c4 100644
--- a/tests/auto/qml/qmltc/tst_qmltc.h
+++ b/tests/auto/qml/qmltc/tst_qmltc.h
@@ -47,4 +47,5 @@ private slots:
void qmlNameConflictResolution();
void helloWorld();
void qtQuickIncludes();
+ void enumerations();
};
diff --git a/tools/qmltc/qmltccodewriter.cpp b/tools/qmltc/qmltccodewriter.cpp
index 7ce489c899..dff4885604 100644
--- a/tools/qmltc/qmltccodewriter.cpp
+++ b/tools/qmltc/qmltccodewriter.cpp
@@ -302,6 +302,7 @@ void QmltcCodeWriter::write(QmltcOutputWrapper &code, const QmltcEnum &enumerati
code.rawAppendToHeader(str, 1);
}
code.rawAppendToHeader(u"};");
+ code.rawAppendToHeader(enumeration.ownMocLine);
}
void QmltcCodeWriter::write(QmltcOutputWrapper &code, const QmltcMethod &method)
diff --git a/tools/qmltc/qmltccompiler.cpp b/tools/qmltc/qmltccompiler.cpp
index 4654ecfd20..0aeff12217 100644
--- a/tools/qmltc/qmltccompiler.cpp
+++ b/tools/qmltc/qmltccompiler.cpp
@@ -31,6 +31,8 @@
#include "qmltccodewriter.h"
#include <QtCore/qloggingcategory.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQmltcCompiler, "qml.qmltc.compiler", QtWarningMsg);
@@ -192,6 +194,30 @@ void QmltcCompiler::compileType(QmltcType &current, const QQmlJSScope::ConstPtr
+ u"(creator, engine, QQmlData::get(parent)->outerContext);";
}
current.init.body << u"return nullptr;"_qs;
+
+ // compile components of a type:
+ // - enums
+ // - properties
+ // - methods
+ // - bindings
+
+ const auto enums = type->ownEnumerations();
+ current.enums.reserve(enums.size());
+ for (auto it = enums.begin(); it != enums.end(); ++it)
+ compileEnum(current, it.value());
+}
+
+void QmltcCompiler::compileEnum(QmltcType &current, const QQmlJSMetaEnum &e)
+{
+ const auto intValues = e.values();
+ QStringList values;
+ values.reserve(intValues.size());
+ std::transform(intValues.cbegin(), intValues.cend(), std::back_inserter(values),
+ [](int x) { return QString::number(x); });
+
+ // structure: (C++ type name, enum keys, enum values, MOC line)
+ current.enums.emplaceBack(e.name(), e.keys(), std::move(values),
+ u"Q_ENUM(%1)"_qs.arg(e.name()));
}
QT_END_NAMESPACE
diff --git a/tools/qmltc/qmltccompiler.h b/tools/qmltc/qmltccompiler.h
index e59cc116f4..8d2f360d75 100644
--- a/tools/qmltc/qmltccompiler.h
+++ b/tools/qmltc/qmltccompiler.h
@@ -64,6 +64,7 @@ private:
QmltcCompilerInfo m_info {}; // miscellaneous input/output information
void compileType(QmltcType &current, const QQmlJSScope::ConstPtr &type);
+ void compileEnum(QmltcType &current, const QQmlJSMetaEnum &e);
bool hasErrors() const { return m_logger->hasErrors(); } // TODO: count warnings as errors?
void recordError(const QQmlJS::SourceLocation &location, const QString &message,
diff --git a/tools/qmltc/qmltcoutputir.h b/tools/qmltc/qmltcoutputir.h
index c299f283a8..067fb1bd43 100644
--- a/tools/qmltc/qmltcoutputir.h
+++ b/tools/qmltc/qmltcoutputir.h
@@ -64,10 +64,11 @@ struct QmltcEnum
QString cppType; // C++ type of an enum
QStringList keys; // enumerator keys
QStringList values; // enumerator values
+ QString ownMocLine; // special MOC line that follows enum declaration
QmltcEnum() = default;
- QmltcEnum(const QString &t, const QStringList &ks, const QStringList &vs)
- : cppType(t), keys(ks), values(vs)
+ QmltcEnum(const QString &t, const QStringList &ks, const QStringList &vs, const QString &l)
+ : cppType(t), keys(ks), values(vs), ownMocLine(l)
{
}
};