From 541aafecbb63c574c6d118833d52ed3628c990fd Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 6 Feb 2023 15:32:00 +0100 Subject: [PATCH] QML: Fix crash when opening context menu The AssistInterface changed to unique_ptr, but the internals of how the QmlJSEditor looked for quick fixes still wrapped it into a QSharedPointer, which then deleted the assist interface in addition to the unique_ptr. Amends 0e4b0a26d34c523463ea68b27caf69cbb89083f2 Fixes: QTCREATORBUG-28742 Change-Id: If685dbb2c49b09d529d0dcb3677dc90b03a039f0 Reviewed-by: Fabian Kosmale Reviewed-by: --- .../qmljscomponentfromobjectdef.cpp | 31 +++++++++---------- .../qmljseditor/qmljscomponentfromobjectdef.h | 4 +-- src/plugins/qmljseditor/qmljsquickfix.cpp | 15 ++++----- src/plugins/qmljseditor/qmljsquickfix.h | 9 +++--- src/plugins/qmljseditor/qmljsquickfixes.cpp | 16 +++++----- src/plugins/qmljseditor/qmljswrapinloader.cpp | 7 ++--- src/plugins/qmljseditor/qmljswrapinloader.h | 3 +- 7 files changed, 40 insertions(+), 45 deletions(-) diff --git a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp index 6ef9a21f992..98713d1a367 100644 --- a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp +++ b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp @@ -58,24 +58,22 @@ public: setDescription(Tr::tr("Move Component into Separate File")); } - Operation(const QSharedPointer &interface, - UiObjectDefinition *objDef) - : QmlJSQuickFixOperation(interface, 0), - m_idName(idOfObject(objDef)), - m_firstSourceLocation(objDef->firstSourceLocation()), - m_lastSourceLocation(objDef->lastSourceLocation()), - m_initializer(objDef->initializer) + Operation(const Internal::QmlJSQuickFixAssistInterface *interface, UiObjectDefinition *objDef) + : QmlJSQuickFixOperation(interface, 0) + , m_idName(idOfObject(objDef)) + , m_firstSourceLocation(objDef->firstSourceLocation()) + , m_lastSourceLocation(objDef->lastSourceLocation()) + , m_initializer(objDef->initializer) { init(); } - Operation(const QSharedPointer &interface, - UiObjectBinding *objDef) - : QmlJSQuickFixOperation(interface, 0), - m_idName(idOfObject(objDef)), - m_firstSourceLocation(objDef->qualifiedTypeNameId->firstSourceLocation()), - m_lastSourceLocation(objDef->lastSourceLocation()), - m_initializer(objDef->initializer) + Operation(const Internal::QmlJSQuickFixAssistInterface *interface, UiObjectBinding *objDef) + : QmlJSQuickFixOperation(interface, 0) + , m_idName(idOfObject(objDef)) + , m_firstSourceLocation(objDef->qualifiedTypeNameId->firstSourceLocation()) + , m_lastSourceLocation(objDef->lastSourceLocation()) + , m_initializer(objDef->initializer) { init(); } @@ -223,7 +221,7 @@ public: } // end of anonymous namespace -void matchComponentFromObjectDefQuickFix(const QmlJSQuickFixInterface &interface, QuickFixOperations &result) +void matchComponentFromObjectDefQuickFix(const QmlJSQuickFixAssistInterface *interface, QuickFixOperations &result) { const int pos = interface->currentFile()->cursor().position(); @@ -254,8 +252,7 @@ void performComponentFromObjectDef(const QString &fileName, QmlJS::AST::UiObject QmlJS::ModelManagerInterface::instance()->snapshot()); QmlJSRefactoringFilePtr current = refactoring.file(Utils::FilePath::fromString(fileName)); - QmlJSQuickFixInterface interface; - Operation operation(interface, objDef); + Operation operation(nullptr, objDef); operation.performChanges(current, refactoring); } diff --git a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.h b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.h index c27fce2dc18..8ac708aed2e 100644 --- a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.h +++ b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.h @@ -8,8 +8,8 @@ namespace QmlJSEditor { -QMLJSEDITOR_EXPORT void matchComponentFromObjectDefQuickFix - (const QmlJSQuickFixInterface &interface, QuickFixOperations &result); +QMLJSEDITOR_EXPORT void matchComponentFromObjectDefQuickFix( + const Internal::QmlJSQuickFixAssistInterface *interface, QuickFixOperations &result); QMLJSEDITOR_EXPORT void performComponentFromObjectDef (const QString &fileName, QmlJS::AST::UiObjectDefinition *objDef); diff --git a/src/plugins/qmljseditor/qmljsquickfix.cpp b/src/plugins/qmljseditor/qmljsquickfix.cpp index 8c55f1e2908..65840389158 100644 --- a/src/plugins/qmljseditor/qmljsquickfix.cpp +++ b/src/plugins/qmljseditor/qmljsquickfix.cpp @@ -2,8 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qmljsquickfix.h" -#include "qmljscomponentfromobjectdef.h" -#include "qmljseditor.h" #include "qmljsquickfixassist.h" #include @@ -23,30 +21,29 @@ namespace QmlJSEditor { using namespace Internal; -QmlJSQuickFixOperation::QmlJSQuickFixOperation(const QmlJSQuickFixInterface &interface, +QmlJSQuickFixOperation::QmlJSQuickFixOperation(const QmlJSQuickFixAssistInterface *interface, int priority) : QuickFixOperation(priority) - , m_interface(interface) + , m_semanticInfo(interface->semanticInfo()) { } void QmlJSQuickFixOperation::perform() { - QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), - m_interface->semanticInfo().snapshot); + QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), semanticInfo().snapshot); QmlJSRefactoringFilePtr current = refactoring.file(fileName()); performChanges(current, refactoring); } -const QmlJSQuickFixAssistInterface *QmlJSQuickFixOperation::assistInterface() const +const QmlJSTools::SemanticInfo &QmlJSQuickFixOperation::semanticInfo() const { - return m_interface.data(); + return m_semanticInfo; } Utils::FilePath QmlJSQuickFixOperation::fileName() const { - return m_interface->semanticInfo().document->fileName(); + return semanticInfo().document->fileName(); } } // namespace QmlJSEditor diff --git a/src/plugins/qmljseditor/qmljsquickfix.h b/src/plugins/qmljseditor/qmljsquickfix.h index 498d07499e0..643334a94c7 100644 --- a/src/plugins/qmljseditor/qmljsquickfix.h +++ b/src/plugins/qmljseditor/qmljsquickfix.h @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -14,7 +15,6 @@ namespace QmlJSEditor { namespace Internal { class QmlJSQuickFixAssistInterface; } -using QmlJSQuickFixInterface = QSharedPointer; using TextEditor::QuickFixOperation; using TextEditor::QuickFixOperations; using TextEditor::QuickFixInterface; @@ -31,7 +31,8 @@ public: \param interface The interface on which the operation is performed. \param priority The priority for this operation. */ - explicit QmlJSQuickFixOperation(const QmlJSQuickFixInterface &interface, int priority = -1); + explicit QmlJSQuickFixOperation(const Internal::QmlJSQuickFixAssistInterface *interface, + int priority = -1); void perform() override; @@ -41,13 +42,13 @@ protected: virtual void performChanges(QmlJSTools::QmlJSRefactoringFilePtr currentFile, const QmlJSTools::QmlJSRefactoringChanges &refactoring) = 0; - const Internal::QmlJSQuickFixAssistInterface *assistInterface() const; + const QmlJSTools::SemanticInfo &semanticInfo() const; /// \returns The name of the file for for which this operation is invoked. Utils::FilePath fileName() const; private: - QmlJSQuickFixInterface m_interface; + const QmlJSTools::SemanticInfo m_semanticInfo; }; TextEditor::QuickFixOperations findQmlJSQuickFixes(const TextEditor::AssistInterface *interface); diff --git a/src/plugins/qmljseditor/qmljsquickfixes.cpp b/src/plugins/qmljseditor/qmljsquickfixes.cpp index fecee0d5bff..2226dc395df 100644 --- a/src/plugins/qmljseditor/qmljsquickfixes.cpp +++ b/src/plugins/qmljseditor/qmljsquickfixes.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qmljscomponentfromobjectdef.h" -#include "qmljseditor.h" #include "qmljseditortr.h" #include "qmljsquickfix.h" #include "qmljsquickfixassist.h" @@ -42,8 +41,8 @@ class SplitInitializerOperation: public QmlJSQuickFixOperation UiObjectInitializer *_objectInitializer; public: - SplitInitializerOperation(const QSharedPointer &interface, - UiObjectInitializer *objectInitializer) + SplitInitializerOperation(const Internal::QmlJSQuickFixAssistInterface *interface, + UiObjectInitializer *objectInitializer) : QmlJSQuickFixOperation(interface, 0) , _objectInitializer(objectInitializer) { @@ -77,7 +76,8 @@ public: } }; -void matchSplitInitializerQuickFix(const QmlJSQuickFixInterface &interface, QuickFixOperations &result) +void matchSplitInitializerQuickFix(const Internal::QmlJSQuickFixAssistInterface *interface, + QuickFixOperations &result) { UiObjectInitializer *objectInitializer = nullptr; @@ -108,7 +108,7 @@ class AnalysizeMessageSuppressionOperation: public QmlJSQuickFixOperation Q_DECLARE_TR_FUNCTIONS(AddAnalysisMessageSuppressionComment) public: - AnalysizeMessageSuppressionOperation(const QSharedPointer &interface, + AnalysizeMessageSuppressionOperation(const Internal::QmlJSQuickFixAssistInterface *interface, const StaticAnalysis::Message &message) : QmlJSQuickFixOperation(interface, 0) , _message(message) @@ -128,7 +128,8 @@ public: } }; -void matchAddAnalysisMessageSuppressionCommentQuickFix(const QmlJSQuickFixInterface &interface, QuickFixOperations &result) +void matchAddAnalysisMessageSuppressionCommentQuickFix( + const Internal::QmlJSQuickFixAssistInterface *interface, QuickFixOperations &result) { const QList &messages = interface->semanticInfo().staticAnalysisMessages; @@ -144,8 +145,7 @@ void matchAddAnalysisMessageSuppressionCommentQuickFix(const QmlJSQuickFixInterf QuickFixOperations findQmlJSQuickFixes(const AssistInterface *interface) { - QSharedPointer assistInterface(interface); - auto qmlJSInterface = assistInterface.staticCast(); + auto qmlJSInterface = static_cast(interface); QuickFixOperations quickFixes; diff --git a/src/plugins/qmljseditor/qmljswrapinloader.cpp b/src/plugins/qmljseditor/qmljswrapinloader.cpp index 9ad59516577..2b0d05928ec 100644 --- a/src/plugins/qmljseditor/qmljswrapinloader.cpp +++ b/src/plugins/qmljseditor/qmljswrapinloader.cpp @@ -67,8 +67,7 @@ class Operation: public QmlJSQuickFixOperation T *m_objDef; public: - Operation(const QSharedPointer &interface, - T *objDef) + Operation(const QmlJSQuickFixAssistInterface *interface, T *objDef) : QmlJSQuickFixOperation(interface, 0) , m_objDef(objDef) { @@ -82,7 +81,7 @@ public: QString tryName = base; int extraNumber = 1; const ObjectValue *found = nullptr; - const ScopeChain &scope = assistInterface()->semanticInfo().scopeChain(); + const ScopeChain &scope = semanticInfo().scopeChain(); forever { scope.lookup(tryName, &found); if (!found || extraNumber > 1000) @@ -157,7 +156,7 @@ public: } // end of anonymous namespace -void matchWrapInLoaderQuickFix(const QmlJSQuickFixInterface &interface, QuickFixOperations &result) +void matchWrapInLoaderQuickFix(const QmlJSQuickFixAssistInterface *interface, QuickFixOperations &result) { const int pos = interface->currentFile()->cursor().position(); diff --git a/src/plugins/qmljseditor/qmljswrapinloader.h b/src/plugins/qmljseditor/qmljswrapinloader.h index 0d60c07a7ff..13a26a27d08 100644 --- a/src/plugins/qmljseditor/qmljswrapinloader.h +++ b/src/plugins/qmljseditor/qmljswrapinloader.h @@ -7,6 +7,7 @@ namespace QmlJSEditor { -void matchWrapInLoaderQuickFix(const QmlJSQuickFixInterface &interface, QuickFixOperations &result); +void matchWrapInLoaderQuickFix(const Internal::QmlJSQuickFixAssistInterface *interface, + QuickFixOperations &result); } // namespace QmlJSEditor