9#include <QtCore/QCborMap>
10#include <QtCore/QMutex>
11#include <QtCore/QMutexLocker>
15Q_LOGGING_CATEGORY(domLog,
"qt.qmldom", QtWarningMsg);
25
26
27
28
29
30
31
34
35
36
37
38
39
40
41
52 sink(QString(groupId()));
58 return QLatin1String(m_groupId);
67
68
69
70
71
72
73
77 for (
int i = 0; i < groups.size(); ++i)
78 groups.at(i).dump(sink);
83 for (
int i = 0; i < groups.size(); ++i)
84 groups.at(i).dumpId(sink);
90 for (
int i = 0; i < groups.size(); ++i)
91 res.append(QCborValue(groups.at(i).groupId()));
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
145 SourceLocation location)
const
147 if (level == ErrorLevel::Fatal)
148 fatal(msg, element, canonicalFilePath, location);
149 return ErrorMessage(dumperToString(msg), *
this, level, element, canonicalFilePath, location);
154 ErrorMessage res(*
this, msg, element, canonicalFilePath);
155 if (res.location == SourceLocation()
156 && (res.location.startLine != 0 || res.location.startColumn != 0)) {
157 res.location.offset = -1;
158 res.location.length = 1;
164 const Dumper &msg,
const Path &element, QStringView canonicalFilePath,
165 SourceLocation location)
const
167 enum { FatalMsgMaxLen = 1023 };
168 char buf[FatalMsgMaxLen+1];
170 auto sink = [&ibuf, &buf](QStringView s) {
172 while (ibuf < FatalMsgMaxLen && is < s.size()) {
174 if (c == QChar::fromLatin1(
'\n') || c == QChar::fromLatin1(
'\r') || (c >= QChar::fromLatin1(
' ') && c <= QChar::fromLatin1(
'~')))
175 buf[ibuf++] = c.toLatin1();
181 if (!canonicalFilePath.isEmpty()) {
182 sink(canonicalFilePath);
185 if (location.length) {
186 sinkInt(sink, location.startLine);
188 sinkInt(sink, location.startColumn);
208 return ErrorMessage(dumperToString(message), *
this, ErrorLevel::Debug);
218 return ErrorMessage(dumperToString(message), *
this, ErrorLevel::Info);
228 return ErrorMessage(dumperToString(message), *
this, ErrorLevel::Warning);
238 return ErrorMessage(dumperToString(message), *
this, ErrorLevel::Error);
243 auto &g1 = o1.groups;
244 auto &g2 = o2.groups;
245 if (g1.size() < g2.size())
247 if (g1.size() < g2.size())
249 for (
int i = 0; i < g1.size(); ++i) {
250 int c = std::strcmp(g1.at(i).groupId().data(), g2.at(i).groupId().data());
258 const QString &msg,
const ErrorGroups &errorGroups, Level level,
const Path &element,
259 const QString &canonicalFilePath, SourceLocation location, QLatin1String errorId)
268 if (level == Level::Fatal)
269 errorGroups.fatal(msg, element, canonicalFilePath, location);
273 const ErrorGroups &errorGroups,
const DiagnosticMessage &msg,
const Path &element,
274 const QString &canonicalFilePath, QLatin1String errorId)
283 if (level == Level::Fatal)
284 errorGroups.fatal(msg.message, element, canonicalFilePath, location);
290 static QBasicMutex rMutex{};
319 static QHash<QLatin1String, StorableMsg> r;
325 return msg(QLatin1String(errorId), std::move(err));
330 using namespace Qt::StringLiterals;
331 bool doubleRegister =
false;
335 auto &r = registry();
336 if (r.contains(err.errorId)) {
337 old = r[err.errorId].msg;
338 doubleRegister =
true;
343 defaultErrorHandler(
myErrors().warning(tr(
"Double registration of error %1: (%2) vs (%3)").arg(errorId, err.withErrorId(errorId).toString(), old.toString())
));
347void ErrorMessage::visitRegisteredMessages(function_ref<
bool(
const ErrorMessage &)> visitor)
349 QHash<QLatin1String, StorableMsg> r;
354 auto it = r.cbegin();
365 s(u"Unregistered error ");
366 s(QString(errorId)); });
369 res = registry().value(errorId,res).msg;
376 return load(QLatin1String(errorId)
);
381 this->errorId = errorId;
411 if (path.length() == 0)
412 path = el.canonicalPath();
414 file = el.canonicalFilePath();
415 if (location == SourceLocation()) {
416 if (
const FileLocations::Tree tree = FileLocations::treeOf(el)) {
417 location = FileLocations::region(tree, MainRegion);
434 if (!file.isEmpty()) {
438 if (location.length) {
439 sinkInt(sink, location.startLine);
441 sinkInt(sink, location.startColumn);
444 errorGroups.dump(sink);
446 dumpErrorLevel(sink, level);
447 if (! errorId.isEmpty()) {
449 sink(QString(errorId));
453 if (path.length()>0) {
455 if (!file.isEmpty() && path.length() > 3 && path.headKind() == Path::Kind::Root)
456 path.mid(3).dump(sink);
464 return dumperToString([
this](
const Sink &sink){
this->dump(sink); });
470 {QStringLiteral(u"errorId"),errorId},
471 {QStringLiteral(u"message"), message},
472 {QStringLiteral(u"errorGroups"), errorGroups.toCbor()},
473 {QStringLiteral(u"level"),
int(level)},
474 {QStringLiteral(u"path"), path.toString()},
475 {QStringLiteral(u"file"), file},
476 {QStringLiteral(u"location"), QCborMap({
477 {QStringLiteral(u"offset"),location.offset},
478 {QStringLiteral(u"length"),location.length},
479 {QStringLiteral(u"startLine"),location.startLine},
480 {QStringLiteral(u"startColumn"),location.startColumn}})}
485
486
487
488
491 dumperToQDebug([&error](
const Sink &s){ error.dump(s); }, error.level);
495
496
497
513
514
515
522
523
524
553#include "moc_qqmldomerrormessage_p.cpp"
A value type that references any element of the Dom.
Helper class to accept eithe a string or a dumper (a function that writes to a sink)
convenience macro creating a new ErrorGroup and registering its groupId as translatable string
QLatin1String groupId() const
void dumpId(const Sink &sink) const
QString groupName() const
Represents a set of tags grouping a set of related error messages.
ErrorMessage debug(const Dumper &message) const
ErrorMessage error(const QString &message) const
ErrorMessage errorMessage(const DiagnosticMessage &msg, const Path &element=Path(), const QString &canonicalFilePath=QString()) const
ErrorMessage warning(const Dumper &message) const
static int cmp(const ErrorGroups &g1, const ErrorGroups &g2)
ErrorMessage debug(const QString &message) const
void dumpId(const Sink &sink) const
ErrorMessage info(const QString &message) const
ErrorMessage warning(const QString &message) const
ErrorMessage errorMessage(const Dumper &msg, ErrorLevel level, const Path &element=Path(), const QString &canonicalFilePath=QString(), SourceLocation location=SourceLocation()) const
ErrorMessage info(const Dumper &message) const
void fatal(const Dumper &msg, const Path &element=Path(), QStringView canonicalFilePath=u"", SourceLocation location=SourceLocation()) const
ErrorMessage error(const Dumper &message) const
QCborArray toCbor() const
Represents an error message connected to the dom.
ErrorMessage & withPath(const Path &)
ErrorMessage & withErrorId(QLatin1String errorId)
ErrorMessage(const ErrorGroups &errorGroups, const DiagnosticMessage &msg, const Path &path=Path(), const QString &file=QString(), QLatin1String errorId=QLatin1String(""))
ErrorMessage & withLocation(SourceLocation)
ErrorMessage handle(const ErrorHandler &errorHandler=nullptr)
ErrorMessage & withFile(const QString &)
ErrorMessage & withItem(const DomItem &)
static ErrorMessage load(const char *errorId)
ErrorMessage(const QString &message, const ErrorGroups &errorGroups, Level level=Level::Warning, const Path &path=Path(), const QString &file=QString(), SourceLocation location=SourceLocation(), QLatin1String errorId=QLatin1String(""))
void dump(const Sink &s) const
ErrorMessage & withFile(QStringView)
QMLDOM_EXPORT void errorToQDebug(const ErrorMessage &)
writes an ErrorMessage to QDebug
static QHash< QLatin1String, StorableMsg > & registry()
QMLDOM_EXPORT void silentError(const ErrorMessage &)
Error handler that ignores all errors (excluding fatal ones)
QMLDOM_EXPORT void setDefaultErrorHandler(const ErrorHandler &h)
Sets the default error handler.
QMLDOM_EXPORT ErrorLevel errorLevelFromQtMsgType(QtMsgType msgType)
static ErrorGroups myErrors()
void errorHandlerHandler(const ErrorMessage &msg, const ErrorHandler *h=nullptr)
std::function< void(const ErrorMessage &)> ErrorHandler
QMLDOM_EXPORT void defaultErrorHandler(const ErrorMessage &)
Calls the default error handler (by default errorToQDebug)
static QBasicMutex * registryMutex()
#define NewErrorGroup(name)
StorableMsg(ErrorMessage &&e)
StorableMsg(const ErrorMessage &e)