1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef ERRORMESSAGE_H
5#define ERRORMESSAGE_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qqmldom_global.h"
19#include "qqmldomstringdumper_p.h"
20#include "qqmldompath_p.h"
21
22#include <QtQml/private/qqmljsast_p.h>
23#include <QtCore/QCoreApplication>
24#include <QtCore/QString>
25#include <QtCore/QCborArray>
26#include <QtCore/QCborMap>
27#include <QtCore/QLoggingCategory>
28#include <QtQml/private/qqmljsdiagnosticmessage_p.h>
29
30QT_BEGIN_NAMESPACE
31
32namespace QQmlJS {
33namespace Dom {
34
35Q_DECLARE_LOGGING_CATEGORY(domLog);
36
37QMLDOM_EXPORT ErrorLevel errorLevelFromQtMsgType(QtMsgType msgType);
38
39class ErrorGroups;
40class DomItem;
41using std::function;
42
43#define NewErrorGroup(name) QQmlJS::Dom::ErrorGroup(QT_TRANSLATE_NOOP("ErrorGroup", name))
44
45class QMLDOM_EXPORT ErrorGroup {
46 Q_GADGET
47 Q_DECLARE_TR_FUNCTIONS(ErrorGroup)
48public:
49 constexpr ErrorGroup(const char *groupId):
50 m_groupId(groupId)
51 {}
52
53
54 void dump(Sink sink) const;
55 void dumpId(Sink sink) const;
56
57 QLatin1String groupId() const;
58 QString groupName() const;
59 private:
60 const char *m_groupId;
61};
62
63class QMLDOM_EXPORT ErrorGroups{
64 Q_GADGET
65public:
66 void dump(Sink sink) const;
67 void dumpId(Sink sink) const;
68 QCborArray toCbor() const;
69
70 [[nodiscard]] ErrorMessage errorMessage(Dumper msg, ErrorLevel level, Path element = Path(), QString canonicalFilePath = QString(), SourceLocation location = SourceLocation()) const;
71 [[nodiscard]] ErrorMessage errorMessage(const DiagnosticMessage &msg, Path element = Path(), QString canonicalFilePath = QString()) const;
72
73 void fatal(Dumper msg, Path element = Path(), QStringView canonicalFilePath = u"", SourceLocation location = SourceLocation()) const;
74
75 [[nodiscard]] ErrorMessage debug(QString message) const;
76 [[nodiscard]] ErrorMessage debug(Dumper message) const;
77 [[nodiscard]] ErrorMessage info(QString message) const;
78 [[nodiscard]] ErrorMessage info(Dumper message) const;
79 [[nodiscard]] ErrorMessage warning(QString message) const;
80 [[nodiscard]] ErrorMessage warning(Dumper message) const;
81 [[nodiscard]] ErrorMessage error(QString message) const;
82 [[nodiscard]] ErrorMessage error(Dumper message) const;
83
84 static int cmp(const ErrorGroups &g1, const ErrorGroups &g2);
85
86 QVector<ErrorGroup> groups;
87};
88
89inline bool operator==(const ErrorGroups& lhs, const ErrorGroups& rhs){ return ErrorGroups::cmp(g1: lhs,g2: rhs) == 0; }
90inline bool operator!=(const ErrorGroups& lhs, const ErrorGroups& rhs){ return ErrorGroups::cmp(g1: lhs,g2: rhs) != 0; }
91inline bool operator< (const ErrorGroups& lhs, const ErrorGroups& rhs){ return ErrorGroups::cmp(g1: lhs,g2: rhs) < 0; }
92inline bool operator> (const ErrorGroups& lhs, const ErrorGroups& rhs){ return ErrorGroups::cmp(g1: lhs,g2: rhs) > 0; }
93inline bool operator<=(const ErrorGroups& lhs, const ErrorGroups& rhs){ return ErrorGroups::cmp(g1: lhs,g2: rhs) <= 0; }
94inline bool operator>=(const ErrorGroups& lhs, const ErrorGroups& rhs){ return ErrorGroups::cmp(g1: lhs,g2: rhs) >= 0; }
95
96class QMLDOM_EXPORT ErrorMessage { // reuse Some of the other DiagnosticMessages?
97 Q_GADGET
98 Q_DECLARE_TR_FUNCTIONS(ErrorMessage)
99public:
100 using Level = ErrorLevel;
101 // error registry (usage is optional)
102 static QLatin1String msg(const char *errorId, ErrorMessage err);
103 static QLatin1String msg(QLatin1String errorId, ErrorMessage err);
104 static void visitRegisteredMessages(function_ref<bool(ErrorMessage)> visitor);
105 [[nodiscard]] static ErrorMessage load(QLatin1String errorId);
106 [[nodiscard]] static ErrorMessage load(const char *errorId);
107 template<typename... T>
108 [[nodiscard]] static ErrorMessage load(QLatin1String errorId, T... args){
109 ErrorMessage res = load(errorId);
110 res.message = res.message.arg(args...);
111 return res;
112 }
113
114 ErrorMessage(QString message, ErrorGroups errorGroups, Level level = Level::Warning, Path path = Path(), QString file = QString(), SourceLocation location = SourceLocation(), QLatin1String errorId = QLatin1String(""));
115 ErrorMessage(ErrorGroups errorGroups, const DiagnosticMessage &msg, Path path = Path(), QString file = QString(), QLatin1String errorId = QLatin1String(""));
116
117 [[nodiscard]] ErrorMessage &withErrorId(QLatin1String errorId);
118 [[nodiscard]] ErrorMessage &withPath(const Path &);
119 [[nodiscard]] ErrorMessage &withFile(QString);
120 [[nodiscard]] ErrorMessage &withFile(QStringView);
121 [[nodiscard]] ErrorMessage &withLocation(SourceLocation);
122 [[nodiscard]] ErrorMessage &withItem(DomItem);
123
124 ErrorMessage handle(const ErrorHandler &errorHandler=nullptr);
125
126 void dump(Sink s) const;
127 QString toString() const;
128 QCborMap toCbor() const;
129 friend int compare(const ErrorMessage &msg1, const ErrorMessage &msg2)
130 {
131 int c;
132 c = msg1.location.offset - msg2.location.offset;
133 if (c != 0)
134 return c;
135 c = msg1.location.startLine - msg2.location.startLine;
136 if (c != 0)
137 return c;
138 c = msg1.errorId.compare(other: msg2.errorId);
139 if (c != 0)
140 return c;
141 if (!msg1.errorId.isEmpty())
142 return 0;
143 c = msg1.message.compare(s: msg2.message);
144 if (c != 0)
145 return c;
146 c = msg1.file.compare(s: msg2.file);
147 if (c != 0)
148 return c;
149 c = Path::cmp(p1: msg1.path, p2: msg2.path);
150 if (c != 0)
151 return c;
152 c = int(msg1.level) - int(msg2.level);
153 if (c != 0)
154 return c;
155 c = int(msg1.errorGroups.groups.size() - msg2.errorGroups.groups.size());
156 if (c != 0)
157 return c;
158 for (qsizetype i = 0; i < msg1.errorGroups.groups.size(); ++i) {
159 c = msg1.errorGroups.groups[i].groupId().compare(other: msg2.errorGroups.groups[i].groupId());
160 if (c != 0)
161 return c;
162 }
163 c = msg1.location.length - msg2.location.length;
164 if (c != 0)
165 return c;
166 c = msg1.location.startColumn - msg2.location.startColumn;
167 return c;
168 }
169
170 QLatin1String errorId;
171 QString message;
172 ErrorGroups errorGroups;
173 Level level;
174 Path path;
175 QString file;
176 SourceLocation location;
177};
178
179inline bool operator !=(const ErrorMessage &e1, const ErrorMessage &e2) {
180 return compare(msg1: e1, msg2: e2) != 0;
181}
182inline bool operator ==(const ErrorMessage &e1, const ErrorMessage &e2) {
183 return compare(msg1: e1, msg2: e2) == 0;
184}
185inline bool operator<(const ErrorMessage &e1, const ErrorMessage &e2)
186{
187 return compare(msg1: e1, msg2: e2) < 0;
188}
189inline bool operator<=(const ErrorMessage &e1, const ErrorMessage &e2)
190{
191 return compare(msg1: e1, msg2: e2) <= 0;
192}
193inline bool operator>(const ErrorMessage &e1, const ErrorMessage &e2)
194{
195 return compare(msg1: e1, msg2: e2) > 0;
196}
197inline bool operator>=(const ErrorMessage &e1, const ErrorMessage &e2)
198{
199 return compare(msg1: e1, msg2: e2) >= 0;
200}
201
202QMLDOM_EXPORT void silentError(const ErrorMessage &);
203QMLDOM_EXPORT void errorToQDebug(const ErrorMessage &);
204
205QMLDOM_EXPORT void defaultErrorHandler(const ErrorMessage &);
206QMLDOM_EXPORT void setDefaultErrorHandler(ErrorHandler h);
207
208} // end namespace Dom
209} // end namespace QQmlJS
210QT_END_NAMESPACE
211#endif // ERRORMESSAGE_H
212

source code of qtdeclarative/src/qmldom/qqmldomerrormessage_p.h