Skip to content
61 changes: 47 additions & 14 deletions include/mrdocs/Support/Report.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
*/
namespace mrdocs::report {

/** Severity levels attached to reported messags.
/** Severity levels attached to reported messages.
*/
enum class Level
{
Expand Down Expand Up @@ -103,11 +103,10 @@ Level
getMinimumLevel() noexcept;

/** If true, source location information will be
printed with warnings, errors, and fatal messages.
printed.

@param b true to enable source location
information, false to disable it. The default
value is true.
@param b true to enable the bug report details,
false to disable them. The default value is true.
*/
MRDOCS_DECL
void
Expand All @@ -133,8 +132,13 @@ print(
trailing newline will be added to the
message automatically.

@param loc The source location of the report.
If this value is null, no location is printed.
@param loc The source location a bug report
should carry. If this value is null, the message
is printed on its own, without the bug report
details.

@param e The error the message reports, when
there is one. Only read when `loc` is not null.
*/
MRDOCS_DECL
void
Expand Down Expand Up @@ -179,49 +183,54 @@ struct Located
column widths) from the public reporting API.
*/
namespace detail {
// `withBugDetails` says whether the message reports a MrDocs defect. Only
// then is the location where MrDocs raised it worth printing, along with
// the rest of what a bug report needs. A message about the user's input
// does not contain such info.
template<class Arg0, class... Args>
requires (!std::same_as<std::decay_t<Arg0>, Error>)
void
log_impl(
Level level,
bool withBugDetails,
Located<std::string_view> fs,
Arg0&& arg0,
Args&&... args)
{
std::string str =
std::vformat(fs.value, std::make_format_args(arg0, args...));
return print(level, str, &fs.where);
return print(level, str, withBugDetails ? &fs.where : nullptr);
}

template<class... Args>
void
log_impl(
Level level,
bool withBugDetails,
Located<std::string_view> fs,
Error const& e,
Args&&... args)
{
// When the message is an error, we send split
// the information relevant to the user from
// the information relevant for bug tracking
// so that users can understand the message.
// The reason is what went wrong; where MrDocs raised it belongs to the
// bug report details, so the message carries the reason alone.
std::string str =
std::vformat(fs.value, std::make_format_args(e.reason(), args...));
return print(
level,
str,
&fs.where,
withBugDetails ? &fs.where : nullptr,
&e);
}

inline
void
log_impl(
Level level,
bool withBugDetails,
Located<std::string_view> fs)
{
std::string str(fs.value);
return print(level, str, &fs.where);
return print(level, str, withBugDetails ? &fs.where : nullptr);
}
}

Expand All @@ -246,6 +255,7 @@ log(
{
return detail::log_impl(
level,
false,
fs,
std::forward<Args>(args)...);
}
Expand Down Expand Up @@ -328,6 +338,29 @@ fatal(
return log(Level::fatal, format, std::forward<Args>(args)...);
}

/** Emit an error that reports a defect in MrDocs itself.

The message is followed by the version and the source location a bug
report needs. Use it where MrDocs reached a state it does not handle.
A mistake in the user's input is not a bug in MrDocs, so it goes
through the other reporting functions.

@param format fmt-style format string.
@param args Arguments substituted into the format string.
*/
template<class... Args>
void
bug(
Located<std::string_view> format,
Args&&... args)
{
return detail::log_impl(
Level::error,
true,
format,
std::forward<Args>(args)...);
}

} // mrdocs

#endif
8 changes: 4 additions & 4 deletions src/mrdocs/AST/ASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2221,7 +2221,7 @@ addMember(
addMember(I.Members.Macros, *U);
return;
}
report::error("Cannot push {} of type {} into members of namespace {}",
report::bug("Cannot push {} of type {} into members of namespace {}",
Member.Name,
mrdocs::toString(Member.Kind),
I.Name);
Expand Down Expand Up @@ -2311,7 +2311,7 @@ addMember(RecordTranche& T, Symbol const& Member)
addMember(T.Usings, *U);
return;
}
report::error("Cannot push {} of type {} into tranche",
report::bug("Cannot push {} of type {} into tranche",
Member.Name,
mrdocs::toString(Member.Kind));
}
Expand All @@ -2325,7 +2325,7 @@ addMember(EnumSymbol& I, Symbol const& Member) const
addMember(I.Constants, *U);
return;
}
report::error("Cannot push {} of type {} into members of enum {}",
report::bug("Cannot push {} of type {} into members of enum {}",
Member.Name,
mrdocs::toString(Member.Kind),
I.Name);
Expand All @@ -2340,7 +2340,7 @@ addMember(OverloadsSymbol& I, Symbol const& Member) const
addMember(I.Members, Member);
return;
}
report::error("Cannot push {} of type {} into members of enum {}",
report::bug("Cannot push {} of type {} into members of overload set {}",
Member.Name,
mrdocs::toString(Member.Kind),
I.Name);
Expand Down
20 changes: 10 additions & 10 deletions src/mrdocs/AST/ExtractDocComment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ convertDirection(clang::comments::ParamCommandPassDirection d)
case D::InOut:
return doc::ParamDirection::inout;
}
report::error(
report::bug(
"error: unsupported ParamCommandPassDirection <{}>",
static_cast<int>(d));
MRDOCS_UNREACHABLE();
Expand All @@ -219,7 +219,7 @@ convertCopydoc(unsigned id)
case T::KCI_copydetails:
return doc::Parts::description;
default:
report::error("error: unsupported CommandTrait id <{}>", id);
report::bug("error: unsupported CommandTrait id <{}>", id);
MRDOCS_UNREACHABLE();
}
}
Expand Down Expand Up @@ -793,7 +793,7 @@ class DocCommentVisitor
Expected<doc::TableCell> cellExp = parseTableCell(sub);
if (!cellExp)
{
warnNear(s, cellExp.error().message());
warnNear(s, cellExp.error().reason());
return;
}
row.Cells.push_back(std::move(*cellExp));
Expand Down Expand Up @@ -894,7 +894,7 @@ class DocCommentVisitor
Expected<doc::TableRow> rowExp = parseTableRow(sub);
if (!rowExp)
{
warnNear(s, rowExp.error().message());
warnNear(s, rowExp.error().reason());
return;
}
// Skip rows whose cells all failed to parse: a row with
Expand Down Expand Up @@ -1049,7 +1049,7 @@ class DocCommentVisitor
Expected<doc::TableBlock> tbExp = parseTable(cur);
if (!tbExp)
{
warnNear(C, tbExp.error().message());
warnNear(C, tbExp.error().reason());
return;
}
// A table with no rows (e.g., because every row's content
Expand Down Expand Up @@ -1185,7 +1185,7 @@ class DocCommentVisitor
// written; the rest of the phrase follows as ordinary text.
if (isSupportedHTMLTag(C->getTagName()))
{
warnOnce(filename, loc.getLine(), compsExp.error().message());
warnOnce(filename, loc.getLine(), compsExp.error().reason());
}
emplaceInline<doc::TextInline>(
C->hasTrailingNewline(),
Expand All @@ -1210,7 +1210,7 @@ class DocCommentVisitor
// problem in the user's doc comment, not in Mr.Docs: warn
// with the location and keep the text instead of failing
// the whole run with an internal-error banner.
warnOnce(filename, loc.getLine(), r.error().message());
warnOnce(filename, loc.getLine(), r.error().reason());
emplaceInline<doc::TextInline>(
C->hasTrailingNewline(),
ensureUTF8(std::move(comps.text)));
Expand Down Expand Up @@ -1276,7 +1276,7 @@ class DocCommentVisitor
auto srcAttr = getAttr("src");
if (!srcAttr)
{
warnOnce(filename, loc.getLine(), srcAttr.error().message());
warnOnce(filename, loc.getLine(), srcAttr.error().reason());
return;
}
std::string alt = getAttr("alt").value_or(std::string());
Expand Down Expand Up @@ -1360,7 +1360,7 @@ class DocCommentVisitor
warnOnce(
files::makePosixStyle(loc.getFilename()),
loc.getLine(),
r.error().message());
r.error().reason());
}
else if (comps.tag == "em")
{
Expand Down Expand Up @@ -1761,7 +1761,7 @@ class DocCommentVisitor
case T::KCI_copybrief:
case T::KCI_copydetails:
case T::KCI_copydoc:
report::error(
report::bug(
"error: inline command {} should be handled elsewhere",
cmd->Name);
MRDOCS_UNREACHABLE();
Expand Down
4 changes: 1 addition & 3 deletions src/mrdocs/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1119,9 +1119,7 @@ struct ConfigSchemaVisitor {
MRDOCS_TRY(
std::string_view const baseDir,
getBaseDir(referenceDirKey, dirs, settings));
if (pos != std::string::npos) {
value = value.substr(pos + 1);
}
value = pos != std::string::npos ? value.substr(pos + 1) : ".";
return std::string(baseDir);
}
};
Expand Down
3 changes: 1 addition & 2 deletions src/mrdocs/Corpus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,7 @@ Corpus::build(
{
return Unexpected(err);
}
report::warn(
"Warning: mapping failed because ", err);
report::warn("Mapping failed: {}", err);
}

MRDOCS_TRY(auto results, context.results());
Expand Down
2 changes: 1 addition & 1 deletion src/mrdocs/Engines/JavaScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ invokeHelper(Value const& fn, dom::Array const& args)
auto ret = fn.apply(callArgs);
if (!ret)
{
return Unexpected(dom::Error(std::string(ret.error().message())));
return Unexpected(dom::Error(std::string(ret.error().reason())));
}
return ret->getDom();
}
Expand Down
2 changes: 1 addition & 1 deletion src/mrdocs/Extensions/ExtensionRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ ExtensionRegistry::applyTransforms(Corpus& corpus, Config const& config) const
{
return Unexpected(formatError(
"extension transform '{}': {}",
id, invoked.error().message()));
id, invoked.error().reason()));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/mrdocs/Extensions/JsBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ loadJsExtensions(std::string const& scriptPath, Config const& config)
if (!ran.has_value())
{
return Unexpected(formatError(
"extension '{}': {}", scriptPath, ran.error().message()));
"extension '{}': {}", scriptPath, ran.error().reason()));
}

