diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/qmllint/checkidentifiers.cpp | 37 | ||||
| -rw-r--r-- | tools/qmllint/checkidentifiers.h | 6 | ||||
| -rw-r--r-- | tools/qmllint/findunqualified.cpp | 43 | ||||
| -rw-r--r-- | tools/qmllint/findunqualified.h | 12 | ||||
| -rw-r--r-- | tools/qmllint/importedmembersvisitor.cpp | 8 | ||||
| -rw-r--r-- | tools/qmllint/importedmembersvisitor.h | 2 | ||||
| -rw-r--r-- | tools/shared/metatypes.h | 7 | ||||
| -rw-r--r-- | tools/shared/scopetree.cpp | 72 | ||||
| -rw-r--r-- | tools/shared/scopetree.h | 17 | ||||
| -rw-r--r-- | tools/shared/typedescriptionreader.cpp | 2 |
10 files changed, 114 insertions, 92 deletions
diff --git a/tools/qmllint/checkidentifiers.cpp b/tools/qmllint/checkidentifiers.cpp index 6b9e48ed38..20b2ba6214 100644 --- a/tools/qmllint/checkidentifiers.cpp +++ b/tools/qmllint/checkidentifiers.cpp @@ -83,14 +83,15 @@ void CheckIdentifiers::printContext(const QQmlJS::SourceLocation &location) cons } bool CheckIdentifiers::checkMemberAccess(const QVector<ScopeTree::FieldMember> &members, - const ScopeTree *scope) const + const ScopeTree::ConstPtr &outerScope) const { QStringList expectedNext; QString detectedRestrictiveName; QString detectedRestrictiveKind; + ScopeTree::ConstPtr scope = outerScope; for (const ScopeTree::FieldMember &access : members) { - if (scope == nullptr) { + if (scope.isNull()) { writeWarning(m_colorOut); m_colorOut->write( QString::fromLatin1("Type \"%1\" of base \"%2\" not found when accessing member \"%3\" at %4:%5.\n") @@ -142,7 +143,7 @@ bool CheckIdentifiers::checkMemberAccess(const QVector<ScopeTree::FieldMember> & continue; } - if (const ScopeTree *type = scopeIt->type()) { + if (const ScopeTree::ConstPtr type = scopeIt->type()) { if (access.m_parentType.isEmpty()) { scope = type; continue; @@ -158,7 +159,7 @@ bool CheckIdentifiers::checkMemberAccess(const QVector<ScopeTree::FieldMember> & detectedRestrictiveName = access.m_name; scope = nullptr; } else { - scope = it->get(); + scope = *it; } continue; } @@ -189,10 +190,10 @@ bool CheckIdentifiers::checkMemberAccess(const QVector<ScopeTree::FieldMember> & const auto typeProperties = type->properties(); const auto typeIt = typeProperties.find(access.m_name); if (typeIt != typeProperties.end()) { - const ScopeTree *propType = access.m_parentType.isEmpty() + const ScopeTree::ConstPtr propType = access.m_parentType.isEmpty() ? typeIt->type() - : m_types.value(access.m_parentType).get(); - scope = propType ? propType : m_types.value(typeIt->typeName()).get(); + : m_types.value(access.m_parentType); + scope = propType ? propType : m_types.value(typeIt->typeName()); typeFound = true; break; } @@ -217,7 +218,7 @@ bool CheckIdentifiers::checkMemberAccess(const QVector<ScopeTree::FieldMember> & if (it != m_types.end() && !(*it)->attachedTypeName().isEmpty()) { const auto attached = m_types.find((*it)->attachedTypeName()); if (attached != m_types.end()) { - scope = attached->get(); + scope = *attached; continue; } } @@ -237,16 +238,16 @@ bool CheckIdentifiers::checkMemberAccess(const QVector<ScopeTree::FieldMember> & return true; } -bool CheckIdentifiers::operator()(const QHash<QString, const ScopeTree *> &qmlIDs, - const ScopeTree *root, const QString &rootId) const +bool CheckIdentifiers::operator()(const QHash<QString, ScopeTree::ConstPtr> &qmlIDs, + const ScopeTree::ConstPtr &root, const QString &rootId) const { bool noUnqualifiedIdentifier = true; // revisit all scopes - QQueue<const ScopeTree *> workQueue; + QQueue<ScopeTree::ConstPtr> workQueue; workQueue.enqueue(root); while (!workQueue.empty()) { - const ScopeTree *currentScope = workQueue.dequeue(); + const ScopeTree::ConstPtr currentScope = workQueue.dequeue(); const auto unmatchedSignalHandlers = currentScope->unmatchedSignalHandlers(); for (const auto &handler : unmatchedSignalHandlers) { writeWarning(m_colorOut); @@ -281,7 +282,7 @@ bool CheckIdentifiers::operator()(const QHash<QString, const ScopeTree *> &qmlID const auto typeIt = m_types.find(qualified); if (typeIt != m_types.end()) { memberAccessChain.takeFirst(); - if (!checkMemberAccess(memberAccessChain, typeIt->get())) + if (!checkMemberAccess(memberAccessChain, *typeIt)) noUnqualifiedIdentifier = false; continue; } @@ -289,7 +290,7 @@ bool CheckIdentifiers::operator()(const QHash<QString, const ScopeTree *> &qmlID } } - auto qmlScope = currentScope->currentQMLScope(); + auto qmlScope = ScopeTree::findCurrentQMLScope(currentScope); if (qmlScope->methods().contains(memberAccessBase.m_name)) { // a property of a JavaScript function continue; @@ -323,7 +324,7 @@ bool CheckIdentifiers::operator()(const QHash<QString, const ScopeTree *> &qmlID const auto typeIt = m_types.find(memberAccessBase.m_name); if (typeIt != m_types.end()) { - if (!checkMemberAccess(memberAccessChain, typeIt->get())) + if (!checkMemberAccess(memberAccessChain, *typeIt)) noUnqualifiedIdentifier = false; continue; } @@ -355,8 +356,8 @@ bool CheckIdentifiers::operator()(const QHash<QString, const ScopeTree *> &qmlID m_colorOut->write(issueLocationWithContext.issueText().toString(), Normal); m_colorOut->write(issueLocationWithContext.afterText() + QLatin1Char('\n'), Normal); } else if (currentScope->isIdInjectedFromSignal(memberAccessBase.m_name)) { - auto methodUsages = currentScope->currentQMLScope()->injectedSignalIdentifiers() - .values(memberAccessBase.m_name); + auto methodUsages = ScopeTree::findCurrentQMLScope(currentScope) + ->injectedSignalIdentifiers().values(memberAccessBase.m_name); auto location = memberAccessBase.m_location; // sort the list of signal handlers by their occurrence in the source code // then, we select the first one whose location is after the unqualified id @@ -402,7 +403,7 @@ bool CheckIdentifiers::operator()(const QHash<QString, const ScopeTree *> &qmlID } const auto childScopes = currentScope->childScopes(); for (auto const &childScope : childScopes) - workQueue.enqueue(childScope.get()); + workQueue.enqueue(childScope); } return noUnqualifiedIdentifier; } diff --git a/tools/qmllint/checkidentifiers.h b/tools/qmllint/checkidentifiers.h index ae924c491c..5d2236b7f9 100644 --- a/tools/qmllint/checkidentifiers.h +++ b/tools/qmllint/checkidentifiers.h @@ -41,12 +41,12 @@ public: m_colorOut(colorOut), m_code(code), m_types(types) {} - bool operator ()(const QHash<QString, const ScopeTree *> &qmlIDs, - const ScopeTree *root, const QString &rootId) const; + bool operator ()(const QHash<QString, ScopeTree::ConstPtr> &qmlIDs, + const ScopeTree::ConstPtr &root, const QString &rootId) const; private: bool checkMemberAccess(const QVector<ScopeTree::FieldMember> &members, - const ScopeTree *scope) const; + const ScopeTree::ConstPtr &outerScope) const; void printContext(const QQmlJS::SourceLocation &location) const; ColorOutput *m_colorOut = nullptr; diff --git a/tools/qmllint/findunqualified.cpp b/tools/qmllint/findunqualified.cpp index 24d133dd81..baae3a3ce7 100644 --- a/tools/qmllint/findunqualified.cpp +++ b/tools/qmllint/findunqualified.cpp @@ -67,7 +67,7 @@ static TypeDescriptionReader createQmltypesReaderForFile(const QString &filename void FindUnqualifiedIDVisitor::enterEnvironment(ScopeType type, const QString &name) { - m_currentScope = m_currentScope->createNewChildScope(type, name).get(); + m_currentScope = ScopeTree::create(type, name, m_currentScope); } void FindUnqualifiedIDVisitor::leaveEnvironment() @@ -99,11 +99,11 @@ void FindUnqualifiedIDVisitor::parseHeaders(QQmlJS::AST::UiHeaderItemList *heade } } -ScopeTree *FindUnqualifiedIDVisitor::parseProgram(QQmlJS::AST::Program *program, - const QString &name) +ScopeTree::Ptr FindUnqualifiedIDVisitor::parseProgram(QQmlJS::AST::Program *program, + const QString &name) { using namespace QQmlJS::AST; - ScopeTree *result = new ScopeTree(ScopeType::JSLexicalScope, name); + ScopeTree::Ptr result = ScopeTree::create(ScopeType::JSLexicalScope, name); for (auto *statement = program->statements; statement; statement = statement->next) { if (auto *function = cast<FunctionDeclaration *>(statement->statement)) { MetaMethod method(function->name.toString()); @@ -204,7 +204,7 @@ FindUnqualifiedIDVisitor::Import FindUnqualifiedIDVisitor::readQmldir(const QStr for (const QString &import : imports) result.dependencies.append(import); - QHash<QString, ScopeTree *> qmlComponents; + QHash<QString, ScopeTree::Ptr> qmlComponents; const auto components = reader.components(); for (auto it = components.begin(), end = components.end(); it != end; ++it) { const QString filePath = path + QLatin1Char('/') + it->fileName; @@ -299,7 +299,7 @@ void FindUnqualifiedIDVisitor::importHelper(const QString &module, const QString } } -ScopeTree *FindUnqualifiedIDVisitor::localFile2ScopeTree(const QString &filePath) +ScopeTree::Ptr FindUnqualifiedIDVisitor::localFile2ScopeTree(const QString &filePath) { using namespace QQmlJS::AST; const QFileInfo info { filePath }; @@ -315,8 +315,8 @@ ScopeTree *FindUnqualifiedIDVisitor::localFile2ScopeTree(const QString &filePath QFile file(filePath); if (!file.open(QFile::ReadOnly)) { - return new ScopeTree(isJavaScript ? ScopeType::JSLexicalScope : ScopeType::QMLScope, - scopeName); + return ScopeTree::create(isJavaScript ? ScopeType::JSLexicalScope : ScopeType::QMLScope, + scopeName); } QString code = file.readAll(); @@ -329,8 +329,8 @@ ScopeTree *FindUnqualifiedIDVisitor::localFile2ScopeTree(const QString &filePath : parser.parseProgram()) : parser.parse(); if (!success) { - return new ScopeTree(isJavaScript ? ScopeType::JSLexicalScope : ScopeType::QMLScope, - scopeName); + return ScopeTree::create(isJavaScript ? ScopeType::JSLexicalScope : ScopeType::QMLScope, + scopeName); } if (!isJavaScript) { @@ -392,7 +392,7 @@ void FindUnqualifiedIDVisitor::importExportedNames(const QStringRef &prefix, QSt scopes.append(scope); const auto properties = scope->properties(); for (auto property : properties) { - property.setType(m_exportedName2Scope.value(property.typeName()).get()); + property.setType(m_exportedName2Scope.value(property.typeName())); m_currentScope->insertPropertyIdentifier(property); } @@ -631,7 +631,7 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiPublicMember *uipm) false, uipm->memberType ? (uipm->memberType->name == QLatin1String("alias")) : false, 0); - property.setType(m_exportedName2Scope.value(property.typeName()).get()); + property.setType(m_exportedName2Scope.value(property.typeName())); m_currentScope->insertPropertyIdentifier(property); return true; } @@ -646,14 +646,15 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::IdentifierExpression *idexp) FindUnqualifiedIDVisitor::FindUnqualifiedIDVisitor(QStringList qmltypeDirs, QString code, QString fileName, bool silent) - : m_rootScope(new ScopeTree { ScopeType::JSFunctionScope, "global" }), - m_currentScope(m_rootScope.get()), + : m_rootScope(ScopeTree::create(ScopeType::JSFunctionScope, "global")), m_qmltypeDirs(std::move(qmltypeDirs)), m_code(std::move(code)), m_rootId(QLatin1String("<id>")), m_filePath(std::move(fileName)), m_colorOut(silent) { + m_currentScope = m_rootScope; + // setup color output m_colorOut.insertMapping(Error, ColorOutput::RedForeground); m_colorOut.insertMapping(Warning, ColorOutput::PurpleForeground); @@ -692,12 +693,12 @@ bool FindUnqualifiedIDVisitor::check() auto targetScope = m_qmlid2scope[outstandingConnection.targetName]; if (outstandingConnection.scope) outstandingConnection.scope->addMethods(targetScope->methods()); - QScopedValueRollback<ScopeTree*> rollback(m_currentScope, outstandingConnection.scope); + QScopedValueRollback<ScopeTree::Ptr> rollback(m_currentScope, outstandingConnection.scope); outstandingConnection.uiod->initializer->accept(this); } CheckIdentifiers check(&m_colorOut, m_code, m_exportedName2Scope); - return check(m_qmlid2scope, m_rootScope.get(), m_rootId); + return check(m_qmlid2scope, m_rootScope, m_rootId); } bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::VariableDeclarationList *vdl) @@ -772,7 +773,7 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiImport *import) if (!import->importId.isEmpty()) { // TODO: do not put imported ids into the same space as qml IDs const QString importId = import->importId.toString(); - m_qmlid2scope.insert(importId, m_exportedName2Scope.value(importId).get()); + m_qmlid2scope.insert(importId, m_exportedName2Scope.value(importId)); } if (import->version) { auto uri = import->importUri; @@ -812,7 +813,7 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiObjectBinding *uiob) MetaProperty prop(uiob->qualifiedId->name.toString(), name, false, true, true, name == QLatin1String("alias"), 0); - prop.setType(m_exportedName2Scope.value(uiob->qualifiedTypeNameId->name.toString()).get()); + prop.setType(m_exportedName2Scope.value(uiob->qualifiedTypeNameId->name.toString())); m_currentScope->addProperty(prop); enterEnvironment(ScopeType::QMLScope, name); @@ -870,14 +871,14 @@ bool FindUnqualifiedIDVisitor::visit(QQmlJS::AST::UiObjectDefinition *uiod) } member = member->next; } - const ScopeTree *targetScope; + ScopeTree::ConstPtr targetScope; if (target.isEmpty()) { // no target set, connection comes from parentF - ScopeTree* scope = m_currentScope; + ScopeTree::Ptr scope = m_currentScope; do { scope = scope->parentScope(); // TODO: rename method } while (scope->scopeType() != ScopeType::QMLScope); - targetScope = m_exportedName2Scope.value(scope->name()).get(); + targetScope = m_exportedName2Scope.value(scope->name()); } else { // there was a target, check if we already can find it auto scopeIt = m_qmlid2scope.find(target); diff --git a/tools/qmllint/findunqualified.h b/tools/qmllint/findunqualified.h index d2ebc947bf..1c1751fafb 100644 --- a/tools/qmllint/findunqualified.h +++ b/tools/qmllint/findunqualified.h @@ -63,14 +63,14 @@ private: QStringList dependencies; }; - QScopedPointer<ScopeTree> m_rootScope; - ScopeTree *m_currentScope; + ScopeTree::Ptr m_rootScope; + ScopeTree::Ptr m_currentScope; QQmlJS::AST::ExpressionNode *m_fieldMemberBase = nullptr; QHash<QString, ScopeTree::ConstPtr> m_types; QHash<QString, ScopeTree::ConstPtr> m_exportedName2Scope; QStringList m_qmltypeDirs; QString m_code; - QHash<QString, const ScopeTree *> m_qmlid2scope; + QHash<QString, ScopeTree::ConstPtr> m_qmlid2scope; QString m_rootId; QString m_filePath; QSet<QPair<QString, QString>> m_alreadySeenImports; @@ -81,7 +81,7 @@ private: struct OutstandingConnection { QString targetName; - ScopeTree *scope; + ScopeTree::Ptr scope; QQmlJS::AST::UiObjectDefinition *uiod; }; @@ -96,13 +96,13 @@ private: Import readQmldir(const QString &dirname); void processImport(const QString &prefix, const Import &import); - ScopeTree *localFile2ScopeTree(const QString &filePath); + ScopeTree::Ptr localFile2ScopeTree(const QString &filePath); void importFileOrDirectory(const QString &directory, const QString &prefix); void importExportedNames(const QStringRef &prefix, QString name); void parseHeaders(QQmlJS::AST::UiHeaderItemList *headers); - ScopeTree *parseProgram(QQmlJS::AST::Program *program, const QString &name); + ScopeTree::Ptr parseProgram(QQmlJS::AST::Program *program, const QString &name); void throwRecursionDepthError() override; diff --git a/tools/qmllint/importedmembersvisitor.cpp b/tools/qmllint/importedmembersvisitor.cpp index c5214f2bb9..bf3787d489 100644 --- a/tools/qmllint/importedmembersvisitor.cpp +++ b/tools/qmllint/importedmembersvisitor.cpp @@ -31,9 +31,9 @@ using namespace QQmlJS::AST; -ScopeTree *ImportedMembersVisitor::result(const QString &scopeName) const +ScopeTree::Ptr ImportedMembersVisitor::result(const QString &scopeName) const { - ScopeTree *result = new ScopeTree(ScopeType::QMLScope); + ScopeTree::Ptr result = ScopeTree::create(); result->setClassName(scopeName); result->setSuperclassName(m_rootObject->superclassName()); const auto properties = m_rootObject->properties(); @@ -41,7 +41,7 @@ ScopeTree *ImportedMembersVisitor::result(const QString &scopeName) const if (property.isAlias()) { const auto it = m_objects.find(property.typeName()); if (it != m_objects.end()) - property.setType(it->get()); + property.setType(*it); result->addProperty(property); } else { result->addProperty(property); @@ -56,7 +56,7 @@ ScopeTree *ImportedMembersVisitor::result(const QString &scopeName) const bool ImportedMembersVisitor::visit(UiObjectDefinition *definition) { - ScopeTree::Ptr scope(new ScopeTree(ScopeType::QMLScope)); + ScopeTree::Ptr scope = ScopeTree::create(); QString superType; for (auto segment = definition->qualifiedTypeNameId; segment; segment = segment->next) { if (!superType.isEmpty()) diff --git a/tools/qmllint/importedmembersvisitor.h b/tools/qmllint/importedmembersvisitor.h index 793ff18dcc..045ba00420 100644 --- a/tools/qmllint/importedmembersvisitor.h +++ b/tools/qmllint/importedmembersvisitor.h @@ -51,7 +51,7 @@ public: m_colorOut(colorOut) {} - ScopeTree *result(const QString &scopeName) const; + ScopeTree::Ptr result(const QString &scopeName) const; private: bool visit(QQmlJS::AST::UiObjectDefinition *) override; diff --git a/tools/shared/metatypes.h b/tools/shared/metatypes.h index d67de2edcd..0ab37d72ca 100644 --- a/tools/shared/metatypes.h +++ b/tools/shared/metatypes.h @@ -41,6 +41,7 @@ #include <QtCore/qstring.h> #include <QtCore/qstringlist.h> +#include <QtCore/qsharedpointer.h> class MetaEnum { @@ -119,7 +120,7 @@ class MetaProperty { QString m_propertyName; QString m_typeName; - const ScopeTree *m_type = nullptr; + QWeakPointer<const ScopeTree> m_type; bool m_isList; bool m_isWritable; bool m_isPointer; @@ -142,8 +143,8 @@ public: QString propertyName() const { return m_propertyName; } QString typeName() const { return m_typeName; } - void setType(const ScopeTree *type) { m_type = type; } - const ScopeTree *type() const { return m_type; } + void setType(const QSharedPointer<const ScopeTree> &type) { m_type = type; } + QSharedPointer<const ScopeTree> type() const { return m_type.toStrongRef(); } bool isList() const { return m_isList; } bool isWritable() const { return m_isWritable; } diff --git a/tools/shared/scopetree.cpp b/tools/shared/scopetree.cpp index 870ba13fc4..ea5175d2d6 100644 --- a/tools/shared/scopetree.cpp +++ b/tools/shared/scopetree.cpp @@ -33,17 +33,20 @@ #include <algorithm> -ScopeTree::ScopeTree(ScopeType type, QString name, ScopeTree *parentScope) - : m_parentScope(parentScope), m_name(std::move(name)), m_scopeType(type) {} - -ScopeTree::Ptr ScopeTree::createNewChildScope(ScopeType type, const QString &name) -{ - Q_ASSERT(type != ScopeType::QMLScope - || !m_parentScope - || m_parentScope->m_scopeType == ScopeType::QMLScope - || m_parentScope->m_name == QLatin1String("global")); - auto childScope = ScopeTree::Ptr(new ScopeTree{type, name, this}); - m_childScopes.push_back(childScope); +ScopeTree::ScopeTree(ScopeType type, const QString &name, const ScopeTree::Ptr &parentScope) + : m_parentScope(parentScope), m_name(name), m_scopeType(type) {} + +ScopeTree::Ptr ScopeTree::create(ScopeType type, const QString &name, + const ScopeTree::Ptr &parentScope) +{ + ScopeTree::Ptr childScope(new ScopeTree{type, name, parentScope}); + if (parentScope) { + Q_ASSERT(type != ScopeType::QMLScope + || !parentScope->m_parentScope + || parentScope->parentScope()->m_scopeType == ScopeType::QMLScope + || parentScope->parentScope()->m_name == QLatin1String("global")); + parentScope->m_childScopes.push_back(childScope); + } return childScope; } @@ -51,13 +54,13 @@ void ScopeTree::insertJSIdentifier(const QString &id, ScopeType scope) { Q_ASSERT(m_scopeType != ScopeType::QMLScope); Q_ASSERT(scope != ScopeType::QMLScope); - if (scope == ScopeType::JSFunctionScope) { - auto targetScope = this; - while (targetScope->scopeType() != ScopeType::JSFunctionScope) - targetScope = targetScope->m_parentScope; - targetScope->m_jsIdentifiers.insert(id); - } else { + if (scope != ScopeType::JSFunctionScope || m_scopeType == ScopeType::JSFunctionScope) { m_jsIdentifiers.insert(id); + } else { + auto targetScope = parentScope(); + while (targetScope->m_scopeType != ScopeType::JSFunctionScope) + targetScope = targetScope->parentScope(); + targetScope->m_jsIdentifiers.insert(id); } } @@ -101,13 +104,22 @@ void ScopeTree::accessMember(const QString &name, const QString &parentType, bool ScopeTree::isVisualRootScope() const { - return m_parentScope && m_parentScope->m_parentScope - && m_parentScope->m_parentScope->m_parentScope == nullptr; + if (!m_parentScope) + return false; + + const auto grandParent = parentScope()->m_parentScope.toStrongRef(); + if (!grandParent) + return false; + + return grandParent->m_parentScope == nullptr; } bool ScopeTree::isIdInCurrentQMlScopes(const QString &id) const { - const auto *qmlScope = currentQMLScope(); + if (m_scopeType == ScopeType::QMLScope) + return m_properties.contains(id) || m_methods.contains(id) || m_enums.contains(id); + + const auto qmlScope = findCurrentQMLScope(parentScope()); return qmlScope->m_properties.contains(id) || qmlScope->m_methods.contains(id) || qmlScope->m_enums.contains(id); @@ -115,25 +127,29 @@ bool ScopeTree::isIdInCurrentQMlScopes(const QString &id) const bool ScopeTree::isIdInCurrentJSScopes(const QString &id) const { - auto jsScope = this; - while (jsScope) { + if (m_scopeType != ScopeType::QMLScope && m_jsIdentifiers.contains(id)) + return true; + + for (auto jsScope = parentScope(); jsScope; jsScope = jsScope->parentScope()) { if (jsScope->m_scopeType != ScopeType::QMLScope && jsScope->m_jsIdentifiers.contains(id)) return true; - jsScope = jsScope->m_parentScope; } + return false; } bool ScopeTree::isIdInjectedFromSignal(const QString &id) const { - return currentQMLScope()->m_injectedSignalIdentifiers.contains(id); + if (m_scopeType == ScopeType::QMLScope) + return m_injectedSignalIdentifiers.contains(id); + return findCurrentQMLScope(parentScope())->m_injectedSignalIdentifiers.contains(id); } -const ScopeTree *ScopeTree::currentQMLScope() const +ScopeTree::ConstPtr ScopeTree::findCurrentQMLScope(const ScopeTree::ConstPtr &scope) { - auto qmlScope = this; + auto qmlScope = scope; while (qmlScope && qmlScope->m_scopeType != ScopeType::QMLScope) - qmlScope = qmlScope->m_parentScope; + qmlScope = qmlScope->parentScope(); return qmlScope; } @@ -148,7 +164,7 @@ void ScopeTree::setExportMetaObjectRevision(int exportIndex, int metaObjectRevis m_exports[exportIndex].setMetaObjectRevision(metaObjectRevision); } -void ScopeTree::updateParentProperty(const ScopeTree *scope) +void ScopeTree::updateParentProperty(const ScopeTree::ConstPtr &scope) { auto it = m_properties.find(QLatin1String("parent")); if (it != m_properties.end() diff --git a/tools/shared/scopetree.h b/tools/shared/scopetree.h index f28f2fa841..90f772ab98 100644 --- a/tools/shared/scopetree.h +++ b/tools/shared/scopetree.h @@ -67,7 +67,9 @@ class ScopeTree Q_DISABLE_COPY_MOVE(ScopeTree) public: using Ptr = QSharedPointer<ScopeTree>; + using WeakPtr = QWeakPointer<ScopeTree>; using ConstPtr = QSharedPointer<const ScopeTree>; + using WeakConstPtr = QWeakPointer<const ScopeTree>; class Export { public: @@ -93,11 +95,11 @@ public: int m_metaObjectRevision = 0; }; - ScopeTree(ScopeType type, QString name = QString(), - ScopeTree *parentScope = nullptr); + static ScopeTree::Ptr create(ScopeType type = ScopeType::QMLScope, const QString &name = QString(), + const ScopeTree::Ptr &parentScope = ScopeTree::Ptr()); + static ScopeTree::ConstPtr findCurrentQMLScope(const ScopeTree::ConstPtr &scope); - ScopeTree::Ptr createNewChildScope(ScopeType type, const QString &name); - ScopeTree *parentScope() const { return m_parentScope; } + ScopeTree::Ptr parentScope() const { return m_parentScope.toStrongRef(); } void insertJSIdentifier(const QString &id, ScopeType scope); void insertSignalIdentifier(const QString &id, const MetaMethod &method, @@ -139,7 +141,7 @@ public: void addProperty(const MetaProperty &prop) { m_properties.insert(prop.propertyName(), prop); } QHash<QString, MetaProperty> properties() const { return m_properties; } - void updateParentProperty(const ScopeTree *scope); + void updateParentProperty(const ScopeTree::ConstPtr &scope); QString defaultPropertyName() const { return m_defaultPropertyName; } void setDefaultPropertyName(const QString &name) { m_defaultPropertyName = name; } @@ -174,7 +176,6 @@ public: bool isIdInCurrentQMlScopes(const QString &id) const; bool isIdInCurrentJSScopes(const QString &id) const; bool isIdInjectedFromSignal(const QString &id) const; - const ScopeTree *currentQMLScope() const; QVector<ScopeTree::Ptr> childScopes() const { @@ -187,6 +188,8 @@ public: } private: + ScopeTree(ScopeType type, const QString &name = QString(), + const ScopeTree::Ptr &parentScope = ScopeTree::Ptr()); QSet<QString> m_jsIdentifiers; QMultiHash<QString, MethodUsage> m_injectedSignalIdentifiers; @@ -199,7 +202,7 @@ private: QVector<QPair<QString, QQmlJS::SourceLocation>> m_unmatchedSignalHandlers; QVector<ScopeTree::Ptr> m_childScopes; - ScopeTree *m_parentScope; + ScopeTree::WeakPtr m_parentScope; QString m_fileName; QString m_name; diff --git a/tools/shared/typedescriptionreader.cpp b/tools/shared/typedescriptionreader.cpp index 495ee57f32..3ca8e7e44a 100644 --- a/tools/shared/typedescriptionreader.cpp +++ b/tools/shared/typedescriptionreader.cpp @@ -188,7 +188,7 @@ void TypeDescriptionReader::readDependencies(UiScriptBinding *ast) void TypeDescriptionReader::readComponent(UiObjectDefinition *ast) { - ScopeTree::Ptr scope(new ScopeTree(ScopeType::QMLScope)); + ScopeTree::Ptr scope = ScopeTree::create(); for (UiObjectMemberList *it = ast->initializer->members; it; it = it->next) { UiObjectMember *member = it->member; |
