Commit 716fe0f6 authored by Erik Verbruggen's avatar Erik Verbruggen

Added an error state to the rewriter for error recovery.

parent 1f6c25a7
......@@ -90,7 +90,8 @@ SOURCES += $$PWD/model/abstractview.cpp \
$$PWD/model/rewriteactioncompressor.cpp \
$$PWD/model/qmltextgenerator.cpp \
$$PWD/model/modelmerger.cpp \
$$PWD/instances/qmltransitionnodeinstance.cpp
$$PWD/instances/qmltransitionnodeinstance.cpp \
$$PWD/exceptions/rewritingexception.cpp
HEADERS += $$PWD/include/corelib_global.h \
$$PWD/include/abstractview.h \
$$PWD/include/nodeinstanceview.h \
......@@ -177,7 +178,8 @@ HEADERS += $$PWD/include/corelib_global.h \
$$PWD/include/modelmerger.h \
$$PWD/include/mathutils.h \
$$PWD/instances/qmltransitionnodeinstance.h \
$$PWD/include/customnotifications.h
$$PWD/include/customnotifications.h \
$$PWD/include/rewritingexception.h
DISTFILES += $$PWD/metafile/widget.metafile
RESOURCES += $$PWD/core.qrc
OTHER_FILES += $$PWD/metainfo/gui.metainfo
......@@ -140,6 +140,8 @@ public:
void setErrors(const QList<Error> &errors);
void addError(const Error &error);
void resetToLastCorrectQml();
QMap<ModelNode, QString> extractText(const QList<ModelNode> &nodes) const;
int nodeOffset(const ModelNode &node) const;
int nodeLength(const ModelNode &node) const;
......@@ -159,6 +161,7 @@ protected: // functions
void setModificationGroupActive(bool active);
void applyModificationGroupChanges();
void setupComponent(const ModelNode &node);
void applyChanges();
private: //variables
DifferenceHandling m_differenceHandling;
......@@ -170,6 +173,8 @@ private: //variables
QList<Error> m_errors;
int transactionLevel;
RewriterTransaction m_removeDefaultPropertyTransaction;
bool errorState;
QString lastCorrectQmlSource;
};
} //QmlDesigner
......
......@@ -33,6 +33,7 @@
#include <customnotifications.h>
#include "rewriterview.h"
#include "rewritingexception.h"
#include "textmodifier.h"
#include "texttomodelmerger.h"
#include "modelnodepositionstorage.h"
......@@ -77,7 +78,7 @@ QString RewriterView::Error::toString() const
if (m_type == ParseError)
str += tr("Error parsing");
else if (m_type == InternalError)
str += tr("Internal error while parsing");
str += tr("Internal error");
if (url().isValid()) {
if (!str.isEmpty())
......@@ -114,7 +115,8 @@ RewriterView::RewriterView(DifferenceHandling differenceHandling, QObject *paren
m_modelToTextMerger(new Internal::ModelToTextMerger(this)),
m_textToModelMerger(new Internal::TextToModelMerger(this)),
m_textModifier(0),
transactionLevel(0)
transactionLevel(0),
errorState(false)
{
}
......@@ -138,7 +140,10 @@ void RewriterView::modelAttached(Model *model)
AbstractView::modelAttached(model);
ModelAmender differenceHandler(m_textToModelMerger.data());
m_textToModelMerger->load(m_textModifier->text().toUtf8(), differenceHandler);
const QString qmlSource = m_textModifier->text();
if (m_textToModelMerger->load(qmlSource.toUtf8(), differenceHandler)) {
lastCorrectQmlSource = qmlSource;
}
}
void RewriterView::modelAboutToBeDetached(Model * /*model*/)
......@@ -158,7 +163,7 @@ void RewriterView::nodeCreated(const ModelNode &createdNode)
modelToTextMerger()->nodeCreated(createdNode);
if (!isModificationGroupActive())
modelToTextMerger()->applyChanges();
applyChanges();
}
void RewriterView::nodeAboutToBeRemoved(const ModelNode &/*removedNode*/)
......@@ -174,7 +179,7 @@ void RewriterView::nodeRemoved(const ModelNode &removedNode, const NodeAbstractP
modelToTextMerger()->nodeRemoved(removedNode, parentProperty, propertyChange);
if (!isModificationGroupActive())
modelToTextMerger()->applyChanges();
applyChanges();
}
void RewriterView::propertiesAdded(const ModelNode &/*node*/, const QList<AbstractProperty>& /*propertyList*/)
......@@ -212,7 +217,7 @@ void RewriterView::propertiesRemoved(const QList<AbstractProperty>& propertyList
m_removeDefaultPropertyTransaction.commit();
if (!isModificationGroupActive())
modelToTextMerger()->applyChanges();
applyChanges();
}
void RewriterView::variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChange)
......@@ -228,7 +233,7 @@ void RewriterView::variantPropertiesChanged(const QList<VariantProperty>& proper
modelToTextMerger()->propertiesChanged(usefulPropertyList, propertyChange);
if (!isModificationGroupActive())
modelToTextMerger()->applyChanges();
applyChanges();
}
void RewriterView::bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChange)
......@@ -244,7 +249,7 @@ void RewriterView::bindingPropertiesChanged(const QList<BindingProperty>& proper
modelToTextMerger()->propertiesChanged(usefulPropertyList, propertyChange);
if (!isModificationGroupActive())
modelToTextMerger()->applyChanges();
applyChanges();
}
void RewriterView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange)
......@@ -259,7 +264,7 @@ void RewriterView::nodeReparented(const ModelNode &node, const NodeAbstractPrope
modelToTextMerger()->nodeReparented(node, newPropertyParent, oldPropertyParent, propertyChange);
if (!isModificationGroupActive())
modelToTextMerger()->applyChanges();
applyChanges();
}
void RewriterView::fileUrlChanged(const QUrl &/*oldUrl*/, const QUrl &/*newUrl*/)
......@@ -275,7 +280,7 @@ void RewriterView::nodeIdChanged(const ModelNode& node, const QString& newId, co
modelToTextMerger()->nodeIdChanged(node, newId, oldId);
if (!isModificationGroupActive())
modelToTextMerger()->applyChanges();
applyChanges();
}
void RewriterView::nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode &movedNode, int /*oldIndex*/)
......@@ -293,7 +298,7 @@ void RewriterView::nodeOrderChanged(const NodeListProperty &listProperty, const
modelToTextMerger()->nodeSlidAround(movedNode, trailingNode);
if (!isModificationGroupActive())
modelToTextMerger()->applyChanges();
applyChanges();
}
void RewriterView::nodeTypeChanged(const ModelNode &node,const QString &type, int majorVersion, int minorVersion)
......@@ -305,7 +310,7 @@ void RewriterView::nodeTypeChanged(const ModelNode &node,const QString &type, in
modelToTextMerger()->nodeTypeChanged(node, type, majorVersion, minorVersion);
if (!isModificationGroupActive())
modelToTextMerger()->applyChanges();
applyChanges();
}
void RewriterView::customNotification(const AbstractView * /*view*/, const QString &identifier, const QList<ModelNode> & /* nodeList */, const QList<QVariant> & /*data */)
......@@ -359,7 +364,7 @@ void RewriterView::setTextModifier(TextModifier *textModifier)
void RewriterView::applyModificationGroupChanges()
{
Q_ASSERT(transactionLevel == 0);
modelToTextMerger()->applyChanges();
applyChanges();
}
void RewriterView::setupComponent(const ModelNode &node)
......@@ -386,6 +391,30 @@ void RewriterView::setupComponent(const ModelNode &node)
node.variantProperty("__component_data") = result;
}
void RewriterView::applyChanges()
{
if (errorState) {
qDebug() << "RewriterView::applyChanges() got called while in error state. Will do a quick-exit now.";
throw RewritingException(__LINE__, __FUNCTION__, __FILE__);
}
bool success = false;
try {
success = modelToTextMerger()->applyChanges();
if (!success) {
errorState = true;
throw RewritingException(__LINE__, __FUNCTION__, __FILE__);
}
} catch (Exception &e) {
Q_UNUSED(e);
errorState = true;
throw RewritingException(__LINE__, __FUNCTION__, __FILE__);
}
}
QList<RewriterView::Error> RewriterView::errors() const
{
return m_errors;
......@@ -409,6 +438,13 @@ void RewriterView::addError(const RewriterView::Error &error)
emit errorsChanged(m_errors);
}
void RewriterView::resetToLastCorrectQml()
{
ModelAmender differenceHandler(m_textToModelMerger.data());
m_textToModelMerger->load(lastCorrectQmlSource.toUtf8(), differenceHandler);
errorState = false;
}
QMap<ModelNode, QString> RewriterView::extractText(const QList<ModelNode> &nodes) const
{
QmlDesigner::ASTObjectTextExtractor extract(m_textModifier->text());
......@@ -461,7 +497,9 @@ void RewriterView::qmlTextChanged()
switch (m_differenceHandling) {
case Validate: {
ModelValidator differenceHandler(m_textToModelMerger.data());
m_textToModelMerger->load(newQmlText.toUtf8(), differenceHandler);
if (m_textToModelMerger->load(newQmlText.toUtf8(), differenceHandler)) {
lastCorrectQmlSource = newQmlText;
}
break;
}
......@@ -469,7 +507,9 @@ void RewriterView::qmlTextChanged()
default: {
emitCustomNotification(StartRewriterAmend);
ModelAmender differenceHandler(m_textToModelMerger.data());
m_textToModelMerger->load(newQmlText.toUtf8(), differenceHandler);
if (m_textToModelMerger->load(newQmlText.toUtf8(), differenceHandler)) {
lastCorrectQmlSource = newQmlText;
}
emitCustomNotification(EndRewriterAmend);
break;
}
......
......@@ -110,7 +110,10 @@ bool TextToModelMerger::load(const QByteArray &data, DifferenceHandler &differen
setActive(false);
return success;
} catch (Exception &e) {
m_rewriterView->addError(RewriterView::Error(&e));
RewriterView::Error error(&e);
// Somehow, the error below gets eaten in upper levels, so printing the exception info here for debugging purposes:
qDebug() << "*** An exception occurred while reading the QML file:" << error.toString();
m_rewriterView->addError(error);
setActive(false);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment