qmllint: Exclude children of custom parser elements from warnings

Some warnings caused by the children of custom parser elements also need to be ignored.

Change-Id: Iff3c6e5ce2ea334c6de7a14c8592ee1ebf80bb58
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Maximilian Goldstein 2021-04-30 10:02:23 +02:00
parent 3464655f5e
commit 56c16d0e97
6 changed files with 53 additions and 5 deletions

View File

@ -861,8 +861,12 @@ void QQmlJSImportVisitor::endVisit(QQmlJS::AST::UiObjectBinding *uiob)
const QString propertyName = group->name.toString();
QQmlJSMetaProperty property = m_currentScope->property(propertyName);
if (property.isValid() && !property.type().isNull()
&& (uiob->hasOnToken || property.type()->canAssign(childScope))) {
if (m_currentScope->isInCustomParserParent()) {
// These warnings do not apply for custom parsers and their children and need to be handled
// on a case by case basis
} else if (property.isValid() && !property.type().isNull()
&& (uiob->hasOnToken || property.type()->canAssign(childScope))) {
QQmlJSMetaPropertyBinding binding = m_currentScope->hasOwnPropertyBinding(propertyName)
? m_currentScope->ownPropertyBinding(propertyName)

View File

@ -493,4 +493,14 @@ bool QQmlJSScope::canAssign(const QQmlJSScope::ConstPtr &derived) const
return internalName() == u"QVariant"_qs || internalName() == u"QJSValue"_qs;
}
bool QQmlJSScope::isInCustomParserParent() const
{
for (const auto *scope = this; scope; scope = scope->parentScope().get()) {
if (!scope->baseType().isNull() && scope->baseType()->hasCustomParser())
return true;
}
return false;
}
QT_END_NAMESPACE

View File

@ -355,6 +355,12 @@ public:
*/
bool canAssign(const QQmlJSScope::ConstPtr &derived) const;
/*!
\internal
Checks whether this type or its parents have a custom parser.
*/
bool isInCustomParserParent() const;
private:
QQmlJSScope(ScopeType type, const QQmlJSScope::Ptr &parentScope = QQmlJSScope::Ptr());

View File

@ -0,0 +1,16 @@
import QtQuick 2.0
ListModel {
id: listModel
ListElement { dataType: "rect"; color: "green"; font.color: "red"; ListElement {} Behavior on FooBar {} }
ListElement { dataType: "image"; source: "../shared/images/qt-logo.png" }
ListElement { dataType: "rect"; color: "green" }
ListElement { dataType: "image"; source: "../shared/images/qt-logo.png" }
ListElement { dataType: "rect"; color: "blue" }
ListElement { dataType: "rect"; color: "blue" }
ListElement { dataType: "rect"; color: "blue" }
ListElement { dataType: "rect"; color: "blue" }
ListElement { dataType: "rect"; color: "blue" }
ListElement { dataType: "rect"; color: "blue" }
}

View File

@ -738,6 +738,7 @@ void TestQmllint::cleanQmlCode_data()
QTest::newRow("propertyOverride") << QStringLiteral("propertyOverride.qml");
QTest::newRow("propertyBindingValue") << QStringLiteral("propertyBindingValue.qml");
QTest::newRow("customParser") << QStringLiteral("customParser.qml");
QTest::newRow("customParser.recursive") << QStringLiteral("customParser.recursive.qml");
QTest::newRow("2Behavior") << QStringLiteral("2behavior.qml");
QTest::newRow("interceptor") << QStringLiteral("interceptor.qml");
QTest::newRow("valueSource") << QStringLiteral("valueSource.qml");

View File

@ -99,6 +99,11 @@ void FindWarningVisitor::checkInheritanceCycle(QQmlJSScope::ConstPtr scope)
void FindWarningVisitor::checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope)
{
// These warnings do not apply for custom parsers and their children and need to be handled on a
// case by case basis
if (scope->isInCustomParserParent())
return;
auto children = scope->childScopes();
while (!children.isEmpty()) {
auto childScope = children.takeFirst();
@ -142,6 +147,11 @@ void FindWarningVisitor::checkDefaultProperty(const QQmlJSScope::ConstPtr &scope
if (scope == m_exportedRootScope || scope->isArrayScope()) // inapplicable
return;
// These warnings do not apply for custom parsers and their children and need to be handled on a
// case by case basis
if (scope->isInCustomParserParent())
return;
const QQmlJSScope *scopeOfDefaultProperty = nullptr;
QString defaultPropertyName;
// NB: start looking for default property in parent scope (because this
@ -288,9 +298,10 @@ bool FindWarningVisitor::visit(QQmlJS::AST::UiScriptBinding *uisb)
}
if (!qmlScope->hasProperty(name.toString())) {
// These warnings do not apply for custom parsers and need to be handled on a case by
// case basis
if (qmlScope->baseType()->hasCustomParser())
// These warnings do not apply for custom parsers and their children and need to be
// handled on a case by case basis
if (qmlScope->isInCustomParserParent())
return true;
// TODO: Can this be in a better suited category?