forked from qt-creator/qt-creator
QmlDesigner: Add module scanner
For performance reason we want to get the qml modules directly from the file system. When the project storage is finished we can get the modules from there. Task-number: QDS-9542 Change-Id: I26d4b028fbf5ebc541fcd8e34d285ded1fb14935 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Thomas Hartmann
parent
79b5a9f03e
commit
6035ff939d
@@ -57,6 +57,7 @@ add_qtc_library(QmlDesignerCore STATIC
|
|||||||
Utils
|
Utils
|
||||||
Qt::Widgets
|
Qt::Widgets
|
||||||
Qt::Qml
|
Qt::Qml
|
||||||
|
Qt::QmlPrivate
|
||||||
Core
|
Core
|
||||||
ProjectExplorer
|
ProjectExplorer
|
||||||
QmakeProjectManager
|
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
|
CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND Qt6_VERSION VERSION_GREATER_EQUAL 6.5.0
|
||||||
|
|
||||||
DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate
|
DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate
|
||||||
DEFINES QDS_HAS_QMLDOM
|
PUBLIC_DEFINES QDS_HAS_QMLPRIVATE
|
||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_library(QmlDesignerCore
|
extend_qtc_library(QmlDesignerCore
|
||||||
@@ -400,6 +401,7 @@ extend_qtc_library(QmlDesignerCore
|
|||||||
filesystem.cpp filesystem.h
|
filesystem.cpp filesystem.h
|
||||||
filestatus.h
|
filestatus.h
|
||||||
filestatuscache.cpp filestatuscache.h
|
filestatuscache.cpp filestatuscache.h
|
||||||
|
modulescanner.cpp modulescanner.h
|
||||||
nonlockingmutex.h
|
nonlockingmutex.h
|
||||||
projectstorageexceptions.cpp projectstorageexceptions.h
|
projectstorageexceptions.cpp projectstorageexceptions.h
|
||||||
projectstorageinterface.h
|
projectstorageinterface.h
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ void DesignerActionManagerView::nodeOrderChanged(const NodeListProperty &)
|
|||||||
setupContext(SelectionContext::UpdateMode::NodeHierachy);
|
setupContext(SelectionContext::UpdateMode::NodeHierachy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManagerView::importsChanged(const QList<Import> &, const QList<Import> &)
|
void DesignerActionManagerView::importsChanged(const Imports &, const Imports &)
|
||||||
{
|
{
|
||||||
setupContext();
|
setupContext();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public:
|
|||||||
void selectedNodesChanged(const QList<ModelNode> &,
|
void selectedNodesChanged(const QList<ModelNode> &,
|
||||||
const QList<ModelNode> &) override;
|
const QList<ModelNode> &) override;
|
||||||
void nodeOrderChanged(const NodeListProperty &) 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 signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty> &/*propertyList*/, PropertyChangeFlags /*propertyChange*/) override;
|
||||||
void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChangeFlag) override;
|
void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChangeFlag) override;
|
||||||
void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChangeFlag) override;
|
void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChangeFlag) override;
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ void ConnectionView::auxiliaryDataChanged([[maybe_unused]] const ModelNode &node
|
|||||||
selectionModel->clearSelection();
|
selectionModel->clearSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionView::importsChanged(const QList<Import> & /*addedImports*/, const QList<Import> & /*removedImports*/)
|
void ConnectionView::importsChanged(const Imports & /*addedImports*/, const Imports & /*removedImports*/)
|
||||||
{
|
{
|
||||||
backendModel()->resetModel();
|
backendModel()->resetModel();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
AuxiliaryDataKeyView key,
|
AuxiliaryDataKeyView key,
|
||||||
const QVariant &data) override;
|
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;
|
void currentStateChanged(const ModelNode &node) override;
|
||||||
|
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ void ContentLibraryView::modelAboutToBeDetached(Model *model)
|
|||||||
AbstractView::modelAboutToBeDetached(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(addedImports)
|
||||||
Q_UNUSED(removedImports)
|
Q_UNUSED(removedImports)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public:
|
|||||||
// AbstractView
|
// AbstractView
|
||||||
void modelAttached(Model *model) override;
|
void modelAttached(Model *model) override;
|
||||||
void modelAboutToBeDetached(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 active3DSceneChanged(qint32 sceneId) override;
|
||||||
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
|
||||||
const QList<ModelNode> &lastSelectedNodeList) override;
|
const QList<ModelNode> &lastSelectedNodeList) override;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ void DebugView::modelAboutToBeDetached(Model *model)
|
|||||||
AbstractView::modelAboutToBeDetached(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()) {
|
if (isDebugViewEnabled()) {
|
||||||
QString message;
|
QString message;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public:
|
|||||||
void modelAttached(Model *model) override;
|
void modelAttached(Model *model) override;
|
||||||
void modelAboutToBeDetached(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 nodeCreated(const ModelNode &createdNode) override;
|
||||||
void nodeAboutToBeRemoved(const ModelNode &removedNode) override;
|
void nodeAboutToBeRemoved(const ModelNode &removedNode) override;
|
||||||
|
|||||||
@@ -312,8 +312,8 @@ void Edit3DView::modelAboutToBeDetached(Model *model)
|
|||||||
AbstractView::modelAboutToBeDetached(model);
|
AbstractView::modelAboutToBeDetached(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Edit3DView::importsChanged([[maybe_unused]] const QList<Import> &addedImports,
|
void Edit3DView::importsChanged([[maybe_unused]] const Imports &addedImports,
|
||||||
[[maybe_unused]] const QList<Import> &removedImports)
|
[[maybe_unused]] const Imports &removedImports)
|
||||||
{
|
{
|
||||||
checkImports();
|
checkImports();
|
||||||
}
|
}
|
||||||
@@ -920,7 +920,7 @@ void Edit3DView::addQuick3DImport()
|
|||||||
{
|
{
|
||||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
if (document && !document->inFileComponentModelActive() && model()) {
|
if (document && !document->inFileComponentModelActive() && model()) {
|
||||||
const QList<Import> imports = model()->possibleImports();
|
const Imports imports = model()->possibleImports();
|
||||||
for (const auto &import : imports) {
|
for (const auto &import : imports) {
|
||||||
if (import.url() == "QtQuick3D") {
|
if (import.url() == "QtQuick3D") {
|
||||||
if (!import.version().isEmpty() && import.majorVersion() >= 6) {
|
if (!import.version().isEmpty() && import.majorVersion() >= 6) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
void updateActiveScene3D(const QVariantMap &sceneState) override;
|
void updateActiveScene3D(const QVariantMap &sceneState) override;
|
||||||
void modelAttached(Model *model) override;
|
void modelAttached(Model *model) override;
|
||||||
void modelAboutToBeDetached(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 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;
|
void nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos3d) override;
|
||||||
|
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ void FormEditorView::modelAboutToBeDetached(Model *model)
|
|||||||
AbstractView::modelAboutToBeDetached(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();
|
reset();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public:
|
|||||||
void modelAttached(Model *model) override;
|
void modelAttached(Model *model) override;
|
||||||
void modelAboutToBeDetached(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 nodeCreated(const ModelNode &createdNode) override;
|
||||||
void nodeAboutToBeRemoved(const ModelNode &removedNode) override;
|
void nodeAboutToBeRemoved(const ModelNode &removedNode) override;
|
||||||
|
|||||||
@@ -56,14 +56,14 @@ QHash<int, QByteArray> ItemLibraryAddImportModel::roleNames() const
|
|||||||
return m_roleNames;
|
return m_roleNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryAddImportModel::update(const QList<Import> &possibleImports)
|
void ItemLibraryAddImportModel::update(const Imports &possibleImports)
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_importList.clear();
|
m_importList.clear();
|
||||||
|
|
||||||
const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
|
const DesignerMcuManager &mcuManager = DesignerMcuManager::instance();
|
||||||
const bool isQtForMCUs = mcuManager.isMCUProject();
|
const bool isQtForMCUs = mcuManager.isMCUProject();
|
||||||
QList<Import> filteredImports;
|
Imports filteredImports;
|
||||||
if (isQtForMCUs) {
|
if (isQtForMCUs) {
|
||||||
const QStringList mcuAllowedList = mcuManager.allowedImports();
|
const QStringList mcuAllowedList = mcuManager.allowedImports();
|
||||||
const QStringList mcuBannedList = mcuManager.bannedImports();
|
const QStringList mcuBannedList = mcuManager.bannedImports();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public:
|
|||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
void update(const QList<Import> &possibleImports);
|
void update(const Imports &possibleImports);
|
||||||
void setSearchText(const QString &searchText);
|
void setSearchText(const QString &searchText);
|
||||||
Import getImportAt(int index) const;
|
Import getImportAt(int index) const;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_searchText;
|
QString m_searchText;
|
||||||
QList<Import> m_importList;
|
Imports m_importList;
|
||||||
QSet<QString> m_importFilterList;
|
QSet<QString> m_importFilterList;
|
||||||
QHash<int, QByteArray> m_roleNames;
|
QHash<int, QByteArray> m_roleNames;
|
||||||
QSet<QString> m_priorityImports;
|
QSet<QString> m_priorityImports;
|
||||||
|
|||||||
@@ -709,9 +709,9 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
|||||||
model->rewriterView()->textModifier()->replace(0, 0, {});
|
model->rewriterView()->textModifier()->replace(0, 0, {});
|
||||||
} else if (counter < 100) {
|
} else if (counter < 100) {
|
||||||
try {
|
try {
|
||||||
const QList<Import> posImports = model->possibleImports();
|
const Imports posImports = model->possibleImports();
|
||||||
const QList<Import> currentImports = model->imports();
|
const Imports currentImports = model->imports();
|
||||||
QList<Import> newImportsToAdd;
|
Imports newImportsToAdd;
|
||||||
|
|
||||||
for (auto &imp : std::as_const(m_requiredImports)) {
|
for (auto &imp : std::as_const(m_requiredImports)) {
|
||||||
const bool isPos = Utils::contains(posImports, [imp](const Import &posImp) {
|
const bool isPos = Utils::contains(posImports, [imp](const Import &posImp) {
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ private:
|
|||||||
int m_currentImportId = 0;
|
int m_currentImportId = 0;
|
||||||
QHash<int, ParseData> m_parseData;
|
QHash<int, ParseData> m_parseData;
|
||||||
QString m_progressTitle;
|
QString m_progressTitle;
|
||||||
QList<Import> m_requiredImports;
|
Imports m_requiredImports;
|
||||||
QList<int> m_puppetQueue;
|
QList<int> m_puppetQueue;
|
||||||
};
|
};
|
||||||
} // QmlDesigner
|
} // QmlDesigner
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
|
|||||||
materialBundlePrefix.append(".MaterialBundle");
|
materialBundlePrefix.append(".MaterialBundle");
|
||||||
|
|
||||||
// create import sections
|
// create import sections
|
||||||
const QList<Import> usedImports = model->usedImports();
|
const Imports usedImports = model->usedImports();
|
||||||
QHash<QString, ItemLibraryImport *> importHash;
|
QHash<QString, ItemLibraryImport *> importHash;
|
||||||
for (const Import &import : model->imports()) {
|
for (const Import &import : model->imports()) {
|
||||||
if (import.url() != projectName) {
|
if (import.url() != projectName) {
|
||||||
@@ -550,7 +550,7 @@ ItemLibraryImport *ItemLibraryModel::importByUrl(const QString &importUrl) const
|
|||||||
return nullptr;
|
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.
|
// imports in the excludeList are not marked used and thus can always be removed even when in use.
|
||||||
const QList<QString> excludeList = {"SimulinkConnector"};
|
const QList<QString> excludeList = {"SimulinkConnector"};
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public:
|
|||||||
ItemLibraryImport *importByUrl(const QString &importName) const;
|
ItemLibraryImport *importByUrl(const QString &importName) const;
|
||||||
|
|
||||||
void update(ItemLibraryInfo *itemLibraryInfo, Model *model);
|
void update(ItemLibraryInfo *itemLibraryInfo, Model *model);
|
||||||
void updateUsedImports(const QList<Import> &usedImports);
|
void updateUsedImports(const Imports &usedImports);
|
||||||
|
|
||||||
QMimeData *getMimeData(const ItemLibraryEntry &itemLibraryEntry);
|
QMimeData *getMimeData(const ItemLibraryEntry &itemLibraryEntry);
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ void ItemLibraryView::modelAboutToBeDetached(Model *model)
|
|||||||
m_widget->setModel(nullptr);
|
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();
|
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
for (const auto &import : addedImports)
|
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();
|
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
for (const auto &import : possibleImports)
|
for (const auto &import : possibleImports)
|
||||||
@@ -120,7 +120,7 @@ void ItemLibraryView::possibleImportsChanged(const QList<Import> &possibleImport
|
|||||||
m_widget->updatePossibleImports(possibleImports);
|
m_widget->updatePossibleImports(possibleImports);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryView::usedImportsChanged(const QList<Import> &usedImports)
|
void ItemLibraryView::usedImportsChanged(const Imports &usedImports)
|
||||||
{
|
{
|
||||||
m_widget->updateUsedImports(usedImports);
|
m_widget->updateUsedImports(usedImports);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ public:
|
|||||||
// AbstractView
|
// AbstractView
|
||||||
void modelAttached(Model *model) override;
|
void modelAttached(Model *model) override;
|
||||||
void modelAboutToBeDetached(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 possibleImportsChanged(const QList<Import> &possibleImports) override;
|
void possibleImportsChanged(const Imports &possibleImports) override;
|
||||||
void usedImportsChanged(const QList<Import> &usedImports) override;
|
void usedImportsChanged(const Imports &usedImports) override;
|
||||||
void documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings) override;
|
void documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings) override;
|
||||||
void updateImport3DSupport(const QVariantMap &supportMap) override;
|
void updateImport3DSupport(const QVariantMap &supportMap) override;
|
||||||
void customNotification(const AbstractView *view, const QString &identifier,
|
void customNotification(const AbstractView *view, const QString &identifier,
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
Import fileImport = Import::createFileImport(entry.requiredImport());
|
Import fileImport = Import::createFileImport(entry.requiredImport());
|
||||||
if (!m_model->hasImport(libImport, true, true)
|
if (!m_model->hasImport(libImport, true, true)
|
||||||
&& !m_model->hasImport(fileImport, 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) {
|
for (const auto &possImport : possImports) {
|
||||||
if ((!possImport.url().isEmpty() && possImport.url() == libImport.url())
|
if ((!possImport.url().isEmpty() && possImport.url() == libImport.url())
|
||||||
|| (!possImport.file().isEmpty() && possImport.file() == fileImport.file())) {
|
|| (!possImport.file().isEmpty() && possImport.file() == fileImport.file())) {
|
||||||
@@ -246,7 +246,7 @@ void ItemLibraryWidget::handleAddImport(int index)
|
|||||||
+ importStr);
|
+ importStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Import> imports;
|
Imports imports;
|
||||||
const QString dependency = getDependencyImport(import);
|
const QString dependency = getDependencyImport(import);
|
||||||
|
|
||||||
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
@@ -346,13 +346,13 @@ void ItemLibraryWidget::updateModel()
|
|||||||
updateSearch();
|
updateSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryWidget::updatePossibleImports(const QList<Import> &possibleImports)
|
void ItemLibraryWidget::updatePossibleImports(const Imports &possibleImports)
|
||||||
{
|
{
|
||||||
m_addModuleModel->update(possibleImports);
|
m_addModuleModel->update(possibleImports);
|
||||||
delayedUpdateModel();
|
delayedUpdateModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryWidget::updateUsedImports(const QList<Import> &usedImports)
|
void ItemLibraryWidget::updateUsedImports(const Imports &usedImports)
|
||||||
{
|
{
|
||||||
m_itemLibraryModel->updateUsedImports(usedImports);
|
m_itemLibraryModel->updateUsedImports(usedImports);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ public:
|
|||||||
void switchToComponentsView();
|
void switchToComponentsView();
|
||||||
void delayedUpdateModel();
|
void delayedUpdateModel();
|
||||||
void updateModel();
|
void updateModel();
|
||||||
void updatePossibleImports(const QList<Import> &possibleImports);
|
void updatePossibleImports(const Imports &possibleImports);
|
||||||
void updateUsedImports(const QList<Import> &usedImports);
|
void updateUsedImports(const Imports &usedImports);
|
||||||
|
|
||||||
void setModel(Model *model);
|
void setModel(Model *model);
|
||||||
void setFlowMode(bool b);
|
void setFlowMode(bool b);
|
||||||
|
|||||||
@@ -469,8 +469,8 @@ ModelNode MaterialBrowserView::getMaterialOfModel(const ModelNode &model, int id
|
|||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialBrowserView::importsChanged([[maybe_unused]] const QList<Import> &addedImports,
|
void MaterialBrowserView::importsChanged([[maybe_unused]] const Imports &addedImports,
|
||||||
[[maybe_unused]] const QList<Import> &removedImports)
|
[[maybe_unused]] const Imports &removedImports)
|
||||||
{
|
{
|
||||||
bool hasQuick3DImport = model()->hasImport("QtQuick3D");
|
bool hasQuick3DImport = model()->hasImport("QtQuick3D");
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
void nodeAboutToBeRemoved(const ModelNode &removedNode) override;
|
void nodeAboutToBeRemoved(const ModelNode &removedNode) override;
|
||||||
void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty,
|
void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty,
|
||||||
PropertyChangeFlags propertyChange) override;
|
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,
|
void customNotification(const AbstractView *view, const QString &identifier,
|
||||||
const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
void instancesCompleted(const QVector<ModelNode> &completedNodeList) override;
|
void instancesCompleted(const QVector<ModelNode> &completedNodeList) override;
|
||||||
|
|||||||
@@ -974,8 +974,8 @@ void MaterialEditorView::modelNodePreviewPixmapChanged(const ModelNode &node, co
|
|||||||
m_qmlBackEnd->updateMaterialPreview(pixmap);
|
m_qmlBackEnd->updateMaterialPreview(pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEditorView::importsChanged([[maybe_unused]] const QList<Import> &addedImports,
|
void MaterialEditorView::importsChanged([[maybe_unused]] const Imports &addedImports,
|
||||||
[[maybe_unused]] const QList<Import> &removedImports)
|
[[maybe_unused]] const Imports &removedImports)
|
||||||
{
|
{
|
||||||
m_hasQuick3DImport = model()->hasImport("QtQuick3D");
|
m_hasQuick3DImport = model()->hasImport("QtQuick3D");
|
||||||
m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport);
|
m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
void nodeTypeChanged(const ModelNode& node, const TypeName &type, int majorVersion, int minorVersion) override;
|
void nodeTypeChanged(const ModelNode& node, const TypeName &type, int majorVersion, int minorVersion) override;
|
||||||
void rootNodeTypeChanged(const QString &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 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,
|
void customNotification(const AbstractView *view, const QString &identifier,
|
||||||
const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent,
|
void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent,
|
||||||
|
|||||||
@@ -901,7 +901,7 @@ void NavigatorTreeModel::addImport(const QString &importName)
|
|||||||
{
|
{
|
||||||
Import import = Import::createLibraryImport(importName);
|
Import import = Import::createLibraryImport(importName);
|
||||||
if (!m_view->model()->hasImport(import, true, true)) {
|
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) {
|
for (const auto &possImport : possImports) {
|
||||||
if (possImport.url() == import.url()) {
|
if (possImport.url() == import.url()) {
|
||||||
import = possImport;
|
import = possImport;
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ void NavigatorView::modelAboutToBeDetached(Model *model)
|
|||||||
AbstractView::modelAboutToBeDetached(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();
|
treeWidget()->update();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
void modelAttached(Model *model) override;
|
void modelAttached(Model *model) override;
|
||||||
void modelAboutToBeDetached(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 nodeAboutToBeRemoved(const ModelNode &removedNode) override;
|
||||||
void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange) override;
|
void nodeRemoved(const ModelNode &removedNode, const NodeAbstractProperty &parentProperty, PropertyChangeFlags propertyChange) override;
|
||||||
|
|||||||
@@ -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*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public:
|
|||||||
void modelAttached(Model *model) override;
|
void modelAttached(Model *model) override;
|
||||||
void modelAboutToBeDetached(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 nodeAboutToBeRemoved(const ModelNode &removedNode) override;
|
||||||
void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) override;
|
void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) override;
|
||||||
|
|||||||
@@ -720,8 +720,8 @@ void TextureEditorView::instancePropertyChanged(const QList<QPair<ModelNode, Pro
|
|||||||
m_locked = false;
|
m_locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureEditorView::importsChanged([[maybe_unused]] const QList<Import> &addedImports,
|
void TextureEditorView::importsChanged([[maybe_unused]] const Imports &addedImports,
|
||||||
[[maybe_unused]] const QList<Import> &removedImports)
|
[[maybe_unused]] const Imports &removedImports)
|
||||||
{
|
{
|
||||||
m_hasQuick3DImport = model()->hasImport("QtQuick3D");
|
m_hasQuick3DImport = model()->hasImport("QtQuick3D");
|
||||||
m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport);
|
m_qmlBackEnd->contextObject()->setHasQuick3DImport(m_hasQuick3DImport);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
void currentStateChanged(const ModelNode &node) override;
|
void currentStateChanged(const ModelNode &node) override;
|
||||||
void instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &propertyList) 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,
|
void customNotification(const AbstractView *view, const QString &identifier,
|
||||||
const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
|
|
||||||
|
|||||||
@@ -195,9 +195,9 @@ public:
|
|||||||
const ModelNode &movedNode,
|
const ModelNode &movedNode,
|
||||||
int oldIndex);
|
int oldIndex);
|
||||||
|
|
||||||
virtual void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports);
|
virtual void importsChanged(const Imports &addedImports, const Imports &removedImports);
|
||||||
virtual void possibleImportsChanged(const QList<Import> &possibleImports);
|
virtual void possibleImportsChanged(const Imports &possibleImports);
|
||||||
virtual void usedImportsChanged(const QList<Import> &usedImports);
|
virtual void usedImportsChanged(const Imports &usedImports);
|
||||||
|
|
||||||
virtual void auxiliaryDataChanged(const ModelNode &node,
|
virtual void auxiliaryDataChanged(const ModelNode &node,
|
||||||
AuxiliaryDataKeyView type,
|
AuxiliaryDataKeyView type,
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public:
|
|||||||
virtual PuppetStartData puppetStartData(const class Model &model) const = 0;
|
virtual PuppetStartData puppetStartData(const class Model &model) const = 0;
|
||||||
virtual bool instantQmlTextUpdate() const = 0;
|
virtual bool instantQmlTextUpdate() const = 0;
|
||||||
virtual Utils::FilePath qmlPuppetPath() const = 0;
|
virtual Utils::FilePath qmlPuppetPath() const = 0;
|
||||||
|
virtual QStringList modulePaths() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
void fileUrlChanged(const QUrl &oldUrl, const QUrl &newUrl) override;
|
void fileUrlChanged(const QUrl &oldUrl, const QUrl &newUrl) override;
|
||||||
|
|
||||||
void nodeOrderChanged(const NodeListProperty &listProperty) 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;
|
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>
|
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))
|
for (const ViewTypePointer &view : std::as_const(m_targetViewList))
|
||||||
view->importChanged(addedImport, removedImport);
|
view->importChanged(addedImport, removedImport);
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ private:
|
|||||||
|
|
||||||
QMLDESIGNERCORE_EXPORT size_t qHash(const Import &import);
|
QMLDESIGNERCORE_EXPORT size_t qHash(const Import &import);
|
||||||
|
|
||||||
|
using Imports = QList<Import>;
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QmlDesigner::Import)
|
Q_DECLARE_METATYPE(QmlDesigner::Import)
|
||||||
|
|||||||
@@ -115,12 +115,12 @@ public:
|
|||||||
// Editing sub-components:
|
// Editing sub-components:
|
||||||
|
|
||||||
// Imports:
|
// Imports:
|
||||||
const QList<Import> &imports() const;
|
const Imports &imports() const;
|
||||||
const QList<Import> &possibleImports() const;
|
const Imports &possibleImports() const;
|
||||||
const QList<Import> &usedImports() const;
|
const Imports &usedImports() const;
|
||||||
void changeImports(const QList<Import> &importsToBeAdded, const QList<Import> &importsToBeRemoved);
|
void changeImports(const Imports &importsToBeAdded, const Imports &importsToBeRemoved);
|
||||||
void setPossibleImports(const QList<Import> &possibleImports);
|
void setPossibleImports(const Imports &possibleImports);
|
||||||
void setUsedImports(const QList<Import> &usedImports);
|
void setUsedImports(const Imports &usedImports);
|
||||||
bool hasImport(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false) const;
|
bool hasImport(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false) const;
|
||||||
bool isImportPossible(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);
|
QString pathForImport(const Import &import);
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public:
|
|||||||
void fileUrlChanged(const QUrl &oldUrl, const QUrl &newUrl) override;
|
void fileUrlChanged(const QUrl &oldUrl, const QUrl &newUrl) override;
|
||||||
void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) override;
|
void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) override;
|
||||||
void nodeOrderChanged(const NodeListProperty &listProperty) 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,
|
void auxiliaryDataChanged(const ModelNode &node,
|
||||||
AuxiliaryDataKeyView key,
|
AuxiliaryDataKeyView key,
|
||||||
const QVariant &data) override;
|
const QVariant &data) override;
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ public:
|
|||||||
void rewriterBeginTransaction() override;
|
void rewriterBeginTransaction() override;
|
||||||
void rewriterEndTransaction() 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;
|
TextModifier *textModifier() const;
|
||||||
void setTextModifier(TextModifier *textModifier);
|
void setTextModifier(TextModifier *textModifier);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public:
|
|||||||
explicit SubComponentManager(Model *model,
|
explicit SubComponentManager(Model *model,
|
||||||
class ExternalDependenciesInterface &externalDependencies);
|
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);
|
void addAndParseImport(const Import &import);
|
||||||
|
|
||||||
QStringList qmlFiles() const;
|
QStringList qmlFiles() const;
|
||||||
@@ -53,7 +53,7 @@ private: // functions
|
|||||||
|
|
||||||
private: // variables
|
private: // variables
|
||||||
QFileSystemWatcher m_watcher;
|
QFileSystemWatcher m_watcher;
|
||||||
QList<Import> m_imports;
|
Imports m_imports;
|
||||||
// key: canonical directory path
|
// key: canonical directory path
|
||||||
QMultiHash<QString,QString> m_dirToQualifier;
|
QMultiHash<QString,QString> m_dirToQualifier;
|
||||||
QUrl m_filePath;
|
QUrl m_filePath;
|
||||||
|
|||||||
@@ -625,7 +625,7 @@ void NodeInstanceView::nodeOrderChanged(const NodeListProperty &listProperty)
|
|||||||
m_nodeInstanceServer->reparentInstances(ReparentInstancesCommand(containerList));
|
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();
|
restartProcess();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -768,7 +768,7 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, TypeName type, int maj, i
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_isFileComponent = true;
|
m_isFileComponent = true;
|
||||||
const Imports *imports = context()->imports(document());
|
const auto *imports = context()->imports(document());
|
||||||
const ImportInfo importInfo = imports->info(lookupNameComponent().constLast(),
|
const ImportInfo importInfo = imports->info(lookupNameComponent().constLast(),
|
||||||
context().data());
|
context().data());
|
||||||
|
|
||||||
@@ -791,7 +791,7 @@ NodeMetaInfoPrivate::NodeMetaInfoPrivate(Model *model, TypeName type, int maj, i
|
|||||||
} else {
|
} else {
|
||||||
// Special case for aliased types for the rewriter
|
// 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),
|
const ImportInfo importInfo = imports->info(QString::fromUtf8(m_qualfiedTypeName),
|
||||||
context().data());
|
context().data());
|
||||||
if (importInfo.isValid()) {
|
if (importInfo.isValid()) {
|
||||||
@@ -1198,7 +1198,7 @@ QString NodeMetaInfoPrivate::importDirectoryPath() const
|
|||||||
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
|
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
|
||||||
|
|
||||||
if (isValid()) {
|
if (isValid()) {
|
||||||
const Imports *imports = context()->imports(document());
|
const auto *imports = context()->imports(document());
|
||||||
ImportInfo importInfo = imports->info(lookupNameComponent().constLast(), context().data());
|
ImportInfo importInfo = imports->info(lookupNameComponent().constLast(), context().data());
|
||||||
|
|
||||||
if (importInfo.type() == ImportType::Directory) {
|
if (importInfo.type() == ImportType::Directory) {
|
||||||
@@ -1333,7 +1333,7 @@ void NodeMetaInfoPrivate::setupPrototypes()
|
|||||||
m_prototypes.append(description);
|
m_prototypes.append(description);
|
||||||
} else {
|
} else {
|
||||||
if (context()->lookupType(document(), {ov->className()})) {
|
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());
|
ImportInfo importInfo = allImports->info(description.className, context().data());
|
||||||
|
|
||||||
if (importInfo.isValid()) {
|
if (importInfo.isValid()) {
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ QStringList SubComponentManager::qmlFiles() const
|
|||||||
return m_watcher.files();
|
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)
|
if (debug)
|
||||||
qDebug() << Q_FUNC_INFO << filePath << imports.size();
|
qDebug() << Q_FUNC_INFO << filePath << imports.size();
|
||||||
|
|||||||
@@ -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)
|
static int getMinorVersionFromImport(const Model *model)
|
||||||
{
|
{
|
||||||
const QList<Import> imports = model->imports();
|
const Imports imports = model->imports();
|
||||||
for (const Import &import : imports) {
|
for (const Import &import : imports) {
|
||||||
if (import.isLibraryImport() && import.url() == "QtQuick") {
|
if (import.isLibraryImport() && import.url() == "QtQuick") {
|
||||||
const QString versionString = import.version();
|
const QString versionString = import.version();
|
||||||
@@ -909,7 +909,7 @@ static int getMinorVersionFromImport(const Model *model)
|
|||||||
|
|
||||||
static int getMajorVersionFromImport(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) {
|
for (const Import &import : imports) {
|
||||||
if (import.isLibraryImport() && import.url() == QStringLiteral("QtQuick")) {
|
if (import.isLibraryImport() && import.url() == QStringLiteral("QtQuick")) {
|
||||||
const QString versionString = import.version();
|
const QString versionString = import.version();
|
||||||
|
|||||||
@@ -108,10 +108,10 @@ void ModelPrivate::detachAllViews()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelPrivate::changeImports(const QList<Import> &toBeAddedImportList,
|
void ModelPrivate::changeImports(const Imports &toBeAddedImportList,
|
||||||
const QList<Import> &toBeRemovedImportList)
|
const Imports &toBeRemovedImportList)
|
||||||
{
|
{
|
||||||
QList<Import> removedImportList;
|
Imports removedImportList;
|
||||||
for (const Import &import : toBeRemovedImportList) {
|
for (const Import &import : toBeRemovedImportList) {
|
||||||
if (m_imports.contains(import)) {
|
if (m_imports.contains(import)) {
|
||||||
removedImportList.append(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) {
|
for (const Import &import : toBeAddedImportList) {
|
||||||
if (!m_imports.contains(import)) {
|
if (!m_imports.contains(import)) {
|
||||||
addedImportList.append(import);
|
addedImportList.append(import);
|
||||||
@@ -131,8 +131,7 @@ void ModelPrivate::changeImports(const QList<Import> &toBeAddedImportList,
|
|||||||
notifyImportsChanged(addedImportList, removedImportList);
|
notifyImportsChanged(addedImportList, removedImportList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelPrivate::notifyImportsChanged(const QList<Import> &addedImports,
|
void ModelPrivate::notifyImportsChanged(const Imports &addedImports, const Imports &removedImports)
|
||||||
const QList<Import> &removedImports)
|
|
||||||
{
|
{
|
||||||
bool resetModel = false;
|
bool resetModel = false;
|
||||||
QString description;
|
QString description;
|
||||||
@@ -157,7 +156,7 @@ void ModelPrivate::notifyImportsChanged(const QList<Import> &addedImports,
|
|||||||
resetModelByRewriter(description);
|
resetModelByRewriter(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelPrivate::notifyPossibleImportsChanged(const QList<Import> &possibleImports)
|
void ModelPrivate::notifyPossibleImportsChanged(const Imports &possibleImports)
|
||||||
{
|
{
|
||||||
for (const QPointer<AbstractView> &view : enabledViews()) {
|
for (const QPointer<AbstractView> &view : enabledViews()) {
|
||||||
Q_ASSERT(view != nullptr);
|
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()) {
|
for (const QPointer<AbstractView> &view : enabledViews()) {
|
||||||
Q_ASSERT(view != nullptr);
|
Q_ASSERT(view != nullptr);
|
||||||
@@ -1400,28 +1399,27 @@ Model::Model(const TypeName &typeName, int major, int minor, Model *metaInfoProx
|
|||||||
|
|
||||||
Model::~Model() = default;
|
Model::~Model() = default;
|
||||||
|
|
||||||
const QList<Import> &Model::imports() const
|
const Imports &Model::imports() const
|
||||||
{
|
{
|
||||||
return d->imports();
|
return d->imports();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<Import> &Model::possibleImports() const
|
const Imports &Model::possibleImports() const
|
||||||
{
|
{
|
||||||
return d->m_possibleImportList;
|
return d->m_possibleImportList;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<Import> &Model::usedImports() const
|
const Imports &Model::usedImports() const
|
||||||
{
|
{
|
||||||
return d->m_usedImportList;
|
return d->m_usedImportList;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::changeImports(const QList<Import> &importsToBeAdded,
|
void Model::changeImports(const Imports &importsToBeAdded, const Imports &importsToBeRemoved)
|
||||||
const QList<Import> &importsToBeRemoved)
|
|
||||||
{
|
{
|
||||||
d->changeImports(importsToBeAdded, importsToBeRemoved);
|
d->changeImports(importsToBeAdded, importsToBeRemoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::setPossibleImports(const QList<Import> &possibleImports)
|
void Model::setPossibleImports(const Imports &possibleImports)
|
||||||
{
|
{
|
||||||
if (d->m_possibleImportList != possibleImports) {
|
if (d->m_possibleImportList != possibleImports) {
|
||||||
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) {
|
if (d->m_usedImportList != usedImports) {
|
||||||
d->m_usedImportList = usedImports;
|
d->m_usedImportList = usedImports;
|
||||||
|
|||||||
@@ -202,13 +202,13 @@ public:
|
|||||||
void resetModelByRewriter(const QString &description);
|
void resetModelByRewriter(const QString &description);
|
||||||
|
|
||||||
// Imports:
|
// Imports:
|
||||||
const QList<Import> &imports() const { return m_imports; }
|
const Imports &imports() const { return m_imports; }
|
||||||
void addImport(const Import &import);
|
void addImport(const Import &import);
|
||||||
void removeImport(const Import &import);
|
void removeImport(const Import &import);
|
||||||
void changeImports(const QList<Import> &importsToBeAdded, const QList<Import> &importToBeRemoved);
|
void changeImports(const Imports &importsToBeAdded, const Imports &importToBeRemoved);
|
||||||
void notifyImportsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports);
|
void notifyImportsChanged(const Imports &addedImports, const Imports &removedImports);
|
||||||
void notifyPossibleImportsChanged(const QList<Import> &possibleImports);
|
void notifyPossibleImportsChanged(const Imports &possibleImports);
|
||||||
void notifyUsedImportsChanged(const QList<Import> &usedImportsChanged);
|
void notifyUsedImportsChanged(const Imports &usedImportsChanged);
|
||||||
|
|
||||||
//node state property manipulation
|
//node state property manipulation
|
||||||
void addProperty(const InternalNodePointer &node, const PropertyName &name);
|
void addProperty(const InternalNodePointer &node, const PropertyName &name);
|
||||||
@@ -269,9 +269,9 @@ private:
|
|||||||
private:
|
private:
|
||||||
Model *m_model = nullptr;
|
Model *m_model = nullptr;
|
||||||
MetaInfo m_metaInfo;
|
MetaInfo m_metaInfo;
|
||||||
QList<Import> m_imports;
|
Imports m_imports;
|
||||||
QList<Import> m_possibleImportList;
|
Imports m_possibleImportList;
|
||||||
QList<Import> m_usedImportList;
|
Imports m_usedImportList;
|
||||||
QList<QPointer<AbstractView>> m_viewList;
|
QList<QPointer<AbstractView>> m_viewList;
|
||||||
QList<QPointer<AbstractView>> m_enabledViewList;
|
QList<QPointer<AbstractView>> m_enabledViewList;
|
||||||
QList<InternalNodePointer> m_selectedInternalNodeList;
|
QList<InternalNodePointer> m_selectedInternalNodeList;
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ ModelNode ModelMerger::insertModel(const ModelNode &modelNode, const MergePredic
|
|||||||
return {};
|
return {};
|
||||||
RewriterTransaction transaction(view()->beginRewriterTransaction(QByteArrayLiteral("ModelMerger::insertModel")));
|
RewriterTransaction transaction(view()->beginRewriterTransaction(QByteArrayLiteral("ModelMerger::insertModel")));
|
||||||
|
|
||||||
QList<Import> newImports;
|
Imports newImports;
|
||||||
|
|
||||||
for (const Import &import : modelNode.model()->imports()) {
|
for (const Import &import : modelNode.model()->imports()) {
|
||||||
if (!view()->model()->hasImport(import, true, true))
|
if (!view()->model()->hasImport(import, true, true))
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ void RewriterView::nodeReparented(const ModelNode &node, const NodeAbstractPrope
|
|||||||
applyChanges();
|
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)
|
for (const Import &import : addedImports)
|
||||||
importAdded(import);
|
importAdded(import);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "signalhandlerproperty.h"
|
#include "signalhandlerproperty.h"
|
||||||
#include "variantproperty.h"
|
#include "variantproperty.h"
|
||||||
#include <externaldependenciesinterface.h>
|
#include <externaldependenciesinterface.h>
|
||||||
|
#include <projectstorage/modulescanner.h>
|
||||||
#include <rewritingexception.h>
|
#include <rewritingexception.h>
|
||||||
|
|
||||||
#include <enumeration.h>
|
#include <enumeration.h>
|
||||||
@@ -44,6 +45,7 @@
|
|||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
using namespace LanguageUtils;
|
using namespace LanguageUtils;
|
||||||
using namespace QmlJS;
|
using namespace QmlJS;
|
||||||
@@ -716,7 +718,7 @@ bool TextToModelMerger::isActive() const
|
|||||||
void TextToModelMerger::setupImports(const Document::Ptr &doc,
|
void TextToModelMerger::setupImports(const Document::Ptr &doc,
|
||||||
DifferenceHandler &differenceHandler)
|
DifferenceHandler &differenceHandler)
|
||||||
{
|
{
|
||||||
QList<Import> existingImports = m_rewriterView->model()->imports();
|
Imports existingImports = m_rewriterView->model()->imports();
|
||||||
|
|
||||||
m_hasVersionlessImport = false;
|
m_hasVersionlessImport = false;
|
||||||
|
|
||||||
@@ -756,87 +758,87 @@ void TextToModelMerger::setupImports(const Document::Ptr &doc,
|
|||||||
differenceHandler.importAbsentInQMl(import);
|
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())
|
return std::any_of(skipModuleNames.begin(),
|
||||||
|| filteredPossibleImportKeys.value(importKey.path()).majorVersion < importKey.majorVersion
|
skipModuleNames.end(),
|
||||||
|| (filteredPossibleImportKeys.value(importKey.path()).majorVersion == importKey.majorVersion
|
[&](const QString &skipModuleName) {
|
||||||
&& filteredPossibleImportKeys.value(importKey.path()).minorVersion < importKey.minorVersion);
|
return moduleName.contains(skipModuleName);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool filterByMetaInfo(const ImportKey &importKey, Model *model)
|
class StartsWith : public QStringView
|
||||||
{
|
{
|
||||||
if (model) {
|
public:
|
||||||
for (const QString &filter : model->metaInfo().itemLibraryInfo()->blacklistImports()) {
|
using QStringView::QStringView;
|
||||||
if (importKey.libraryQualifiedPath().contains(filter))
|
bool operator()(QStringView moduleName) const { return moduleName.startsWith(*this); }
|
||||||
return true;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
}
|
class EndsWith : public QStringView
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isBlacklistImport(const ImportKey &importKey, Model *model)
|
|
||||||
{
|
{
|
||||||
const QString &importPathFirst = importKey.splitPath.constFirst();
|
public:
|
||||||
const QString &importPathLast = importKey.splitPath.constLast();
|
using QStringView::QStringView;
|
||||||
return importPathFirst == QStringLiteral("<cpp>")
|
bool operator()(QStringView moduleName) const { return moduleName.endsWith(*this); }
|
||||||
|| 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);
|
class StartsAndEndsWith : public std::pair<QStringView, QStringView>
|
||||||
}
|
|
||||||
|
|
||||||
static QHash<QString, ImportKey> filterPossibleImportKeys(const QSet<ImportKey> &possibleImportKeys, Model *model)
|
|
||||||
{
|
{
|
||||||
QHash<QString, ImportKey> filteredPossibleImportKeys;
|
public:
|
||||||
for (const ImportKey &importKey : possibleImportKeys) {
|
using Base = std::pair<QStringView, QStringView>;
|
||||||
if (isLatestImportVersion(importKey, filteredPossibleImportKeys) && !isBlacklistImport(importKey, model))
|
using Base::Base;
|
||||||
filteredPossibleImportKeys.insert(importKey.path(), importKey);
|
bool operator()(QStringView moduleName) const
|
||||||
}
|
|
||||||
|
|
||||||
return filteredPossibleImportKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void removeUsedImports(QHash<QString, ImportKey> &filteredPossibleImportKeys, const QList<QmlJS::Import> &usedImports)
|
|
||||||
{
|
{
|
||||||
for (const QmlJS::Import &import : usedImports)
|
return moduleName.startsWith(first) && moduleName.endsWith(second);
|
||||||
filteredPossibleImportKeys.remove(import.info.path());
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Equals : public QStringView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using QStringView::QStringView;
|
||||||
|
bool operator()(QStringView moduleName) const { return moduleName == *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
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"));
|
||||||
|
|
||||||
|
bool skipModule(QStringView moduleName)
|
||||||
|
{
|
||||||
|
return std::apply([=](const auto &...skipModule) { return (skipModule(moduleName) || ...); },
|
||||||
|
skipModules);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QList<QmlDesigner::Import> generatePossibleFileImports(const QString &path,
|
bool skipModule(QStringView moduleName, const QStringList &skipModuleNames)
|
||||||
const QList<QmlJS::Import> &usedImports)
|
|
||||||
{
|
{
|
||||||
QSet<QString> usedImportsSet;
|
return skipModule(moduleName) || skipByMetaInfo(moduleName, skipModuleNames);
|
||||||
for (const QmlJS::Import &i : usedImports)
|
}
|
||||||
usedImportsSet.insert(i.info.path());
|
|
||||||
|
|
||||||
QList<QmlDesigner::Import> possibleImports;
|
void collectPossibleFileImports(const QString &checkPath,
|
||||||
|
QSet<QString> usedImportsSet,
|
||||||
|
QList<QmlDesigner::Import> &possibleImports)
|
||||||
|
{
|
||||||
const QStringList qmlList("*.qml");
|
const QStringList qmlList("*.qml");
|
||||||
const QStringList qmldirList("qmldir");
|
const QStringList qmldirList("qmldir");
|
||||||
|
|
||||||
QStringList fileImportPaths;
|
|
||||||
const QChar delimeter('/');
|
const QChar delimeter('/');
|
||||||
|
|
||||||
std::function<void(const QString &)> checkDir;
|
|
||||||
checkDir = [&](const QString &checkPath) {
|
|
||||||
|
|
||||||
if (QFileInfo(checkPath).isRoot())
|
if (QFileInfo(checkPath).isRoot())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -848,70 +850,33 @@ static QList<QmlDesigner::Import> generatePossibleFileImports(const QString &pat
|
|||||||
if (!dir.entryInfoList(qmlList, QDir::Files).isEmpty()
|
if (!dir.entryInfoList(qmlList, QDir::Files).isEmpty()
|
||||||
&& dir.entryInfoList(qmldirList, QDir::Files).isEmpty()
|
&& dir.entryInfoList(qmldirList, QDir::Files).isEmpty()
|
||||||
&& !usedImportsSet.contains(dirPath)) {
|
&& !usedImportsSet.contains(dirPath)) {
|
||||||
const QString importName = dir.path().mid(path.size() + 1);
|
const QString importName = dir.path().mid(checkPath.size() + 1);
|
||||||
QmlDesigner::Import import = QmlDesigner::Import::createFileImport(importName);
|
QmlDesigner::Import import = QmlDesigner::Import::createFileImport(importName);
|
||||||
possibleImports.append(import);
|
possibleImports.append(import);
|
||||||
}
|
}
|
||||||
checkDir(dirPath);
|
collectPossibleFileImports(dirPath, usedImportsSet, possibleImports);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
checkDir(path);
|
|
||||||
|
|
||||||
return possibleImports;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QList<QmlDesigner::Import> generatePossibleLibraryImports(const QHash<QString, ImportKey> &filteredPossibleImportKeys)
|
QList<QmlDesigner::Import> generatePossibleFileImports(const QString &path,
|
||||||
|
const QList<QmlJS::Import> &usedImports)
|
||||||
{
|
{
|
||||||
|
QSet<QString> usedImportsSet;
|
||||||
|
for (const QmlJS::Import &i : usedImports)
|
||||||
|
usedImportsSet.insert(i.info.path());
|
||||||
|
|
||||||
QList<QmlDesigner::Import> possibleImports;
|
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) {
|
QStringList fileImportPaths;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasVersionlessControls && !hasVersionedControls && !controlsImplVersions.isEmpty()) {
|
|
||||||
for (const auto &version : std::as_const(controlsImplVersions))
|
|
||||||
possibleImports.append(QmlDesigner::Import::createLibraryImport(controlsName, version));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
collectPossibleFileImports(path, usedImportsSet, possibleImports);
|
||||||
|
|
||||||
return possibleImports;
|
return possibleImports;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextToModelMerger::setupPossibleImports(const QmlJS::Snapshot &snapshot, const QmlJS::ViewerContext &viewContext)
|
} // namespace
|
||||||
|
|
||||||
|
void TextToModelMerger::setupPossibleImports()
|
||||||
{
|
{
|
||||||
if (!m_rewriterView->possibleImportsEnabled())
|
if (!m_rewriterView->possibleImportsEnabled())
|
||||||
return;
|
return;
|
||||||
@@ -919,27 +884,25 @@ void TextToModelMerger::setupPossibleImports(const QmlJS::Snapshot &snapshot, co
|
|||||||
static QUrl lastProjectUrl;
|
static QUrl lastProjectUrl;
|
||||||
auto &externalDependencies = m_rewriterView->externalDependencies();
|
auto &externalDependencies = m_rewriterView->externalDependencies();
|
||||||
auto projectUrl = externalDependencies.projectUrl();
|
auto projectUrl = externalDependencies.projectUrl();
|
||||||
|
auto allUsedImports = m_scopeChain->context()->imports(m_document.data())->all();
|
||||||
|
|
||||||
if (m_possibleImportKeys.isEmpty() || projectUrl != lastProjectUrl)
|
if (m_possibleModules.isEmpty() || projectUrl != lastProjectUrl) {
|
||||||
m_possibleImportKeys = snapshot.importDependencies()->libraryImports(viewContext);
|
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;
|
lastProjectUrl = projectUrl;
|
||||||
|
|
||||||
QHash<QString, ImportKey> filteredPossibleImportKeys = filterPossibleImportKeys(
|
auto modules = m_possibleModules;
|
||||||
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);
|
|
||||||
|
|
||||||
if (document()->fileName() != "<internal>")
|
if (document()->fileName() != "<internal>")
|
||||||
possibleImports.append(
|
modules.append(generatePossibleFileImports(document()->path().toString(), allUsedImports));
|
||||||
generatePossibleFileImports(document()->path().toString(), imports->all()));
|
|
||||||
|
|
||||||
if (m_rewriterView->isAttached())
|
if (m_rewriterView->isAttached())
|
||||||
m_rewriterView->model()->setPossibleImports(possibleImports);
|
m_rewriterView->model()->setPossibleImports(modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextToModelMerger::setupUsedImports()
|
void TextToModelMerger::setupUsedImports()
|
||||||
@@ -951,7 +914,7 @@ void TextToModelMerger::setupUsedImports()
|
|||||||
const QList<QmlJS::Import> allImports = imports->all();
|
const QList<QmlJS::Import> allImports = imports->all();
|
||||||
|
|
||||||
QSet<QString> usedImportsSet;
|
QSet<QString> usedImportsSet;
|
||||||
QList<Import> usedImports;
|
Imports usedImports;
|
||||||
|
|
||||||
// populate usedImportsSet from current model nodes
|
// populate usedImportsSet from current model nodes
|
||||||
const QList<ModelNode> allModelNodes = m_rewriterView->allModelNodes();
|
const QList<ModelNode> allModelNodes = m_rewriterView->allModelNodes();
|
||||||
@@ -964,9 +927,6 @@ void TextToModelMerger::setupUsedImports()
|
|||||||
for (const QmlJS::Import &import : allImports) {
|
for (const QmlJS::Import &import : allImports) {
|
||||||
QString version = import.info.version().toString();
|
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.name().isEmpty() && usedImportsSet.contains(import.info.name())) {
|
||||||
if (import.info.type() == ImportType::Library)
|
if (import.info.type() == ImportType::Library)
|
||||||
usedImports.append(
|
usedImports.append(
|
||||||
@@ -1077,7 +1037,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
|
|||||||
collectLinkErrors(&errors, ctxt);
|
collectLinkErrors(&errors, ctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
setupPossibleImports(snapshot, m_vContext);
|
setupPossibleImports();
|
||||||
|
|
||||||
qCInfo(rewriterBenchmark) << "possible imports:" << time.elapsed();
|
qCInfo(rewriterBenchmark) << "possible imports:" << time.elapsed();
|
||||||
|
|
||||||
@@ -1115,12 +1075,6 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
|
|||||||
|
|
||||||
setActive(false);
|
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;
|
return true;
|
||||||
} catch (Exception &e) {
|
} catch (Exception &e) {
|
||||||
DocumentMessage error(&e);
|
DocumentMessage error(&e);
|
||||||
@@ -2387,8 +2341,8 @@ QList<QmlTypeData> TextToModelMerger::getQMLSingletons() const
|
|||||||
|
|
||||||
void TextToModelMerger::clearPossibleImportKeys()
|
void TextToModelMerger::clearPossibleImportKeys()
|
||||||
{
|
{
|
||||||
m_possibleImportKeys.clear();
|
m_possibleModules.clear();
|
||||||
m_previousPossibleImportsSize = -1;
|
m_previousPossibleModulesSize = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TextToModelMerger::textAt(const Document::Ptr &doc,
|
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());
|
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;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public:
|
|||||||
bool isActive() const;
|
bool isActive() const;
|
||||||
|
|
||||||
void setupImports(const QmlJS::Document::Ptr &doc, DifferenceHandler &differenceHandler);
|
void setupImports(const QmlJS::Document::Ptr &doc, DifferenceHandler &differenceHandler);
|
||||||
void setupPossibleImports(const QmlJS::Snapshot &snapshot, const QmlJS::ViewerContext &viewContext);
|
void setupPossibleImports();
|
||||||
void setupUsedImports();
|
void setupUsedImports();
|
||||||
bool load(const QString &data, DifferenceHandler &differenceHandler);
|
bool load(const QString &data, DifferenceHandler &differenceHandler);
|
||||||
|
|
||||||
@@ -137,8 +137,6 @@ private:
|
|||||||
const QmlJS::SourceLocation &from,
|
const QmlJS::SourceLocation &from,
|
||||||
const QmlJS::SourceLocation &to);
|
const QmlJS::SourceLocation &to);
|
||||||
|
|
||||||
QString getHighestPossibleImport(const QString &importName) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RewriterView *m_rewriterView;
|
RewriterView *m_rewriterView;
|
||||||
bool m_isActive;
|
bool m_isActive;
|
||||||
@@ -150,8 +148,8 @@ private:
|
|||||||
QSet<ModelNode> m_clearImplicitComponentList;
|
QSet<ModelNode> m_clearImplicitComponentList;
|
||||||
QmlJS::ViewerContext m_vContext;
|
QmlJS::ViewerContext m_vContext;
|
||||||
QSet<QPair<QString, QString> > m_qrcMapping;
|
QSet<QPair<QString, QString> > m_qrcMapping;
|
||||||
QSet<QmlJS::ImportKey> m_possibleImportKeys;
|
Imports m_possibleModules;
|
||||||
int m_previousPossibleImportsSize = -1;
|
int m_previousPossibleModulesSize = -1;
|
||||||
bool m_hasVersionlessImport = false;
|
bool m_hasVersionlessImport = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <sqlitedatabase.h>
|
#include <sqlitedatabase.h>
|
||||||
|
|
||||||
#ifdef QDS_HAS_QMLDOM
|
#ifdef QDS_HAS_QMLPRIVATE
|
||||||
#include <private/qqmldomtop_p.h>
|
#include <private/qqmldomtop_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
#ifdef QDS_HAS_QMLDOM
|
#ifdef QDS_HAS_QMLPRIVATE
|
||||||
|
|
||||||
namespace QmlDom = QQmlJS::Dom;
|
namespace QmlDom = QQmlJS::Dom;
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>;
|
using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>;
|
||||||
using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>;
|
using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>;
|
||||||
|
|
||||||
#ifdef QDS_HAS_QMLDOM
|
#ifdef QDS_HAS_QMLPRIVATE
|
||||||
QmlDocumentParser(ProjectStorage &storage, PathCache &pathCache)
|
QmlDocumentParser(ProjectStorage &storage, PathCache &pathCache)
|
||||||
: m_storage{storage}
|
: m_storage{storage}
|
||||||
, m_pathCache{pathCache}
|
, m_pathCache{pathCache}
|
||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// m_pathCache and m_storage are only used when compiled for QDS
|
// m_pathCache and m_storage are only used when compiled for QDS
|
||||||
#ifdef QDS_HAS_QMLDOM
|
#ifdef QDS_HAS_QMLPRIVATE
|
||||||
ProjectStorage &m_storage;
|
ProjectStorage &m_storage;
|
||||||
PathCache &m_pathCache;
|
PathCache &m_pathCache;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include <sqlitedatabase.h>
|
#include <sqlitedatabase.h>
|
||||||
|
|
||||||
#ifdef QDS_HAS_QMLDOM
|
#ifdef QDS_HAS_QMLPRIVATE
|
||||||
#include <private/qqmldomtop_p.h>
|
#include <private/qqmldomtop_p.h>
|
||||||
#include <private/qqmljstypedescriptionreader_p.h>
|
#include <private/qqmljstypedescriptionreader_p.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
#ifdef QDS_HAS_QMLDOM
|
#ifdef QDS_HAS_QMLPRIVATE
|
||||||
|
|
||||||
namespace QmlDom = QQmlJS::Dom;
|
namespace QmlDom = QQmlJS::Dom;
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public:
|
|||||||
using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>;
|
using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>;
|
||||||
using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>;
|
using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>;
|
||||||
|
|
||||||
#ifdef QDS_HAS_QMLDOM
|
#ifdef QDS_HAS_QMLPRIVATE
|
||||||
QmlTypesParser(PathCache &pathCache, ProjectStorage &storage)
|
QmlTypesParser(PathCache &pathCache, ProjectStorage &storage)
|
||||||
: m_pathCache{pathCache}
|
: m_pathCache{pathCache}
|
||||||
, m_storage{storage}
|
, m_storage{storage}
|
||||||
@@ -41,7 +41,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// m_pathCache and m_storage are only used when compiled for QDS
|
// m_pathCache and m_storage are only used when compiled for QDS
|
||||||
#ifdef QDS_HAS_QMLDOM
|
#ifdef QDS_HAS_QMLPRIVATE
|
||||||
PathCache &m_pathCache;
|
PathCache &m_pathCache;
|
||||||
ProjectStorage &m_storage;
|
ProjectStorage &m_storage;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,9 +9,11 @@
|
|||||||
#include <edit3d/edit3dviewconfig.h>
|
#include <edit3d/edit3dviewconfig.h>
|
||||||
#include <itemlibraryimport.h>
|
#include <itemlibraryimport.h>
|
||||||
#include <projectexplorer/kit.h>
|
#include <projectexplorer/kit.h>
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
#include <puppetenvironmentbuilder.h>
|
#include <puppetenvironmentbuilder.h>
|
||||||
|
#include <qmlprojectmanager/qmlproject.h>
|
||||||
#include <qmlpuppetpaths.h>
|
#include <qmlpuppetpaths.h>
|
||||||
#include <qtsupport/baseqtversion.h>
|
#include <qtsupport/baseqtversion.h>
|
||||||
#include <qtsupport/qtkitinformation.h>
|
#include <qtsupport/qtkitinformation.h>
|
||||||
@@ -186,4 +188,50 @@ Utils::FilePath ExternalDependencies::qmlPuppetPath() const
|
|||||||
return puppetPath;
|
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
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public:
|
|||||||
PuppetStartData puppetStartData(const class Model &model) const override;
|
PuppetStartData puppetStartData(const class Model &model) const override;
|
||||||
bool instantQmlTextUpdate() const override;
|
bool instantQmlTextUpdate() const override;
|
||||||
Utils::FilePath qmlPuppetPath() const override;
|
Utils::FilePath qmlPuppetPath() const override;
|
||||||
|
QStringList modulePaths() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const DesignerSettings &m_designerSettings;
|
const DesignerSettings &m_designerSettings;
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ void projectQmldirPaths(::ProjectExplorer::Target *target, QStringList &qmldirPa
|
|||||||
qmldirPaths.push_back(QDir::cleanPath(pojectDirectory.absoluteFilePath(importPath))
|
qmldirPaths.push_back(QDir::cleanPath(pojectDirectory.absoluteFilePath(importPath))
|
||||||
+ "/qmldir");
|
+ "/qmldir");
|
||||||
}
|
}
|
||||||
#ifdef QDS_HAS_QMLDOM
|
#ifdef QDS_HAS_QMLPRIVATE
|
||||||
bool skipPath(const std::filesystem::path &path)
|
bool skipPath(const std::filesystem::path &path)
|
||||||
{
|
{
|
||||||
auto directory = path.filename();
|
auto directory = path.filename();
|
||||||
@@ -359,10 +359,11 @@ bool skipPath(const std::filesystem::path &path)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void qtQmldirPaths([[maybe_unused]] ::ProjectExplorer::Target *target,
|
void qtQmldirPaths(::ProjectExplorer::Target *target, QStringList &qmldirPaths)
|
||||||
[[maybe_unused]] QStringList &qmldirPaths)
|
|
||||||
{
|
{
|
||||||
#ifdef QDS_HAS_QMLDOM
|
#ifdef QDS_HAS_QMLPRIVATE
|
||||||
|
|
||||||
|
if (useProjectStorage()) {
|
||||||
const QString installDirectory = qmlPath(target).toString();
|
const QString installDirectory = qmlPath(target).toString();
|
||||||
|
|
||||||
const std::filesystem::path installDirectoryPath{installDirectory.toStdString()};
|
const std::filesystem::path installDirectoryPath{installDirectory.toStdString()};
|
||||||
@@ -380,6 +381,7 @@ void qtQmldirPaths([[maybe_unused]] ::ProjectExplorer::Target *target,
|
|||||||
qmldirPaths.push_back(QString::fromStdU16String(path.generic_u16string()));
|
qmldirPaths.push_back(QString::fromStdU16String(path.generic_u16string()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ public:
|
|||||||
PuppetStartData puppetStartData(const class Model &) const override { return {}; }
|
PuppetStartData puppetStartData(const class Model &) const override { return {}; }
|
||||||
bool instantQmlTextUpdate() const override { return true; }
|
bool instantQmlTextUpdate() const override { return true; }
|
||||||
Utils::FilePath qmlPuppetPath() const override { return {}; }
|
Utils::FilePath qmlPuppetPath() const override { return {}; }
|
||||||
|
QStringList modulePaths() const override { return {}; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QSettings qsettings;
|
QSettings qsettings;
|
||||||
@@ -1074,10 +1075,10 @@ void tst_TestCore::testRewriterChangeImports()
|
|||||||
//
|
//
|
||||||
Import webkitImport = Import::createLibraryImport("QtWebKit", "1.0");
|
Import webkitImport = Import::createLibraryImport("QtWebKit", "1.0");
|
||||||
|
|
||||||
QList<Import> importList;
|
Imports importList;
|
||||||
importList << webkitImport;
|
importList << webkitImport;
|
||||||
|
|
||||||
model->changeImports(importList, QList<Import>());
|
model->changeImports(importList, Imports());
|
||||||
|
|
||||||
const QLatin1String qmlWithImport("\n"
|
const QLatin1String qmlWithImport("\n"
|
||||||
"import QtQuick 2.1\n"
|
"import QtQuick 2.1\n"
|
||||||
@@ -1086,7 +1087,7 @@ void tst_TestCore::testRewriterChangeImports()
|
|||||||
"Rectangle {}\n");
|
"Rectangle {}\n");
|
||||||
QCOMPARE(textEdit.toPlainText(), qmlWithImport);
|
QCOMPARE(textEdit.toPlainText(), qmlWithImport);
|
||||||
|
|
||||||
model->changeImports(QList<Import>(), importList);
|
model->changeImports(Imports(), importList);
|
||||||
|
|
||||||
QCOMPARE(model->imports().size(), 1);
|
QCOMPARE(model->imports().size(), 1);
|
||||||
QCOMPARE(model->imports().first(), Import::createLibraryImport("QtQuick", "2.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");
|
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"
|
const QLatin1String qmlWithAliasImport("\n"
|
||||||
"import QtQuick 2.1\n"
|
"import QtQuick 2.1\n"
|
||||||
@@ -1109,7 +1110,7 @@ void tst_TestCore::testRewriterChangeImports()
|
|||||||
"Rectangle {}\n");
|
"Rectangle {}\n");
|
||||||
QCOMPARE(textEdit.toPlainText(), qmlWithAliasImport);
|
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(model->imports().first(), Import::createLibraryImport("QtQuick", "2.1"));
|
||||||
|
|
||||||
QCOMPARE(textEdit.toPlainText(), qmlString);
|
QCOMPARE(textEdit.toPlainText(), qmlString);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ add_qtc_test(unittest GTEST
|
|||||||
BEFORE "../mockup/qmldesigner/designercore/include"
|
BEFORE "../mockup/qmldesigner/designercore/include"
|
||||||
DEPENDS
|
DEPENDS
|
||||||
Qt::Core Qt::Network Qt::Widgets
|
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
|
Qt6Core5Compat QmlJS Sqlite SqliteC
|
||||||
Googletest
|
Googletest
|
||||||
DEFINES
|
DEFINES
|
||||||
@@ -36,6 +36,7 @@ add_qtc_test(unittest GTEST
|
|||||||
QTC_RESOURCE_DIR="${CMAKE_CURRENT_LIST_DIR}/../../../share/qtcreator"
|
QTC_RESOURCE_DIR="${CMAKE_CURRENT_LIST_DIR}/../../../share/qtcreator"
|
||||||
TESTDATA_DIR="${CMAKE_CURRENT_BINARY_DIR}/data"
|
TESTDATA_DIR="${CMAKE_CURRENT_BINARY_DIR}/data"
|
||||||
TEST_RELATIVE_LIBEXEC_PATH="${TEST_RELATIVE_LIBEXEC_PATH}"
|
TEST_RELATIVE_LIBEXEC_PATH="${TEST_RELATIVE_LIBEXEC_PATH}"
|
||||||
|
QT6_INSTALL_PREFIX="${QT6_INSTALL_PREFIX}"
|
||||||
SOURCES
|
SOURCES
|
||||||
abstractviewmock.h
|
abstractviewmock.h
|
||||||
compare-operators.h
|
compare-operators.h
|
||||||
@@ -97,6 +98,7 @@ add_qtc_test(unittest GTEST
|
|||||||
mockimagecachestorage.h
|
mockimagecachestorage.h
|
||||||
asynchronousexplicitimagecache-test.cpp
|
asynchronousexplicitimagecache-test.cpp
|
||||||
asynchronousimagefactory-test.cpp
|
asynchronousimagefactory-test.cpp
|
||||||
|
modulescanner-test.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if (NOT TARGET unittest)
|
if (NOT TARGET unittest)
|
||||||
@@ -250,6 +252,7 @@ extend_qtc_test(unittest
|
|||||||
projectstorage/filesystem.cpp projectstorage/filesystem.h
|
projectstorage/filesystem.cpp projectstorage/filesystem.h
|
||||||
projectstorage/filestatus.h
|
projectstorage/filestatus.h
|
||||||
projectstorage/filestatuscache.cpp projectstorage/filestatuscache.h
|
projectstorage/filestatuscache.cpp projectstorage/filestatuscache.h
|
||||||
|
projectstorage/modulescanner.cpp projectstorage/modulescanner.h
|
||||||
projectstorage/nonlockingmutex.h
|
projectstorage/nonlockingmutex.h
|
||||||
projectstorage/projectstorageexceptions.cpp projectstorage/projectstorageexceptions.h
|
projectstorage/projectstorageexceptions.cpp projectstorage/projectstorageexceptions.h
|
||||||
projectstorage/projectstorageinterface.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
|
CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND Qt6_VERSION VERSION_GREATER_EQUAL 6.5.0
|
||||||
SOURCES_PREFIX "${QmlDesignerDir}/designercore"
|
SOURCES_PREFIX "${QmlDesignerDir}/designercore"
|
||||||
DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate
|
DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate
|
||||||
DEFINES QDS_HAS_QMLDOM
|
DEFINES QDS_HAS_QMLPRIVATE
|
||||||
SOURCES
|
SOURCES
|
||||||
projectstorage/qmldocumentparser.cpp projectstorage/qmldocumentparser.h
|
projectstorage/qmldocumentparser.cpp projectstorage/qmldocumentparser.h
|
||||||
projectstorage/qmltypesparser.cpp projectstorage/qmltypesparser.h
|
projectstorage/qmltypesparser.cpp projectstorage/qmltypesparser.h
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
|
|
||||||
|
|
||||||
using testing::_;
|
using testing::_;
|
||||||
using testing::A;
|
using testing::A;
|
||||||
using testing::AllOf;
|
using testing::AllOf;
|
||||||
@@ -21,6 +20,7 @@ using testing::ByRef;
|
|||||||
using testing::ContainerEq;
|
using testing::ContainerEq;
|
||||||
using testing::Contains;
|
using testing::Contains;
|
||||||
using testing::ElementsAre;
|
using testing::ElementsAre;
|
||||||
|
using testing::EndsWith;
|
||||||
using testing::Eq;
|
using testing::Eq;
|
||||||
using testing::Exactly;
|
using testing::Exactly;
|
||||||
using testing::Field;
|
using testing::Field;
|
||||||
@@ -29,7 +29,6 @@ using testing::Gt;
|
|||||||
using testing::HasSubstr;
|
using testing::HasSubstr;
|
||||||
using testing::InSequence;
|
using testing::InSequence;
|
||||||
using testing::Invoke;
|
using testing::Invoke;
|
||||||
using testing::IsEmpty;
|
|
||||||
using testing::IsNull;
|
using testing::IsNull;
|
||||||
using testing::Le;
|
using testing::Le;
|
||||||
using testing::Lt;
|
using testing::Lt;
|
||||||
|
|||||||
53
tests/unit/unittest/modulescanner-test.cpp
Normal file
53
tests/unit/unittest/modulescanner-test.cpp
Normal file
@@ -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
|
||||||
@@ -9,8 +9,6 @@
|
|||||||
#include <utils/smallstringio.h>
|
#include <utils/smallstringio.h>
|
||||||
#include <utils/smallstringvector.h>
|
#include <utils/smallstringvector.h>
|
||||||
|
|
||||||
using namespace ::testing;
|
|
||||||
|
|
||||||
using Utils::PathString;
|
using Utils::PathString;
|
||||||
using Utils::SmallString;
|
using Utils::SmallString;
|
||||||
using Utils::SmallStringLiteral;
|
using Utils::SmallStringLiteral;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include <utils/smallstringio.h>
|
#include <utils/smallstringio.h>
|
||||||
|
|
||||||
namespace UnitTests {
|
namespace Internal {
|
||||||
|
|
||||||
template <typename StringType>
|
template <typename StringType>
|
||||||
class EndsWithMatcher
|
class EndsWithMatcher
|
||||||
@@ -46,10 +46,68 @@ private:
|
|||||||
const StringType m_suffix;
|
const StringType m_suffix;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
class QStringEndsWithMatcher
|
||||||
testing::PolymorphicMatcher<EndsWithMatcher<Utils::SmallString> >
|
|
||||||
EndsWith(const Utils::SmallString &suffix)
|
|
||||||
{
|
{
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,9 @@ bool operator==(const QString &first, const char *second)
|
|||||||
|
|
||||||
namespace UnitTest {
|
namespace UnitTest {
|
||||||
|
|
||||||
inline
|
inline ::Utils::PathString temporaryDirPath()
|
||||||
Utils::PathString temporaryDirPath()
|
|
||||||
{
|
{
|
||||||
return Utils::PathString::fromQString(Utils::TemporaryDirectory::masterDirectoryPath());
|
return ::Utils::PathString::fromQString(Utils::TemporaryDirectory::masterDirectoryPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace UnitTest
|
} // namespace UnitTest
|
||||||
|
|||||||
Reference in New Issue
Block a user