diff options
| -rw-r--r-- | src/qmlcompiler/qqmljsimportvisitor.cpp | 21 | ||||
| -rw-r--r-- | tests/auto/qml/qmlcachegen/data/crashes/buggyFixSuggestion.qml | 25 | ||||
| -rw-r--r-- | tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp | 54 |
3 files changed, 90 insertions, 10 deletions
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp index 5e3db1b2bd..b55dbb4d60 100644 --- a/src/qmlcompiler/qqmljsimportvisitor.cpp +++ b/src/qmlcompiler/qqmljsimportvisitor.cpp @@ -1055,16 +1055,17 @@ void QQmlJSImportVisitor::checkRequiredProperties() : u"here"_s; if (!prevRequiredScope.isNull()) { - auto sourceScope = prevRequiredScope->baseType(); - suggestion = QQmlJSFixSuggestion{ - "%1:%2:%3: Property marked as required in %4."_L1 - .arg(sourceScope->filePath()) - .arg(sourceScope->sourceLocation().startLine) - .arg(sourceScope->sourceLocation().startColumn) - .arg(requiredScopeName), - sourceScope->sourceLocation() - }; - suggestion->setFilename(sourceScope->filePath()); + if (auto sourceScope = prevRequiredScope->baseType()) { + suggestion = QQmlJSFixSuggestion{ + "%1:%2:%3: Property marked as required in %4."_L1 + .arg(sourceScope->filePath()) + .arg(sourceScope->sourceLocation().startLine) + .arg(sourceScope->sourceLocation().startColumn) + .arg(requiredScopeName), + sourceScope->sourceLocation() + }; + suggestion->setFilename(sourceScope->filePath()); + } } else { message += " (marked as required by %1)"_L1.arg(requiredScopeName); } diff --git a/tests/auto/qml/qmlcachegen/data/crashes/buggyFixSuggestion.qml b/tests/auto/qml/qmlcachegen/data/crashes/buggyFixSuggestion.qml new file mode 100644 index 0000000000..f435d2ec4a --- /dev/null +++ b/tests/auto/qml/qmlcachegen/data/crashes/buggyFixSuggestion.qml @@ -0,0 +1,25 @@ +import QtQuick + +Item { + id: root + + Item { + id: inner + + Tumbler { + id: year + + delegate: Rectangle { + required property var modelData + } + } + + Tumbler { + id: month + + delegate: Rectangle { + required property var modelData + } + } + } +} diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp index 653556a213..21e76a4ab5 100644 --- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp +++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp @@ -74,6 +74,9 @@ private slots: void aotstatsGeneration_data(); void aotstatsGeneration(); void aotstatsFormatRevisionMissmatch(); + + void crash_data(); + void crash(); }; // A wrapper around QQmlComponent to ensure the temporary reference counts @@ -122,6 +125,36 @@ static bool generateCache(const QString &qmlFileName, QByteArray *capturedStderr return proc.exitCode() == 0; } +static bool generateCpp(const QString &qmlFileName, QByteArray *capturedStderr = nullptr) +{ +#if defined(QTEST_CROSS_COMPILED) + QTest::qFail("You cannot call qmlcachegen on the target.", __FILE__, __LINE__); + return false; +#endif + QProcess proc; + if (capturedStderr == nullptr) + proc.setProcessChannelMode(QProcess::ForwardedChannels); + proc.setProgram(QLibraryInfo::path(QLibraryInfo::LibraryExecutablesPath) + + QLatin1String("/qmlcachegen")); + QTemporaryDir outputDir; + const QString outputFile = outputDir.filePath("output.cpp"_L1); + proc.setArguments(QStringList{ "--resource-path"_L1, "qrc:/qt/qml/Crashes/testFile.qml"_L1, + "-o"_L1, outputFile, qmlFileName }); + proc.start(); + if (!proc.waitForFinished()) + return false; + + if (capturedStderr) + *capturedStderr = proc.readAllStandardError(); + + if (!QFile::exists(outputFile)) + return false; + + if (proc.exitStatus() != QProcess::NormalExit) + return false; + return proc.exitCode() == 0; +} + tst_qmlcachegen::tst_qmlcachegen() : QQmlDataTest(QT_QMLTEST_DATADIR) { @@ -1049,6 +1082,27 @@ void tst_qmlcachegen::aotstatsFormatRevisionMissmatch() QVERIFY(!QQmlJS::AotStats::fromJsonDocument(document).has_value()); } +void tst_qmlcachegen::crash_data() +{ + QTest::addColumn<QString>("fileName"); + + QTest::addRow("buggyFixSuggestion") << u"buggyFixSuggestion.qml"_s; +} + +void tst_qmlcachegen::crash() +{ +#if defined(QTEST_CROSS_COMPILED) + QSKIP("Cannot call qmlcachegen on cross-compiled target."); +#endif + + QFETCH(QString, fileName); + const QString filePath = testFile("crashes/" + fileName); + + QFile file(filePath); + QVERIFY(file.exists()); + QVERIFY(generateCpp(filePath)); +} + const QQmlScriptString &ScriptStringProps::undef() const { return m_undef; |
