aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljslogger.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2025-01-20 14:02:11 +0100
committerUlf Hermann <ulf.hermann@qt.io>2025-01-21 16:56:47 +0100
commitd3492ff7c105a9d85434c125655e6668f0befd9a (patch)
treef9cf21198dee659ff55507fc23ba9fe7379898ff /src/qmlcompiler/qqmljslogger.cpp
parent87866c09b2d380fdea7af8352ad2b9c2395be3ed (diff)
QmlCompiler: Introduce transactions for the logger
Certain compile passes may be run multiple times and only the last run counts. We need to be able to roll back the logger to the state before the pass in that case. Amends commit d70abd83dc94d722cde6d4b19b9d35c5f4f19946 Pick-to: 6.9 Task-number: QTBUG-124913 Change-Id: Ie6174fc3d6ce60ca3f0a3fa27484a58e6febcc17 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmlcompiler/qqmljslogger.cpp')
-rw-r--r--src/qmlcompiler/qqmljslogger.cpp73
1 files changed, 68 insertions, 5 deletions
diff --git a/src/qmlcompiler/qqmljslogger.cpp b/src/qmlcompiler/qqmljslogger.cpp
index 1b6e2296b9..18bf1de15f 100644
--- a/src/qmlcompiler/qqmljslogger.cpp
+++ b/src/qmlcompiler/qqmljslogger.cpp
@@ -279,11 +279,11 @@ void QQmlJSLogger::log(const QString &message, QQmlJS::LoggerWarningId id,
diagMsg.type = type;
diagMsg.fixSuggestion = suggestion;
- switch (type) {
- case QtWarningMsg: m_warnings.push_back(diagMsg); break;
- case QtCriticalMsg: m_errors.push_back(diagMsg); break;
- case QtInfoMsg: m_infos.push_back(diagMsg); break;
- default: break;
+ if (m_inTransaction) {
+ m_pendingMessages.push_back(std::move(diagMsg));
+ } else {
+ countMessage(diagMsg);
+ m_committedMessages.push_back(std::move(diagMsg));
}
if (srcLocation.length > 0 && !m_code.isEmpty() && showContext)
@@ -291,6 +291,23 @@ void QQmlJSLogger::log(const QString &message, QQmlJS::LoggerWarningId id,
if (suggestion.has_value())
printFix(suggestion.value());
+
+ if (!m_inTransaction)
+ m_output.flushBuffer();
+}
+
+void QQmlJSLogger::countMessage(const Message &message)
+{
+ switch (message.type) {
+ case QtWarningMsg:
+ ++m_numWarnings;
+ break;
+ case QtCriticalMsg:
+ ++m_numErrors;
+ break;
+ default:
+ break;
+ }
}
void QQmlJSLogger::processMessages(const QList<QQmlJS::DiagnosticMessage> &messages,
@@ -310,6 +327,52 @@ void QQmlJSLogger::processMessages(const QList<QQmlJS::DiagnosticMessage> &messa
m_output.write(QStringLiteral("---\n\n"));
}
+/*!
+ \internal
+ Starts a transaction for a compile pass. This buffers all messages until the
+ transaction completes. If you commit the transaction, the messages are printed
+ and added to the list of committed messages. If you roll it back, the logger
+ reverts to the state before the start of the transaction.
+
+ This is useful for compile passes that potentially have to be repeated, such
+ as the type propagator. We don't want to see the same messages logged multiple
+ times.
+ */
+void QQmlJSLogger::startTransaction()
+{
+ Q_ASSERT(!m_inTransaction);
+ m_inTransaction = true;
+}
+
+/*!
+ \internal
+ Commit the current transaction. Print all pending messages, and add them to
+ the list of committed messages. Then, clear the transaction flag.
+ */
+void QQmlJSLogger::commit()
+{
+ Q_ASSERT(m_inTransaction);
+ for (const Message &message : std::as_const(m_pendingMessages))
+ countMessage(message);
+
+ m_committedMessages.append(std::exchange(m_pendingMessages, {}));
+ m_output.flushBuffer();
+ m_inTransaction = false;
+}
+
+/*!
+ \internal
+ Roll back the current transaction and revert the logger to the state before
+ it was started.
+ */
+void QQmlJSLogger::rollback()
+{
+ Q_ASSERT(m_inTransaction);
+ m_pendingMessages.clear();
+ m_output.discardBuffer();
+ m_inTransaction = false;
+}
+
void QQmlJSLogger::printContext(const QString &overrideFileName,
const QQmlJS::SourceLocation &location)
{