QmlDesigner.Rewriter: Cleaning up the warning code

The class is renamed to RewriterError and moved outside of RewriterView.
Reason: Inner classes cannot be forward declared in C++.

Changing RewriterView::Error to RewriterError, because inner
classes cannot be forward declared.

Change-Id: I51e3b08efeda44a8cd2abe84e833a5f8c190b84e
Reviewed-by: Tim Jenssen <tim.jenssen@theqtcompany.com>
This commit is contained in:
Thomas Hartmann
2015-07-09 13:41:25 +02:00
committed by Thomas Hartmann
parent 9b4512f906
commit 8cdfc4e097
9 changed files with 177 additions and 149 deletions

View File

@@ -171,7 +171,7 @@ Model* DesignDocument::createInFileComponentModel()
/*!
Returns any errors that happened when parsing the latest qml file.
*/
QList<RewriterView::Error> DesignDocument::qmlSyntaxErrors() const
QList<RewriterError> DesignDocument::qmlSyntaxErrors() const
{
return m_rewriterView->errors();
}

View File

@@ -86,7 +86,7 @@ public:
Model *documentModel() const;
QString contextHelpId() const;
QList<RewriterView::Error> qmlSyntaxErrors() const;
QList<RewriterError> qmlSyntaxErrors() const;
bool hasQmlSyntaxErrors() const;
RewriterView *rewriterView() const;
@@ -111,7 +111,7 @@ signals:
void undoAvailable(bool isAvailable);
void redoAvailable(bool isAvailable);
void designDocumentClosed();
void qmlErrorsChanged(const QList<RewriterView::Error> &errors);
void qmlErrorsChanged(const QList<RewriterError> &errors);
public slots:
void deleteSelected();

View File

