aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/qmllint/quick/qquickliteralbindingcheck.cpp16
-rw-r--r--src/plugins/qmllint/quick/qquickliteralbindingcheck_p.h8
-rw-r--r--src/qmlcompiler/qqmljsliteralbindingcheck.cpp59
-rw-r--r--src/qmlcompiler/qqmljsliteralbindingcheck_p.h6
-rw-r--r--tests/auto/qml/qmllint/tst_qmllint.cpp11
5 files changed, 54 insertions, 46 deletions
diff --git a/src/plugins/qmllint/quick/qquickliteralbindingcheck.cpp b/src/plugins/qmllint/quick/qquickliteralbindingcheck.cpp
index a39ea6d2c9..47db2e33ca 100644
--- a/src/plugins/qmllint/quick/qquickliteralbindingcheck.cpp
+++ b/src/plugins/qmllint/quick/qquickliteralbindingcheck.cpp
@@ -14,4 +14,20 @@ QQmlJSStructuredTypeError QQuickLiteralBindingCheck::check(const QString &typeNa
return QQuickValueTypeFromStringCheck::check(typeName, value);
}
+void QQuickLiteralBindingCheck::onBinding(
+ const QQmlSA::Element &element, const QString &propertyName, const QQmlSA::Binding &binding,
+ const QQmlSA::Element &bindingScope, const QQmlSA::Element &value)
+{
+ Q_UNUSED(value);
+ Q_UNUSED(element);
+
+ const auto property = getProperty(propertyName, binding, bindingScope);
+ if (!property.isValid())
+ return;
+
+ if (const auto propertyType = property.type())
+ warnOnCheckedBinding(binding, propertyType);
+}
+
+
QT_END_NAMESPACE
diff --git a/src/plugins/qmllint/quick/qquickliteralbindingcheck_p.h b/src/plugins/qmllint/quick/qquickliteralbindingcheck_p.h
index 058b5f7f5c..31e735b6b8 100644
--- a/src/plugins/qmllint/quick/qquickliteralbindingcheck_p.h
+++ b/src/plugins/qmllint/quick/qquickliteralbindingcheck_p.h
@@ -29,8 +29,12 @@ class QQuickLiteralBindingCheck: public LiteralBindingCheckBase
public:
using LiteralBindingCheckBase::LiteralBindingCheckBase;
- virtual QQmlJSStructuredTypeError check(const QString &typeName,
- const QString &value) const override;
+ void onBinding(
+ const QQmlSA::Element &element, const QString &propertyName,
+ const QQmlSA::Binding &binding, const QQmlSA::Element &bindingScope,
+ const QQmlSA::Element &value) override;
+
+ QQmlJSStructuredTypeError check(const QString &typeName, const QString &value) const override;
};
QT_END_NAMESPACE
diff --git a/src/qmlcompiler/qqmljsliteralbindingcheck.cpp b/src/qmlcompiler/qqmljsliteralbindingcheck.cpp
index c2498afbed..f136bf38da 100644
--- a/src/qmlcompiler/qqmljsliteralbindingcheck.cpp
+++ b/src/qmlcompiler/qqmljsliteralbindingcheck.cpp
@@ -93,44 +93,26 @@ QQmlSA::Property LiteralBindingCheckBase::getProperty(const QString &propertyNam
return bindingScope.property(unqualifiedPropertyName);
}
-
-void LiteralBindingCheckBase::onBinding(const QQmlSA::Element &element, const QString &propertyName,
- const QQmlSA::Binding &binding,
- const QQmlSA::Element &bindingScope,
- const QQmlSA::Element &value)
+void LiteralBindingCheckBase::warnOnCheckedBinding(
+ const QQmlSA::Binding &binding, const QQmlSA::Element &propertyType)
{
- Q_UNUSED(value);
-
- const auto property = getProperty(propertyName, binding, bindingScope);
- if (!property.isValid())
+ auto construction = check(propertyType.internalId(), binding.stringValue());
+ if (!construction.isValid())
return;
- // If the property is defined in the same scope where it is set,
- // we are in fact allowed to set it, even if it's not writable.
- if (property.isReadonly() && !element.hasOwnProperty(propertyName)) {
- emitWarning(u"Cannot assign to read-only property %1"_s.arg(propertyName),
- qmlReadOnlyProperty, binding.sourceLocation());
+ const QString warningMessage =
+ u"Construction from string is deprecated. Use structured value type "
+ u"construction instead for type \"%1\""_s.arg(propertyType.internalId());
+
+ if (construction.code.isEmpty()) {
+ emitWarning(warningMessage, qmlIncompatibleType, binding.sourceLocation());
return;
}
- if (auto propertyType = property.type(); propertyType) {
- auto construction = check(propertyType.internalId(), binding.stringValue());
- if (construction.isValid()) {
- const QString warningMessage =
- u"Construction from string is deprecated. Use structured value type "
- u"construction instead for type \"%1\""_s.arg(propertyType.internalId());
-
- if (!construction.code.isNull()) {
- QQmlSA::FixSuggestion suggestion(
- u"Replace string by structured value construction"_s,
- binding.sourceLocation(), construction.code);
- emitWarning(warningMessage, qmlIncompatibleType, binding.sourceLocation(), suggestion);
- return;
- }
- emitWarning(warningMessage, qmlIncompatibleType, binding.sourceLocation());
- return;
- }
- }
+ const QQmlSA::FixSuggestion suggestion(
+ u"Replace string by structured value construction"_s,
+ binding.sourceLocation(), construction.code);
+ emitWarning(warningMessage, qmlIncompatibleType, binding.sourceLocation(), suggestion);
}
void QQmlJSLiteralBindingCheck::onBinding(const QQmlSA::Element &element,
@@ -139,12 +121,23 @@ void QQmlJSLiteralBindingCheck::onBinding(const QQmlSA::Element &element,
const QQmlSA::Element &bindingScope,
const QQmlSA::Element &value)
{
- LiteralBindingCheckBase::onBinding(element, propertyName, binding, bindingScope, value);
+ Q_UNUSED(value);
const auto property = getProperty(propertyName, binding, bindingScope);
if (!property.isValid())
return;
+ // If the property is defined in the same scope where it is set,
+ // we are in fact allowed to set it, even if it's not writable.
+ if (property.isReadonly() && !element.hasOwnProperty(propertyName)) {
+ emitWarning(u"Cannot assign to read-only property %1"_s.arg(propertyName),
+ qmlReadOnlyProperty, binding.sourceLocation());
+ return;
+ }
+
+ if (const auto propertyType = property.type())
+ warnOnCheckedBinding(binding, propertyType);
+
if (!canConvertForLiteralBinding(m_resolver, resolveLiteralType(binding), property.type())) {
emitWarning(u"Cannot assign literal of type %1 to %2"_s.arg(
literalPrettyTypeName(binding.bindingType()),
diff --git a/src/qmlcompiler/qqmljsliteralbindingcheck_p.h b/src/qmlcompiler/qqmljsliteralbindingcheck_p.h
index ca5c65e9b4..d4fac3f52a 100644
--- a/src/qmlcompiler/qqmljsliteralbindingcheck_p.h
+++ b/src/qmlcompiler/qqmljsliteralbindingcheck_p.h
@@ -30,15 +30,13 @@ class Q_QMLCOMPILER_EXPORT LiteralBindingCheckBase : public QQmlSA::PropertyPass
public:
using QQmlSA::PropertyPass::PropertyPass;
- void onBinding(const QQmlSA::Element &element, const QString &propertyName,
- const QQmlSA::Binding &binding, const QQmlSA::Element &bindingScope,
- const QQmlSA::Element &value) override;
-
protected:
virtual QQmlJSStructuredTypeError check(const QString &typeName, const QString &value) const = 0;
QQmlSA::Property getProperty(const QString &propertyName, const QQmlSA::Binding &binding,
const QQmlSA::Element &bindingScope) const;
+
+ void warnOnCheckedBinding(const QQmlSA::Binding &binding, const QQmlSA::Element &propertyType);
};
class Q_QMLCOMPILER_EXPORT QQmlJSLiteralBindingCheck: public LiteralBindingCheckBase
diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp
index d90fb2c6b7..b871bcf7f7 100644
--- a/tests/auto/qml/qmllint/tst_qmllint.cpp
+++ b/tests/auto/qml/qmllint/tst_qmllint.cpp
@@ -36,8 +36,7 @@ public:
ExitsNormally = 0x1,
NoMessages = 0x2,
AutoFixable = 0x4,
- HasDuplicates = 0x8,
- UseSettings = 0x10
+ UseSettings = 0x8
};
Q_DECLARE_FLAGS(Flags, Flag)
@@ -971,8 +970,7 @@ expression: \${expr} \${expr} \\\${expr} \\\${expr}`)",
<< Result{
{ Message{ QStringLiteral("Cannot assign to read-only property activeFocus") } },
{},
- {},
- Result::HasDuplicates
+ {}
};
QTest::newRow("AssignToReadOnlyProperty")
<< QStringLiteral("assignToReadOnlyProperty2.qml")
@@ -1879,10 +1877,9 @@ void TestQmllint::checkResult(const QJsonArray &warnings, const Result &result,
const auto firstDuplicate =
std::adjacent_find(sortedWarnings.constBegin(), sortedWarnings.constEnd());
for (auto it = firstDuplicate; it != sortedWarnings.constEnd();
- it = std::adjacent_find(it + 1, sortedWarnings.constEnd()))
+ it = std::adjacent_find(it + 1, sortedWarnings.constEnd())) {
qDebug() << "Found duplicate warning: " << it->toString();
- if (result.flags.testFlag(Result::HasDuplicates))
- QEXPECT_FAIL("", "TODO: remove duplicate warnings", Continue);
+ }
QVERIFY2(firstDuplicate == sortedWarnings.constEnd(), "Found duplicate warnings!");
}