[breaking] Move error_logged() from logger to parser

This commit is contained in:
Jonathan Müller 2017-06-27 10:58:24 +02:00
commit 44708fff76
9 changed files with 47 additions and 20 deletions

View file

@ -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

View file

@ -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});
} }

View file

@ -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});

View file

@ -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;
} }

View file

@ -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;

View file

@ -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...

View file

@ -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);
} }

View file

@ -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;
} }

View file

@ -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;
} }