Added generate_message_comments configuration option
This commit is contained in:
@@ -849,4 +849,30 @@ bool parse_source_location(const std::string &location_str, std::string &file,
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<std::string> get_expression_comment(
|
||||
const clang::SourceManager &sm, const clang::ASTContext &context,
|
||||
const clang::Stmt *stmt)
|
||||
{
|
||||
// First get the first line of the expression
|
||||
auto expr_begin = stmt->getSourceRange().getBegin();
|
||||
const auto expr_begin_line = sm.getSpellingLineNumber(expr_begin);
|
||||
|
||||
if (!context.Comments.empty())
|
||||
for (const auto [offset, raw_comment] :
|
||||
*context.Comments.getCommentsInFile(sm.getMainFileID())) {
|
||||
|
||||
auto comment =
|
||||
raw_comment->getFormattedText(sm, sm.getDiagnostics());
|
||||
|
||||
const auto comment_end_line = sm.getSpellingLineNumber(
|
||||
raw_comment->getSourceRange().getEnd());
|
||||
|
||||
if (expr_begin_line == comment_end_line ||
|
||||
expr_begin_line == comment_end_line + 1)
|
||||
return comment;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace clanguml::common
|
||||
|
||||
@@ -282,4 +282,8 @@ clang::QualType dereference(clang::QualType type);
|
||||
std::pair<clang::QualType, std::deque<common::model::context>>
|
||||
consume_type_context(clang::QualType type);
|
||||
|
||||
std::optional<std::string> get_expression_comment(
|
||||
const clang::SourceManager &sm, const clang::ASTContext &context,
|
||||
const clang::Stmt *stmt);
|
||||
|
||||
} // namespace clanguml::common
|
||||
|
||||
@@ -480,6 +480,7 @@ struct inheritable_diagram_options {
|
||||
option<bool> generate_condition_statements{
|
||||
"generate_condition_statements", false};
|
||||
option<std::vector<std::string>> participants_order{"participants_order"};
|
||||
option<bool> generate_message_comments{"generate_message_comments", false};
|
||||
option<bool> debug_mode{"debug_mode", false};
|
||||
option<bool> generate_metadata{"generate_metadata", true};
|
||||
|
||||
|
||||
@@ -201,6 +201,7 @@ types:
|
||||
combine_free_functions_into_file_participants: !optional bool
|
||||
generate_return_types: !optional bool
|
||||
generate_condition_statements: !optional bool
|
||||
generate_message_comments: !optional bool
|
||||
participants_order: !optional [string]
|
||||
start_from: !optional [source_location_t] # deprecated -> 'from'
|
||||
from: !optional [source_location_t]
|
||||
@@ -311,6 +312,7 @@ root:
|
||||
combine_free_functions_into_file_participants: !optional bool
|
||||
generate_return_types: !optional bool
|
||||
generate_condition_statements: !optional bool
|
||||
generate_message_comments: !optional bool
|
||||
generate_packages: !optional bool
|
||||
group_methods: !optional bool
|
||||
package_type: !optional package_type_t
|
||||
|
||||
@@ -603,6 +603,7 @@ template <> struct convert<sequence_diagram> {
|
||||
get_option(node, rhs.relative_to);
|
||||
get_option(node, rhs.participants_order);
|
||||
get_option(node, rhs.generate_method_arguments);
|
||||
get_option(node, rhs.generate_message_comments);
|
||||
|
||||
// Ensure relative_to has a value
|
||||
if (!rhs.relative_to.has_value)
|
||||
@@ -792,6 +793,7 @@ template <> struct convert<config> {
|
||||
get_option(node, rhs.combine_free_functions_into_file_participants);
|
||||
get_option(node, rhs.generate_return_types);
|
||||
get_option(node, rhs.generate_condition_statements);
|
||||
get_option(node, rhs.generate_message_comments);
|
||||
|
||||
rhs.base_directory.set(node["__parent_path"].as<std::string>());
|
||||
get_option(node, rhs.relative_to);
|
||||
|
||||
@@ -325,6 +325,7 @@ YAML::Emitter &operator<<(
|
||||
out << c.generate_method_arguments;
|
||||
out << c.generate_return_types;
|
||||
out << c.participants_order;
|
||||
out << c.generate_message_comments;
|
||||
}
|
||||
else if (const auto *pd = dynamic_cast<const package_diagram *>(&c);
|
||||
pd != nullptr) {
|
||||
|
||||
@@ -83,6 +83,8 @@ void generator::generate_call(const message &m, std::ostream &ostr) const
|
||||
|
||||
print_debug(m, ostr);
|
||||
|
||||
generate_message_comment(ostr, m);
|
||||
|
||||
ostr << from_alias << " "
|
||||
<< common::generators::plantuml::to_plantuml(message_t::kCall) << " ";
|
||||
|
||||
@@ -178,6 +180,7 @@ void generator::generate_activity(const activity &a, std::ostream &ostr,
|
||||
}
|
||||
else if (m.type() == message_t::kIf) {
|
||||
print_debug(m, ostr);
|
||||
generate_message_comment(ostr, m);
|
||||
ostr << "alt";
|
||||
if (const auto &text = m.condition_text(); text.has_value())
|
||||
ostr << " " << text.value();
|
||||
@@ -199,6 +202,7 @@ void generator::generate_activity(const activity &a, std::ostream &ostr,
|
||||
}
|
||||
else if (m.type() == message_t::kWhile) {
|
||||
print_debug(m, ostr);
|
||||
generate_message_comment(ostr, m);
|
||||
ostr << "loop";
|
||||
if (const auto &text = m.condition_text(); text.has_value())
|
||||
ostr << " " << text.value();
|
||||
@@ -209,6 +213,7 @@ void generator::generate_activity(const activity &a, std::ostream &ostr,
|
||||
}
|
||||
else if (m.type() == message_t::kFor) {
|
||||
print_debug(m, ostr);
|
||||
generate_message_comment(ostr, m);
|
||||
ostr << "loop";
|
||||
if (const auto &text = m.condition_text(); text.has_value())
|
||||
ostr << " " << text.value();
|
||||
@@ -219,6 +224,7 @@ void generator::generate_activity(const activity &a, std::ostream &ostr,
|
||||
}
|
||||
else if (m.type() == message_t::kDo) {
|
||||
print_debug(m, ostr);
|
||||
generate_message_comment(ostr, m);
|
||||
ostr << "loop";
|
||||
if (const auto &text = m.condition_text(); text.has_value())
|
||||
ostr << " " << text.value();
|
||||
@@ -229,6 +235,7 @@ void generator::generate_activity(const activity &a, std::ostream &ostr,
|
||||
}
|
||||
else if (m.type() == message_t::kTry) {
|
||||
print_debug(m, ostr);
|
||||
generate_message_comment(ostr, m);
|
||||
ostr << "group try\n";
|
||||
}
|
||||
else if (m.type() == message_t::kCatch) {
|
||||
@@ -241,6 +248,7 @@ void generator::generate_activity(const activity &a, std::ostream &ostr,
|
||||
}
|
||||
else if (m.type() == message_t::kSwitch) {
|
||||
print_debug(m, ostr);
|
||||
generate_message_comment(ostr, m);
|
||||
ostr << "group switch\n";
|
||||
}
|
||||
else if (m.type() == message_t::kCase) {
|
||||
@@ -252,6 +260,7 @@ void generator::generate_activity(const activity &a, std::ostream &ostr,
|
||||
}
|
||||
else if (m.type() == message_t::kConditional) {
|
||||
print_debug(m, ostr);
|
||||
generate_message_comment(ostr, m);
|
||||
ostr << "alt";
|
||||
if (const auto &text = m.condition_text(); text.has_value())
|
||||
ostr << " " << text.value();
|
||||
@@ -267,6 +276,33 @@ void generator::generate_activity(const activity &a, std::ostream &ostr,
|
||||
}
|
||||
}
|
||||
|
||||
void generator::generate_message_comment(
|
||||
std::ostream &ostr, const model::message &m) const
|
||||
{
|
||||
if (!config().generate_message_comments() || !m.comment())
|
||||
return;
|
||||
|
||||
const auto &from = model().get_participant<model::participant>(m.from());
|
||||
|
||||
if (!from)
|
||||
return;
|
||||
|
||||
if (m.type() == message_t::kCall) {
|
||||
const auto &to = model().get_participant<model::participant>(m.to());
|
||||
if (!to)
|
||||
return;
|
||||
|
||||
ostr << "note over " << generate_alias(from.value()) << ", "
|
||||
<< generate_alias(to.value()) << '\n';
|
||||
}
|
||||
else {
|
||||
ostr << "note over " << generate_alias(from.value()) << '\n';
|
||||
}
|
||||
|
||||
ostr << m.comment().value() << '\n';
|
||||
ostr << "end note" << '\n';
|
||||
}
|
||||
|
||||
void generator::generate_participant(
|
||||
std::ostream &ostr, const std::string &name) const
|
||||
{
|
||||
|
||||
@@ -147,6 +147,9 @@ private:
|
||||
model::function::message_render_mode
|
||||
select_method_arguments_render_mode() const;
|
||||
|
||||
void generate_message_comment(
|
||||
std::ostream &ostr, const model::message &m) const;
|
||||
|
||||
mutable std::set<common::id_t> generated_participants_;
|
||||
mutable std::vector<model::message> already_generated_in_static_context_;
|
||||
};
|
||||
|
||||
@@ -58,6 +58,16 @@ void message::set_return_type(std::string t) { return_type_ = std::move(t); }
|
||||
|
||||
const std::string &message::return_type() const { return return_type_; }
|
||||
|
||||
const std::optional<std::string> &message::comment() const { return comment_; }
|
||||
|
||||
void message::set_comment(std::string c) { comment_ = std::move(c); }
|
||||
|
||||
void message::set_comment(const std::optional<std::string> &c)
|
||||
{
|
||||
if (c)
|
||||
set_comment(c.value());
|
||||
}
|
||||
|
||||
void message::set_message_scope(common::model::message_scope_t scope)
|
||||
{
|
||||
scope_ = scope;
|
||||
|
||||
@@ -119,6 +119,12 @@ public:
|
||||
*/
|
||||
const std::string &return_type() const;
|
||||
|
||||
const std::optional<std::string> &comment() const;
|
||||
|
||||
void set_comment(std::string c);
|
||||
|
||||
void set_comment(const std::optional<std::string> &c);
|
||||
|
||||
/**
|
||||
* @brief Set message scope
|
||||
*
|
||||
@@ -172,6 +178,8 @@ private:
|
||||
|
||||
std::optional<std::string> condition_text_;
|
||||
|
||||
std::optional<std::string> comment_;
|
||||
|
||||
bool in_static_declaration_context_{false};
|
||||
};
|
||||
|
||||
|
||||
@@ -613,6 +613,8 @@ bool translation_unit_visitor::TraverseIfStmt(clang::IfStmt *stmt)
|
||||
message m{message_t::kElseIf, current_caller_id};
|
||||
set_source_location(*stmt, m);
|
||||
m.condition_text(condition_text);
|
||||
m.set_comment(clanguml::common::get_expression_comment(
|
||||
source_manager(), *context().get_ast_context(), stmt));
|
||||
diagram().add_block_message(std::move(m));
|
||||
}
|
||||
else {
|
||||
@@ -621,6 +623,8 @@ bool translation_unit_visitor::TraverseIfStmt(clang::IfStmt *stmt)
|
||||
message m{message_t::kIf, current_caller_id};
|
||||
set_source_location(*stmt, m);
|
||||
m.condition_text(condition_text);
|
||||
m.set_comment(clanguml::common::get_expression_comment(
|
||||
source_manager(), *context().get_ast_context(), stmt));
|
||||
diagram().add_block_message(std::move(m));
|
||||
}
|
||||
}
|
||||
@@ -655,6 +659,8 @@ bool translation_unit_visitor::TraverseWhileStmt(clang::WhileStmt *stmt)
|
||||
message m{message_t::kWhile, current_caller_id};
|
||||
set_source_location(*stmt, m);
|
||||
m.condition_text(condition_text);
|
||||
m.set_comment(clanguml::common::get_expression_comment(
|
||||
source_manager(), *context().get_ast_context(), stmt));
|
||||
diagram().add_block_message(std::move(m));
|
||||
}
|
||||
RecursiveASTVisitor<translation_unit_visitor>::TraverseWhileStmt(stmt);
|
||||
@@ -685,6 +691,8 @@ bool translation_unit_visitor::TraverseDoStmt(clang::DoStmt *stmt)
|
||||
message m{message_t::kDo, current_caller_id};
|
||||
set_source_location(*stmt, m);
|
||||
m.condition_text(condition_text);
|
||||
m.set_comment(clanguml::common::get_expression_comment(
|
||||
source_manager(), *context().get_ast_context(), stmt));
|
||||
diagram().add_block_message(std::move(m));
|
||||
}
|
||||
|
||||
@@ -716,6 +724,10 @@ bool translation_unit_visitor::TraverseForStmt(clang::ForStmt *stmt)
|
||||
message m{message_t::kFor, current_caller_id};
|
||||
set_source_location(*stmt, m);
|
||||
m.condition_text(condition_text);
|
||||
|
||||
m.set_comment(clanguml::common::get_expression_comment(
|
||||
source_manager(), *context().get_ast_context(), stmt));
|
||||
|
||||
diagram().add_block_message(std::move(m));
|
||||
}
|
||||
|
||||
@@ -742,6 +754,8 @@ bool translation_unit_visitor::TraverseCXXTryStmt(clang::CXXTryStmt *stmt)
|
||||
context().enter_trystmt(stmt);
|
||||
message m{message_t::kTry, current_caller_id};
|
||||
set_source_location(*stmt, m);
|
||||
m.set_comment(clanguml::common::get_expression_comment(
|
||||
source_manager(), *context().get_ast_context(), stmt));
|
||||
diagram().add_block_message(std::move(m));
|
||||
}
|
||||
|
||||
@@ -800,6 +814,8 @@ bool translation_unit_visitor::TraverseCXXForRangeStmt(
|
||||
message m{message_t::kFor, current_caller_id};
|
||||
set_source_location(*stmt, m);
|
||||
m.condition_text(condition_text);
|
||||
m.set_comment(clanguml::common::get_expression_comment(
|
||||
source_manager(), *context().get_ast_context(), stmt));
|
||||
diagram().add_block_message(std::move(m));
|
||||
}
|
||||
|
||||
@@ -825,6 +841,8 @@ bool translation_unit_visitor::TraverseSwitchStmt(clang::SwitchStmt *stmt)
|
||||
context().enter_switchstmt(stmt);
|
||||
model::message m{message_t::kSwitch, current_caller_id};
|
||||
set_source_location(*stmt, m);
|
||||
m.set_comment(clanguml::common::get_expression_comment(
|
||||
source_manager(), *context().get_ast_context(), stmt));
|
||||
diagram().add_block_message(std::move(m));
|
||||
}
|
||||
|
||||
@@ -891,6 +909,8 @@ bool translation_unit_visitor::TraverseConditionalOperator(
|
||||
model::message m{message_t::kConditional, current_caller_id};
|
||||
set_source_location(*stmt, m);
|
||||
m.condition_text(condition_text);
|
||||
m.set_comment(clanguml::common::get_expression_comment(
|
||||
source_manager(), *context().get_ast_context(), stmt));
|
||||
diagram().add_block_message(std::move(m));
|
||||
}
|
||||
|
||||
@@ -1015,6 +1035,10 @@ bool translation_unit_visitor::VisitCallExpr(clang::CallExpr *expr)
|
||||
}
|
||||
|
||||
if (m.from() > 0 && m.to() > 0) {
|
||||
auto expr_comment = clanguml::common::get_expression_comment(
|
||||
source_manager(), *context().get_ast_context(), expr);
|
||||
m.set_comment(expr_comment);
|
||||
|
||||
if (diagram().sequences().find(m.from()) ==
|
||||
diagram().sequences().end()) {
|
||||
activity a{m.from()};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
compilation_database_dir: ..
|
||||
output_directory: diagrams
|
||||
add_compile_flags:
|
||||
- -fparse-all-comments
|
||||
diagrams:
|
||||
t20029_sequence:
|
||||
type: sequence
|
||||
@@ -15,6 +17,7 @@ diagrams:
|
||||
- clanguml::t20029
|
||||
from:
|
||||
- function: clanguml::t20029::tmain()
|
||||
generate_message_comments: true
|
||||
participants_order:
|
||||
- clanguml::t20029::tmain()
|
||||
- clanguml::t20029::Encoder<clanguml::t20029::Retrier<clanguml::t20029::ConnectionPool>>
|
||||
|
||||
@@ -56,8 +56,10 @@ int tmain()
|
||||
{
|
||||
auto pool = std::make_shared<Encoder<Retrier<ConnectionPool>>>();
|
||||
|
||||
// Establish connection to the remote server synchronously
|
||||
pool->connect();
|
||||
|
||||
// Repeat for each line in the input stream
|
||||
for (std::string line; std::getline(std::cin, line);) {
|
||||
if (!pool->send(std::move(line)))
|
||||
break;
|
||||
|
||||
@@ -46,6 +46,11 @@ load_config(const std::string &test_name)
|
||||
LOG_DBG("Loading compilation database from {}",
|
||||
res.first.compilation_database_dir());
|
||||
|
||||
std::vector<std::string> remove_compile_flags{
|
||||
std::string{"-Wno-class-memaccess"}};
|
||||
|
||||
res.first.remove_compile_flags.set(remove_compile_flags);
|
||||
|
||||
res.second =
|
||||
clanguml::common::compilation_database::auto_detect_from_directory(
|
||||
res.first);
|
||||
|
||||
Reference in New Issue
Block a user