summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-01-16 12:37:23 +0100
committerUlf Hermann <ulf.hermann@qt.io>2023-01-17 20:58:31 +0000
commite3cb23d34b89c0f7f26d55d8e87e4390123b09cc (patch)
tree551ddb8562f9ff9a4063e26a33647a139f023c3d
parent47e111800e3c259cc5030cf841a6d43fa43a8e97 (diff)
downloadqtdeclarative-e3cb23d34b89c0f7f26d55d8e87e4390123b09cc.tar.gz
qmllint: Print fix suggestions for pragma ComponentBehavior
Pick-to: 6.5 Fixes: QTBUG-104576 Fixes: QTBUG-104632 Change-Id: I9e0919feb04798fb4c5d0c8c0ed2f5cbc7a0b552 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qmlcompiler/qqmljsscopesbyid_p.h1
-rw-r--r--src/qmlcompiler/qqmljstypepropagator.cpp12
-rw-r--r--tests/auto/qml/qmllint/data/missingComponentBehaviorBound.qml10
-rw-r--r--tests/auto/qml/qmllint/tst_qmllint.cpp10
4 files changed, 33 insertions, 0 deletions
diff --git a/src/qmlcompiler/qqmljsscopesbyid_p.h b/src/qmlcompiler/qqmljsscopesbyid_p.h
index 783161dc55..dcf72d5003 100644
--- a/src/qmlcompiler/qqmljsscopesbyid_p.h
+++ b/src/qmlcompiler/qqmljsscopesbyid_p.h
@@ -25,6 +25,7 @@ QT_BEGIN_NAMESPACE
class QQmlJSScopesById
{
public:
+ bool componentsAreBound() const { return m_componentsAreBound; }
void setComponentsAreBound(bool bound) { m_componentsAreBound = bound; }
void setSignaturesAreEnforced(bool enforced) { m_signaturesAreEnforced = enforced; }
diff --git a/src/qmlcompiler/qqmljstypepropagator.cpp b/src/qmlcompiler/qqmljstypepropagator.cpp
index 648cf2c7e6..4e8f598b32 100644
--- a/src/qmlcompiler/qqmljstypepropagator.cpp
+++ b/src/qmlcompiler/qqmljstypepropagator.cpp
@@ -393,6 +393,18 @@ void QQmlJSTypePropagator::handleUnqualifiedAccess(const QString &name, bool isM
}
}
+ if (!suggestion.has_value() && !m_function->addressableScopes.componentsAreBound()
+ && m_function->addressableScopes.existsAnywhereInDocument(name)) {
+ FixSuggestion::Fix bindComponents;
+ const QLatin1String replacement = "pragma ComponentBehavior: Bound"_L1;
+ bindComponents.replacementString = replacement + '\n'_L1;
+ bindComponents.message = "Set \"%1\" in order to use IDs "
+ "from outer components in nested components."_L1.arg(replacement);
+ bindComponents.cutLocation = QQmlJS::SourceLocation(0, 0, 1, 1);
+ bindComponents.isHint = false;
+ suggestion = FixSuggestion {{ bindComponents }};
+ }
+
if (!suggestion.has_value()) {
if (auto didYouMean =
QQmlJSUtils::didYouMean(name,
diff --git a/tests/auto/qml/qmllint/data/missingComponentBehaviorBound.qml b/tests/auto/qml/qmllint/data/missingComponentBehaviorBound.qml
new file mode 100644
index 0000000000..0a66ec140d
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/missingComponentBehaviorBound.qml
@@ -0,0 +1,10 @@
+import QtQuick
+Item {
+ id: barsty
+ property int fooInt: 42
+
+ Repeater {
+ model: 5
+ Text { text: "Foo=" + barsty.fooInt }
+ }
+}
diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp
index 41ede4c713..57af0f7aac 100644
--- a/tests/auto/qml/qmllint/tst_qmllint.cpp
+++ b/tests/auto/qml/qmllint/tst_qmllint.cpp
@@ -1021,6 +1021,16 @@ expression: \${expr} \${expr} \\\${expr} \\\${expr}`)",
QTest::newRow("duplicatedSignalName")
<< QStringLiteral("duplicatedPropertyName.qml")
<< Result{ { Message{ QStringLiteral("Duplicated signal name \"clicked\"."), 8, 5 } } };
+ QTest::newRow("missingComponentBehaviorBound")
+ << QStringLiteral("missingComponentBehaviorBound.qml")
+ << Result {
+ { Message{ QStringLiteral("Unqualified access"), 8, 31 } },
+ {},
+ { Message{ QStringLiteral("Set \"pragma ComponentBehavior: Bound\" in "
+ "order to use IDs from outer components "
+ "in nested components."), 0, 0, QtInfoMsg } },
+ Result::AutoFixable
+ };
}
void TestQmllint::dirtyQmlCode()