diff options
author | Andrei Golubev <andrei.golubev@qt.io> | 2021-10-29 12:43:44 +0200 |
---|---|---|
committer | Andrei Golubev <andrei.golubev@qt.io> | 2021-11-17 18:04:41 +0100 |
commit | 590dd43c4d1bdb67a2db66081357390458f87de8 (patch) | |
tree | 3236800c2538b1940eb727d5498156588e9768b1 | |
parent | 06d99e4032ecd0611513d500d7c099ad9cb5d872 (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.txt | 1 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/data/typeWithEnums.qml | 10 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/tst_qmltc.cpp | 34 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/tst_qmltc.h | 1 | ||||
-rw-r--r-- | tools/qmltc/qmltccodewriter.cpp | 1 | ||||
-rw-r--r-- | tools/qmltc/qmltccompiler.cpp | 26 | ||||
-rw-r--r-- | tools/qmltc/qmltccompiler.h | 1 | ||||
-rw-r--r-- | tools/qmltc/qmltcoutputir.h | 5 |
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 ¤t, 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 ¤t, 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 ¤t, const QQmlJSScope::ConstPtr &type); + void compileEnum(QmltcType ¤t, 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) { } }; |