aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2020-03-18 11:44:13 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-03-18 12:37:04 +0100
commit13caf26b29283b544edc2974fa1ea0481c63b435 (patch)
treec06077293de36f69c42b5e1a38844e2b8bbe07c4 /tools
parent36fb7cf832e801a7b3718fa443ec2f1b83e0fea2 (diff)
parent869efe4a49c5286493d7f039325992725bcac6c3 (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts: tools/qmllint/findunqualified.cpp Change-Id: I2593b5cc0db1d14e0c944aec4b88a80f46f5b0c1
Diffstat (limited to 'tools')
-rw-r--r--tools/qmllint/findunqualified.cpp9
-rw-r--r--tools/qmllint/importedmembersvisitor.cpp11
-rw-r--r--tools/qmllint/scopetree.cpp66
3 files changed, 63 insertions, 23 deletions
diff --git a/tools/qmllint/findunqualified.cpp b/tools/qmllint/findunqualified.cpp
index 6155ea4637..305dd65c66 100644
--- a/tools/qmllint/findunqualified.cpp
+++ b/tools/qmllint/findunqualified.cpp
@@ -43,6 +43,7 @@
static const QString prefixedName(const QString &prefix, const QString &name)
{
+ Q_ASSERT(!prefix.endsWith('.'));
return prefix.isEmpty() ? name : (prefix + QLatin1Char('.') + name);
}
@@ -88,11 +89,9 @@ void FindUnqualifiedIDVisitor::parseHeaders(QQmlJS::AST::UiHeaderItemList *heade
uri = uri->next;
}
path.chop(1);
- QString prefix = QLatin1String("");
- if (import->asToken.isValid()) {
- prefix += import->importId + QLatin1Char('.');
- }
- importHelper(path, prefix, import->version->version);
+ importHelper(path,
+ import->asToken.isValid() ? import->importId.toString() : QString(),
+ import->version->version);
}
}
header = header->next;
diff --git a/tools/qmllint/importedmembersvisitor.cpp b/tools/qmllint/importedmembersvisitor.cpp
index 676903d135..c5214f2bb9 100644
--- a/tools/qmllint/importedmembersvisitor.cpp
+++ b/tools/qmllint/importedmembersvisitor.cpp
@@ -57,10 +57,13 @@ ScopeTree *ImportedMembersVisitor::result(const QString &scopeName) const
bool ImportedMembersVisitor::visit(UiObjectDefinition *definition)
{
ScopeTree::Ptr scope(new ScopeTree(ScopeType::QMLScope));
- auto qualifiedId = definition->qualifiedTypeNameId;
- while (qualifiedId && qualifiedId->next)
- qualifiedId = qualifiedId->next;
- scope->setSuperclassName(qualifiedId->name.toString());
+ QString superType;
+ for (auto segment = definition->qualifiedTypeNameId; segment; segment = segment->next) {
+ if (!superType.isEmpty())
+ superType.append('.');
+ superType.append(segment->name.toString());
+ }
+ scope->setSuperclassName(superType);
if (!m_rootObject)
m_rootObject = scope;
m_currentObjects.append(scope);
diff --git a/tools/qmllint/scopetree.cpp b/tools/qmllint/scopetree.cpp
index e7e0113f35..8c5358c7a5 100644
--- a/tools/qmllint/scopetree.cpp
+++ b/tools/qmllint/scopetree.cpp
@@ -134,6 +134,15 @@ private:
QStringRef m_afterText;
};
+static const QStringList unknownBuiltins = {
+ // TODO: "string" should be added to builtins.qmltypes, and the special handling below removed
+ QStringLiteral("alias"), // TODO: we cannot properly resolve aliases, yet
+ QStringLiteral("QRectF"), // TODO: should be added to builtins.qmltypes
+ QStringLiteral("QFont"), // TODO: should be added to builtins.qmltypes
+ QStringLiteral("QJSValue"), // We cannot say anything intelligent about untyped JS values.
+ QStringLiteral("variant"), // Same for generic variants
+};
+
bool ScopeTree::checkMemberAccess(
const QString &code,
FieldMemberList *members,
@@ -169,10 +178,31 @@ bool ScopeTree::checkMemberAccess(
}
return true;
}
- const ScopeTree *type = (scopeIt->type() && access->m_parentType.isEmpty())
- ? scopeIt->type()
- : types.value(typeName).get();
- return checkMemberAccess(code, access.get(), type, types, colorOut);
+
+ if (!access->m_child)
+ return true;
+
+ if (const ScopeTree *type = scopeIt->type()) {
+ if (access->m_parentType.isEmpty())
+ return checkMemberAccess(code, access.get(), type, types, colorOut);
+ }
+
+ if (unknownBuiltins.contains(typeName))
+ return true;
+
+ const auto it = types.find(typeName);
+ if (it != types.end())
+ return checkMemberAccess(code, access.get(), it->get(), types, colorOut);
+
+ colorOut.write("Warning: ", Warning);
+ colorOut.write(
+ QString::fromLatin1("Type \"%1\" of member \"%2\" not found at %3:%4.\n")
+ .arg(typeName)
+ .arg(access->m_name)
+ .arg(access->m_location.startLine)
+ .arg(access->m_location.startColumn), Normal);
+ printContext(colorOut, code, access->m_location);
+ return false;
}
const auto scopeMethodIt = scope->m_methods.find(access->m_name);
@@ -251,13 +281,6 @@ bool ScopeTree::checkMemberAccess(
return false;
}
-static const QStringList unknownBuiltins = {
- QStringLiteral("alias"), // TODO: we cannot properly resolve aliases, yet
- QStringLiteral("QRectF"), // TODO: should be added to builtins.qmltypes
- QStringLiteral("QJSValue"), // We cannot say anything intelligent about untyped JS values.
- QStringLiteral("variant"), // Same for generic variants
-};
-
bool ScopeTree::recheckIdentifiers(
const QString &code,
const QHash<QString, const ScopeTree *> &qmlIDs,
@@ -287,9 +310,24 @@ bool ScopeTree::recheckIdentifiers(
auto it = qmlIDs.find(memberAccessTree->m_name);
if (it != qmlIDs.end()) {
- if (!checkMemberAccess(code, memberAccessTree.get(), *it, types, colorOut))
- noUnqualifiedIdentifier = false;
- continue;
+ if (*it != nullptr) {
+ if (!checkMemberAccess(code, memberAccessTree.get(), *it, types, colorOut))
+ noUnqualifiedIdentifier = false;
+ continue;
+ } else if (memberAccessTree->m_child
+ && memberAccessTree->m_child->m_name.front().isUpper()) {
+ // It could be a qualified type name
+ const QString qualified = memberAccessTree->m_name + QLatin1Char('.')
+ + memberAccessTree->m_child->m_name;
+ const auto typeIt = types.find(qualified);
+ if (typeIt != types.end()) {
+ if (!checkMemberAccess(code, memberAccessTree->m_child.get(), typeIt->get(),
+ types, colorOut)) {
+ noUnqualifiedIdentifier = false;
+ }
+ continue;
+ }
+ }
}
auto qmlScope = currentScope->currentQMLScope();