@@ -62,29 +62,19 @@ class ModelNodePositionStorage;
} //Internal
class QMLDESIGNERCORE_EXPORT RewriterView : public AbstractView
{
Q_OBJECT
class RewriterError {
public:
enum DifferenceHandling {
Validate,
Amend
};
class Error {
public:
enum Type {
NoError = 0,
InternalError = 1,
ParseError = 2
};
public:
Error();
Error(const QmlJS::DiagnosticMessage &qmlError, const QUrl &document);
Error(const QString &shortDescription);
Error(const Exception *exception);
public:
RewriterError();
RewriterError(const QmlJS::DiagnosticMessage &qmlError, const QUrl &document);
RewriterError(const QString &shortDescription);
RewriterError(Exception *exception);
Type type() const
{ return m_type; }
@@ -103,12 +93,22 @@ public:
QString toString() const;
private:
private:
Type m_type;
int m_line;
int m_column;
QString m_description;
QUrl m_url;
};
class QMLDESIGNERCORE_EXPORT RewriterView : public AbstractView
{
Q_OBJECT
public:
enum DifferenceHandling {
Validate,
Amend
};
public:
@@ -171,10 +171,10 @@ public:
Internal::ModelNodePositionStorage *positionStorage() const
{ return m_positionStorage; }
QList<Error> errors() const;
QList<RewriterError> errors() const;
void clearErrors();
void setErrors(const QList<Error> &errors);
void addError(const Error &error);
void setErrors(const QList<RewriterError> &errors);
void addError(const RewriterError &error);
void enterErrorState(const QString &errorMessage);
bool inErrorState() const { return !m_rewritingErrorMessage.isEmpty(); }
@@ -209,7 +209,7 @@ public:
QSet<QPair<QString, QString> > qrcMapping() const;
signals:
void errorsChanged(const QList<RewriterView::Error> &errors);
void errorsChanged(const QList<RewriterError> &errors);
public slots:
void qmlTextChanged();
@@ -233,7 +233,7 @@ private: //variables
QScopedPointer<Internal::ModelToTextMerger> m_modelToTextMerger;
QScopedPointer<Internal::TextToModelMerger> m_textToModelMerger;
TextModifier *m_textModifier;
QList<Error> m_errors;
QList<RewriterError> m_errors;
int transactionLevel;
RewriterTransaction m_removeDefaultPropertyTransaction;
QString m_rewritingErrorMessage;

View File

@@ -50,14 +50,14 @@ using namespace QmlDesigner::Internal;
namespace QmlDesigner {
RewriterView::Error::Error():
RewriterError::RewriterError():
m_type(NoError),
m_line(-1),
m_column(-1)
{
}
RewriterView::Error::Error(const Exception *exception):
RewriterError::RewriterError(Exception *exception):
m_type(InternalError),
m_line(exception->line()),
m_column(-1),
@@ -66,7 +66,7 @@ RewriterView::Error::Error(const Exception *exception):
{
}
RewriterView::Error::Error(const QmlJS::DiagnosticMessage &qmlError, const QUrl &document):
RewriterError::RewriterError(const QmlJS::DiagnosticMessage &qmlError, const QUrl &document):
m_type(ParseError),
m_line(qmlError.loc.startLine),
m_column(qmlError.loc.startColumn),
@@ -75,7 +75,7 @@ RewriterView::Error::Error(const QmlJS::DiagnosticMessage &qmlError, const QUrl
{
}
RewriterView::Error::Error(const QString &shortDescription) :
RewriterError::RewriterError(const QString &shortDescription) :
m_type(ParseError),
m_line(1),
m_column(0),
@@ -85,33 +85,33 @@ RewriterView::Error::Error(const QString &shortDescription) :
}
QString RewriterView::Error::toString() const
QString RewriterError::toString() const
{
QString str;
if (m_type == ParseError)
str += tr("Error parsing");
str += RewriterView::tr("Error parsing");
else if (m_type == InternalError)
str += tr("Internal error");
str += RewriterView::tr("Internal error");
if (url().isValid()) {
if (!str.isEmpty())
str += QLatin1Char(' ');
str += tr("\"%1\"").arg(url().toString());
str += RewriterView::tr("\"%1\"").arg(url().toString());
}
if (line() != -1) {
if (!str.isEmpty())
str += QLatin1Char(' ');
str += tr("line %1").arg(line());
str += RewriterView::tr("line %1").arg(line());
}
if (column() != -1) {
if (!str.isEmpty())
str += QLatin1Char(' ');
str += tr("column %1").arg(column());
str += RewriterView::tr("column %1").arg(column());
}
if (!str.isEmpty())
@@ -541,7 +541,7 @@ void RewriterView::applyChanges()
}
}
QList<RewriterView::Error> RewriterView::errors() const
QList<RewriterError> RewriterView::errors() const
{
return m_errors;
}
@@ -552,13 +552,13 @@ void RewriterView::clearErrors()
emit errorsChanged(m_errors);
}
void RewriterView::setErrors(const QList<RewriterView::Error> &errors)
void RewriterView::setErrors(const QList<RewriterError> &errors)
{
m_errors = errors;
emit errorsChanged(m_errors);
}
void RewriterView::addError(const RewriterView::Error &error)
void RewriterView::addError(const RewriterError &error)
{
m_errors.append(error);
emit errorsChanged(m_errors);

View File

@@ -885,9 +885,9 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
doc->parseQml();
if (!doc->isParsedCorrectly()) {
QList<RewriterView::Error> errors;
foreach (const DiagnosticMessage &message, doc->diagnosticMessages())
errors.append(RewriterView::Error(message, QUrl::fromLocalFile(doc->fileName())));
QList<RewriterError> errors;
foreach (const QmlJS::DiagnosticMessage &message, doc->diagnosticMessages())
errors.append(RewriterError(message, QUrl::fromLocalFile(doc->fileName())));
m_rewriterView->setErrors(errors);
setActive(false);
return false;
@@ -899,66 +899,19 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
new ScopeChain(ctxt.scopeChain()));
m_document = doc;
QList<RewriterView::Error> errors;
QList<RewriterView::Error> warnings;
QList<RewriterError> errors;
QList<RewriterError> warnings;
foreach (const DiagnosticMessage &diagnosticMessage, ctxt.diagnosticLinkMessages()) {
errors.append(RewriterView::Error(diagnosticMessage, QUrl::fromLocalFile(doc->fileName())));
}
collectLinkErrors(&errors, ctxt);
setupImports(doc, differenceHandler);
setupPossibleImports(snapshot, m_vContext);
if (m_rewriterView->model()->imports().isEmpty()) {
const DiagnosticMessage diagnosticMessage(Severity::Error, AST::SourceLocation(0, 0, 0, 0), QCoreApplication::translate("QmlDesigner::TextToModelMerger", "No import statements found"));
errors.append(RewriterView::Error(diagnosticMessage, QUrl::fromLocalFile(doc->fileName())));
}
foreach (const QmlDesigner::Import &import, m_rewriterView->model()->imports()) {
if (import.isLibraryImport() && import.url() == QStringLiteral("QtQuick") && !supportedQtQuickVersion(import.version())) {
const DiagnosticMessage diagnosticMessage(Severity::Error, AST::SourceLocation(0, 0, 0, 0),
QCoreApplication::translate("QmlDesigner::TextToModelMerger", "Unsupported QtQuick version"));
errors.append(RewriterView::Error(diagnosticMessage, QUrl::fromLocalFile(doc->fileName())));
}
}
collectImportErrors(&errors);
if (view()->checkSemanticErrors()) {
Check check(doc, m_scopeChain->context());
check.disableMessage(StaticAnalysis::ErrPrototypeCycle);
check.disableMessage(StaticAnalysis::ErrCouldNotResolvePrototype);
check.disableMessage(StaticAnalysis::ErrCouldNotResolvePrototypeOf);
foreach (StaticAnalysis::Type type, StaticAnalysis::Message::allMessageTypes()) {
StaticAnalysis::PrototypeMessageData prototypeMessageData = StaticAnalysis::Message::prototypeForMessageType(type);
if (prototypeMessageData.severity == Severity::MaybeWarning
|| prototypeMessageData.severity == Severity::Warning) {
check.disableMessage(type);
}
}
check.enableMessage(StaticAnalysis::WarnImperativeCodeNotEditableInVisualDesigner);
check.enableMessage(StaticAnalysis::WarnUnsupportedTypeInVisualDesigner);
check.enableMessage(StaticAnalysis::WarnReferenceToParentItemNotSupportedByVisualDesigner);
check.enableMessage(StaticAnalysis::WarnReferenceToParentItemNotSupportedByVisualDesigner);
check.enableMessage(StaticAnalysis::WarnAboutQtQuick1InsteadQtQuick2);
check.enableMessage(StaticAnalysis::ErrUnsupportedRootTypeInVisualDesigner);
//## triggers too often ## check.enableMessage(StaticAnalysis::WarnUndefinedValueForVisualDesigner);
foreach (const StaticAnalysis::Message &message, check()) {
if (message.severity == Severity::Error) {
if (message.type == StaticAnalysis::ErrUnknownComponent)
warnings.append(RewriterView::Error(message.toDiagnosticMessage(), QUrl::fromLocalFile(doc->fileName())));
else
errors.append(RewriterView::Error(message.toDiagnosticMessage(), QUrl::fromLocalFile(doc->fileName())));
}
if (message.severity == Severity::Warning) {
if (message.type == StaticAnalysis::WarnAboutQtQuick1InsteadQtQuick2) {
errors.append(RewriterView::Error(message.toDiagnosticMessage(), QUrl::fromLocalFile(doc->fileName())));
} else {
warnings.append(RewriterView::Error(message.toDiagnosticMessage(), QUrl::fromLocalFile(doc->fileName())));
}
}
}
collectSemanticErrorsAndWarnings(&errors, &warnings);
if (!errors.isEmpty()) {
m_rewriterView->setErrors(errors);
@@ -966,24 +919,19 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
return false;
}
if (!warnings.isEmpty() && differenceHandler.isValidator() && !m_rewriterView->inErrorState()) {
QStringList message;
foreach (const RewriterView::Error &warning, warnings) {
QString string = QStringLiteral("Line: ") + QString::number(warning.line()) + QStringLiteral(": ") + warning.description();
//string += QStringLiteral(" <a href=\"") + QString::number(warning.line()) + QStringLiteral("\">Go to error</a>") + QStringLiteral("<p>");
message << string;
}
QmlWarningDialog warningDialog(0, message);
if (warningDialog.warningsEnabled() && warningDialog.exec()) {
/*
* If there are warnings and we are validating the document, then show a warning dialog.
* If the warning dialog is not ignored we set the warnings as errors and do not load the document
*/
if (!warnings.isEmpty()
&& differenceHandler.isValidator()
&& !m_rewriterView->inErrorState()
&& !showWarningsDialogIgnored(warnings)) {
m_rewriterView->setErrors(warnings);
setActive(false);
return false;
}
}
}
setupUsedImports();
AST::UiObjectMember *astRootNode = 0;
@@ -997,8 +945,8 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
setActive(false);
return true;
} catch (const Exception &e) {
RewriterView::Error error(&e);
} catch (Exception &e) {
RewriterError 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:"
@@ -1932,6 +1880,80 @@ void TextToModelMerger::setupComponent(const ModelNode &node)
ModelNode(node).setNodeSource(result);
}
void TextToModelMerger::collectLinkErrors(QList<RewriterError> *errors, const ReadingContext &ctxt)
{
foreach (const QmlJS::DiagnosticMessage &diagnosticMessage, ctxt.diagnosticLinkMessages()) {
errors->append(RewriterError(diagnosticMessage, QUrl::fromLocalFile(m_document->fileName())));
}
}
void TextToModelMerger::collectImportErrors(QList<RewriterError> *errors)
{
if (m_rewriterView->model()->imports().isEmpty()) {
const QmlJS::DiagnosticMessage diagnosticMessage(QmlJS::Severity::Error, AST::SourceLocation(0, 0, 0, 0), QCoreApplication::translate("QmlDesigner::TextToModelMerger", "No import statements found"));
errors->append(RewriterError(diagnosticMessage, QUrl::fromLocalFile(m_document->fileName())));
}
foreach (const QmlDesigner::Import &import, m_rewriterView->model()->imports()) {
if (import.isLibraryImport() && import.url() == QStringLiteral("QtQuick") && !supportedQtQuickVersion(import.version())) {
const QmlJS::DiagnosticMessage diagnosticMessage(QmlJS::Severity::Error, AST::SourceLocation(0, 0, 0, 0),
QCoreApplication::translate("QmlDesigner::TextToModelMerger", "Unsupported QtQuick version"));
errors->append(RewriterError(diagnosticMessage, QUrl::fromLocalFile(m_document->fileName())));
}
}
}
void TextToModelMerger::collectSemanticErrorsAndWarnings(QList<RewriterError> *errors, QList<RewriterError> *warnings)
{
Check check(m_document, m_scopeChain->context());
check.disableMessage(StaticAnalysis::ErrPrototypeCycle);
check.disableMessage(StaticAnalysis::ErrCouldNotResolvePrototype);
check.disableMessage(StaticAnalysis::ErrCouldNotResolvePrototypeOf);
foreach (StaticAnalysis::Type type, StaticAnalysis::Message::allMessageTypes()) {
StaticAnalysis::PrototypeMessageData prototypeMessageData = StaticAnalysis::Message::prototypeForMessageType(type);
if (prototypeMessageData.severity == Severity::MaybeWarning
|| prototypeMessageData.severity == Severity::Warning) {
check.disableMessage(type);
}
}
check.enableQmlDesignerChecks();
foreach (const StaticAnalysis::Message &message, check()) {
if (message.severity == Severity::Error) {
if (message.type == StaticAnalysis::ErrUnknownComponent)
warnings->append(RewriterError(message.toDiagnosticMessage(), QUrl::fromLocalFile(m_document->fileName())));
else
errors->append(RewriterError(message.toDiagnosticMessage(), QUrl::fromLocalFile(m_document->fileName())));
}
if (message.severity == Severity::Warning) {
if (message.type == StaticAnalysis::WarnAboutQtQuick1InsteadQtQuick2) {
errors->append(RewriterError(message.toDiagnosticMessage(), QUrl::fromLocalFile(m_document->fileName())));
} else {
warnings->append(RewriterError(message.toDiagnosticMessage(), QUrl::fromLocalFile(m_document->fileName())));
}
}
}
}
bool TextToModelMerger::showWarningsDialogIgnored(const QList<RewriterError> &warnings)
{
QStringList message;
foreach (const RewriterError &warning, warnings) {
QString string = QStringLiteral("Line: ") + QString::number(warning.line()) + QStringLiteral(": ") + warning.description();
message << string;
}
QmlWarningDialog warningDialog(0, message);
if (warningDialog.warningsEnabled() && warningDialog.exec()) {
return false;
}
return true;
}
void TextToModelMerger::populateQrcMapping(const QString &filePath)
{
QString path = removeFileFromQrcPath(filePath);

View File

@@ -44,6 +44,7 @@
namespace QmlDesigner {
class RewriterView;
class RewriterError;
namespace Internal {
@@ -137,6 +138,11 @@ public:
private:
void setupCustomParserNode(const ModelNode &node);
void setupComponent(const ModelNode &node);
void collectLinkErrors(QList<RewriterError> *errors, const ReadingContext &ctxt);
void collectImportErrors(QList<RewriterError> *errors);
void collectSemanticErrorsAndWarnings(QList<RewriterError> *errors,
QList<RewriterError> *warnings);
bool showWarningsDialogIgnored(const QList<RewriterError> &warnings);
void populateQrcMapping(const QString &filePath);

View File

@@ -98,14 +98,14 @@ DocumentWarningWidget::DocumentWarningWidget(DesignModeWidget *parent) :
layout->addWidget(m_goToError, 1, Qt::AlignRight);
}
void DocumentWarningWidget::setError(const RewriterView::Error &error)
void DocumentWarningWidget::setError(const RewriterError &error)
{
m_error = error;
QString str;
if (error.type() == RewriterView::Error::ParseError) {
if (error.type() == RewriterError::ParseError) {
str = tr("%3 (%1:%2)").arg(QString::number(error.line()), QString::number(error.column()), error.description());
m_goToError->show();
} else if (error.type() == RewriterView::Error::InternalError) {
} else if (error.type() == RewriterError::InternalError) {
str = tr("Internal error (%1)").arg(error.description());
m_goToError->hide();
}
@@ -278,7 +278,7 @@ void DesignModeWidget::disableWidgets()
m_isDisabled = true;
}
void DesignModeWidget::updateErrorStatus(const QList<RewriterView::Error> &errors)
void DesignModeWidget::updateErrorStatus(const QList<RewriterError> &errors)
{
if (debug)
qDebug() << Q_FUNC_INFO << errors.count();
@@ -459,8 +459,8 @@ void DesignModeWidget::deleteSidebarWidgets()
void DesignModeWidget::qmlPuppetCrashed()
{
QList<RewriterView::Error> errorList;
RewriterView::Error error(tr("Qt Quick emulation layer crashed"));
QList<RewriterError> errorList;
RewriterError error(tr("Qt Quick emulation layer crashed"));
errorList.append(error);
disableWidgets();
@@ -616,7 +616,7 @@ QWidget *DesignModeWidget::createCrumbleBarFrame()
return frame;
}
void DesignModeWidget::showErrorMessage(const QList<RewriterView::Error> &errors)
void DesignModeWidget::showErrorMessage(const QList<RewriterError> &errors)
{
Q_ASSERT(!errors.isEmpty());
m_warningWidget->setError(errors.first());

View File

@@ -73,7 +73,7 @@ class DocumentWarningWidget : public Utils::FakeToolTip
public:
explicit DocumentWarningWidget(DesignModeWidget *parent = 0);
void setError(const RewriterView::Error &error);
void setError(const RewriterError &error);
private slots:
void goToError();
@@ -81,7 +81,7 @@ private slots:
private:
QLabel *m_errorMessage;
QLabel *m_goToError;
RewriterView::Error m_error;
RewriterError m_error;
DesignModeWidget *m_designModeWidget;
};
@@ -109,12 +109,12 @@ public:
void enableWidgets();
void disableWidgets();
void showErrorMessage(const QList<RewriterView::Error> &errors);
void showErrorMessage(const QList<RewriterError> &errors);
CrumbleBar* crumbleBar() const;
public slots:
void updateErrorStatus(const QList<RewriterView::Error> &errors);
void updateErrorStatus(const QList<RewriterError> &errors);
void restoreDefaultView();
void toggleSidebars();
void toggleLeftSidebar();

View File

@@ -316,7 +316,7 @@ void QmlDesignerPlugin::activateAutoSynchronization()
viewManager().attachComponentView();
viewManager().attachViewsExceptRewriterAndComponetView();
QList<RewriterView::Error> errors = currentDesignDocument()->qmlSyntaxErrors();
QList<RewriterError> errors = currentDesignDocument()->qmlSyntaxErrors();
if (errors.isEmpty()) {
selectModelNodeUnderTextCursor();
data->mainWidget->enableWidgets();
@@ -329,9 +329,9 @@ void QmlDesignerPlugin::activateAutoSynchronization()
currentDesignDocument()->updateSubcomponentManager();
connect(rewriterView(),
SIGNAL(errorsChanged(QList<RewriterView::Error>)),
SIGNAL(errorsChanged(QList<RewriterError>)),
data->mainWidget,
SLOT(updateErrorStatus(QList<RewriterView::Error>)));
SLOT(updateErrorStatus(QList<RewriterError>)));
}
void QmlDesignerPlugin::deactivateAutoSynchronization()
@@ -342,9 +342,9 @@ void QmlDesignerPlugin::deactivateAutoSynchronization()
documentManager().currentDesignDocument()->resetToDocumentModel();
disconnect(rewriterView(),
SIGNAL(errorsChanged(QList<RewriterView::Error>)),
SIGNAL(errorsChanged(QList<RewriterError>)),
data->mainWidget,
SLOT(updateErrorStatus(QList<RewriterView::Error>)));
SLOT(updateErrorStatus(QList<RewriterError>)));
}