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 Pick-to: 6.2 Change-Id: I347a2753b8674e53aaad6febb239c44089f08a8a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
24bff37f9e
commit
df351e0739
|
@ -416,13 +416,27 @@ void QQmlJSImportVisitor::processDefaultProperties()
|
||||||
{
|
{
|
||||||
for (auto it = m_pendingDefaultProperties.constBegin();
|
for (auto it = m_pendingDefaultProperties.constBegin();
|
||||||
it != m_pendingDefaultProperties.constEnd(); ++it) {
|
it != m_pendingDefaultProperties.constEnd(); ++it) {
|
||||||
const QQmlJSScope::ConstPtr parentScope = it.key();
|
QQmlJSScope::ConstPtr parentScope = it.key();
|
||||||
|
|
||||||
// We can't expect custom parser default properties to be sensible, discard them for now.
|
// We can't expect custom parser default properties to be sensible, discard them for now.
|
||||||
if (parentScope->isInCustomParserParent())
|
if (parentScope->isInCustomParserParent())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const QString defaultPropertyName = parentScope->defaultPropertyName();
|
/* consider:
|
||||||
|
*
|
||||||
|
* QtObject { // <- parentScope
|
||||||
|
* 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 parent scope to detect a default property
|
||||||
|
parentScope = parentScope->baseType();
|
||||||
|
|
||||||
|
const QString defaultPropertyName =
|
||||||
|
parentScope ? parentScope->defaultPropertyName() : QString();
|
||||||
|
|
||||||
if (defaultPropertyName.isEmpty()) {
|
if (defaultPropertyName.isEmpty()) {
|
||||||
// If the parent scope is based on Component it can have any child element
|
// If the parent scope is based on Component it can have any child element
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
import QtQml 2.0
|
||||||
|
QtObject {
|
||||||
|
default property list<QtObject> children
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
import QtQml 2.0
|
||||||
|
QtObject {
|
||||||
|
default property QtObject child
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
import QtQml 2.0
|
||||||
|
QtObject {
|
||||||
|
default property string child
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
import QtQml 2.0
|
||||||
|
QtObject {
|
||||||
|
default property var child
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
import QtQml 2.0
|
import QtQml 2.0
|
||||||
|
|
||||||
QtObject {
|
TypeWithDefaultProperty {
|
||||||
default property QtObject child
|
|
||||||
QtObject {}
|
QtObject {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import QtQml 2.0
|
import QtQml 2.0
|
||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
|
|
||||||
QtObject {
|
TypeWithDefaultListProperty {
|
||||||
default property list<QtObject> children
|
|
||||||
QtObject {}
|
QtObject {}
|
||||||
Rectangle {}
|
Rectangle {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import QtQml 2.0
|
import QtQml 2.0
|
||||||
|
|
||||||
QtObject {
|
TypeWithDefaultVarProperty {
|
||||||
default property var child
|
|
||||||
|
|
||||||
QtObject {}
|
QtObject {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import QtQml 2.0
|
import QtQml 2.0
|
||||||
|
|
||||||
QtObject {
|
TypeWithDefaultProperty {
|
||||||
default property QtObject child
|
|
||||||
QtObject {}
|
QtObject {}
|
||||||
QtObject {}
|
QtObject {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import QtQml 2.0
|
import QtQml 2.0
|
||||||
|
|
||||||
QtObject {
|
TypeWithDefaultStringProperty {
|
||||||
default property string child
|
// default property has type `string`, so cannot assing an object to it
|
||||||
QtObject {}
|
QtObject {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
import QtQml 2.0
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
default property QtObject child
|
||||||
|
QtObject {}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
import DuplicateImport // imports QtQml
|
||||||
|
QtObject {
|
||||||
|
default property QtObject child
|
||||||
|
}
|
|
@ -1,8 +1,6 @@
|
||||||
import DuplicateImport // imports QtQml directly and indirectly via QtQuick
|
import DuplicateImport // imports QtQml directly and indirectly via QtQuick
|
||||||
|
|
||||||
QtObject {
|
QtObjectWithDefaultProperty { // for default property
|
||||||
default property QtObject child
|
|
||||||
|
|
||||||
ItemDerived { // item derived has compatible QtObject type
|
ItemDerived { // item derived has compatible QtObject type
|
||||||
x: 4
|
x: 4
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
import Things // imports QtQml
|
||||||
|
QtObject {
|
||||||
|
default property QtObject child
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
import Things
|
import Things
|
||||||
|
|
||||||
QtObject {
|
QtObjectWithDefaultProperty { // for default property
|
||||||
default property QtObject child
|
|
||||||
objectName: "QtQml was imported from Things/qmldir"
|
objectName: "QtQml was imported from Things/qmldir"
|
||||||
|
|
||||||
ItemDerived {
|
ItemDerived {
|
||||||
|
|
|
@ -508,8 +508,12 @@ void TestQmllint::dirtyQmlCode_data()
|
||||||
<< false;
|
<< false;
|
||||||
QTest::newRow("MissingDefaultProperty")
|
QTest::newRow("MissingDefaultProperty")
|
||||||
<< QStringLiteral("defaultPropertyWithoutKeyword.qml")
|
<< 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")
|
QTest::newRow("DoubleAssignToDefaultProperty")
|
||||||
<< QStringLiteral("defaultPropertyWithDoubleAssignment.qml")
|
<< QStringLiteral("defaultPropertyWithDoubleAssignment.qml")
|
||||||
<< QStringLiteral("Cannot assign multiple objects to a default non-list property")
|
<< QStringLiteral("Cannot assign multiple objects to a default non-list property")
|
||||||
|
|
Loading…
Reference in New Issue