aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-02-11 13:17:29 +0100
committerUlf Hermann <ulf.hermann@qt.io>2021-02-12 12:48:08 +0100
commit06d819cd714542427ed9f70820b84004c874a9db (patch)
tree9ec55c5dac1408314b25c587b6b0bfb8ccdf31fb /tools
parente7695ce2ca2e8aa29c8b689f4cdb97e8b8fa43ef (diff)
QML: Warn about variables being used before their declaration
This collides with injected signal parameters. qmlcachegen cannot tell those cases apart. [ChangeLog][QML][Important Behavior Changes] QML warns about JavaScript variables being used before their declaration now. This is almost always a mistake. It is particularly dangerous in the presence of injected signal parameters because qmlcachegen cannot identify a name collision between an injected signal parameter and a variable being used before its declaration. It therefore miscompiles such code. You can turn off the deprecation warning using the "qt.qml.compiler" logging category. Task-number: QTBUG-89943 Change-Id: I8a9424ca8c6edd562402fe5c560ba7e8344b5585 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit ab71cdafca87513a4e214d3af056d8990bc1eddb) Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'tools')
-rw-r--r--tools/qmllint/checkidentifiers.cpp32
1 files changed, 23 insertions, 9 deletions
diff --git a/tools/qmllint/checkidentifiers.cpp b/tools/qmllint/checkidentifiers.cpp
index 6400e5db77..e78ebdae90 100644
--- a/tools/qmllint/checkidentifiers.cpp
+++ b/tools/qmllint/checkidentifiers.cpp
@@ -281,7 +281,7 @@ bool CheckIdentifiers::operator()(
const MemberAccessChains &memberAccessChains,
const QQmlJSScope::ConstPtr &root, const QString &rootId) const
{
- bool noUnqualifiedIdentifier = true;
+ bool identifiersClean = true;
// revisit all scopes
QQueue<QQmlJSScope::ConstPtr> workQueue;
@@ -296,14 +296,28 @@ bool CheckIdentifiers::operator()(
auto memberAccessBase = memberAccessChain.takeFirst();
const auto jsId = currentScope->findJSIdentifier(memberAccessBase.m_name);
- if (jsId.has_value() && jsId->kind != QQmlJSScope::JavaScriptIdentifier::Injected)
+ if (jsId.has_value() && jsId->kind != QQmlJSScope::JavaScriptIdentifier::Injected) {
+ if (memberAccessBase.m_location.end() < jsId->location.begin()) {
+ m_colorOut->writePrefixedMessage(
+ QStringLiteral(
+ "Variable \"%1\" is used before its declaration at %2:%3. "
+ "The declaration is at %4:%5.\n")
+ .arg(memberAccessBase.m_name)
+ .arg(memberAccessBase.m_location.startLine)
+ .arg(memberAccessBase.m_location.startColumn)
+ .arg(jsId->location.startLine)
+ .arg(jsId->location.startColumn), Warning);
+ printContext(m_code, m_colorOut, memberAccessBase.m_location);
+ identifiersClean = false;
+ }
continue;
+ }
auto it = qmlIDs.find(memberAccessBase.m_name);
if (it != qmlIDs.end()) {
if (!it->isNull()) {
if (!checkMemberAccess(memberAccessChain, *it))
- noUnqualifiedIdentifier = false;
+ identifiersClean = false;
continue;
} else if (!memberAccessChain.isEmpty()) {
// It could be a qualified type name
@@ -315,7 +329,7 @@ bool CheckIdentifiers::operator()(
if (typeIt != m_types.end()) {
memberAccessChain.takeFirst();
if (!checkMemberAccess(memberAccessChain, *typeIt))
- noUnqualifiedIdentifier = false;
+ identifiersClean = false;
continue;
}
}
@@ -341,9 +355,9 @@ bool CheckIdentifiers::operator()(
.arg(memberAccessBase.m_location.startLine)
.arg(memberAccessBase.m_location.startColumn), Warning);
printContext(m_code, m_colorOut, memberAccessBase.m_location);
- noUnqualifiedIdentifier = false;
+ identifiersClean = false;
} else if (!checkMemberAccess(memberAccessChain, property.type(), &property)) {
- noUnqualifiedIdentifier = false;
+ identifiersClean = false;
}
continue;
@@ -368,11 +382,11 @@ bool CheckIdentifiers::operator()(
if (typeIt != m_types.end() && !typeIt->isNull()) {
if (!checkMemberAccess(memberAccessChain, *typeIt))
- noUnqualifiedIdentifier = false;
+ identifiersClean = false;
continue;
}
- noUnqualifiedIdentifier = false;
+ identifiersClean = false;
const auto location = memberAccessBase.m_location;
if (baseIsPrefixed) {
@@ -444,5 +458,5 @@ bool CheckIdentifiers::operator()(
for (auto const &childScope : childScopes)
workQueue.enqueue(childScope);
}
- return noUnqualifiedIdentifier;
+ return identifiersClean;
}