aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4function.cpp19
-rw-r--r--tests/auto/qml/qqmllanguage/data/badICAnnotation.qml25
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp34
3 files changed, 72 insertions, 6 deletions
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 2e51366d64..a853eac41d 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -154,16 +154,23 @@ Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit,
base->stringAt(type), typeLoader).type
: QQmlType();
- if (!qmltype.isValid() || qmltype.typeId().isValid())
+ if (!qmltype.isValid() || qmltype.isComposite())
return qmltype;
- if (!qmltype.isComposite()) {
- return qmltype.isInlineComponentType()
- ? base->qmlTypeForComponent(qmltype.elementName())
- : QQmlType();
+ if (qmltype.isInlineComponentType()) {
+ if (qmltype.typeId().isValid()) {
+ // If it seems to be an IC type, make sure there is an actual
+ // compilation unit for it. We create inline component types speculatively.
+ return QQmlMetaType::obtainCompilationUnit(qmltype.typeId())
+ ? qmltype
+ : QQmlType();
+ } else {
+ // TODO: Can this actually happen?
+ return base->qmlTypeForComponent(qmltype.elementName());
+ }
}
- return qmltype;
+ return qmltype.typeId().isValid() ? qmltype : QQmlType();
};
for (quint16 i = 0; i < nFormals; ++i)
diff --git a/tests/auto/qml/qqmllanguage/data/badICAnnotation.qml b/tests/auto/qml/qqmllanguage/data/badICAnnotation.qml
new file mode 100644
index 0000000000..6f0db53f2a
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/badICAnnotation.qml
@@ -0,0 +1,25 @@
+import QtQml
+
+QtObject {
+ id: self
+
+ function doStuff(status: Binding.NotAnInlineComponent) : int {
+ return status
+ }
+
+ function doStuff2(status: InlineComponentBase.IC) : QtObject {
+ return status
+ }
+
+ function doStuff3(status: InlineComponentBase.NotIC) : QtObject {
+ return status
+ }
+
+ property InlineComponentBase.IC ic: InlineComponentBase.IC {}
+
+ property int a: doStuff(5)
+ property QtObject b: doStuff2(ic)
+ property QtObject c: doStuff3(ic)
+ property QtObject d: doStuff2(self)
+}
+
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 66246b7a49..ec906e61df 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -443,6 +443,7 @@ private slots:
void ambiguousComponents();
void writeNumberToEnumAlias();
+ void badInlineComponentAnnotation();
private:
QQmlEngine engine;
@@ -8512,6 +8513,39 @@ void tst_qqmllanguage::writeNumberToEnumAlias()
QCOMPARE(o->property("strokeStyle").toInt(), 1);
}
+void tst_qqmllanguage::badInlineComponentAnnotation()
+{
+ QQmlEngine engine;
+ const QUrl url = testFileUrl("badICAnnotation.qml");
+ QQmlComponent c(&engine, testFileUrl("badICAnnotation.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+
+ QTest::ignoreMessage(
+ QtCriticalMsg,
+ qPrintable(url.toString() + ":20: 5 should be coerced to void because the function "
+ "called is insufficiently annotated. The original "
+ "value is retained. This will change in a future "
+ "version of Qt."));
+ QTest::ignoreMessage(
+ QtCriticalMsg,
+ QRegularExpression(":22: IC\\([^\\)]+\\) should be coerced to void because the "
+ "function called is insufficiently annotated. The original "
+ "value is retained. This will change in a future version of "
+ "Qt\\."));
+
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+
+ QCOMPARE(o->property("a").toInt(), 5);
+
+ QObject *ic = o->property("ic").value<QObject *>();
+ QVERIFY(ic);
+
+ QCOMPARE(o->property("b").value<QObject *>(), ic);
+ QCOMPARE(o->property("c").value<QObject *>(), ic);
+ QCOMPARE(o->property("d").value<QObject *>(), nullptr);
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"