if (loaded.transforms.empty() && loaded.generators.empty())
Expand Down
8 changes: 4 additions & 4 deletions src/mrdocs/Generators/hbs/Builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ registerUserJsHelpers(
{
return Unexpected(formatError(
"Error loading utility {}: {}",
utilPath, exp.error().message()));
utilPath, exp.error().reason()));
}
}

Expand Down Expand Up @@ -417,7 +417,7 @@ registerUserLuaHelpers(
{
return Unexpected(formatError(
"Error loading utility {}: {}",
utilPath, exp.error().message()));
utilPath, exp.error().reason()));
}
}

Expand Down Expand Up @@ -680,7 +680,7 @@ operator()(std::ostream& os, T const& I)
// Reuse the already-built context to avoid recomputing DOM data.
if (auto exp = callTemplate(os, templateFile, ctx); !exp)
{
return Unexpected(dom::Error(std::string(exp.error().message())));
return Unexpected(dom::Error(std::string(exp.error().reason())));
}
return {};
}));
Expand Down Expand Up @@ -715,7 +715,7 @@ renderWrapped(
ctx.set("contents",
dom::makeInvocable([&](dom::Value const &) -> dom::Expected<dom::Value> {
if (auto exp = contentsCb(); !exp) {
return Unexpected(dom::Error(std::string(exp.error().message())));
return Unexpected(dom::Error(std::string(exp.error().reason())));
}
return {};
}));
Expand Down
4 changes: 2 additions & 2 deletions src/mrdocs/Generators/script/ScriptGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ buildOutputApi(OutputSink& sink)
doAppend);
!wrote)
{
result = Unexpected(dom::Error(std::string(wrote.error().message())));
result = Unexpected(dom::Error(std::string(wrote.error().reason())));
}
else
{
Expand Down Expand Up @@ -212,7 +212,7 @@ build(Corpus const& corpus, Config const& config) const
if (!invoked)
{
result = Unexpected(formatError(
"generator '{}': {}", id_, invoked.error().message()));
"generator '{}': {}", id_, invoked.error().reason()));
}
return result;
}
Expand Down
14 changes: 0 additions & 14 deletions src/mrdocs/Support/Report.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,20 +107,6 @@ print(

//------------------------------------------------

Level
getLevel(unsigned level) noexcept
{
switch(level)
{
case 0: return Level::debug;
case 1: return Level::info;
case 2: return Level::warn;
case 3: return Level::error;
default:
return Level::fatal;
}
}

constexpr
llvm::raw_ostream::Colors
getLevelColor(Level level)
Expand Down
Loading
Loading