[breaking] Move error_logged() from logger to parser
This commit is contained in:
parent
6dd85cb7a7
commit
44708fff76
9 changed files with 47 additions and 20 deletions
|
|
@ -21,7 +21,7 @@ namespace cppast
|
||||||
class diagnostic_logger
|
class diagnostic_logger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
diagnostic_logger() noexcept : error_(false)
|
diagnostic_logger() noexcept : verbose_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,15 +34,6 @@ namespace cppast
|
||||||
/// \notes `source` points to a string literal that gives additional context to what generates the message.
|
/// \notes `source` points to a string literal that gives additional context to what generates the message.
|
||||||
bool log(const char* source, const diagnostic& d) const;
|
bool log(const char* source, const diagnostic& d) const;
|
||||||
|
|
||||||
/// \returns Whether or not a diagnostic of [severity::error]() was logged.
|
|
||||||
/// \notes If an error happens, the parser will still continue to build the AST,
|
|
||||||
/// unless the error is critical
|
|
||||||
/// so the result will be incomplete if this function returns `true`.
|
|
||||||
bool error_logged() const noexcept
|
|
||||||
{
|
|
||||||
return error_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \effects Sets whether or not the logger prints debugging diagnostics.
|
/// \effects Sets whether or not the logger prints debugging diagnostics.
|
||||||
void set_verbose(bool value) noexcept
|
void set_verbose(bool value) noexcept
|
||||||
{
|
{
|
||||||
|
|
@ -58,8 +49,7 @@ namespace cppast
|
||||||
private:
|
private:
|
||||||
virtual bool do_log(const char* source, const diagnostic& d) const = 0;
|
virtual bool do_log(const char* source, const diagnostic& d) const = 0;
|
||||||
|
|
||||||
mutable std::atomic<bool> error_;
|
bool verbose_;
|
||||||
bool verbose_ = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A [cppast::diagnostic_logger]() that logs to `stderr`.
|
/// A [cppast::diagnostic_logger]() that logs to `stderr`.
|
||||||
|
|
@ -86,15 +76,30 @@ namespace cppast
|
||||||
/// \returns The [cppast::cpp_file]() object describing it.
|
/// \returns The [cppast::cpp_file]() object describing it.
|
||||||
/// It can be `nullptr`, if there was an error or the specified file already registered in the index.
|
/// It can be `nullptr`, if there was an error or the specified file already registered in the index.
|
||||||
/// \requires The dynamic type of `config` must match the required config type.
|
/// \requires The dynamic type of `config` must match the required config type.
|
||||||
|
/// \notes This function is thread safe.
|
||||||
std::unique_ptr<cpp_file> parse(const cpp_entity_index& idx, std::string path,
|
std::unique_ptr<cpp_file> parse(const cpp_entity_index& idx, std::string path,
|
||||||
const compile_config& config) const
|
const compile_config& config) const
|
||||||
{
|
{
|
||||||
return do_parse(idx, std::move(path), config);
|
return do_parse(idx, std::move(path), config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \returns Whether or not an error occurred during parsing.
|
||||||
|
/// If that happens, the AST might be incomplete.
|
||||||
|
bool error() const noexcept
|
||||||
|
{
|
||||||
|
return error_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \effects Resets the error state.
|
||||||
|
void reset_error() noexcept
|
||||||
|
{
|
||||||
|
error_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// \effects Creates it giving it a reference to the logger it uses.
|
/// \effects Creates it giving it a reference to the logger it uses.
|
||||||
explicit parser(type_safe::object_ref<const diagnostic_logger> logger) : logger_(logger)
|
explicit parser(type_safe::object_ref<const diagnostic_logger> logger)
|
||||||
|
: logger_(logger), error_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,13 +109,22 @@ namespace cppast
|
||||||
return *logger_;
|
return *logger_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \effects Sets the error state.
|
||||||
|
/// This must be called when an error or critical diagnostic is logged and the AST is incomplete.
|
||||||
|
void set_error() const noexcept
|
||||||
|
{
|
||||||
|
error_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// \effects Parses the given file.
|
/// \effects Parses the given file.
|
||||||
/// \returns The [cppast::cpp_file]() object describing it.
|
/// \returns The [cppast::cpp_file]() object describing it.
|
||||||
|
/// \requires The function must be thread safe.
|
||||||
virtual std::unique_ptr<cpp_file> do_parse(const cpp_entity_index& idx, std::string path,
|
virtual std::unique_ptr<cpp_file> do_parse(const cpp_entity_index& idx, std::string path,
|
||||||
const compile_config& config) const = 0;
|
const compile_config& config) const = 0;
|
||||||
|
|
||||||
type_safe::object_ref<const diagnostic_logger> logger_;
|
type_safe::object_ref<const diagnostic_logger> logger_;
|
||||||
|
mutable std::atomic<bool> error_;
|
||||||
};
|
};
|
||||||
} // namespace cppast
|
} // namespace cppast
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,10 +94,12 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_enum(const detail::parse_context&
|
||||||
}
|
}
|
||||||
catch (parse_error& ex)
|
catch (parse_error& ex)
|
||||||
{
|
{
|
||||||
|
context.error = true;
|
||||||
context.logger->log("libclang parser", ex.get_diagnostic());
|
context.logger->log("libclang parser", ex.get_diagnostic());
|
||||||
}
|
}
|
||||||
catch (std::logic_error& ex)
|
catch (std::logic_error& ex)
|
||||||
{
|
{
|
||||||
|
context.error = true;
|
||||||
context.logger->log("libclang parser",
|
context.logger->log("libclang parser",
|
||||||
diagnostic{ex.what(), make_location(child), severity::error});
|
diagnostic{ex.what(), make_location(child), severity::error});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,10 +46,12 @@ namespace
|
||||||
}
|
}
|
||||||
catch (detail::parse_error& ex)
|
catch (detail::parse_error& ex)
|
||||||
{
|
{
|
||||||
|
context.error = true;
|
||||||
context.logger->log("libclang parser", ex.get_diagnostic());
|
context.logger->log("libclang parser", ex.get_diagnostic());
|
||||||
}
|
}
|
||||||
catch (std::logic_error& ex)
|
catch (std::logic_error& ex)
|
||||||
{
|
{
|
||||||
|
context.error = true;
|
||||||
context.logger->log("libclang parser",
|
context.logger->log("libclang parser",
|
||||||
diagnostic{ex.what(), detail::make_location(child),
|
diagnostic{ex.what(), detail::make_location(child),
|
||||||
severity::error});
|
severity::error});
|
||||||
|
|
|
||||||
|
|
@ -400,8 +400,12 @@ std::unique_ptr<cpp_file> libclang_parser::do_parse(const cpp_entity_index& idx,
|
||||||
auto include_iter = preprocessed.includes.begin();
|
auto include_iter = preprocessed.includes.begin();
|
||||||
|
|
||||||
// convert entity hierarchies
|
// convert entity hierarchies
|
||||||
detail::parse_context context{tu.get(), file, type_safe::ref(logger()), type_safe::ref(idx),
|
detail::parse_context context{tu.get(),
|
||||||
detail::comment_context(preprocessed.comments)};
|
file,
|
||||||
|
type_safe::ref(logger()),
|
||||||
|
type_safe::ref(idx),
|
||||||
|
detail::comment_context(preprocessed.comments),
|
||||||
|
false};
|
||||||
detail::visit_tu(tu, path.c_str(), [&](const CXCursor& cur) {
|
detail::visit_tu(tu, path.c_str(), [&](const CXCursor& cur) {
|
||||||
if (clang_getCursorKind(cur) == CXCursor_InclusionDirective)
|
if (clang_getCursorKind(cur) == CXCursor_InclusionDirective)
|
||||||
{
|
{
|
||||||
|
|
@ -439,10 +443,14 @@ std::unique_ptr<cpp_file> libclang_parser::do_parse(const cpp_entity_index& idx,
|
||||||
builder.add_unmatched_comment(std::move(c.comment));
|
builder.add_unmatched_comment(std::move(c.comment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.error)
|
||||||
|
set_error();
|
||||||
|
|
||||||
return builder.finish(idx);
|
return builder.finish(idx);
|
||||||
}
|
}
|
||||||
catch (detail::parse_error& ex)
|
catch (detail::parse_error& ex)
|
||||||
{
|
{
|
||||||
logger().log("libclang parser", ex.get_diagnostic());
|
logger().log("libclang parser", ex.get_diagnostic());
|
||||||
|
set_error();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -230,11 +230,13 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
|
||||||
}
|
}
|
||||||
catch (parse_error& ex)
|
catch (parse_error& ex)
|
||||||
{
|
{
|
||||||
|
context.error = true;
|
||||||
context.logger->log("libclang parser", ex.get_diagnostic());
|
context.logger->log("libclang parser", ex.get_diagnostic());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
catch (std::logic_error& ex)
|
catch (std::logic_error& ex)
|
||||||
{
|
{
|
||||||
|
context.error = true;
|
||||||
context.logger->log("libclang parser",
|
context.logger->log("libclang parser",
|
||||||
diagnostic{ex.what(), detail::make_location(cur), severity::error});
|
diagnostic{ex.what(), detail::make_location(cur), severity::error});
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ namespace cppast
|
||||||
type_safe::object_ref<const diagnostic_logger> logger;
|
type_safe::object_ref<const diagnostic_logger> logger;
|
||||||
type_safe::object_ref<const cpp_entity_index> idx;
|
type_safe::object_ref<const cpp_entity_index> idx;
|
||||||
comment_context comments;
|
comment_context comments;
|
||||||
|
mutable bool error;
|
||||||
};
|
};
|
||||||
|
|
||||||
// parse default value of variable, function parameter...
|
// parse default value of variable, function parameter...
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,7 @@ using namespace cppast;
|
||||||
|
|
||||||
bool diagnostic_logger::log(const char* source, const diagnostic& d) const
|
bool diagnostic_logger::log(const char* source, const diagnostic& d) const
|
||||||
{
|
{
|
||||||
if (d.severity == severity::error || d.severity == severity::critical)
|
if (!verbose_ && d.severity == severity::debug)
|
||||||
error_ = true;
|
|
||||||
else if (!verbose_ && d.severity == severity::debug)
|
|
||||||
return false;
|
return false;
|
||||||
return do_log(source, d);
|
return do_log(source, d);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ inline std::unique_ptr<cppast::cpp_file> parse_file(const cppast::cpp_entity_ind
|
||||||
|
|
||||||
std::unique_ptr<cppast::cpp_file> result;
|
std::unique_ptr<cppast::cpp_file> result;
|
||||||
REQUIRE_NOTHROW(result = p.parse(idx, name, config));
|
REQUIRE_NOTHROW(result = p.parse(idx, name, config));
|
||||||
REQUIRE(!logger.error_logged());
|
REQUIRE(!p.error());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ std::unique_ptr<cppast::cpp_file> parse_file(const cppast::libclang_compile_conf
|
||||||
cppast::libclang_parser parser(type_safe::ref(logger));
|
cppast::libclang_parser parser(type_safe::ref(logger));
|
||||||
// parse the file
|
// parse the file
|
||||||
auto file = parser.parse(idx, filename, config);
|
auto file = parser.parse(idx, filename, config);
|
||||||
if (fatal_error && logger.error_logged())
|
if (fatal_error && parser.error())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue