106class MessageFormattedText {
108 template <
typename... A>
110 : severity_{text.severity()} {
111 Format(&text, Convert(std::forward<A>(x))...);
113 MessageFormattedText(
const MessageFormattedText &) =
default;
114 MessageFormattedText(MessageFormattedText &&) =
default;
115 MessageFormattedText &operator=(
const MessageFormattedText &) =
default;
116 MessageFormattedText &operator=(MessageFormattedText &&) =
default;
117 const std::string &string()
const {
return string_; }
118 bool IsFatal()
const {
119 return severity_ == Severity::Error || severity_ == Severity::Todo;
121 Severity severity()
const {
return severity_; }
122 MessageFormattedText &set_severity(Severity severity) {
123 severity_ = severity;
126 std::string MoveString() {
return std::move(string_); }
127 bool operator==(
const MessageFormattedText &that)
const {
128 return severity_ == that.severity_ && string_ == that.string_;
130 bool operator!=(
const MessageFormattedText &that)
const {
131 return !(*
this == that);
137 template <
typename A> A Convert(
const A &x) {
138 static_assert(!std::is_class_v<std::decay_t<A>>);
141 template <
typename A> common::IfNoLvalue<A, A> Convert(A &&x) {
142 static_assert(!std::is_class_v<std::decay_t<A>>);
145 const char *Convert(
const char *s) {
return s; }
146 const char *Convert(
char *s) {
return s; }
147 const char *Convert(
const std::string &);
148 const char *Convert(std::string &&);
149 const char *Convert(
const std::string_view &);
150 const char *Convert(std::string_view &&);
152 std::intmax_t Convert(std::int64_t x) {
return x; }
153 std::uintmax_t Convert(std::uint64_t x) {
return x; }
157 std::forward_list<std::string> conversions_;
194 Message(
const Message &) =
default;
195 Message(Message &&) =
default;
196 Message &operator=(
const Message &) =
default;
197 Message &operator=(Message &&) =
default;
200 : location_{pr}, text_{t} {}
202 : location_{pr}, text_{s} {}
204 : location_{pr}, text_{std::move(s)} {}
206 : location_{pr}, text_{t} {}
208 Message(common::LanguageFeature feature, ProvenanceRange pr,
210 : location_{pr}, text_{t}, languageFeature_{feature} {}
211 Message(common::LanguageFeature feature, ProvenanceRange pr,
213 : location_{pr}, text_{s}, languageFeature_{feature} {}
214 Message(common::LanguageFeature feature, ProvenanceRange pr,
216 : location_{pr}, text_{std::move(s)}, languageFeature_{feature} {}
218 Message(common::UsageWarning warning, ProvenanceRange pr,
220 : location_{pr}, text_{t}, usageWarning_{warning} {}
221 Message(common::UsageWarning warning, ProvenanceRange pr,
223 : location_{pr}, text_{s}, usageWarning_{warning} {}
224 Message(common::UsageWarning warning, ProvenanceRange pr,
226 : location_{pr}, text_{std::move(s)}, usageWarning_{warning} {}
229 : location_{csr}, text_{t} {}
231 : location_{csr}, text_{s} {}
233 : location_{csr}, text_{std::move(s)} {}
235 : location_{csr}, text_{t} {}
239 : location_{csr}, text_{t}, languageFeature_{feature} {}
240 Message(common::LanguageFeature feature,
CharBlock csr,
242 : location_{csr}, text_{s}, languageFeature_{feature} {}
245 : location_{csr}, text_{std::move(s)}, languageFeature_{feature} {}
249 : location_{csr}, text_{t}, usageWarning_{warning} {}
250 Message(common::UsageWarning warning,
CharBlock csr,
252 : location_{csr}, text_{s}, usageWarning_{warning} {}
254 : location_{csr}, text_{std::move(s)}, usageWarning_{warning} {}
256 template <
typename RANGE,
typename A,
typename... As>
259 t, std::forward<A>(x), std::forward<As>(xs)...}} {}
260 template <
typename RANGE,
typename A,
typename... As>
261 Message(common::LanguageFeature feature, RANGE r,
const MessageFixedText &t,
264 t, std::forward<A>(x), std::forward<As>(xs)...}},
265 languageFeature_{feature} {}
266 template <
typename RANGE,
typename A,
typename... As>
270 t, std::forward<A>(x), std::forward<As>(xs)...}},
271 usageWarning_{warning} {}
273 Reference attachment()
const {
return attachment_; }
275 void SetContext(Message *c) {
277 attachmentIsContext_ =
true;
279 Message &Attach(Message *);
280 Message &Attach(std::unique_ptr<Message> &&);
281 template <
typename... A> Message &Attach(A &&...args) {
282 return Attach(
new Message{std::forward<A>(args)...});
285 bool SortBefore(
const Message &that)
const;
286 bool IsFatal()
const;
287 Severity severity()
const;
288 Message &set_severity(Severity);
289 std::optional<common::LanguageFeature> languageFeature()
const;
290 Message &set_languageFeature(common::LanguageFeature);
291 std::optional<common::UsageWarning> usageWarning()
const;
292 Message &set_usageWarning(common::UsageWarning);
293 std::string ToString()
const;
294 std::optional<ProvenanceRange> GetProvenanceRange(
297 bool echoSourceLine =
true,
304 bool IsMergeable()
const {
305 return std::holds_alternative<MessageExpectedText>(text_);
307 bool Merge(
const Message &);
308 bool operator==(
const Message &that)
const;
309 bool operator!=(
const Message &that)
const {
return !(*
this == that); }
310 bool AtSameLocation(
const Message &)
const;
313 std::variant<ProvenanceRange, CharBlock> location_;
314 std::variant<MessageFixedText, MessageFormattedText, MessageExpectedText>
316 bool attachmentIsContext_{
false};
317 Reference attachment_;
318 std::optional<common::LanguageFeature> languageFeature_;
319 std::optional<common::UsageWarning> usageWarning_;
325 Messages(Messages &&that) : messages_{std::move(that.messages_)} {}
326 Messages &operator=(Messages &&that) {
327 messages_ = std::move(that.messages_);
331 std::list<Message> &messages() {
return messages_; }
332 bool empty()
const {
return messages_.empty(); }
333 void clear() { messages_.clear(); }
335 template <
typename... A>
Message &Say(A &&...args) {
336 return messages_.emplace_back(std::forward<A>(args)...);
339 template <
typename... A>
340 Message *Warn(
bool isInModuleFile,
342 common::LanguageFeature feature, A &&...args) {
343 if (!isInModuleFile && control.ShouldWarn(feature)) {
344 return &AddWarning(feature, std::forward<A>(args)...);
349 template <
typename... A>
350 Message *Warn(
bool isInModuleFile,
352 common::UsageWarning warning, A &&...args) {
353 if (!isInModuleFile && control.ShouldWarn(warning)) {
354 return &AddWarning(warning, std::forward<A>(args)...);
359 void Annex(Messages &&that) {
360 messages_.splice(messages_.end(), that.messages_);
364 void Merge(Messages &&);
365 void Copy(
const Messages &);
368 bool echoSourceLines =
true,
370 std::size_t maxErrorsToEmit = 0,
bool warningsAreErrors =
false)
const;
371 void AttachTo(
Message &, std::optional<Severity> = std::nullopt);
372 bool AnyFatalError(
bool warningsAreErrors =
false)
const;
375 template <
typename... A>
376 Message &AddWarning(common::UsageWarning warning, A &&...args) {
377 return messages_.emplace_back(warning, std::forward<A>(args)...);
379 template <
typename... A>
380 Message &AddWarning(common::LanguageFeature feature, A &&...args) {
381 return messages_.emplace_back(feature, std::forward<A>(args)...);
383 std::list<Message> messages_;
386class ContextualMessages {
388 ContextualMessages() =
default;
390 explicit ContextualMessages(
Messages *m) : messages_{m} {}
391 ContextualMessages(
const ContextualMessages &that)
392 : at_{that.at_}, messages_{that.messages_} {}
395 Messages *messages()
const {
return messages_; }
396 Message::Reference contextMessage()
const {
return contextMessage_; }
397 bool empty()
const {
return !messages_ || messages_->empty(); }
404 return common::ScopedSet(at_, std::move(at));
409 m = contextMessage_.get();
411 return common::ScopedSet(contextMessage_, m);
417 return common::ScopedSet(messages_, &buffer);
421 return common::ScopedSet(messages_,
nullptr);
424 template <
typename... A>
Message *Say(A &&...args) {
425 return Say(at_, std::forward<A>(args)...);
429 if (messages_ !=
nullptr) {
430 auto &msg{messages_->Say(at, std::forward<A>(args)...)};
431 if (contextMessage_) {
432 msg.SetContext(contextMessage_.get());
440 template <
typename... A>
441 Message *Say(std::optional<CharBlock> at, A &&...args) {
442 return Say(at.value_or(at_), std::forward<A>(args)...);
446 if (messages_ !=
nullptr) {
447 if (contextMessage_) {
448 msg.SetContext(contextMessage_.get());
450 return &messages_->Say(std::move(msg));
456 template <
typename FeatureOrUsageWarning,
typename... A>
457 Message *Warn(
bool isInModuleFile,
459 FeatureOrUsageWarning feature,
CharBlock at, A &&...args) {
460 if (messages_ !=
nullptr) {
462 msg{messages_->Warn(isInModuleFile, control, feature, at,
463 std::forward<A>(args)...)}) {
464 if (contextMessage_) {
465 msg->SetContext(contextMessage_.get());
473 template <
typename FeatureOrUsageWarning,
typename... A>
474 Message *Warn(
bool isInModuleFile,
476 FeatureOrUsageWarning feature, A &&...args) {
478 isInModuleFile, control, feature, at_, std::forward<A>(args)...);
481 template <
typename FeatureOrUsageWarning,
typename... A>
482 Message *Warn(
bool isInModuleFile,
484 FeatureOrUsageWarning feature, std::optional<CharBlock> at, A &&...args) {
485 return Warn(isInModuleFile, control, feature, at.value_or(at_),
486 std::forward<A>(args)...);
492 Message::Reference contextMessage_;