aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Golubev <andrei.golubev@qt.io>2021-07-19 16:32:18 +0200
committerAndrei Golubev <andrei.golubev@qt.io>2021-07-21 12:27:02 +0200
commit531c757f300119d237bab5e72ccb762b7ed86e19 (patch)
tree7c68d712a18460a00645685fd43f0f3787507306
parent0ac3ed4782b3bfb81a17c7f3061746a6ec804262 (diff)
Align qmllint default property handling with QQmlComponent model
Make qmllint work on default properties that come from the base type of the scope and not from the scope itself. Otherwise, cases like: QtObject { default property QtObject child QtObject {} } become valid in qmllint (and related tooling), while this code produces an error when QQmlComponent reads it Change-Id: I347a2753b8674e53aaad6febb239c44089f08a8a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit df351e07396429b9eab35eec0cb8c0271b2b6bcf)
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor.cpp16
-rw-r--r--tests/auto/qml/qmllint/data/TypeWithDefaultListProperty.qml4
-rw-r--r--tests/auto/qml/qmllint/data/TypeWithDefaultProperty.qml4
-rw-r--r--tests/auto/qml/qmllint/data/TypeWithDefaultStringProperty.qml4
-rw-r--r--tests/auto/qml/qmllint/data/TypeWithDefaultVarProperty.qml4
-rw-r--r--tests/auto/qml/qmllint/data/defaultProperty.qml3
-rw-r--r--tests/auto/qml/qmllint/data/defaultPropertyList.qml3
-rw-r--r--tests/auto/qml/qmllint/data/defaultPropertyVar.qml4
-rw-r--r--tests/auto/qml/qmllint/data/defaultPropertyWithDoubleAssignment.qml3
-rw-r--r--tests/auto/qml/qmllint/data/defaultPropertyWithWrongType.qml4
-rw-r--r--tests/auto/qml/qmllint/data/defaultPropertyWithinTheSameType.qml6
-rw-r--r--tests/auto/qml/qmllint/data/qmldirImport/QtObjectWithDefaultProperty.qml4
-rw-r--r--tests/auto/qml/qmllint/data/qmldirImport/duplicate.qml4
-rw-r--r--tests/auto/qml/qmllint/data/qmldirImportAndDepend/QtObjectWithDefaultProperty.qml4
-rw-r--r--tests/auto/qml/qmllint/data/qmldirImportAndDepend/good.qml3
-rw-r--r--tests/auto/qml/qmllint/tst_qmllint.cpp8
16 files changed, 56 insertions, 22 deletions
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp
index 4aaf294835..3a3fd5d2ce 100644
--- a/src/qmlcompiler/qqmljsimportvisitor.cpp
+++ b/src/qmlcompiler/qqmljsimportvisitor.cpp
@@ -402,11 +402,19 @@ void QQmlJSImportVisitor::processDefaultProperties()
const QQmlJSScope *scopeOfDefaultProperty = nullptr;
QString defaultPropertyName;
- // NB: start looking for default property in parent scope (because this
- // scope is not suitable), but progress through baseType()
-
bool isComponent = false;
- for (const auto *s = it.key().get(); s; s = s->baseType().get()) {
+ /* consider:
+ *
+ * QtObject { // <- it.key()
+ * default property var p // (1)
+ * QtObject {} // (2)
+ * }
+ *
+ * `p` (1) is a property of a subtype of QtObject, it couldn't be used
+ * in a property binding (2)
+ */
+ // thus, use a base type of it.key() to detect a default property
+ for (const auto *s = it.key()->baseType().get(); s; s = s->baseType().get()) {
defaultPropertyName = s->defaultPropertyName();
if (!defaultPropertyName.isEmpty()) {
scopeOfDefaultProperty = s;
diff --git a/tests/auto/qml/qmllint/data/TypeWithDefaultListProperty.qml b/tests/auto/qml/qmllint/data/TypeWithDefaultListProperty.qml
new file mode 100644
index 0000000000..e30314a825
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/TypeWithDefaultListProperty.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ default property list<QtObject> children
+}
diff --git a/tests/auto/qml/qmllint/data/TypeWithDefaultProperty.qml b/tests/auto/qml/qmllint/data/TypeWithDefaultProperty.qml
new file mode 100644
index 0000000000..e64befb764
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/TypeWithDefaultProperty.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ default property QtObject child
+}
diff --git a/tests/auto/qml/qmllint/data/TypeWithDefaultStringProperty.qml b/tests/auto/qml/qmllint/data/TypeWithDefaultStringProperty.qml
new file mode 100644
index 0000000000..98c446870c
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/TypeWithDefaultStringProperty.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ default property string child
+}
diff --git a/tests/auto/qml/qmllint/data/TypeWithDefaultVarProperty.qml b/tests/auto/qml/qmllint/data/TypeWithDefaultVarProperty.qml
new file mode 100644
index 0000000000..9fa89833d5
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/TypeWithDefaultVarProperty.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ default property var child
+}
diff --git a/tests/auto/qml/qmllint/data/defaultProperty.qml b/tests/auto/qml/qmllint/data/defaultProperty.qml
index 6284cca15c..be9368c7aa 100644
--- a/tests/auto/qml/qmllint/data/defaultProperty.qml
+++ b/tests/auto/qml/qmllint/data/defaultProperty.qml
@@ -1,6 +1,5 @@
import QtQml 2.0
-QtObject {
- default property QtObject child
+TypeWithDefaultProperty {
QtObject {}
}
diff --git a/tests/auto/qml/qmllint/data/defaultPropertyList.qml b/tests/auto/qml/qmllint/data/defaultPropertyList.qml
index fd4f0f7f98..ebf6357c34 100644
--- a/tests/auto/qml/qmllint/data/defaultPropertyList.qml
+++ b/tests/auto/qml/qmllint/data/defaultPropertyList.qml
@@ -1,8 +1,7 @@
import QtQml 2.0
import QtQuick 2.15
-QtObject {
- default property list<QtObject> children
+TypeWithDefaultListProperty {
QtObject {}
Rectangle {}
}
diff --git a/tests/auto/qml/qmllint/data/defaultPropertyVar.qml b/tests/auto/qml/qmllint/data/defaultPropertyVar.qml
index 7aac1a9a75..1202d5384d 100644
--- a/tests/auto/qml/qmllint/data/defaultPropertyVar.qml
+++ b/tests/auto/qml/qmllint/data/defaultPropertyVar.qml
@@ -1,7 +1,5 @@
import QtQml 2.0
-QtObject {
- default property var child
-
+TypeWithDefaultVarProperty {
QtObject {}
}
diff --git a/tests/auto/qml/qmllint/data/defaultPropertyWithDoubleAssignment.qml b/tests/auto/qml/qmllint/data/defaultPropertyWithDoubleAssignment.qml
index af05983f02..8c2d09fb97 100644
--- a/tests/auto/qml/qmllint/data/defaultPropertyWithDoubleAssignment.qml
+++ b/tests/auto/qml/qmllint/data/defaultPropertyWithDoubleAssignment.qml
@@ -1,7 +1,6 @@
import QtQml 2.0
-QtObject {
- default property QtObject child
+TypeWithDefaultProperty {
QtObject {}
QtObject {}
}
diff --git a/tests/auto/qml/qmllint/data/defaultPropertyWithWrongType.qml b/tests/auto/qml/qmllint/data/defaultPropertyWithWrongType.qml
index b846e24790..d04fecda49 100644
--- a/tests/auto/qml/qmllint/data/defaultPropertyWithWrongType.qml
+++ b/tests/auto/qml/qmllint/data/defaultPropertyWithWrongType.qml
@@ -1,6 +1,6 @@
import QtQml 2.0
-QtObject {
- default property string child
+TypeWithDefaultStringProperty {
+ // default property has type `string`, so cannot assing an object to it
QtObject {}
}
diff --git a/tests/auto/qml/qmllint/data/defaultPropertyWithinTheSameType.qml b/tests/auto/qml/qmllint/data/defaultPropertyWithinTheSameType.qml
new file mode 100644
index 0000000000..6284cca15c
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/defaultPropertyWithinTheSameType.qml
@@ -0,0 +1,6 @@
+import QtQml 2.0
+
+QtObject {
+ default property QtObject child
+ QtObject {}
+}
diff --git a/tests/auto/qml/qmllint/data/qmldirImport/QtObjectWithDefaultProperty.qml b/tests/auto/qml/qmllint/data/qmldirImport/QtObjectWithDefaultProperty.qml
new file mode 100644
index 0000000000..d33d0b5c94
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/qmldirImport/QtObjectWithDefaultProperty.qml
@@ -0,0 +1,4 @@
+import DuplicateImport // imports QtQml
+QtObject {
+ default property QtObject child
+}
diff --git a/tests/auto/qml/qmllint/data/qmldirImport/duplicate.qml b/tests/auto/qml/qmllint/data/qmldirImport/duplicate.qml
index 0040e67f7c..22f454ad44 100644
--- a/tests/auto/qml/qmllint/data/qmldirImport/duplicate.qml
+++ b/tests/auto/qml/qmllint/data/qmldirImport/duplicate.qml
@@ -1,8 +1,6 @@
import DuplicateImport // imports QtQml directly and indirectly via QtQuick
-QtObject {
- default property QtObject child
-
+QtObjectWithDefaultProperty { // for default property
ItemDerived { // item derived has compatible QtObject type
x: 4
}
diff --git a/tests/auto/qml/qmllint/data/qmldirImportAndDepend/QtObjectWithDefaultProperty.qml b/tests/auto/qml/qmllint/data/qmldirImportAndDepend/QtObjectWithDefaultProperty.qml
new file mode 100644
index 0000000000..fb856d0b29
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/qmldirImportAndDepend/QtObjectWithDefaultProperty.qml
@@ -0,0 +1,4 @@
+import Things // imports QtQml
+QtObject {
+ default property QtObject child
+}
diff --git a/tests/auto/qml/qmllint/data/qmldirImportAndDepend/good.qml b/tests/auto/qml/qmllint/data/qmldirImportAndDepend/good.qml
index 4e97bd6a64..987301ef76 100644
--- a/tests/auto/qml/qmllint/data/qmldirImportAndDepend/good.qml
+++ b/tests/auto/qml/qmllint/data/qmldirImportAndDepend/good.qml
@@ -1,7 +1,6 @@
import Things
-QtObject {
- default property QtObject child
+QtObjectWithDefaultProperty { // for default property
objectName: "QtQml was imported from Things/qmldir"
ItemDerived {
diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp
index a2cdcb07b8..79225d92de 100644
--- a/tests/auto/qml/qmllint/tst_qmllint.cpp
+++ b/tests/auto/qml/qmllint/tst_qmllint.cpp
@@ -510,8 +510,12 @@ void TestQmllint::dirtyQmlCode_data()
<< false;
QTest::newRow("MissingDefaultProperty")
<< QStringLiteral("defaultPropertyWithoutKeyword.qml")
- << QStringLiteral("Cannot assign to non-existent default property") << QString() << false;
-
+ << QStringLiteral("Cannot assign to non-existent default property") << QString()
+ << false;
+ QTest::newRow("MissingDefaultPropertyDefinedInTheSameType")
+ << QStringLiteral("defaultPropertyWithinTheSameType.qml")
+ << QStringLiteral("Cannot assign to non-existent default property") << QString()
+ << false;
QTest::newRow("DoubleAssignToDefaultProperty")
<< QStringLiteral("defaultPropertyWithDoubleAssignment.qml")
<< QStringLiteral("Cannot assign multiple objects to a default non-list property")