diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-02-11 13:17:29 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-02-12 12:48:08 +0100 |
commit | 06d819cd714542427ed9f70820b84004c874a9db (patch) | |
tree | 9ec55c5dac1408314b25c587b6b0bfb8ccdf31fb /tools | |
parent | e7695ce2ca2e8aa29c8b689f4cdb97e8b8fa43ef (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.cpp | 32 |
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; } |