diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2020-03-18 11:44:13 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-03-18 12:37:04 +0100 |
commit | 13caf26b29283b544edc2974fa1ea0481c63b435 (patch) | |
tree | c06077293de36f69c42b5e1a38844e2b8bbe07c4 /tools/qmllint | |
parent | 36fb7cf832e801a7b3718fa443ec2f1b83e0fea2 (diff) | |
parent | 869efe4a49c5286493d7f039325992725bcac6c3 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts:
tools/qmllint/findunqualified.cpp
Change-Id: I2593b5cc0db1d14e0c944aec4b88a80f46f5b0c1
Diffstat (limited to 'tools/qmllint')
-rw-r--r-- | tools/qmllint/findunqualified.cpp | 9 | ||||
-rw-r--r-- | tools/qmllint/importedmembersvisitor.cpp | 11 | ||||
-rw-r--r-- | tools/qmllint/scopetree.cpp | 66 |
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(); |