diff options
68 files changed, 532 insertions, 321 deletions
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index ed558082e1e..59a517a529d 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -57,6 +57,7 @@ add_qtc_library(QmlDesignerCore STATIC Utils Qt::Widgets Qt::Qml + Qt::QmlPrivate Core ProjectExplorer QmakeProjectManager @@ -92,7 +93,7 @@ extend_qtc_library(QmlDesignerCore CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND Qt6_VERSION VERSION_GREATER_EQUAL 6.5.0 DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate - DEFINES QDS_HAS_QMLDOM + PUBLIC_DEFINES QDS_HAS_QMLPRIVATE ) extend_qtc_library(QmlDesignerCore @@ -400,6 +401,7 @@ extend_qtc_library(QmlDesignerCore filesystem.cpp filesystem.h filestatus.h filestatuscache.cpp filestatuscache.h + modulescanner.cpp modulescanner.h nonlockingmutex.h projectstorageexceptions.cpp projectstorageexceptions.h projectstorageinterface.h diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp index 14f55efa3f8..90bcc54fddc 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.cpp @@ -95,7 +95,7 @@ void DesignerActionManagerView::nodeOrderChanged(const NodeListProperty &) setupContext(SelectionContext::UpdateMode::NodeHierachy); } -void DesignerActionManagerView::importsChanged(const QList<Import> &, const QList<Import> &) +void DesignerActionManagerView::importsChanged(const Imports &, const Imports &) { setupContext(); } diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.h b/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.h index 41210602b38..9ccfe4e7379 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.h +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanagerview.h @@ -37,7 +37,7 @@ public: void selectedNodesChanged(const QList<ModelNode> &, const QList<ModelNode> &) override; void nodeOrderChanged(const NodeListProperty &) override; - void importsChanged(const QList<Import> &, const QList<Import> &) override; + void importsChanged(const Imports &, const Imports &) override; void signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty> &/*propertyList*/, PropertyChangeFlags /*propertyChange*/) override; void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChangeFlag) override; void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChangeFlag) override; diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp index 39e05a898ca..56fcc7ef6bf 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp @@ -183,7 +183,7 @@ void ConnectionView::auxiliaryDataChanged([[maybe_unused]] const ModelNode &node selectionModel->clearSelection(); } -void ConnectionView::importsChanged(const QList<Import> & /*addedImports*/, const QList<Import> & /*removedImports*/) +void ConnectionView::importsChanged(const Imports & /*addedImports*/, const Imports & /*removedImports*/) { backendModel()->resetModel(); } diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionview.h b/src/plugins/qmldesigner/components/connectioneditor/connectionview.h index dcf61ad79d9..89c6c489105 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionview.h +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionview.h @@ -50,7 +50,7 @@ public: AuxiliaryDataKeyView key, const QVariant &data) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void currentStateChanged(const ModelNode &node) override; diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index 01932900e9e..105bfed89dd 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -144,7 +144,7 @@ void ContentLibraryView::modelAboutToBeDetached(Model *model) AbstractView::modelAboutToBeDetached(model); } -void ContentLibraryView::importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) +void ContentLibraryView::importsChanged(const Imports &addedImports, const Imports &removedImports) { Q_UNUSED(addedImports) Q_UNUSED(removedImports) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h index 1d27f6e260c..137034dd955 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h @@ -31,7 +31,7 @@ public: // AbstractView void modelAttached(Model *model) override; void modelAboutToBeDetached(Model *model) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void active3DSceneChanged(qint32 sceneId) override; void selectedNodesChanged(const QList<ModelNode> &selectedNodeList, const QList<ModelNode> &lastSelectedNodeList) override; diff --git a/src/plugins/qmldesigner/components/debugview/debugview.cpp b/src/plugins/qmldesigner/components/debugview/debugview.cpp index 2888575e44c..2a62d7a6b2b 100644 --- a/src/plugins/qmldesigner/components/debugview/debugview.cpp +++ b/src/plugins/qmldesigner/components/debugview/debugview.cpp @@ -65,7 +65,7 @@ void DebugView::modelAboutToBeDetached(Model *model) AbstractView::modelAboutToBeDetached(model); } -void DebugView::importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) +void DebugView::importsChanged(const Imports &addedImports, const Imports &removedImports) { if (isDebugViewEnabled()) { QString message; diff --git a/src/plugins/qmldesigner/components/debugview/debugview.h b/src/plugins/qmldesigner/components/debugview/debugview.h index 885030545cf..e80c619c818 100644 --- a/src/plugins/qmldesigner/components/debugview/debugview.h +++ b/src/plugins/qmldesigner/components/debugview/debugview.h @@ -24,7 +24,7 @@ public: void modelAttached(Model *model) override; void modelAboutToBeDetached(Model *model) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void nodeCreated(const ModelNode &createdNode) override; void nodeAboutToBeRemoved(const ModelNode &removedNode) override; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index d346e2bf164..39125c8f698 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -312,8 +312,8 @@ void Edit3DView::modelAboutToBeDetached(Model *model) AbstractView::modelAboutToBeDetached(model); } -void Edit3DView::importsChanged([[maybe_unused]] const QList<Import> &addedImports, - [[maybe_unused]] const QList<Import> &removedImports) +void Edit3DView::importsChanged([[maybe_unused]] const Imports &addedImports, + [[maybe_unused]] const Imports &removedImports) { checkImports(); } @@ -920,7 +920,7 @@ void Edit3DView::addQuick3DImport() { DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); if (document && !document->inFileComponentModelActive() && model()) { - const QList<Import> imports = model()->possibleImports(); + const Imports imports = model()->possibleImports(); for (const auto &import : imports) { if (import.url() == "QtQuick3D") { if (!import.version().isEmpty() && import.majorVersion() >= 6) { diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index 109555f586b..cd3e686d3bb 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -44,7 +44,7 @@ public: void updateActiveScene3D(const QVariantMap &sceneState) override; void modelAttached(Model *model) override; void modelAboutToBeDetached(Model *model) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override; void nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos3d) override; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index 1f4d5262852..5661e4ff793 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -253,7 +253,7 @@ void FormEditorView::modelAboutToBeDetached(Model *model) AbstractView::modelAboutToBeDetached(model); } -void FormEditorView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/) +void FormEditorView::importsChanged(const Imports &/*addedImports*/, const Imports &/*removedImports*/) { reset(); } diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.h b/src/plugins/qmldesigner/components/formeditor/formeditorview.h index fde20427628..f97959acb37 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.h @@ -48,7 +48,7 @@ public: void modelAttached(Model *model) override; void modelAboutToBeDetached(Model *model) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void nodeCreated(const ModelNode &createdNode) override; void nodeAboutToBeRemoved(const ModelNode &removedNode) override; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp index 5b46c1d12ef..41a9c6b5f4a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.cpp @@ -56,14 +56,14 @@ QHash<int, QByteArray> ItemLibraryAddImportModel::roleNames() const return m_roleNames; } -void ItemLibraryAddImportModel::update(const QList<Import> &possibleImports) +void ItemLibraryAddImportModel::update(const Imports &possibleImports) { beginResetModel(); m_importList.clear(); const DesignerMcuManager &mcuManager = DesignerMcuManager::instance(); const bool isQtForMCUs = mcuManager.isMCUProject(); - QList<Import> filteredImports; + Imports filteredImports; if (isQtForMCUs) { const QStringList mcuAllowedList = mcuManager.allowedImports(); const QStringList mcuBannedList = mcuManager.bannedImports(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.h index 5785b67301a..2989fd51642 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryaddimportmodel.h @@ -24,7 +24,7 @@ public: QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QHash<int, QByteArray> roleNames() const override; - void update(const QList<Import> &possibleImports); + void update(const Imports &possibleImports); void setSearchText(const QString &searchText); Import getImportAt(int index) const; @@ -33,7 +33,7 @@ public: private: QString m_searchText; - QList<Import> m_importList; + Imports m_importList; QSet<QString> m_importFilterList; QHash<int, QByteArray> m_roleNames; QSet<QString> m_priorityImports; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp index d9b82419433..e7002ff2503 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp @@ -709,9 +709,9 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport() model->rewriterView()->textModifier()->replace(0, 0, {}); } else if (counter < 100) { try { - const QList<Import> posImports = model->possibleImports(); - const QList<Import> currentImports = model->imports(); - QList<Import> newImportsToAdd; + const Imports posImports = model->possibleImports(); + const Imports currentImports = model->imports(); + Imports newImportsToAdd; for (auto &imp : std::as_const(m_requiredImports)) { const bool isPos = Utils::contains(posImports, [imp](const Import &posImp) { diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h index c7952e9b8f6..94413af392e 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h @@ -107,7 +107,7 @@ private: int m_currentImportId = 0; QHash<int, ParseData> m_parseData; QString m_progressTitle; - QList<Import> m_requiredImports; + Imports m_requiredImports; QList<int> m_puppetQueue; }; } // QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index 556d0c978fe..18430ca0179 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -343,7 +343,7 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model) materialBundlePrefix.append(".MaterialBundle"); // create import sections - const QList<Import> usedImports = model->usedImports(); + const Imports usedImports = model->usedImports(); QHash<QString, ItemLibraryImport *> importHash; for (const Import &import : model->imports()) { if (import.url() != projectName) { @@ -550,7 +550,7 @@ ItemLibraryImport *ItemLibraryModel::importByUrl(const QString &importUrl) const return nullptr; } -void ItemLibraryModel::updateUsedImports(const QList<Import> &usedImports) +void ItemLibraryModel::updateUsedImports(const Imports &usedImports) { // imports in the excludeList are not marked used and thus can always be removed even when in use. const QList<QString> excludeList = {"SimulinkConnector"}; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h index 4e9c5809c12..212ddf8e040 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h @@ -38,7 +38,7 @@ public: ItemLibraryImport *importByUrl(const QString &importName) const; void update(ItemLibraryInfo *itemLibraryInfo, Model *model); - void updateUsedImports(const QList<Import> &usedImports); + void updateUsedImports(const Imports &usedImports); QMimeData *getMimeData(const ItemLibraryEntry &itemLibraryEntry); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp index e8d1b584bfd..89b16fcd8e5 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp @@ -74,7 +74,7 @@ void ItemLibraryView::modelAboutToBeDetached(Model *model) m_widget->setModel(nullptr); } -void ItemLibraryView::importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) +void ItemLibraryView::importsChanged(const Imports &addedImports, const Imports &removedImports) { DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); for (const auto &import : addedImports) @@ -111,7 +111,7 @@ void ItemLibraryView::importsChanged(const QList<Import> &addedImports, const QL } } -void ItemLibraryView::possibleImportsChanged(const QList<Import> &possibleImports) +void ItemLibraryView::possibleImportsChanged(const Imports &possibleImports) { DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); for (const auto &import : possibleImports) @@ -120,7 +120,7 @@ void ItemLibraryView::possibleImportsChanged(const QList<Import> &possibleImport m_widget->updatePossibleImports(possibleImports); } -void ItemLibraryView::usedImportsChanged(const QList<Import> &usedImports) +void ItemLibraryView::usedImportsChanged(const Imports &usedImports) { m_widget->updateUsedImports(usedImports); } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h index e28f39318c0..43287ae0e5a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h @@ -26,9 +26,9 @@ public: // AbstractView void modelAttached(Model *model) override; void modelAboutToBeDetached(Model *model) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; - void possibleImportsChanged(const QList<Import> &possibleImports) override; - void usedImportsChanged(const QList<Import> &usedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; + void possibleImportsChanged(const Imports &possibleImports) override; + void usedImportsChanged(const Imports &usedImports) override; void documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings) override; void updateImport3DSupport(const QVariantMap &supportMap) override; void customNotification(const AbstractView *view, const QString &identifier, diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 549f9e69c10..1fafc91ea6a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -86,7 +86,7 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event) Import fileImport = Import::createFileImport(entry.requiredImport()); if (!m_model->hasImport(libImport, true, true) && !m_model->hasImport(fileImport, true, true)) { - const QList<Import> possImports = m_model->possibleImports(); + const Imports possImports = m_model->possibleImports(); for (const auto &possImport : possImports) { if ((!possImport.url().isEmpty() && possImport.url() == libImport.url()) || (!possImport.file().isEmpty() && possImport.file() == fileImport.file())) { @@ -246,7 +246,7 @@ void ItemLibraryWidget::handleAddImport(int index) + importStr); } - QList<Import> imports; + Imports imports; const QString dependency = getDependencyImport(import); auto document = QmlDesignerPlugin::instance()->currentDesignDocument(); @@ -346,13 +346,13 @@ void ItemLibraryWidget::updateModel() updateSearch(); } -void ItemLibraryWidget::updatePossibleImports(const QList<Import> &possibleImports) +void ItemLibraryWidget::updatePossibleImports(const Imports &possibleImports) { m_addModuleModel->update(possibleImports); delayedUpdateModel(); } -void ItemLibraryWidget::updateUsedImports(const QList<Import> &usedImports) +void ItemLibraryWidget::updateUsedImports(const Imports &usedImports) { m_itemLibraryModel->updateUsedImports(usedImports); } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index 394b3ea6103..38cd782d097 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -60,8 +60,8 @@ public: void switchToComponentsView(); void delayedUpdateModel(); void updateModel(); - void updatePossibleImports(const QList<Import> &possibleImports); - void updateUsedImports(const QList<Import> &usedImports); + void updatePossibleImports(const Imports &possibleImports); + void updateUsedImports(const Imports &usedImports); void setModel(Model *model); void setFlowMode(bool b); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 8e799336f85..5caf0169eec 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -469,8 +469,8 @@ ModelNode MaterialBrowserView::getMaterialOfModel(const ModelNode &model, int id return mat; } -void MaterialBrowserView::importsChanged([[maybe_unused]] const QList<Import> &addedImports, - [[maybe_unused]] const QList<Import> &removedImports) +void MaterialBrowserView::importsChanged([[maybe_unused]] const Imports &addedImports, + [[maybe_unused]] const Imports &removedImports) { bool hasQuick3DImport = model()->hasImport("QtQuick3D"); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index 811d6679b63..2e0227be413 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -44,7 +44,7 @@ public: void nodeAboutToBeRemoved(const ModelNode &removedNode) override; void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override; void instancesCompleted(const QVector<ModelNode> &completedNodeList) override; diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 47d47985ebd..9cb4959e132 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -974,8 +974,8 @@ void MaterialEditorView::modelNodePreviewPixmapChanged(const ModelNode &node, co m_qmlBackEnd->updateMaterialPreview(pixmap); } -void MaterialEditorView::importsChanged([[maybe_unused]] const QList<Import> &addedImports, - [[maybe_unused]] const QList<Import> &removedImports) +void MaterialEditorView::importsChanged([[maybe_unused]] const Imports &addedImports, + [[maybe_unused]] const Imports &removedImports) { m_hasQuick3DImport = model()->hasImport("QtQuick3D"); m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport); diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h index d47d030e57b..c201742bd51 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h @@ -55,7 +55,7 @@ public: void nodeTypeChanged(const ModelNode& node, const TypeName &type, int majorVersion, int minorVersion) override; void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override; void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override; void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 62868290285..9dcf81a1738 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -901,7 +901,7 @@ void NavigatorTreeModel::addImport(const QString &importName) { Import import = Import::createLibraryImport(importName); if (!m_view->model()->hasImport(import, true, true)) { - const QList<Import> possImports = m_view->model()->possibleImports(); + const Imports possImports = m_view->model()->possibleImports(); for (const auto &possImport : possImports) { if (possImport.url() == import.url()) { import = possImport; diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 28481aae798..97c7285d49d 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -228,7 +228,7 @@ void NavigatorView::modelAboutToBeDetached(Model *model) AbstractView::modelAboutToBeDetached(model); } -void NavigatorView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/) +void NavigatorView::importsChanged(const Imports &/*addedImports*/, const Imports &/*removedImports*/) { treeWidget()->update(); } diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.h b/src/plugins/qmldesigner/components/navigator/navigatorview.h index f5fa81591d9..662b749ecec 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.h +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.h @@ -50,7 +50,7 @@ public: void modelAttached(Model *model) override; void modelAboutToBeDetached(Model *model) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void nodeAboutToBeRemoved(const ModelNode &removedNode) override; void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange) override; diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp index 1921487aa0b..6c6102036ac 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp +++ b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp @@ -103,7 +103,7 @@ void TextEditorView::modelAboutToBeDetached(Model *model) } } -void TextEditorView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/) +void TextEditorView::importsChanged(const Imports &/*addedImports*/, const Imports &/*removedImports*/) { } diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorview.h b/src/plugins/qmldesigner/components/texteditor/texteditorview.h index b1865e78f9f..e50372279d9 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorview.h +++ b/src/plugins/qmldesigner/components/texteditor/texteditorview.h @@ -34,7 +34,7 @@ public: void modelAttached(Model *model) override; void modelAboutToBeDetached(Model *model) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void nodeAboutToBeRemoved(const ModelNode &removedNode) override; void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) override; diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp index 38664c146e4..a4132d0eb7a 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp @@ -720,8 +720,8 @@ void TextureEditorView::instancePropertyChanged(const QList<QPair<ModelNode, Pro m_locked = false; } -void TextureEditorView::importsChanged([[maybe_unused]] const QList<Import> &addedImports, - [[maybe_unused]] const QList<Import> &removedImports) +void TextureEditorView::importsChanged([[maybe_unused]] const Imports &addedImports, + [[maybe_unused]] const Imports &removedImports) { m_hasQuick3DImport = model()->hasImport("QtQuick3D"); m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport); diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h index b299a1e99ae..7baa07e9d30 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h @@ -58,7 +58,7 @@ public: void currentStateChanged(const ModelNode &node) override; void instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &propertyList) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) override; diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index 2d886d959be..0c3df94030c 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -195,9 +195,9 @@ public: const ModelNode &movedNode, int oldIndex); - virtual void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports); - virtual void possibleImportsChanged(const QList<Import> &possibleImports); - virtual void usedImportsChanged(const QList<Import> &usedImports); + virtual void importsChanged(const Imports &addedImports, const Imports &removedImports); + virtual void possibleImportsChanged(const Imports &possibleImports); + virtual void usedImportsChanged(const Imports &usedImports); virtual void auxiliaryDataChanged(const ModelNode &node, AuxiliaryDataKeyView type, diff --git a/src/plugins/qmldesigner/designercore/include/externaldependenciesinterface.h b/src/plugins/qmldesigner/designercore/include/externaldependenciesinterface.h index 7b2b8a2c55f..d6af071a30a 100644 --- a/src/plugins/qmldesigner/designercore/include/externaldependenciesinterface.h +++ b/src/plugins/qmldesigner/designercore/include/externaldependenciesinterface.h @@ -40,6 +40,7 @@ public: virtual PuppetStartData puppetStartData(const class Model &model) const = 0; virtual bool instantQmlTextUpdate() const = 0; virtual Utils::FilePath qmlPuppetPath() const = 0; + virtual QStringList modulePaths() const = 0; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/forwardview.h b/src/plugins/qmldesigner/designercore/include/forwardview.h index 7041e851096..386ac83141c 100644 --- a/src/plugins/qmldesigner/designercore/include/forwardview.h +++ b/src/plugins/qmldesigner/designercore/include/forwardview.h @@ -44,7 +44,7 @@ public: void fileUrlChanged(const QUrl &oldUrl, const QUrl &newUrl) override; void nodeOrderChanged(const NodeListProperty &listProperty) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void auxiliaryDataChanged(const ModelNode &node, const PropertyName &name, const QVariant &data) override; @@ -197,7 +197,7 @@ void ForwardView<ViewType>::nodeOrderChanged(const NodeListProperty &listPropert } template <class ViewType> -void ForwardView<ViewType>::importChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) +void ForwardView<ViewType>::importChanged(const Imports &addedImports, const Imports &removedImports) { for (const ViewTypePointer &view : std::as_const(m_targetViewList)) view->importChanged(addedImport, removedImport); diff --git a/src/plugins/qmldesigner/designercore/include/import.h b/src/plugins/qmldesigner/designercore/include/import.h index b221b861732..ff9e90f162f 100644 --- a/src/plugins/qmldesigner/designercore/include/import.h +++ b/src/plugins/qmldesigner/designercore/include/import.h @@ -56,6 +56,8 @@ private: QMLDESIGNERCORE_EXPORT size_t qHash(const Import &import); +using Imports = QList<Import>; + } // namespace QmlDesigner Q_DECLARE_METATYPE(QmlDesigner::Import) diff --git a/src/plugins/qmldesigner/designercore/include/model.h b/src/plugins/qmldesigner/designercore/include/model.h index f3227361e68..d36086777d8 100644 --- a/src/plugins/qmldesigner/designercore/include/model.h +++ b/src/plugins/qmldesigner/designercore/include/model.h @@ -115,12 +115,12 @@ public: // Editing sub-components: // Imports: - const QList<Import> &imports() const; - const QList<Import> &possibleImports() const; - const QList<Import> &usedImports() const; - void changeImports(const QList<Import> &importsToBeAdded, const QList<Import> &importsToBeRemoved); - void setPossibleImports(const QList<Import> &possibleImports); - void setUsedImports(const QList<Import> &usedImports); + const Imports &imports() const; + const Imports &possibleImports() const; + const Imports &usedImports() const; + void changeImports(const Imports &importsToBeAdded, const Imports &importsToBeRemoved); + void setPossibleImports(const Imports &possibleImports); + void setUsedImports(const Imports &usedImports); bool hasImport(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false) const; bool isImportPossible(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false) const; QString pathForImport(const Import &import); diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h index 11017a27b1c..0a9af39fc5e 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h @@ -85,7 +85,7 @@ public: void fileUrlChanged(const QUrl &oldUrl, const QUrl &newUrl) override; void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) override; void nodeOrderChanged(const NodeListProperty &listProperty) override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; void auxiliaryDataChanged(const ModelNode &node, AuxiliaryDataKeyView key, const QVariant &data) override; diff --git a/src/plugins/qmldesigner/designercore/include/rewriterview.h b/src/plugins/qmldesigner/designercore/include/rewriterview.h index 9387fdb345e..95e2e51d8a1 100644 --- a/src/plugins/qmldesigner/designercore/include/rewriterview.h +++ b/src/plugins/qmldesigner/designercore/include/rewriterview.h @@ -84,7 +84,7 @@ public: void rewriterBeginTransaction() override; void rewriterEndTransaction() override; - void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; TextModifier *textModifier() const; void setTextModifier(TextModifier *textModifier); diff --git a/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h b/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h index 207f1b7104b..dbc89c1cccd 100644 --- a/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h +++ b/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h @@ -27,7 +27,7 @@ public: explicit SubComponentManager(Model *model, class ExternalDependenciesInterface &externalDependencies); - void update(const QUrl &fileUrl, const QList<Import> &imports); + void update(const QUrl &fileUrl, const Imports &imports); void addAndParseImport(const Import &import); QStringList qmlFiles() const; @@ -53,7 +53,7 @@ private: // functions private: // variables QFileSystemWatcher m_watcher; - QList<Import> m_imports; + Imports m_imports; // key: canonical directory path QMultiHash<QString,QString> m_dirToQualifier; QUrl m_filePath; diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index ebe5acd9d28..bd28ce2069e 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -625,7 +625,7 @@ void NodeInstanceView::nodeOrderChanged(const NodeListProperty &listProperty) m_nodeInstanceServer->reparentInstances(ReparentInstancesCommand(containerList)); } -void NodeInstanceView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/) +void NodeInstanceView::importsChanged(const Imports &/*addedImports*/, const Imports &/*removedImports*/) { restartProcess(); } diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index f4b505c4e70..bebd01b422f 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -768,7 +768,7 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, TypeName type, int maj, i } } else { m_isFileComponent = true; - const Imports *imports = context()->imports(document()); + const auto *imports = context()->imports(document()); const ImportInfo importInfo = imports->info(lookupNameComponent().constLast(), context().data()); @@ -791,7 +791,7 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, TypeName type, int maj, i } else { // Special case for aliased types for the rewriter - const Imports *imports = context()->imports(document()); + const auto *imports = context()->imports(document()); const ImportInfo importInfo = imports->info(QString::fromUtf8(m_qualfiedTypeName), context().data()); if (importInfo.isValid()) { @@ -1198,7 +1198,7 @@ QString NodeMetaInfoPrivate::importDirectoryPath() const ModelManagerInterface *modelManager = ModelManagerInterface::instance(); if (isValid()) { - const Imports *imports = context()->imports(document()); + const auto *imports = context()->imports(document()); ImportInfo importInfo = imports->info(lookupNameComponent().constLast(), context().data()); if (importInfo.type() == ImportType::Directory) { @@ -1333,7 +1333,7 @@ void NodeMetaInfoPrivate::setupPrototypes() m_prototypes.append(description); } else { if (context()->lookupType(document(), {ov->className()})) { - const Imports *allImports = context()->imports(document()); + const auto *allImports = context()->imports(document()); ImportInfo importInfo = allImports->info(description.className, context().data()); if (importInfo.isValid()) { diff --git a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp index e7feb0d4454..0afd0d735c7 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp @@ -491,7 +491,7 @@ QStringList SubComponentManager::qmlFiles() const return m_watcher.files(); } -void SubComponentManager::update(const QUrl &filePath, const QList<Import> &imports) +void SubComponentManager::update(const QUrl &filePath, const Imports &imports) { if (debug) qDebug() << Q_FUNC_INFO << filePath << imports.size(); diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index b9f0315c196..ec6ddb6aa43 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -315,15 +315,15 @@ void AbstractView::nodeTypeChanged(const ModelNode & /*node*/, const TypeName & } -void AbstractView::importsChanged(const QList<Import> &/*addedImports*/, const QList<Import> &/*removedImports*/) +void AbstractView::importsChanged(const Imports &/*addedImports*/, const Imports &/*removedImports*/) { } -void AbstractView::possibleImportsChanged(const QList<Import> &/*possibleImports*/) +void AbstractView::possibleImportsChanged(const Imports &/*possibleImports*/) { } -void AbstractView::usedImportsChanged(const QList<Import> &/*usedImports*/) +void AbstractView::usedImportsChanged(const Imports &/*usedImports*/) { } @@ -893,7 +893,7 @@ QmlTimeline AbstractView::currentTimeline() const static int getMinorVersionFromImport(const Model *model) { - const QList<Import> imports = model->imports(); + const Imports imports = model->imports(); for (const Import &import : imports) { if (import.isLibraryImport() && import.url() == "QtQuick") { const QString versionString = import.version(); @@ -909,7 +909,7 @@ static int getMinorVersionFromImport(const Model *model) static int getMajorVersionFromImport(const Model *model) { - const QList<Import> imports = model->imports(); + const Imports imports = model->imports(); for (const Import &import : imports) { if (import.isLibraryImport() && import.url() == QStringLiteral("QtQuick")) { const QString versionString = import.version(); diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 13197666fc4..33571cc3ce1 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -108,10 +108,10 @@ void ModelPrivate::detachAllViews() } } -void ModelPrivate::changeImports(const QList<Import> &toBeAddedImportList, - const QList<Import> &toBeRemovedImportList) +void ModelPrivate::changeImports(const Imports &toBeAddedImportList, + const Imports &toBeRemovedImportList) { - QList<Import> removedImportList; + Imports removedImportList; for (const Import &import : toBeRemovedImportList) { if (m_imports.contains(import)) { removedImportList.append(import); @@ -119,7 +119,7 @@ void ModelPrivate::changeImports(const QList<Import> &toBeAddedImportList, } } - QList<Import> addedImportList; + Imports addedImportList; for (const Import &import : toBeAddedImportList) { if (!m_imports.contains(import)) { addedImportList.append(import); @@ -131,8 +131,7 @@ void ModelPrivate::changeImports(const QList<Import> &toBeAddedImportList, notifyImportsChanged(addedImportList, removedImportList); } -void ModelPrivate::notifyImportsChanged(const QList<Import> &addedImports, - const QList<Import> &removedImports) +void ModelPrivate::notifyImportsChanged(const Imports &addedImports, const Imports &removedImports) { bool resetModel = false; QString description; @@ -157,7 +156,7 @@ void ModelPrivate::notifyImportsChanged(const QList<Import> &addedImports, resetModelByRewriter(description); } -void ModelPrivate::notifyPossibleImportsChanged(const QList<Import> &possibleImports) +void ModelPrivate::notifyPossibleImportsChanged(const Imports &possibleImports) { for (const QPointer<AbstractView> &view : enabledViews()) { Q_ASSERT(view != nullptr); @@ -165,7 +164,7 @@ void ModelPrivate::notifyPossibleImportsChanged(const QList<Import> &possibleImp } } -void ModelPrivate::notifyUsedImportsChanged(const QList<Import> &usedImports) +void ModelPrivate::notifyUsedImportsChanged(const Imports &usedImports) { for (const QPointer<AbstractView> &view : enabledViews()) { Q_ASSERT(view != nullptr); @@ -1400,28 +1399,27 @@ Model::Model(const TypeName &typeName, int major, int minor, Model *metaInfoProx Model::~Model() = default; -const QList<Import> &Model::imports() const +const Imports &Model::imports() const { return d->imports(); } -const QList<Import> &Model::possibleImports() const +const Imports &Model::possibleImports() const { return d->m_possibleImportList; } -const QList<Import> &Model::usedImports() const +const Imports &Model::usedImports() const { return d->m_usedImportList; } -void Model::changeImports(const QList<Import> &importsToBeAdded, - const QList<Import> &importsToBeRemoved) +void Model::changeImports(const Imports &importsToBeAdded, const Imports &importsToBeRemoved) { d->changeImports(importsToBeAdded, importsToBeRemoved); } -void Model::setPossibleImports(const QList<Import> &possibleImports) +void Model::setPossibleImports(const Imports &possibleImports) { if (d->m_possibleImportList != possibleImports) { d->m_possibleImportList = possibleImports; @@ -1429,7 +1427,7 @@ void Model::setPossibleImports(const QList<Import> &possibleImports) } } -void Model::setUsedImports(const QList<Import> &usedImports) +void Model::setUsedImports(const Imports &usedImports) { if (d->m_usedImportList != usedImports) { d->m_usedImportList = usedImports; diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index b08b7388518..95985482548 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -202,13 +202,13 @@ public: void resetModelByRewriter(const QString &description); // Imports: - const QList<Import> &imports() const { return m_imports; } + const Imports &imports() const { return m_imports; } void addImport(const Import &import); void removeImport(const Import &import); - void changeImports(const QList<Import> &importsToBeAdded, const QList<Import> &importToBeRemoved); - void notifyImportsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports); - void notifyPossibleImportsChanged(const QList<Import> &possibleImports); - void notifyUsedImportsChanged(const QList<Import> &usedImportsChanged); + void changeImports(const Imports &importsToBeAdded, const Imports &importToBeRemoved); + void notifyImportsChanged(const Imports &addedImports, const Imports &removedImports); + void notifyPossibleImportsChanged(const Imports &possibleImports); + void notifyUsedImportsChanged(const Imports &usedImportsChanged); //node state property manipulation void addProperty(const InternalNodePointer &node, const PropertyName &name); @@ -269,9 +269,9 @@ private: private: Model *m_model = nullptr; MetaInfo m_metaInfo; - QList<Import> m_imports; - QList<Import> m_possibleImportList; - QList<Import> m_usedImportList; + Imports m_imports; + Imports m_possibleImportList; + Imports m_usedImportList; QList<QPointer<AbstractView>> m_viewList; QList<QPointer<AbstractView>> m_enabledViewList; QList<InternalNodePointer> m_selectedInternalNodeList; diff --git a/src/plugins/qmldesigner/designercore/model/modelmerger.cpp b/src/plugins/qmldesigner/designercore/model/modelmerger.cpp index 75cdcf83582..30d100f3503 100644 --- a/src/plugins/qmldesigner/designercore/model/modelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelmerger.cpp @@ -173,7 +173,7 @@ ModelNode ModelMerger::insertModel(const ModelNode &modelNode, const MergePredic return {}; RewriterTransaction transaction(view()->beginRewriterTransaction(QByteArrayLiteral("ModelMerger::insertModel"))); - QList<Import> newImports; + Imports newImports; for (const Import &import : modelNode.model()->imports()) { if (!view()->model()->hasImport(import, true, true)) diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp index d8088de64be..53a0f4de596 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp @@ -261,7 +261,7 @@ void RewriterView::nodeReparented(const ModelNode &node, const NodeAbstractPrope applyChanges(); } -void RewriterView::importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) +void RewriterView::importsChanged(const Imports &addedImports, const Imports &removedImports) { for (const Import &import : addedImports) importAdded(import); diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 236b690bb4f..bb09d664a77 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -19,6 +19,7 @@ #include "signalhandlerproperty.h" #include "variantproperty.h" #include <externaldependenciesinterface.h> +#include <projectstorage/modulescanner.h> #include <rewritingexception.h> #include <enumeration.h> @@ -44,6 +45,7 @@ #include <QSet> #include <memory> +#include <tuple> using namespace LanguageUtils; using namespace QmlJS; @@ -716,7 +718,7 @@ bool TextToModelMerger::isActive() const void TextToModelMerger::setupImports(const Document::Ptr &doc, DifferenceHandler &differenceHandler) { - QList<Import> existingImports = m_rewriterView->model()->imports(); + Imports existingImports = m_rewriterView->model()->imports(); m_hasVersionlessImport = false; @@ -756,162 +758,125 @@ void TextToModelMerger::setupImports(const Document::Ptr &doc, differenceHandler.importAbsentInQMl(import); } -static bool isLatestImportVersion(const ImportKey &importKey, const QHash<QString, ImportKey> &filteredPossibleImportKeys) +namespace { + +bool skipByMetaInfo(QStringView moduleName, const QStringList &skipModuleNames) { - return !filteredPossibleImportKeys.contains(importKey.path()) - || filteredPossibleImportKeys.value(importKey.path()).majorVersion < importKey.majorVersion - || (filteredPossibleImportKeys.value(importKey.path()).majorVersion == importKey.majorVersion - && filteredPossibleImportKeys.value(importKey.path()).minorVersion < importKey.minorVersion); + return std::any_of(skipModuleNames.begin(), + skipModuleNames.end(), + [&](const QString &skipModuleName) { + return moduleName.contains(skipModuleName); + }); } -static bool filterByMetaInfo(const ImportKey &importKey, Model *model) +class StartsWith : public QStringView { - if (model) { - for (const QString &filter : model->metaInfo().itemLibraryInfo()->blacklistImports()) { - if (importKey.libraryQualifiedPath().contains(filter)) - return true; - } +public: + using QStringView::QStringView; + bool operator()(QStringView moduleName) const { return moduleName.startsWith(*this); } +}; +class EndsWith : public QStringView +{ +public: + using QStringView::QStringView; + bool operator()(QStringView moduleName) const { return moduleName.endsWith(*this); } +}; + +class StartsAndEndsWith : public std::pair<QStringView, QStringView> +{ +public: + using Base = std::pair<QStringView, QStringView>; + using Base::Base; + bool operator()(QStringView moduleName) const + { + return moduleName.startsWith(first) && moduleName.endsWith(second); } +}; - return false; -} +class Equals : public QStringView +{ +public: + using QStringView::QStringView; + bool operator()(QStringView moduleName) const { return moduleName == *this; } +}; -static bool isBlacklistImport(const ImportKey &importKey, Model *model) -{ - const QString &importPathFirst = importKey.splitPath.constFirst(); - const QString &importPathLast = importKey.splitPath.constLast(); - return importPathFirst == QStringLiteral("<cpp>") - || importPathFirst == QStringLiteral("QML") - || importPathFirst == QStringLiteral("QtQml") - || (importPathFirst == QStringLiteral("QtQuick") && importPathLast == QStringLiteral("PrivateWidgets")) - || importPathLast == QStringLiteral("Private") - || importPathLast == QStringLiteral("private") - || importKey.libraryQualifiedPath() == QStringLiteral("QtQuick.Particles") //Unsupported - || importKey.libraryQualifiedPath() == QStringLiteral("QtQuick.Dialogs") //Unsupported - || importKey.libraryQualifiedPath() == QStringLiteral("QtQuick.Controls.Styles") //Unsupported - || importKey.libraryQualifiedPath() == QStringLiteral("QtNfc") //Unsupported - || importKey.libraryQualifiedPath() == QStringLiteral("Qt.WebSockets") - || importKey.libraryQualifiedPath() == QStringLiteral("QtWebkit") - || importKey.libraryQualifiedPath() == QStringLiteral("QtLocation") - || importKey.libraryQualifiedPath() == QStringLiteral("QtWebChannel") - || importKey.libraryQualifiedPath() == QStringLiteral("QtWinExtras") - || importKey.libraryQualifiedPath() == QStringLiteral("QtPurchasing") - || importKey.libraryQualifiedPath() == QStringLiteral("QtBluetooth") - || importKey.libraryQualifiedPath() == QStringLiteral("Enginio") - - || filterByMetaInfo(importKey, model); -} - -static QHash<QString, ImportKey> filterPossibleImportKeys(const QSet<ImportKey> &possibleImportKeys, Model *model) -{ - QHash<QString, ImportKey> filteredPossibleImportKeys; - for (const ImportKey &importKey : possibleImportKeys) { - if (isLatestImportVersion(importKey, filteredPossibleImportKeys) && !isBlacklistImport(importKey, model)) - filteredPossibleImportKeys.insert(importKey.path(), importKey); - } +constexpr auto skipModules = std::make_tuple(EndsWith(u".impl"), + StartsWith(u"QML"), + StartsWith(u"QtQml"), + StartsAndEndsWith(u"QtQuick", u".PrivateWidgets"), + EndsWith(u".private"), + EndsWith(u".Private"), + Equals(u"QtQuick.Particles"), + Equals(u"QtQuick.Dialogs"), + Equals(u"QtQuick.Controls.Styles"), + Equals(u"QtNfc"), + Equals(u"Qt.WebSockets"), + Equals(u"QtWebkit"), + Equals(u"QtLocation"), + Equals(u"QtWebChannel"), + Equals(u"QtWinExtras"), + Equals(u"QtPurchasing"), + Equals(u"QtBluetooth"), + Equals(u"Enginio")); - return filteredPossibleImportKeys; +bool skipModule(QStringView moduleName) +{ + return std::apply([=](const auto &...skipModule) { return (skipModule(moduleName) || ...); }, + skipModules); } -static void removeUsedImports(QHash<QString, ImportKey> &filteredPossibleImportKeys, const QList<QmlJS::Import> &usedImports) +bool skipModule(QStringView moduleName, const QStringList &skipModuleNames) { - for (const QmlJS::Import &import : usedImports) - filteredPossibleImportKeys.remove(import.info.path()); + return skipModule(moduleName) || skipByMetaInfo(moduleName, skipModuleNames); } -static QList<QmlDesigner::Import> generatePossibleFileImports(const QString &path, - const QList<QmlJS::Import> &usedImports) +void collectPossibleFileImports(const QString &checkPath, + QSet<QString> usedImportsSet, + QList<QmlDesigner::Import> &possibleImports) { - QSet<QString> usedImportsSet; - for (const QmlJS::Import &i : usedImports) - usedImportsSet.insert(i.info.path()); - - QList<QmlDesigner::Import> possibleImports; const QStringList qmlList("*.qml"); const QStringList qmldirList("qmldir"); - - QStringList fileImportPaths; const QChar delimeter('/'); - std::function<void(const QString &)> checkDir; - checkDir = [&](const QString &checkPath) { - - if (QFileInfo(checkPath).isRoot()) - return; + if (QFileInfo(checkPath).isRoot()) + return; - const QStringList entries = QDir(checkPath).entryList(QDir::Dirs | QDir::NoDot | QDir::NoDotDot); - const QString checkPathDelim = checkPath + delimeter; - for (const QString &entry : entries) { - QDir dir(checkPathDelim + entry); - const QString dirPath = dir.path(); - if (!dir.entryInfoList(qmlList, QDir::Files).isEmpty() - && dir.entryInfoList(qmldirList, QDir::Files).isEmpty() - && !usedImportsSet.contains(dirPath)) { - const QString importName = dir.path().mid(path.size() + 1); - QmlDesigner::Import import = QmlDesigner::Import::createFileImport(importName); - possibleImports.append(import); - } - checkDir(dirPath); + const QStringList entries = QDir(checkPath).entryList(QDir::Dirs | QDir::NoDot | QDir::NoDotDot); + const QString checkPathDelim = checkPath + delimeter; + for (const QString &entry : entries) { + QDir dir(checkPathDelim + entry); + const QString dirPath = dir.path(); + if (!dir.entryInfoList(qmlList, QDir::Files).isEmpty() + && dir.entryInfoList(qmldirList, QDir::Files).isEmpty() + && !usedImportsSet.contains(dirPath)) { + const QString importName = dir.path().mid(checkPath.size() + 1); + QmlDesigner::Import import = QmlDesigner::Import::createFileImport(importName); + possibleImports.append(import); } - }; - checkDir(path); - - return possibleImports; + collectPossibleFileImports(dirPath, usedImportsSet, possibleImports); + } } -static QList<QmlDesigner::Import> generatePossibleLibraryImports(const QHash<QString, ImportKey> &filteredPossibleImportKeys) +QList<QmlDesigner::Import> generatePossibleFileImports(const QString &path, + const QList<QmlJS::Import> &usedImports) { - QList<QmlDesigner::Import> possibleImports; - QSet<QString> controlsImplVersions; - bool hasVersionedControls = false; - bool hasVersionlessControls = false; - const QString controlsName = "QtQuick.Controls"; - const QString controlsImplName = "QtQuick.Controls.impl"; - - for (const ImportKey &importKey : filteredPossibleImportKeys) { - QString libraryName = importKey.splitPath.join(QLatin1Char('.')); - int majorVersion = importKey.majorVersion; - if (majorVersion >= 0) { - int minorVersion = (importKey.minorVersion == LanguageUtils::ComponentVersion::NoVersion) ? 0 : importKey.minorVersion; - - if (libraryName.contains("QtQuick.Studio")) { - majorVersion = 1; - minorVersion = 0; - } + QSet<QString> usedImportsSet; + for (const QmlJS::Import &i : usedImports) + usedImportsSet.insert(i.info.path()); - QString version = QStringLiteral("%1.%2").arg(majorVersion).arg(minorVersion); - if (!libraryName.endsWith(".impl")) - possibleImports.append(QmlDesigner::Import::createLibraryImport(libraryName, version)); - - // In Qt6, QtQuick.Controls itself doesn't have any version as it has no types, - // so it never gets added normally to possible imports. - // We work around this by injecting corresponding QtQuick.Controls version for each - // found impl version, if no valid QtQuick.Controls versions are found. - if (!hasVersionedControls) { - if (libraryName == controlsImplName) - controlsImplVersions.insert(version); - else if (libraryName == controlsName) - hasVersionedControls = true; - } - } else if (!hasVersionlessControls && libraryName == controlsName) { - // If QtQuick.Controls module is not included even in non-versioned, it means - // QtQuick.Controls is either in use or not available at all, - // so we shouldn't inject it. - hasVersionlessControls = true; - } - } + QList<QmlDesigner::Import> possibleImports; - if (hasVersionlessControls && !hasVersionedControls && !controlsImplVersions.isEmpty()) { - for (const auto &version : std::as_const(controlsImplVersions)) - possibleImports.append(QmlDesigner::Import::createLibraryImport(controlsName, version)); - } + QStringList fileImportPaths; + collectPossibleFileImports(path, usedImportsSet, possibleImports); return possibleImports; } -void TextToModelMerger::setupPossibleImports(const QmlJS::Snapshot &snapshot, const QmlJS::ViewerContext &viewContext) +} // namespace + +void TextToModelMerger::setupPossibleImports() { if (!m_rewriterView->possibleImportsEnabled()) return; @@ -919,27 +884,25 @@ void TextToModelMerger::setupPossibleImports(const QmlJS::Snapshot &snapshot, co static QUrl lastProjectUrl; auto &externalDependencies = m_rewriterView->externalDependencies(); auto projectUrl = externalDependencies.projectUrl(); - - if (m_possibleImportKeys.isEmpty() || projectUrl != lastProjectUrl) - m_possibleImportKeys = snapshot.importDependencies()->libraryImports(viewContext); + auto allUsedImports = m_scopeChain->context()->imports(m_document.data())->all(); + + if (m_possibleModules.isEmpty() || projectUrl != lastProjectUrl) { + const auto skipModuleNames = m_rewriterView->model()->metaInfo().itemLibraryInfo()->blacklistImports(); + ModuleScanner moduleScanner{ + [&](QStringView moduleName) { return skipModule(moduleName, skipModuleNames); }}; + moduleScanner.scan(m_rewriterView->externalDependencies().modulePaths()); + m_possibleModules = moduleScanner.modules(); + } lastProjectUrl = projectUrl; - QHash<QString, ImportKey> filteredPossibleImportKeys = filterPossibleImportKeys( - m_possibleImportKeys, m_rewriterView->model()); - - const QmlJS::Imports *imports = m_scopeChain->context()->imports(m_document.data()); - if (imports) - removeUsedImports(filteredPossibleImportKeys, imports->all()); - - QList<QmlDesigner::Import> possibleImports = generatePossibleLibraryImports(filteredPossibleImportKeys); + auto modules = m_possibleModules; if (document()->fileName() != "<internal>") - possibleImports.append( - generatePossibleFileImports(document()->path().toString(), imports->all())); + modules.append(generatePossibleFileImports(document()->path().toString(), allUsedImports)); if (m_rewriterView->isAttached()) - m_rewriterView->model()->setPossibleImports(possibleImports); + m_rewriterView->model()->setPossibleImports(modules); } void TextToModelMerger::setupUsedImports() @@ -951,7 +914,7 @@ void TextToModelMerger::setupUsedImports() const QList<QmlJS::Import> allImports = imports->all(); QSet<QString> usedImportsSet; - QList<Import> usedImports; + Imports usedImports; // populate usedImportsSet from current model nodes const QList<ModelNode> allModelNodes = m_rewriterView->allModelNodes(); @@ -964,9 +927,6 @@ void TextToModelMerger::setupUsedImports() for (const QmlJS::Import &import : allImports) { QString version = import.info.version().toString(); - if (!import.info.version().isValid()) - version = getHighestPossibleImport(import.info.name()); - if (!import.info.name().isEmpty() && usedImportsSet.contains(import.info.name())) { if (import.info.type() == ImportType::Library) usedImports.append( @@ -1077,7 +1037,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH collectLinkErrors(&errors, ctxt); } - setupPossibleImports(snapshot, m_vContext); + setupPossibleImports(); qCInfo(rewriterBenchmark) << "possible imports:" << time.elapsed(); @@ -1115,12 +1075,6 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH setActive(false); - // Clear possible imports cache if code model hasn't settled yet - const int importKeysSize = m_possibleImportKeys.size(); - if (m_previousPossibleImportsSize != importKeysSize) - m_possibleImportKeys.clear(); - m_previousPossibleImportsSize = importKeysSize; - return true; } catch (Exception &e) { DocumentMessage error(&e); @@ -2387,8 +2341,8 @@ QList<QmlTypeData> TextToModelMerger::getQMLSingletons() const void TextToModelMerger::clearPossibleImportKeys() { - m_possibleImportKeys.clear(); - m_previousPossibleImportsSize = -1; + m_possibleModules.clear(); + m_previousPossibleModulesSize = -1; } QString TextToModelMerger::textAt(const Document::Ptr &doc, @@ -2403,19 +2357,3 @@ QString TextToModelMerger::textAt(const Document::Ptr &doc, { return doc->source().mid(from.offset, to.end() - from.begin()); } - -QString TextToModelMerger::getHighestPossibleImport(const QString &importName) const -{ - QString version = "2.15"; - int maj = -1; - const auto imports = m_possibleImportKeys.values(); - for (const ImportKey &import : imports) { - if (importName == import.libraryQualifiedPath()) { - if (import.majorVersion > maj) { - version = QString("%1.%2").arg(import.majorVersion).arg(import.minorVersion); - maj = import.majorVersion; - } - } - } - return version; -} diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.h b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.h index 5ed2e24c7a4..50b3a423678 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.h +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.h @@ -37,7 +37,7 @@ public: bool isActive() const; void setupImports(const QmlJS::Document::Ptr &doc, DifferenceHandler &differenceHandler); - void setupPossibleImports(const QmlJS::Snapshot &snapshot, const QmlJS::ViewerContext &viewContext); + void setupPossibleImports(); void setupUsedImports(); bool load(const QString &data, DifferenceHandler &differenceHandler); @@ -137,8 +137,6 @@ private: const QmlJS::SourceLocation &from, const QmlJS::SourceLocation &to); - QString getHighestPossibleImport(const QString &importName) const; - private: RewriterView *m_rewriterView; bool m_isActive; @@ -150,8 +148,8 @@ private: QSet<ModelNode> m_clearImplicitComponentList; QmlJS::ViewerContext m_vContext; QSet<QPair<QString, QString> > m_qrcMapping; - QSet<QmlJS::ImportKey> m_possibleImportKeys; - int m_previousPossibleImportsSize = -1; + Imports m_possibleModules; + int m_previousPossibleModulesSize = -1; bool m_hasVersionlessImport = false; }; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/modulescanner.cpp b/src/plugins/qmldesigner/designercore/projectstorage/modulescanner.cpp new file mode 100644 index 00000000000..5fd70bfdd35 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/projectstorage/modulescanner.cpp @@ -0,0 +1,73 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "modulescanner.h" + +#ifdef QDS_HAS_QMLPRIVATE +#include <private/qqmldirparser_p.h> +#endif + +#include <QFile> + +#include <filesystem> + +namespace QmlDesigner { + +namespace { + +std::optional<QString> contentAsQString(const QString &filePath) +{ + QFile file{filePath}; + if (file.open(QIODevice::ReadOnly)) + return {QString::fromUtf8(file.readAll())}; + + return {}; +} + +} // namespace + +void ModuleScanner::scan(const QStringList &modulePaths) +{ + for (const QString &modulePath : modulePaths) + scan(modulePath.toStdString()); +} + +void ModuleScanner::scan(std::string_view modulePath) +{ +#ifdef QDS_HAS_QMLPRIVATE + try { + const std::filesystem::path installDirectoryPath{modulePath}; + + auto current = std::filesystem::recursive_directory_iterator{installDirectoryPath}; + auto end = std::filesystem::end(current); + + for (; current != end; ++current) { + const auto &entry = *current; + auto path = entry.path(); + + if (path.filename() == "qmldir") { + QQmlDirParser parser; + + auto content = contentAsQString(QString::fromStdU16String(path.u16string())); + if (!content) + continue; + + bool hasError = parser.parse(*content); + if (hasError) + continue; + + auto moduleName = parser.typeNamespace(); + + if (moduleName.isEmpty() || m_skip(moduleName)) + continue; + + m_modules.push_back(Import::createLibraryImport(moduleName)); + } + } + } catch (const std::filesystem::filesystem_error &) { + return; + } +#endif +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/projectstorage/modulescanner.h b/src/plugins/qmldesigner/designercore/projectstorage/modulescanner.h new file mode 100644 index 00000000000..3c03f9cd36d --- /dev/null +++ b/src/plugins/qmldesigner/designercore/projectstorage/modulescanner.h @@ -0,0 +1,37 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include <qmldesignercorelib_global.h> + +#include <import.h> + +#include <optional> + +namespace QmlDesigner { + +class QMLDESIGNERCORE_EXPORT ModuleScanner +{ +public: + using SkipFunction = std::function<bool(QStringView)>; + + ModuleScanner(SkipFunction skip) + : m_skip{std::move(skip)} + { + m_modules.reserve(128); + } + + void scan(const QStringList &modulePaths); + + const Imports &modules() const { return m_modules; } + +private: + void scan(std::string_view modulePaths); + +private: + SkipFunction m_skip; + Imports m_modules; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp index 97aac6a8577..894299e7958 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp @@ -10,7 +10,7 @@ #include <sqlitedatabase.h> -#ifdef QDS_HAS_QMLDOM +#ifdef QDS_HAS_QMLPRIVATE #include <private/qqmldomtop_p.h> #endif @@ -19,7 +19,7 @@ namespace QmlDesigner { -#ifdef QDS_HAS_QMLDOM +#ifdef QDS_HAS_QMLPRIVATE namespace QmlDom = QQmlJS::Dom; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h index 744825aadc5..87fb03ddaba 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h @@ -18,7 +18,7 @@ public: using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>; using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>; -#ifdef QDS_HAS_QMLDOM +#ifdef QDS_HAS_QMLPRIVATE QmlDocumentParser(ProjectStorage &storage, PathCache &pathCache) : m_storage{storage} , m_pathCache{pathCache} @@ -35,7 +35,7 @@ public: private: // m_pathCache and m_storage are only used when compiled for QDS -#ifdef QDS_HAS_QMLDOM +#ifdef QDS_HAS_QMLPRIVATE ProjectStorage &m_storage; PathCache &m_pathCache; #endif diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp index bca7b3279d8..3ed15639982 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp @@ -8,7 +8,7 @@ #include <sqlitedatabase.h> -#ifdef QDS_HAS_QMLDOM +#ifdef QDS_HAS_QMLPRIVATE #include <private/qqmldomtop_p.h> #include <private/qqmljstypedescriptionreader_p.h> #endif @@ -20,7 +20,7 @@ namespace QmlDesigner { -#ifdef QDS_HAS_QMLDOM +#ifdef QDS_HAS_QMLPRIVATE namespace QmlDom = QQmlJS::Dom; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h index 902d3c5a44f..522e5d3292e 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h @@ -24,7 +24,7 @@ public: using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>; using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>; -#ifdef QDS_HAS_QMLDOM +#ifdef QDS_HAS_QMLPRIVATE QmlTypesParser(PathCache &pathCache, ProjectStorage &storage) : m_pathCache{pathCache} , m_storage{storage} @@ -41,7 +41,7 @@ public: private: // m_pathCache and m_storage are only used when compiled for QDS -#ifdef QDS_HAS_QMLDOM +#ifdef QDS_HAS_QMLPRIVATE PathCache &m_pathCache; ProjectStorage &m_storage; #endif diff --git a/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp b/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp index a3fdc762448..71c5379cda6 100644 --- a/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp +++ b/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp @@ -9,9 +9,11 @@ #include <edit3d/edit3dviewconfig.h> #include <itemlibraryimport.h> #include <projectexplorer/kit.h> +#include <projectexplorer/project.h> #include <projectexplorer/session.h> #include <projectexplorer/target.h> #include <puppetenvironmentbuilder.h> +#include <qmlprojectmanager/qmlproject.h> #include <qmlpuppetpaths.h> #include <qtsupport/baseqtversion.h> #include <qtsupport/qtkitinformation.h> @@ -186,4 +188,50 @@ Utils::FilePath ExternalDependencies::qmlPuppetPath() const return puppetPath; } +namespace { + +QString qmlPath(ProjectExplorer::Target *target) +{ + auto kit = target->kit(); + + if (!kit) + return {}; + + auto qtVersion = QtSupport::QtKitAspect::qtVersion(kit); + if (!qtVersion) + return {}; + + return qtVersion->qmlPath().toString(); +} +} // namespace + +QStringList ExternalDependencies::modulePaths() const +{ + QStringList modulePaths; + + auto project = ProjectExplorer::SessionManager::startupProject(); + + if (!project) + return modulePaths; + + auto target = project->activeTarget(); + + if (!target) + return modulePaths; + + if (auto path = qmlPath(target); !path.isEmpty()) + modulePaths.push_back(path); + + const auto qmlBuildSystem = qobject_cast<QmlProjectManager::QmlBuildSystem *>( + target->buildSystem()); + + if (!qmlBuildSystem) + return modulePaths; + + for (const QString &modulePath : qmlBuildSystem->customImportPaths()) + modulePaths.append(project->projectDirectory().pathAppended(modulePath).toString()); + + return modulePaths; +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/qmldesignerexternaldependencies.h b/src/plugins/qmldesigner/qmldesignerexternaldependencies.h index 3e57847ce9d..b19ad0ae111 100644 --- a/src/plugins/qmldesigner/qmldesignerexternaldependencies.h +++ b/src/plugins/qmldesigner/qmldesignerexternaldependencies.h @@ -36,6 +36,7 @@ public: PuppetStartData puppetStartData(const class Model &model) const override; bool instantQmlTextUpdate() const override; Utils::FilePath qmlPuppetPath() const override; + QStringList modulePaths() const override; private: const DesignerSettings &m_designerSettings; diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp index e6a02fecab7..67144a813b4 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp @@ -342,7 +342,7 @@ void projectQmldirPaths(::ProjectExplorer::Target *target, QStringList &qmldirPa qmldirPaths.push_back(QDir::cleanPath(pojectDirectory.absoluteFilePath(importPath)) + "/qmldir"); } -#ifdef QDS_HAS_QMLDOM +#ifdef QDS_HAS_QMLPRIVATE bool skipPath(const std::filesystem::path &path) { auto directory = path.filename(); @@ -359,25 +359,27 @@ bool skipPath(const std::filesystem::path &path) } #endif -void qtQmldirPaths([[maybe_unused]] ::ProjectExplorer::Target *target, - [[maybe_unused]] QStringList &qmldirPaths) +void qtQmldirPaths(::ProjectExplorer::Target *target, QStringList &qmldirPaths) { -#ifdef QDS_HAS_QMLDOM - const QString installDirectory = qmlPath(target).toString(); +#ifdef QDS_HAS_QMLPRIVATE - const std::filesystem::path installDirectoryPath{installDirectory.toStdString()}; + if (useProjectStorage()) { + const QString installDirectory = qmlPath(target).toString(); - auto current = std::filesystem::recursive_directory_iterator{installDirectoryPath}; - auto end = std::filesystem::end(current); - for (; current != end; ++current) { - const auto &entry = *current; - auto path = entry.path(); - if (current.depth() < 3 && !current->is_regular_file() && skipPath(path)) { - current.disable_recursion_pending(); - continue; - } - if (path.filename() == "qmldir") { - qmldirPaths.push_back(QString::fromStdU16String(path.generic_u16string())); + const std::filesystem::path installDirectoryPath{installDirectory.toStdString()}; + + auto current = std::filesystem::recursive_directory_iterator{installDirectoryPath}; + auto end = std::filesystem::end(current); + for (; current != end; ++current) { + const auto &entry = *current; + auto path = entry.path(); + if (current.depth() < 3 && !current->is_regular_file() && skipPath(path)) { + current.disable_recursion_pending(); + continue; + } + if (path.filename() == "qmldir") { + qmldirPaths.push_back(QString::fromStdU16String(path.generic_u16string())); + } } } #endif diff --git a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp index 7850d4512a0..0efa20ff8a2 100644 --- a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp +++ b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp @@ -160,6 +160,7 @@ public: PuppetStartData puppetStartData(const class Model &) const override { return {}; } bool instantQmlTextUpdate() const override { return true; } Utils::FilePath qmlPuppetPath() const override { return {}; } + QStringList modulePaths() const override { return {}; } public: QSettings qsettings; @@ -1074,10 +1075,10 @@ void tst_TestCore::testRewriterChangeImports() // Import webkitImport = Import::createLibraryImport("QtWebKit", "1.0"); - QList<Import> importList; + Imports importList; importList << webkitImport; - model->changeImports(importList, QList<Import>()); + model->changeImports(importList, Imports()); const QLatin1String qmlWithImport("\n" "import QtQuick 2.1\n" @@ -1086,7 +1087,7 @@ void tst_TestCore::testRewriterChangeImports() "Rectangle {}\n"); QCOMPARE(textEdit.toPlainText(), qmlWithImport); - model->changeImports(QList<Import>(), importList); + model->changeImports(Imports(), importList); QCOMPARE(model->imports().size(), 1); QCOMPARE(model->imports().first(), Import::createLibraryImport("QtQuick", "2.1")); @@ -1100,7 +1101,7 @@ void tst_TestCore::testRewriterChangeImports() Import webkitImportAlias = Import::createLibraryImport("QtWebKit", "1.0", "Web"); - model->changeImports(QList<Import>() << webkitImportAlias, QList<Import>() << webkitImport); + model->changeImports(Imports() << webkitImportAlias, Imports() << webkitImport); const QLatin1String qmlWithAliasImport("\n" "import QtQuick 2.1\n" @@ -1109,7 +1110,7 @@ void tst_TestCore::testRewriterChangeImports() "Rectangle {}\n"); QCOMPARE(textEdit.toPlainText(), qmlWithAliasImport); - model->changeImports(QList<Import>(), QList<Import>() << webkitImportAlias); + model->changeImports(Imports(), Imports() << webkitImportAlias); QCOMPARE(model->imports().first(), Import::createLibraryImport("QtQuick", "2.1")); QCOMPARE(textEdit.toPlainText(), qmlString); diff --git a/tests/unit/unittest/CMakeLists.txt b/tests/unit/unittest/CMakeLists.txt index 3df9686e906..8d3898d7f7c 100644 --- a/tests/unit/unittest/CMakeLists.txt +++ b/tests/unit/unittest/CMakeLists.txt @@ -25,7 +25,7 @@ add_qtc_test(unittest GTEST BEFORE "../mockup/qmldesigner/designercore/include" DEPENDS Qt::Core Qt::Network Qt::Widgets - Qt::Xml Qt::Concurrent Qt::Qml Qt::Gui + Qt::Xml Qt::Concurrent Qt::QmlPrivate Qt::Gui Qt6Core5Compat QmlJS Sqlite SqliteC Googletest DEFINES @@ -36,6 +36,7 @@ add_qtc_test(unittest GTEST QTC_RESOURCE_DIR="${CMAKE_CURRENT_LIST_DIR}/../../../share/qtcreator" TESTDATA_DIR="${CMAKE_CURRENT_BINARY_DIR}/data" TEST_RELATIVE_LIBEXEC_PATH="${TEST_RELATIVE_LIBEXEC_PATH}" + QT6_INSTALL_PREFIX="${QT6_INSTALL_PREFIX}" SOURCES abstractviewmock.h compare-operators.h @@ -97,6 +98,7 @@ add_qtc_test(unittest GTEST mockimagecachestorage.h asynchronousexplicitimagecache-test.cpp asynchronousimagefactory-test.cpp + modulescanner-test.cpp ) if (NOT TARGET unittest) @@ -250,6 +252,7 @@ extend_qtc_test(unittest projectstorage/filesystem.cpp projectstorage/filesystem.h projectstorage/filestatus.h projectstorage/filestatuscache.cpp projectstorage/filestatuscache.h + projectstorage/modulescanner.cpp projectstorage/modulescanner.h projectstorage/nonlockingmutex.h projectstorage/projectstorageexceptions.cpp projectstorage/projectstorageexceptions.h projectstorage/projectstorageinterface.h @@ -335,7 +338,7 @@ extend_qtc_test(unittest CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND Qt6_VERSION VERSION_GREATER_EQUAL 6.5.0 SOURCES_PREFIX "${QmlDesignerDir}/designercore" DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate - DEFINES QDS_HAS_QMLDOM + DEFINES QDS_HAS_QMLPRIVATE SOURCES projectstorage/qmldocumentparser.cpp projectstorage/qmldocumentparser.h projectstorage/qmltypesparser.cpp projectstorage/qmltypesparser.h diff --git a/tests/unit/unittest/google-using-declarations.h b/tests/unit/unittest/google-using-declarations.h index 67e887c696d..85fc82282f6 100644 --- a/tests/unit/unittest/google-using-declarations.h +++ b/tests/unit/unittest/google-using-declarations.h @@ -5,7 +5,6 @@ #include <gmock/gmock.h> - using testing::_; using testing::A; using testing::AllOf; @@ -21,6 +20,7 @@ using testing::ByRef; using testing::ContainerEq; using testing::Contains; using testing::ElementsAre; +using testing::EndsWith; using testing::Eq; using testing::Exactly; using testing::Field; @@ -29,7 +29,6 @@ using testing::Gt; using testing::HasSubstr; using testing::InSequence; using testing::Invoke; -using testing::IsEmpty; using testing::IsNull; using testing::Le; using testing::Lt; diff --git a/tests/unit/unittest/modulescanner-test.cpp b/tests/unit/unittest/modulescanner-test.cpp new file mode 100644 index 00000000000..bd72d3db901 --- /dev/null +++ b/tests/unit/unittest/modulescanner-test.cpp @@ -0,0 +1,53 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "googletest.h" + +#include <projectstorage/modulescanner.h> + +#include <QDebug> + +namespace { + +template<typename Matcher> +auto UrlProperty(const Matcher &matcher) +{ + return Property(&QmlDesigner::Import::url, matcher); +} + +class ModuleScanner : public testing::Test +{ +protected: + QmlDesigner::ModuleScanner scanner{ + [](QStringView moduleName) { return moduleName.endsWith(u"impl"); }}; +}; + +TEST_F(ModuleScanner, ReturnEmptyOptionalForWrongPath) +{ + scanner.scan(QStringList{""}); + + ASSERT_THAT(scanner.modules(), IsEmpty()); +} + +TEST_F(ModuleScanner, GetQtQuick) +{ + scanner.scan(QStringList{QT6_INSTALL_PREFIX}); + + ASSERT_THAT(scanner.modules(), Contains(UrlProperty("QtQuick"))); +} + +TEST_F(ModuleScanner, SkipEmptyModules) +{ + scanner.scan(QStringList{QT6_INSTALL_PREFIX}); + + ASSERT_THAT(scanner.modules(), Not(Contains(UrlProperty(IsEmpty())))); +} + +TEST_F(ModuleScanner, UseSkipFunction) +{ + scanner.scan(QStringList{QT6_INSTALL_PREFIX}); + + ASSERT_THAT(scanner.modules(), Not(Contains(UrlProperty(EndsWith(QStringView{u"impl"}))))); +} + +} // namespace diff --git a/tests/unit/unittest/smallstring-test.cpp b/tests/unit/unittest/smallstring-test.cpp index d8321ec98f4..6364bd9c646 100644 --- a/tests/unit/unittest/smallstring-test.cpp +++ b/tests/unit/unittest/smallstring-test.cpp @@ -9,8 +9,6 @@ #include <utils/smallstringio.h> #include <utils/smallstringvector.h> -using namespace ::testing; - using Utils::PathString; using Utils::SmallString; using Utils::SmallStringLiteral; diff --git a/tests/unit/unittest/unittest-matchers.h b/tests/unit/unittest/unittest-matchers.h index 12f47074835..0f59a5e79a8 100644 --- a/tests/unit/unittest/unittest-matchers.h +++ b/tests/unit/unittest/unittest-matchers.h @@ -7,7 +7,7 @@ #include <utils/smallstringio.h> -namespace UnitTests { +namespace Internal { template <typename StringType> class EndsWithMatcher @@ -46,10 +46,68 @@ private: const StringType m_suffix; }; -inline -testing::PolymorphicMatcher<EndsWithMatcher<Utils::SmallString> > -EndsWith(const Utils::SmallString &suffix) +class QStringEndsWithMatcher { - return testing::MakePolymorphicMatcher(EndsWithMatcher<Utils::SmallString>(suffix)); +public: + explicit QStringEndsWithMatcher(const QString &suffix) + : m_suffix(suffix) + {} + + template<typename MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType &s, testing::MatchResultListener * /* listener */) const + { + return s.endsWith(m_suffix); + } + + void DescribeTo(::std::ostream *os) const + { + *os << "ends with " << testing::PrintToString(m_suffix); + } + + void DescribeNegationTo(::std::ostream *os) const + { + *os << "doesn't end with " << testing::PrintToString(m_suffix); + } + +private: + const QString m_suffix; +}; + +class IsEmptyMatcher : public testing::internal::IsEmptyMatcher +{ +public: + using Base = testing::internal::IsEmptyMatcher; + + using Base::MatchAndExplain; + + bool MatchAndExplain(const QString &s, testing::MatchResultListener *listener) const + { + if (s.isEmpty()) { + return true; + } + + *listener << "whose size is " << s.size(); + return false; + } + + void DescribeTo(std::ostream *os) const { *os << "is empty"; } + + void DescribeNegationTo(std::ostream *os) const { *os << "isn't empty"; } +}; + +} // namespace Internal + +inline auto EndsWith(const Utils::SmallString &suffix) +{ + return Internal::EndsWithMatcher(suffix); } + +inline auto EndsWith(const QStringView &suffix) +{ + return ::testing::PolymorphicMatcher(Internal::QStringEndsWithMatcher(suffix.toString())); +} + +inline auto IsEmpty() +{ + return ::testing::PolymorphicMatcher(Internal::IsEmptyMatcher()); } diff --git a/tests/unit/unittest/unittest-utility-functions.h b/tests/unit/unittest/unittest-utility-functions.h index a4866cfa889..090360e8a70 100644 --- a/tests/unit/unittest/unittest-utility-functions.h +++ b/tests/unit/unittest/unittest-utility-functions.h @@ -15,10 +15,9 @@ bool operator==(const QString &first, const char *second) namespace UnitTest { -inline -Utils::PathString temporaryDirPath() +inline ::Utils::PathString temporaryDirPath() { - return Utils::PathString::fromQString(Utils::TemporaryDirectory::masterDirectoryPath()); + return ::Utils::PathString::fromQString(Utils::TemporaryDirectory::masterDirectoryPath()); } } // namespace UnitTest |