qmllint: Complain if member access check fails for namespaced types
Before, we would prepend the namespace to the name, but then continue right away, never checking the new name. Change-Id: If90db7d33536fb4b549321c2d6b677040605b6f0 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
48b6e192bb
commit
ed59dfeb70
|
@ -0,0 +1,5 @@
|
||||||
|
import QtQuick as T
|
||||||
|
|
||||||
|
T.Item {
|
||||||
|
objectName: T.some.bs
|
||||||
|
}
|
|
@ -273,6 +273,10 @@ void TestQmllint::dirtyQmlCode_data()
|
||||||
<< QStringLiteral("badScript.qml")
|
<< QStringLiteral("badScript.qml")
|
||||||
<< QString("Warning: Property \"stuff\" not found on type \"Empty\"")
|
<< QString("Warning: Property \"stuff\" not found on type \"Empty\"")
|
||||||
<< QString();
|
<< QString();
|
||||||
|
QTest::newRow("brokenNamespace")
|
||||||
|
<< QStringLiteral("brokenNamespace.qml")
|
||||||
|
<< QString("Warning: type not found in namespace at %1:4:17")
|
||||||
|
<< QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestQmllint::dirtyQmlCode()
|
void TestQmllint::dirtyQmlCode()
|
||||||
|
|
|
@ -299,7 +299,7 @@ bool CheckIdentifiers::operator()(
|
||||||
if (memberAccessChain.isEmpty())
|
if (memberAccessChain.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto memberAccessBase = memberAccessChain.takeFirst();
|
auto memberAccessBase = memberAccessChain.takeFirst();
|
||||||
const auto jsId = currentScope->findJSIdentifier(memberAccessBase.m_name);
|
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)
|
||||||
continue;
|
continue;
|
||||||
|
@ -354,24 +354,45 @@ bool CheckIdentifiers::operator()(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto typeIt = m_types.find(memberAccessBase.m_name);
|
const QString baseName = memberAccessBase.m_name;
|
||||||
if (typeIt != m_types.end()) {
|
auto typeIt = m_types.find(memberAccessBase.m_name);
|
||||||
if (typeIt->isNull()) {
|
bool baseIsPrefixed = false;
|
||||||
// This is a namespaced import. Check with the full name.
|
while (typeIt != m_types.end() && typeIt->isNull()) {
|
||||||
if (!memberAccessChain.isEmpty())
|
// This is a namespaced import. Check with the full name.
|
||||||
memberAccessChain.front().m_name.prepend(memberAccessBase.m_name + u'.');
|
if (!memberAccessChain.isEmpty()) {
|
||||||
} else if (!checkMemberAccess(memberAccessChain, *typeIt)) {
|
auto location = memberAccessBase.m_location;
|
||||||
noUnqualifiedIdentifier = false;
|
memberAccessBase = memberAccessChain.takeFirst();
|
||||||
|
memberAccessBase.m_name.prepend(baseName + u'.');
|
||||||
|
location.length = memberAccessBase.m_location.offset - location.offset
|
||||||
|
+ memberAccessBase.m_location.length;
|
||||||
|
memberAccessBase.m_location = location;
|
||||||
|
typeIt = m_types.find(memberAccessBase.m_name);
|
||||||
|
baseIsPrefixed = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeIt != m_types.end() && !typeIt->isNull()) {
|
||||||
|
if (!checkMemberAccess(memberAccessChain, *typeIt))
|
||||||
|
noUnqualifiedIdentifier = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
noUnqualifiedIdentifier = false;
|
noUnqualifiedIdentifier = false;
|
||||||
const auto location = memberAccessBase.m_location;
|
const auto location = memberAccessBase.m_location;
|
||||||
m_colorOut->writePrefixedMessage(QString::fromLatin1("unqualified access at %1:%2:%3\n")
|
|
||||||
.arg(m_fileName)
|
if (baseIsPrefixed) {
|
||||||
.arg(location.startLine).arg(location.startColumn),
|
m_colorOut->writePrefixedMessage(
|
||||||
Warning);
|
QString::fromLatin1("type not found in namespace at %1:%2:%3\n")
|
||||||
|
.arg(m_fileName)
|
||||||
|
.arg(location.startLine).arg(location.startColumn),
|
||||||
|
Warning);
|
||||||
|
} else {
|
||||||
|
m_colorOut->writePrefixedMessage(
|
||||||
|
QString::fromLatin1("unqualified access at %1:%2:%3\n")
|
||||||
|
.arg(m_fileName)
|
||||||
|
.arg(location.startLine).arg(location.startColumn),
|
||||||
|
Warning);
|
||||||
|
}
|
||||||
|
|
||||||
printContext(m_code, m_colorOut, location);
|
printContext(m_code, m_colorOut, location);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue