forked from qt-creator/qt-creator
QmlDesigner: fix crash at RewriterView::amendQmlText()
RewriterView does not own m_textModifier, so it needs to be checked.
Especially if it is called by a timer like in the amendQmlText() case.
With m_textToModelMerger, its a different story because its
an owned unique_ptr. So no need to check it.
Change-Id: If19b58cc94ec5e8ddd68a8c12acba0f880cbdc6b
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
(cherry picked from commit 6bcf4c9dc7
)
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -196,7 +196,7 @@ private: //variables
|
|||||||
void handleProjectUpdate();
|
void handleProjectUpdate();
|
||||||
bool inErrorState() const { return !m_rewritingErrorMessage.isEmpty(); }
|
bool inErrorState() const { return !m_rewritingErrorMessage.isEmpty(); }
|
||||||
|
|
||||||
TextModifier *m_textModifier = nullptr;
|
QPointer<TextModifier> m_textModifier;
|
||||||
int transactionLevel = 0;
|
int transactionLevel = 0;
|
||||||
bool m_modificationGroupActive = false;
|
bool m_modificationGroupActive = false;
|
||||||
bool m_checkSemanticErrors = true;
|
bool m_checkSemanticErrors = true;
|
||||||
|
@@ -88,6 +88,7 @@ Internal::TextToModelMerger *RewriterView::textToModelMerger() const
|
|||||||
|
|
||||||
void RewriterView::modelAttached(Model *model)
|
void RewriterView::modelAttached(Model *model)
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(m_textModifier, return);
|
||||||
m_modelAttachPending = false;
|
m_modelAttachPending = false;
|
||||||
|
|
||||||
AbstractView::modelAttached(model);
|
AbstractView::modelAttached(model);
|
||||||
@@ -431,7 +432,7 @@ void RewriterView::deactivateTextMofifierChangeSignals()
|
|||||||
|
|
||||||
void RewriterView::auxiliaryDataChanged(const ModelNode &, AuxiliaryDataKeyView key, const QVariant &)
|
void RewriterView::auxiliaryDataChanged(const ModelNode &, AuxiliaryDataKeyView key, const QVariant &)
|
||||||
{
|
{
|
||||||
if (m_restoringAuxData)
|
if (m_restoringAuxData || !m_textModifier)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (key.type == AuxiliaryDataType::Document)
|
if (key.type == AuxiliaryDataType::Document)
|
||||||
@@ -488,9 +489,9 @@ void RewriterView::amendQmlText()
|
|||||||
|
|
||||||
if (!model()->rewriterView())
|
if (!model()->rewriterView())
|
||||||
return;
|
return;
|
||||||
|
QTC_ASSERT(m_textModifier, return);
|
||||||
|
|
||||||
emitCustomNotification(StartRewriterAmend);
|
emitCustomNotification(StartRewriterAmend);
|
||||||
|
|
||||||
const QString newQmlText = m_textModifier->text();
|
const QString newQmlText = m_textModifier->text();
|
||||||
|
|
||||||
ModelAmender differenceHandler(m_textToModelMerger.data());
|
ModelAmender differenceHandler(m_textToModelMerger.data());
|
||||||
@@ -754,6 +755,7 @@ void RewriterView::enterErrorState(const QString &errorMessage)
|
|||||||
|
|
||||||
void RewriterView::resetToLastCorrectQml()
|
void RewriterView::resetToLastCorrectQml()
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(m_textModifier, return);
|
||||||
m_textModifier->textDocument()->undo();
|
m_textModifier->textDocument()->undo();
|
||||||
m_textModifier->textDocument()->clearUndoRedoStacks(QTextDocument::RedoStack);
|
m_textModifier->textDocument()->clearUndoRedoStacks(QTextDocument::RedoStack);
|
||||||
ModelAmender differenceHandler(m_textToModelMerger.data());
|
ModelAmender differenceHandler(m_textToModelMerger.data());
|
||||||
@@ -766,6 +768,7 @@ void RewriterView::resetToLastCorrectQml()
|
|||||||
|
|
||||||
QMap<ModelNode, QString> RewriterView::extractText(const QList<ModelNode> &nodes) const
|
QMap<ModelNode, QString> RewriterView::extractText(const QList<ModelNode> &nodes) const
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(m_textModifier, return {});
|
||||||
QmlDesigner::ASTObjectTextExtractor extract(m_textModifier->text());
|
QmlDesigner::ASTObjectTextExtractor extract(m_textModifier->text());
|
||||||
QMap<ModelNode, QString> result;
|
QMap<ModelNode, QString> result;
|
||||||
|
|
||||||
@@ -792,6 +795,7 @@ int RewriterView::nodeOffset(const ModelNode &node) const
|
|||||||
*/
|
*/
|
||||||
int RewriterView::nodeLength(const ModelNode &node) const
|
int RewriterView::nodeLength(const ModelNode &node) const
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(m_textModifier, return -1);
|
||||||
ObjectLengthCalculator objectLengthCalculator;
|
ObjectLengthCalculator objectLengthCalculator;
|
||||||
unsigned length;
|
unsigned length;
|
||||||
if (objectLengthCalculator(m_textModifier->text(), nodeOffset(node), length))
|
if (objectLengthCalculator(m_textModifier->text(), nodeOffset(node), length))
|
||||||
@@ -802,12 +806,14 @@ int RewriterView::nodeLength(const ModelNode &node) const
|
|||||||
|
|
||||||
int RewriterView::firstDefinitionInsideOffset(const ModelNode &node) const
|
int RewriterView::firstDefinitionInsideOffset(const ModelNode &node) const
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(m_textModifier, return -1);
|
||||||
FirstDefinitionFinder firstDefinitionFinder(m_textModifier->text());
|
FirstDefinitionFinder firstDefinitionFinder(m_textModifier->text());
|
||||||
return firstDefinitionFinder(nodeOffset(node));
|
return firstDefinitionFinder(nodeOffset(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
int RewriterView::firstDefinitionInsideLength(const ModelNode &node) const
|
int RewriterView::firstDefinitionInsideLength(const ModelNode &node) const
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(m_textModifier, return -1);
|
||||||
FirstDefinitionFinder firstDefinitionFinder(m_textModifier->text());
|
FirstDefinitionFinder firstDefinitionFinder(m_textModifier->text());
|
||||||
const int offset = firstDefinitionFinder(nodeOffset(node));
|
const int offset = firstDefinitionFinder(nodeOffset(node));
|
||||||
|
|
||||||
@@ -831,6 +837,7 @@ static bool isInNodeDefinition(int nodeTextOffset, int nodeTextLength, int curso
|
|||||||
|
|
||||||
ModelNode RewriterView::nodeAtTextCursorPositionHelper(const ModelNode &root, int cursorPosition) const
|
ModelNode RewriterView::nodeAtTextCursorPositionHelper(const ModelNode &root, int cursorPosition) const
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(m_textModifier, return {});
|
||||||
using myPair = std::pair<ModelNode,int>;
|
using myPair = std::pair<ModelNode,int>;
|
||||||
std::vector<myPair> data;
|
std::vector<myPair> data;
|
||||||
|
|
||||||
@@ -1080,36 +1087,35 @@ void RewriterView::qmlTextChanged()
|
|||||||
{
|
{
|
||||||
if (inErrorState())
|
if (inErrorState())
|
||||||
return;
|
return;
|
||||||
|
QTC_ASSERT(m_textModifier, return);
|
||||||
|
|
||||||
if (m_textToModelMerger && m_textModifier) {
|
const QString newQmlText = m_textModifier->text();
|
||||||
const QString newQmlText = m_textModifier->text();
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
qDebug() << "old:" << lastCorrectQmlSource;
|
qDebug() << "old:" << lastCorrectQmlSource;
|
||||||
qDebug() << "new:" << newQmlText;
|
qDebug() << "new:" << newQmlText;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (m_differenceHandling) {
|
switch (m_differenceHandling) {
|
||||||
case Validate: {
|
case Validate: {
|
||||||
ModelValidator differenceHandler(m_textToModelMerger.data());
|
ModelValidator differenceHandler(m_textToModelMerger.data());
|
||||||
if (m_textToModelMerger->load(newQmlText, differenceHandler))
|
if (m_textToModelMerger->load(newQmlText, differenceHandler))
|
||||||
m_lastCorrectQmlSource = newQmlText;
|
m_lastCorrectQmlSource = newQmlText;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Amend: {
|
case Amend: {
|
||||||
if (m_instantQmlTextUpdate || externalDependencies().instantQmlTextUpdate()) {
|
if (m_instantQmlTextUpdate || externalDependencies().instantQmlTextUpdate()) {
|
||||||
amendQmlText();
|
amendQmlText();
|
||||||
} else {
|
} else {
|
||||||
if (externalDependencies().viewManagerUsesRewriterView(this)) {
|
if (externalDependencies().viewManagerUsesRewriterView(this)) {
|
||||||
externalDependencies().viewManagerDiableWidgets();
|
externalDependencies().viewManagerDiableWidgets();
|
||||||
m_amendTimer.start();
|
m_amendTimer.start();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user