forked from qt-creator/qt-creator
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 0e4b0a26d3
Fixes: QTCREATORBUG-28742
Change-Id: If685dbb2c49b09d529d0dcb3677dc90b03a039f0
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
committed by
David Schulz
parent
8512aba9eb
commit
541aafecbb
@@ -58,24 +58,22 @@ public:
|
|||||||
setDescription(Tr::tr("Move Component into Separate File"));
|
setDescription(Tr::tr("Move Component into Separate File"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Operation(const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface,
|
Operation(const Internal::QmlJSQuickFixAssistInterface *interface, UiObjectDefinition *objDef)
|
||||||
UiObjectDefinition *objDef)
|
: QmlJSQuickFixOperation(interface, 0)
|
||||||
: QmlJSQuickFixOperation(interface, 0),
|
, m_idName(idOfObject(objDef))
|
||||||
m_idName(idOfObject(objDef)),
|
, m_firstSourceLocation(objDef->firstSourceLocation())
|
||||||
m_firstSourceLocation(objDef->firstSourceLocation()),
|
, m_lastSourceLocation(objDef->lastSourceLocation())
|
||||||
m_lastSourceLocation(objDef->lastSourceLocation()),
|
, m_initializer(objDef->initializer)
|
||||||
m_initializer(objDef->initializer)
|
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
Operation(const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface,
|
Operation(const Internal::QmlJSQuickFixAssistInterface *interface, UiObjectBinding *objDef)
|
||||||
UiObjectBinding *objDef)
|
: QmlJSQuickFixOperation(interface, 0)
|
||||||
: QmlJSQuickFixOperation(interface, 0),
|
, m_idName(idOfObject(objDef))
|
||||||
m_idName(idOfObject(objDef)),
|
, m_firstSourceLocation(objDef->qualifiedTypeNameId->firstSourceLocation())
|
||||||
m_firstSourceLocation(objDef->qualifiedTypeNameId->firstSourceLocation()),
|
, m_lastSourceLocation(objDef->lastSourceLocation())
|
||||||
m_lastSourceLocation(objDef->lastSourceLocation()),
|
, m_initializer(objDef->initializer)
|
||||||
m_initializer(objDef->initializer)
|
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -223,7 +221,7 @@ public:
|
|||||||
} // end of anonymous namespace
|
} // 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();
|
const int pos = interface->currentFile()->cursor().position();
|
||||||
|
|
||||||
@@ -254,8 +252,7 @@ void performComponentFromObjectDef(const QString &fileName, QmlJS::AST::UiObject
|
|||||||
QmlJS::ModelManagerInterface::instance()->snapshot());
|
QmlJS::ModelManagerInterface::instance()->snapshot());
|
||||||
QmlJSRefactoringFilePtr current = refactoring.file(Utils::FilePath::fromString(fileName));
|
QmlJSRefactoringFilePtr current = refactoring.file(Utils::FilePath::fromString(fileName));
|
||||||
|
|
||||||
QmlJSQuickFixInterface interface;
|
Operation operation(nullptr, objDef);
|
||||||
Operation operation(interface, objDef);
|
|
||||||
|
|
||||||
operation.performChanges(current, refactoring);
|
operation.performChanges(current, refactoring);
|
||||||
}
|
}
|
||||||
|
@@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
namespace QmlJSEditor {
|
namespace QmlJSEditor {
|
||||||
|
|
||||||
QMLJSEDITOR_EXPORT void matchComponentFromObjectDefQuickFix
|
QMLJSEDITOR_EXPORT void matchComponentFromObjectDefQuickFix(
|
||||||
(const QmlJSQuickFixInterface &interface, QuickFixOperations &result);
|
const Internal::QmlJSQuickFixAssistInterface *interface, QuickFixOperations &result);
|
||||||
|
|
||||||
QMLJSEDITOR_EXPORT void performComponentFromObjectDef
|
QMLJSEDITOR_EXPORT void performComponentFromObjectDef
|
||||||
(const QString &fileName, QmlJS::AST::UiObjectDefinition *objDef);
|
(const QString &fileName, QmlJS::AST::UiObjectDefinition *objDef);
|
||||||
|
@@ -2,8 +2,6 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "qmljsquickfix.h"
|
#include "qmljsquickfix.h"
|
||||||
#include "qmljscomponentfromobjectdef.h"
|
|
||||||
#include "qmljseditor.h"
|
|
||||||
#include "qmljsquickfixassist.h"
|
#include "qmljsquickfixassist.h"
|
||||||
|
|
||||||
#include <extensionsystem/iplugin.h>
|
#include <extensionsystem/iplugin.h>
|
||||||
@@ -23,30 +21,29 @@ namespace QmlJSEditor {
|
|||||||
|
|
||||||
using namespace Internal;
|
using namespace Internal;
|
||||||
|
|
||||||
QmlJSQuickFixOperation::QmlJSQuickFixOperation(const QmlJSQuickFixInterface &interface,
|
QmlJSQuickFixOperation::QmlJSQuickFixOperation(const QmlJSQuickFixAssistInterface *interface,
|
||||||
int priority)
|
int priority)
|
||||||
: QuickFixOperation(priority)
|
: QuickFixOperation(priority)
|
||||||
, m_interface(interface)
|
, m_semanticInfo(interface->semanticInfo())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlJSQuickFixOperation::perform()
|
void QmlJSQuickFixOperation::perform()
|
||||||
{
|
{
|
||||||
QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(),
|
QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), semanticInfo().snapshot);
|
||||||
m_interface->semanticInfo().snapshot);
|
|
||||||
QmlJSRefactoringFilePtr current = refactoring.file(fileName());
|
QmlJSRefactoringFilePtr current = refactoring.file(fileName());
|
||||||
|
|
||||||
performChanges(current, refactoring);
|
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
|
Utils::FilePath QmlJSQuickFixOperation::fileName() const
|
||||||
{
|
{
|
||||||
return m_interface->semanticInfo().document->fileName();
|
return semanticInfo().document->fileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlJSEditor
|
} // namespace QmlJSEditor
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
#include <qmljs/parser/qmljsastfwd_p.h>
|
#include <qmljs/parser/qmljsastfwd_p.h>
|
||||||
#include <qmljs/qmljsdocument.h>
|
#include <qmljs/qmljsdocument.h>
|
||||||
#include <qmljstools/qmljsrefactoringchanges.h>
|
#include <qmljstools/qmljsrefactoringchanges.h>
|
||||||
|
#include <qmljstools/qmljssemanticinfo.h>
|
||||||
|
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
|
|
||||||
@@ -14,7 +15,6 @@ namespace QmlJSEditor {
|
|||||||
|
|
||||||
namespace Internal { class QmlJSQuickFixAssistInterface; }
|
namespace Internal { class QmlJSQuickFixAssistInterface; }
|
||||||
|
|
||||||
using QmlJSQuickFixInterface = QSharedPointer<const Internal::QmlJSQuickFixAssistInterface>;
|
|
||||||
using TextEditor::QuickFixOperation;
|
using TextEditor::QuickFixOperation;
|
||||||
using TextEditor::QuickFixOperations;
|
using TextEditor::QuickFixOperations;
|
||||||
using TextEditor::QuickFixInterface;
|
using TextEditor::QuickFixInterface;
|
||||||
@@ -31,7 +31,8 @@ public:
|
|||||||
\param interface The interface on which the operation is performed.
|
\param interface The interface on which the operation is performed.
|
||||||
\param priority The priority for this operation.
|
\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;
|
void perform() override;
|
||||||
|
|
||||||
@@ -41,13 +42,13 @@ protected:
|
|||||||
virtual void performChanges(QmlJSTools::QmlJSRefactoringFilePtr currentFile,
|
virtual void performChanges(QmlJSTools::QmlJSRefactoringFilePtr currentFile,
|
||||||
const QmlJSTools::QmlJSRefactoringChanges &refactoring) = 0;
|
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.
|
/// \returns The name of the file for for which this operation is invoked.
|
||||||
Utils::FilePath fileName() const;
|
Utils::FilePath fileName() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QmlJSQuickFixInterface m_interface;
|
const QmlJSTools::SemanticInfo m_semanticInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
TextEditor::QuickFixOperations findQmlJSQuickFixes(const TextEditor::AssistInterface *interface);
|
TextEditor::QuickFixOperations findQmlJSQuickFixes(const TextEditor::AssistInterface *interface);
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "qmljscomponentfromobjectdef.h"
|
#include "qmljscomponentfromobjectdef.h"
|
||||||
#include "qmljseditor.h"
|
|
||||||
#include "qmljseditortr.h"
|
#include "qmljseditortr.h"
|
||||||
#include "qmljsquickfix.h"
|
#include "qmljsquickfix.h"
|
||||||
#include "qmljsquickfixassist.h"
|
#include "qmljsquickfixassist.h"
|
||||||
@@ -42,8 +41,8 @@ class SplitInitializerOperation: public QmlJSQuickFixOperation
|
|||||||
UiObjectInitializer *_objectInitializer;
|
UiObjectInitializer *_objectInitializer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SplitInitializerOperation(const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface,
|
SplitInitializerOperation(const Internal::QmlJSQuickFixAssistInterface *interface,
|
||||||
UiObjectInitializer *objectInitializer)
|
UiObjectInitializer *objectInitializer)
|
||||||
: QmlJSQuickFixOperation(interface, 0)
|
: QmlJSQuickFixOperation(interface, 0)
|
||||||
, _objectInitializer(objectInitializer)
|
, _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;
|
UiObjectInitializer *objectInitializer = nullptr;
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ class AnalysizeMessageSuppressionOperation: public QmlJSQuickFixOperation
|
|||||||
Q_DECLARE_TR_FUNCTIONS(AddAnalysisMessageSuppressionComment)
|
Q_DECLARE_TR_FUNCTIONS(AddAnalysisMessageSuppressionComment)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AnalysizeMessageSuppressionOperation(const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface,
|
AnalysizeMessageSuppressionOperation(const Internal::QmlJSQuickFixAssistInterface *interface,
|
||||||
const StaticAnalysis::Message &message)
|
const StaticAnalysis::Message &message)
|
||||||
: QmlJSQuickFixOperation(interface, 0)
|
: QmlJSQuickFixOperation(interface, 0)
|
||||||
, _message(message)
|
, _message(message)
|
||||||
@@ -128,7 +128,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void matchAddAnalysisMessageSuppressionCommentQuickFix(const QmlJSQuickFixInterface &interface, QuickFixOperations &result)
|
void matchAddAnalysisMessageSuppressionCommentQuickFix(
|
||||||
|
const Internal::QmlJSQuickFixAssistInterface *interface, QuickFixOperations &result)
|
||||||
{
|
{
|
||||||
const QList<StaticAnalysis::Message> &messages = interface->semanticInfo().staticAnalysisMessages;
|
const QList<StaticAnalysis::Message> &messages = interface->semanticInfo().staticAnalysisMessages;
|
||||||
|
|
||||||
@@ -144,8 +145,7 @@ void matchAddAnalysisMessageSuppressionCommentQuickFix(const QmlJSQuickFixInterf
|
|||||||
|
|
||||||
QuickFixOperations findQmlJSQuickFixes(const AssistInterface *interface)
|
QuickFixOperations findQmlJSQuickFixes(const AssistInterface *interface)
|
||||||
{
|
{
|
||||||
QSharedPointer<const AssistInterface> assistInterface(interface);
|
auto qmlJSInterface = static_cast<const QmlJSQuickFixAssistInterface *>(interface);
|
||||||
auto qmlJSInterface = assistInterface.staticCast<const QmlJSQuickFixAssistInterface>();
|
|
||||||
|
|
||||||
QuickFixOperations quickFixes;
|
QuickFixOperations quickFixes;
|
||||||
|
|
||||||
|
@@ -67,8 +67,7 @@ class Operation: public QmlJSQuickFixOperation
|
|||||||
T *m_objDef;
|
T *m_objDef;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Operation(const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface,
|
Operation(const QmlJSQuickFixAssistInterface *interface, T *objDef)
|
||||||
T *objDef)
|
|
||||||
: QmlJSQuickFixOperation(interface, 0)
|
: QmlJSQuickFixOperation(interface, 0)
|
||||||
, m_objDef(objDef)
|
, m_objDef(objDef)
|
||||||
{
|
{
|
||||||
@@ -82,7 +81,7 @@ public:
|
|||||||
QString tryName = base;
|
QString tryName = base;
|
||||||
int extraNumber = 1;
|
int extraNumber = 1;
|
||||||
const ObjectValue *found = nullptr;
|
const ObjectValue *found = nullptr;
|
||||||
const ScopeChain &scope = assistInterface()->semanticInfo().scopeChain();
|
const ScopeChain &scope = semanticInfo().scopeChain();
|
||||||
forever {
|
forever {
|
||||||
scope.lookup(tryName, &found);
|
scope.lookup(tryName, &found);
|
||||||
if (!found || extraNumber > 1000)
|
if (!found || extraNumber > 1000)
|
||||||
@@ -157,7 +156,7 @@ public:
|
|||||||
} // end of anonymous namespace
|
} // 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();
|
const int pos = interface->currentFile()->cursor().position();
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
namespace QmlJSEditor {
|
namespace QmlJSEditor {
|
||||||
|
|
||||||
void matchWrapInLoaderQuickFix(const QmlJSQuickFixInterface &interface, QuickFixOperations &result);
|
void matchWrapInLoaderQuickFix(const Internal::QmlJSQuickFixAssistInterface *interface,
|
||||||
|
QuickFixOperations &result);
|
||||||
|
|
||||||
} // namespace QmlJSEditor
|
} // namespace QmlJSEditor
|
||||||
|
Reference in New Issue
Block a user